Store developer SSH keys and API secrets in Vault's KV v2 secrets engine, and inject them at runtime via Vault Agent sidecar or environment‑variable templating.
1. Enable KV v2
```hcl
vault secrets enable -path=secret kv-v2
```
2. Write secrets (use ssh_key and api_token fields)
```bash
vault kv put secret/dev/app ssh_key=@id_rsa api_token=$(cat token.txt)
```
3. Create a policy restricting access to the path
```hcl
path "secret/data/dev/app" {
capabilities = ["read"]
}
```
```bash
vault policy write app-read app-policy.hcl
```
4. Generate a short‑lived token for CI/CD
```bash
vault token create -policy=app-read -ttl=30m -orphan
```
5. Configure Vault Agent sidecar (template renders env file)
```hcl
pid_file = "/tmp/vault-agent.pid"
auto_auth {
method "approle" {
mount_path = "auth/approle"
config = {
role_id_file_path = "/etc/vault/role_id"
secret_id_file_path = "/etc/vault/secret_id"
}
}
sink "file" {
config = { path = "/tmp/vault-token" }
}
}
template {
source = "/etc/vault/templates/env.tmpl"
destination = "/app/.env"
}
```
6. Template (env.tmpl)
```gotmpl
SSH_KEY={{ with secret "secret/data/dev/app" }}{{ .Data.data.ssh_key }}{{ end }}
API_TOKEN={{ with secret "secret/data/dev/app" }}{{ .Data.data.api_token }}{{ end }}
```
7. Deploy: run the app container with --env-file /app/.env and the Vault Agent sidecar sharing the network namespace.
Quick comparison
| Injection method | Pros | Cons |
|---|---|---|
| Vault Agent sidecar | Automatic renewal, no code changes | Extra container, slight latency |
| vault kv get -field=... in entry script | Simple, no sidecar | Manual token handling, harder to rotate |
Gotcha: Vault token TTLs shorter than the longest CI job cause auth failures; set max_ttl on the token role to exceed the job’s maximum runtime and enable renewable=true to avoid mid‑run expirations.