# Docker Writer Image

## Overview

The Docker Writer Image for KSM is an image that can download secret files and also generate a file containing secrets.

The image can be pulled with the following command:

```
$ docker pull keeper/keeper-secrets-manager-writer
```

When run, its parameters are passed in via environmental variables.

```
$ docker run \
    -v $PWD:/wd --workdir /wd \
    -e "KSM_CONFIG=BASE64 CONFIG" \
    -e "SECRETS=JfXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt"
    keeper/keeper-secrets-manager-writer
```

{% hint style="info" %}
The writer is used to copy files from the vault and to create files containing secrets. Due to writing information to disk, there is always risk of exposure. An alternative is the [keeper/keeper-secrets-manager-cli](https://github.com/Keeper-Security/gitbook-secrets-manager/blob/master/keeperpam/secrets-manager/secrets-manager-command-line-interface/docker-container/README.md) image and the `exec` command.
{% endhint %}

## Parameters

The parameters are handled by passing environment variables into the container.

| Parameter           | Description                                                                                                                                   |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `KSM_CONFIG`        | A base64 encode configuration file.                                                                                                           |
| `SECRETS`           | A line-feed separated list of Keeper notation and destinations.                                                                               |
| `SECRETS_FILE`      | A filename to write the non-file destination secrets.                                                                                         |
| `SECRETS_FILE_TYPE` | The format of the secrets file. Valid format are export, setenv, set, and JSON. JSON is the default.                                          |
| `CLEANUP_FILE`      | If set, all files created will be added to the shell file to be removed when executed. This file can be executed to remove the files created. |

## Secrets List

The `SECRETS` are a list of Keeper Notation and destinations. The values are separated by line feeds. For example:

```
fXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt
cl9a9k0DWP-Iy227rBo5gQ/field/login > MY_LOGIN
gpsBL343CVYMFgOKZ-L2hQ/custom_field/Ip Address > IP_ADDR
```

Each line is "[Keeper Notation](https://github.com/Keeper-Security/gitbook-secrets-manager/blob/master/keeperpam/secrets-manager/about/keeper-notation/README.md) > destination". The destination can be either an environmental variable/JSON key or a file path and name. If a file, the path is prefixed with the text `file:`. It is recommended not to place binary data into an environmental variable due to unknown string encoding.

### Secret File Type

The secrets file contains the values of the environmental variable `SECRETS`. The format of the file is based on the value of `SECRETS_FILE_TYPE`. The type can be the following values:

* **json** - Values stored in a JSON format.
* **export** - Values stored as export commands commonly used with a BASH shell.
* **setenv** - Values stored as setenv commands commonly used with C shell.
* **set** - Values stored as set commands commonly used with C shell.

The types related to a shell can be sourced to place the secrets into the environment.

## Examples

The Docker Writer Image for KSM can be used for many applications. Here are some examples.

### Kubernetes

The writer image is best used in an [Init Container](https://kubernetes.io/docs/concepts/workloads/pods/init-containers/).

```
 initContainers:
    - name: my_app
      image: keeper/keeper-secrets-manager-writer:latest
      env:
        - name: SECRETS
          value: |
            qCAw9dMQgr3Hs7EdfFpfkA/field/password > my_password
            qCAw9dMQgr3Hs7EdfFpfkA/file/exmaple.crt > file:/etc/keys/example.crt
            qCAw9dMQgr3Hs7EdfFpfkA/file/exmaple.key > file:/etc/keys/example.key
```

In this container, the writer image is used to save a file and create a secrets file that the main container can access. This can be done by mounting a volume, writing the files, and then having the main container mount the same value. The pod's emptyDir is a good choice.

### Docker Compose

By using the `depends_on` options in the **main** service, the Docker Writer Image for KSM can be used in the initialization service. In the example below, the Docker Writer pulls secrets from the vault and shares them on a volume mount to the main image.

```
---
version: "2"
services:
  init:
    image: keeper/keeper-secrets-manager-writer:latest
    environment:
      KSM_CONFIG: R2VwWTVDS ... dmVyUHVibGljS2V5SWQiOiAiMTAiCn0=
      SECRETS: |
        qCAw9dMQgr3Hs7EdfFpfkA/field/password > file:/etc/keys/global.pass
        qCAw9dMQgr3Hs7EdfFpfkA/file/myserver.crt > file:/etc/keys/myserver.crt
        qCAw9dMQgr3Hs7EdfFpfkA/file/myserver.key > file:/etc/keys/myserver.key
    volumes:
      - keys-volume:/etc/keys
  main:
    image: nginx
    restart: always
    volumes:
     - ./config:/etc/nginx/conf.d
     - keys-volume:/etc/keys
    ports:
     - "80:80"
     - "443:443"
    environment:
     - NGINX_HOST=example.com
    depends_on:
      init:
        condition: service_completed_successfully
volumes:
  keys-volume:
```

Normally services start in parallel, however by using the `depends_on` option the service startup can be controlled. In the above, the **main** service depends on the **init** service.

The **init** service will start, retrieve and save the files into the keys-volume, then exit. By using the condition `service_completed_successfully`, when the **init** service successfully exits, it will start the **main** service. The **main** service will also mount the `keys-volume` and use the stored keys.

### Docker Command Line

The writer image can be executed in the command line by using `docker run`.

```
docker run \
    -v $PWD:/wd --workdir /wd \
    -e "KSM_CONIFG=BASE64 CONFIG" \
    -e "SECRETS=JfXpSQ2nZG6lkdl1rxB0dg/file/example.crt > file:example.crt"
    keeper/keeper-secrets-manager-writer
```

If `SECRETS` has multiple secrets, the line-feed character (\n) is hard to represent. The solution is to surround the `--env,-e` value with $". For example

```
-e $'SECRETS=V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png > file:my.png\nIumwT1QYRr8TTCtY8rqzhw/custom_field/S3_BUCKET > s3'
```

Between **file:my.png** and the next record UID, there is a '\n'. If you don't wrap the entire value with $'' the my.png file name will include the escape line feed and the next record UID.

###
