|
1 | | -# Run commands using parameters stored in SSM |
| 1 | +# Sesame |
2 | 2 |
|
3 | | -# USAGE |
| 3 | +Run commands with secrets fetched from AWS Systems Manager Parameter Store. |
4 | 4 |
|
5 | | -``` |
6 | | -Usage: |
7 | | - sesame [--verbose][--human][--configuration CONFIG_FILE] -- <CMD> |
8 | | -
|
9 | | -Options: |
10 | | - -V, --version print version and exit |
11 | | - -v, --verbose Set debug output |
12 | | - -H, --human Use humanly read-able logs, default is JSON |
13 | | - -c, --configuration CONFIG_FILE configuration file to read |
| 5 | +Sesame fetches parameters by path recursively and by explicit name, injects |
| 6 | +them as environment variables, then executes the target command. No secrets |
| 7 | +written to disk, no scripts to maintain. |
14 | 8 |
|
15 | | -AWS environment variables: |
| 9 | +# Quick start |
16 | 10 |
|
17 | | -- AWS_PROFILE |
18 | | -- AWS_REGION |
19 | | -- AWS_ACCESS_KEY |
20 | | -- AWS_SECRET_KEY |
| 11 | +```toml |
| 12 | +# sesame.toml |
| 13 | +prefix = "/myapp/production" |
| 14 | +secrets = [ |
| 15 | + "/myapp/production/DB_PASSWORD", |
| 16 | + "/myapp/production/API_KEY", |
| 17 | +] |
| 18 | +``` |
21 | 19 |
|
22 | | -Example: |
23 | | - sesame -c /config.toml -- bash -c env |
24 | | - sesame -v -- python main.py |
| 20 | +```sh |
| 21 | +sesame -c sesame.toml -- python main.py |
25 | 22 | ``` |
26 | 23 |
|
27 | | -# Containers' Entrypoint |
| 24 | +The application `main.py` will have `API_KEY` and `DB_PASSWORD` available as |
| 25 | +environment variables. |
| 26 | + |
| 27 | +# Configuration |
| 28 | + |
| 29 | +## File format |
28 | 30 |
|
29 | | -```docker |
30 | | -FROM scratch |
31 | | -COPY sesame /sesame |
32 | | -COPY sesame.toml /sesame.toml |
33 | | -COPY app /app |
34 | | -ENTRYPOINT ["/sesame", "-c", "/sesame.toml", "--"] |
35 | | -CMD ["/app", "-x"] |
| 31 | +```toml |
| 32 | +prefix = "/myapp/staging" |
| 33 | +secrets = [ |
| 34 | + "/myapp/staging/DB_USER", |
| 35 | + "/myapp/staging/DB_PASSWORD", |
| 36 | +] |
36 | 37 | ``` |
37 | 38 |
|
38 | | -# Configuration file |
| 39 | +- `prefix`: SSM path. Sesame will fetch all parameters under this path |
| 40 | + recursively. |
| 41 | +- `secrets`: explicit list of full parameter names. This is a limitation of the |
| 42 | + AWS APIs. |
| 43 | + |
| 44 | +## Env var expansion |
39 | 45 |
|
40 | | -All configuration values will be parsed and expanded with the current |
41 | | -environment variables. In the example below, the command has access to |
42 | | -`$PROJECT`, `$ENVIRONMENT` and `$SERVICE_NAME` environment variables. The |
43 | | -resulting calls to the AWS API will be, for example, |
44 | | -`proj/production/web-api-01` |
| 46 | +Configuration supports `$VAR` and `${VAR}` syntax for both parameter prefix and |
| 47 | +secret names: |
45 | 48 |
|
46 | 49 | ```toml |
47 | | -prefix = "$PROJECT/$ENVIRONMENT/$SERVICE_NAME" |
| 50 | +prefix = "$PROJECT/$ENV/$SERVICE" |
48 | 51 | secrets = [ |
49 | | - "$PROJECT/$ENVIRONMENT/$SERVICE_NAME/DB_USER", |
50 | | - "$PROJECT/$ENVIRONMENT/$SERVICE_NAME/DB_PASSWORD", |
51 | | - "$PROJECT/$ENVIRONMENT/$SERVICE_NAME/API_SECRET", |
52 | | - "$PROJECT/$ENVIRONMENT/$SERVICE_NAME/API_CERTIFICATE", |
| 52 | + "$PROJECT/$ENV/$SERVICE/DB_PASSWORD", |
53 | 53 | ] |
54 | 54 | ``` |
55 | 55 |
|
56 | | -# LICENSE |
| 56 | +**NOTE**: If any variable is unset it expands to an empty string. |
| 57 | + |
| 58 | +# Requirements |
| 59 | + |
| 60 | +Sesame uses AWS's SDK default authentication chain. |
| 61 | + |
| 62 | +## IAM policy |
| 63 | + |
| 64 | +The executing principal (via instance role, ECS task role, or explicit keys) requires: |
| 65 | + |
| 66 | +```json |
| 67 | +{ |
| 68 | + "Version": "2012-10-17", |
| 69 | + "Statement": [ |
| 70 | + { |
| 71 | + "Effect": "Allow", |
| 72 | + "Action": [ |
| 73 | + "ssm:GetParametersByPath", |
| 74 | + "ssm:GetParameters" |
| 75 | + ], |
| 76 | + "Resource": "arn:aws:ssm:*:*:parameter/myapp/*" |
| 77 | + } |
| 78 | + ] |
| 79 | +} |
| 80 | +``` |
| 81 | + |
| 82 | +`GetParametersByPath` requires `WithDecryption` if parameters are |
| 83 | +SecureStrings. The policy above works for both encrypted and unencrypted |
| 84 | +parameters. |
| 85 | + |
| 86 | +**IMPORTANT**: The application also requires `kms:Decrypt` on the right key to |
| 87 | +decrypt secrets and parameters. |
| 88 | + |
| 89 | +# Command line |
| 90 | + |
| 91 | +``` |
| 92 | +sesame [flags] -- <CMD> [ARGS...] |
| 93 | +
|
| 94 | +Flags: |
| 95 | + -V, --version print version and exit |
| 96 | + -v, --verbose debug output (JSON) |
| 97 | + -H, --human human-readable logs (text) |
| 98 | + -c, --config FILE config file path (default: sesame.toml) |
| 99 | +``` |
| 100 | + |
| 101 | +> **Important** |
| 102 | +> |
| 103 | +> `--` separates sesame flags from the command. Everything after `--` is passed to `execve` unchanged. |
| 104 | +
|
| 105 | +# How it works |
| 106 | + |
| 107 | +1. Read and parse the configuration. Expand environment variables in |
| 108 | + secret/parameters keys. |
| 109 | +2. Call `GetParametersByPath` recursively under `prefix`. |
| 110 | +3. Call `GetParameters` for each item in `secrets` (requests are performed in |
| 111 | + batches of 10 secrets). |
| 112 | +4. Expose the values of parameters and secrets as environment variables. |
| 113 | +5. Call `syscall.Exec` to execute and handover the environment to the |
| 114 | + application. |
| 115 | + |
| 116 | +Sesame dies when calling the application freeing used resources and giving |
| 117 | +control to the child application. |
| 118 | + |
| 119 | +# Security notes |
| 120 | + |
| 121 | +- Secrets travel from AWS to the process env, never to disk. |
| 122 | +- The parent process is replaced by the child. |
| 123 | +- Access is controlled by IAM alone, applications should have |
| 124 | +- If the config file is user-controlled, `$VAR` expansion lets them override any env var present at startup. Restrict file permissions on `sesame.toml`. |
| 125 | + |
| 126 | +# License |
57 | 127 |
|
58 | 128 | [MIT-0](./LICENSE) |
0 commit comments