Overview

The pk sh command runs processes with injected OS environment variables. You can also mount config files containing sensitive information to temporary storage. This works any cli tools, e.g "aws", "bash", "zsh", "kubectl", "docker", "docker-compose" and any process you can run from the commandline.

e.g Running bash

pk sh -s dev -n myenv,devenv -- bash
This command will download the environments "myenv" and "devenv", create a new child OS process (here running bash) and make the key=val pairs in the environments available as OS environment variables to the process.

Requirements

We assume you have:

Use case

In this use case we are going to write a small python app that read AWS keys from environment variables and a database url with user name and password from a file. The app won't actually connect to AWS or a DB and the aim is to show how you can securely pass credentials either via OS variables or temporary files. Note: Always prefer environment variables over files, file access is process global on the same machine while while environment variables are limited to the child processes.

1. Lets write our small app

#!/usr/bin/env python

import os
import time
import yaml


def read_config():
    '''
    this function is deliberately simple for example purposes.
    '''
    aws_key = os.environ['AWS_ACCESS_KEY_ID']
    aws_secret = os.environ['AWS_SECRET_ACCESS_KEY']

    with open(os.environ['CONF'], 'r') as f:
        db_conf = yaml.safe_load(f)

    return {'aws_key': aws_key,
            'aws_secret': aws_secret,
            'db': db_conf['db']}


if __name__ == '__main__':
    conf = read_config()

    db = conf['db']

    print("This is a demo script, we print secret info to stdout for example purposes")
    print("Downloading from db: '{}' user '{}' pwd '{}'".format(db['url'], db['user'], db['password']))
    time.sleep(1)

    print("Uploading to aws s3 with keys: '{}'/'{}'".format(conf['aws_key'], conf['aws_secret']))

Step 2: Create the pk environments

  • Create an environment named dev-env
  • Create an environment named db-conf

Step 3: Run our app with "pk sh"

pk sh  -s myorg -n dev-env -v db-dev-conf:CONF python dbapp.py
The pk sh command takes:
    • "-s" [safe] => The pk safe you have created the environment in
      "-n" [env] => The pk environment that contains the VAR=val pairs
      "-v" [volume]:[ENV_VAR] => The pk environment that you want to mount as a file, and make path available to the specified environment variable.
  • In the example above example the environment variables "AWS_ACCESS_KEY_ID", and "AWS_SECRET_ACCESS_KEY" are specified in the "dev-env" environment and made available as OS environment variables to the python process.

    The yaml configuration in the "db-dev-conf" environment is mounted as a temporary file ( written to temporary in-memory storage and with a random file name), and its file name is set to the environment variable CONF (we can specify any variable name here). The python scripts reads the yaml configuration from the file specified in CONF.

    Summary

    In this use case we have shown how to download encrypted secret information as environment variables or mount configuration that contain secret information as files.

    As an example we have used a simple python script, but any software that runs from a terminal can be used here.

    TIP:
    If you are going to run the command multiple times or multiple different commands it works best to enter a bash/zsh shell from the pk sh command and then run the commands. Please remember to use the "-i" flag for interactive commands.
    For example:
    pk sh  -s myorg -n dev-env -v db-dev-conf:CONF -i -- bash
    python dbapp.py