Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use LookPath #8

Merged
merged 1 commit into from
Jun 7, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM amazonlinux:2

ADD https://github.com/s12v/exec-with-secrets/releases/download/v0.4.0/exec-with-secrets-linux-amd64 /exec-with-secrets
ADD https://github.com/s12v/exec-with-secrets/releases/latest/download/exec-with-secrets-linux-amd64 /exec-with-secrets

RUN chmod +x /exec-with-secrets

Expand Down
62 changes: 27 additions & 35 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,60 @@
[![Build Status](https://travis-ci.com/s12v/exec-with-secrets.svg?branch=master)](https://travis-ci.com/s12v/exec-with-secrets)
[![codecov](https://codecov.io/gh/s12v/exec-with-secrets/branch/master/graph/badge.svg)](https://codecov.io/gh/s12v/exec-with-secrets)

# Pass secrets from AWS KMS/SSM/Secrets Manager or Azure Key Vault into your app environment
# Inject secrets from AWS KMS/SSM/Secrets Manager and Azure Key Vault into your app environment

`exec-with-secrets` it supports the following services as secrets providers:
`exec-with-secrets` supports the following services as secrets providers:
- [AWS Key Management (KMS)](https://aws.amazon.com/kms/)
- [AWS Systems Manager Parameter Store (SSM)](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html)
- [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/)
- [Azure Key Vault](https://azure.microsoft.com/en-in/services/key-vault/)

This small utility looks for prefixed variables in environment and replaces them with the secret value:
This utility looks for prefixed variables in environment and replaces them with secret values:
- `{aws-kms}AQICAHjA3mwbmf...` - decrypts the value using AWS KMS
- `{aws-ssm}/app/staging/param` - loads parameter `/app/staging/param` from AWS Systems Manager Parameter Store
- `{aws-sm}/app/staging/param` - loads secret `/app/staging/param` from AWS Secrets Manager
- `{aws-sm}/app/staging/param{prop1}` - loads secret `/app/staging/param` from AWS Secrets Manager and takes `prop1` property
- `{aws-ssm}/app/param` - loads parameter `/app/param` from AWS Systems Manager Parameter Store
- `{aws-sm}/app/param` - loads secret `/app/param` from AWS Secrets Manager
- `{aws-sm}/app/param{prop1}` - loads secret `/app/param` from AWS Secrets Manager and takes `prop1` property
- `{az-kv}vault/name` - loads secret `name` from Azure Key Vault `vault`

Then it runs `exec` system call. **The secrets are only available to your application and not accessible with `docker inspect`**
After decrypting secrets it runs [`exec`](https://en.wikipedia.org/wiki/Exec_(system_call) system call, replacing itself with your app.
The app can simply access decrypted secrets in the environment.

Basic example:
```
SECRET="{aws-ssm}/my/secret" exec-with-secrets myapp # $SECRET is plaintext in myapp environment
SECRET="{aws-ssm}/my/secret" exec-with-secrets myapp # SECRET value is in myapp environment
```

Access:
- The default credentials chain is used for AWS access
- Azure authorizer from environment variables/MSI
- Azure authorizer from configuration file, if the file is set using `AZURE_AUTH_LOCATION` variable
## Docker example

## Examples

### Wrap executable
Build the example Docker image:

```
# Download the latest binary
curl -L https://github.com/s12v/exec-with-secrets/releases/download/v0.4.0/exec-with-secrets-darwin-amd64 -o exec-with-secrets
chmod +x ./exec-with-secrets

# Wrap /bin/sh
PARAM="{aws-kms}c2VjcmV0" ./exec-with-secrets /bin/sh -c 'echo $PARAM'
make docker
```

`PARAM` will be decrypted and passed to `/bin/sh` via environment.
Run:
```
docker run -e PARAM="text" -e KMS_PARAM="{aws-kms}c2VjcmV0" exec-with-secrets-example echo $KMS_PARAM
```

### Docker example
You need to put a real KMS-encrypted value and pass AWS credentials to the container.

Build the [example Docker image](Dockerfile):
- `KMS_PARAM` will be decrypted and passed to `echo` as an environment variable
- `PARAM` will be passed without modifications

You can adapt [Dockerfile](Dockerfile) for your use-case. Use `exec-with-secrets` just like the regular `exec`. For example, run a Java application with:
```
make docker
CMD exec-with-secrets java -jar myapp.jar
```
**Note that the decrypted secrets are only visible to your application. `docker inspect` will show encrypted values**

Run:
```
docker run \
-e PLAINTEXT_PARAM="text" \
-e KMS_PARAM="{aws-kms}c2VjcmV0" \
-e SSM_PARAM="{aws-ssm}/myapp/param" \
exec-with-secrets-example \
/bin/env
```
## Secret provider access

`KMS_PARAM` and `SSM_PARAM` will be decrypted and passed to `/bin/env` as environment variables.
Your container should have appropriate permissions to the secrets provider.

- The default AWS credentials chain is used
- Azure authorizer from environment variables/MSI
- Azure authorizer from configuration file, if the file is set using `AZURE_AUTH_LOCATION` variable

## Build

Expand Down
17 changes: 14 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ import (
_ "github.com/s12v/exec-with-secrets/provider/awsssm"
_ "github.com/s12v/exec-with-secrets/provider/azurekeyvault"
"os"
"os/exec"
"syscall"
)

func main() {
defer func() {
if r := recover(); r != nil {
fmt.Println("exec-with-secrets:", r)
os.Exit(1)
}
}()

Expand All @@ -23,9 +25,18 @@ func main() {
os.Exit(0)
}

path := lookPath(os.Args[1])
env := provider.Populate(os.Environ())
_ = syscall.Exec(os.Args[1], os.Args[1:], env)
_ = syscall.Exec(path, os.Args[1:], env)

fmt.Println("exec-with-secrets program: Unable to start", os.Args[1])
os.Exit(1)
panic("Unable to start " + path)
}

func lookPath(name string) string {
path, err := exec.LookPath(name)
if err != nil {
panic(err)
}

return path
}