Skip to content

Commit 4c2484f

Browse files
authored
Merge pull request #2217 from dgageot/board/fix-docker-agent-issue-2216-53081e7f
docs: add Managing Secrets guide
2 parents 09e1ac1 + 1a80806 commit 4c2484f

4 files changed

Lines changed: 245 additions & 1 deletion

File tree

docs/_data/nav.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,8 @@
126126
items:
127127
- title: Tips & Best Practices
128128
url: /guides/tips/
129+
- title: Managing Secrets
130+
url: /guides/secrets/
129131
- title: Go SDK
130132
url: /guides/go-sdk/
131133

docs/configuration/overview/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ Models can be referenced inline or defined in the `models` section:
135135

136136
## Environment Variables
137137

138-
API keys and secrets are read from environment variables — never stored in config files:
138+
API keys and secrets are read from environment variables — never stored in config files. See [Managing Secrets]({{ '/guides/secrets/' | relative_url }}) for all the ways to provide credentials (env files, Docker Compose secrets, macOS Keychain, `pass`):
139139

140140
| Variable | Provider |
141141
| ------------------- | ------------- |

docs/guides/secrets/index.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
title: "Managing Secrets"
3+
description: "How to securely provide API keys and credentials to docker-agent using environment variables, env files, Docker Compose secrets, macOS Keychain, and pass."
4+
permalink: /guides/secrets/
5+
---
6+
7+
# Managing Secrets
8+
9+
_How to securely provide API keys and credentials to docker-agent._
10+
11+
## Overview
12+
13+
docker-agent needs API keys to talk to model providers (OpenAI, Anthropic, etc.) and MCP tool servers (GitHub, Slack, etc.). These keys are **never stored in config files**. Instead, docker-agent resolves them at runtime through a chain of secret providers, checked in order:
14+
15+
| Priority | Provider | Description |
16+
| --- | --- | --- |
17+
| 1 | [Environment variables](#environment-variables) | `export OPENAI_API_KEY=sk-...` |
18+
| 2 | [Docker secrets](#docker-compose-secrets) | Files in `/run/secrets/` |
19+
| 3 | [`pass` password manager](#pass-password-manager) | `pass insert OPENAI_API_KEY` |
20+
| 4 | [macOS Keychain](#macos-keychain) | `security add-generic-password` |
21+
22+
The first provider that has a value wins. You can mix and match — for example, use environment variables for one key and Keychain for another.
23+
24+
## Environment Variables
25+
26+
The simplest approach. Set variables in your shell before running docker-agent:
27+
28+
```bash
29+
export OPENAI_API_KEY=sk-...
30+
export ANTHROPIC_API_KEY=sk-ant-...
31+
docker agent run agent.yaml
32+
```
33+
34+
Common variables:
35+
36+
| Variable | Provider |
37+
| --- | --- |
38+
| `OPENAI_API_KEY` | OpenAI |
39+
| `ANTHROPIC_API_KEY` | Anthropic |
40+
| `GOOGLE_API_KEY` | Google Gemini |
41+
| `MISTRAL_API_KEY` | Mistral |
42+
| `XAI_API_KEY` | xAI |
43+
| `NEBIUS_API_KEY` | Nebius |
44+
45+
MCP tools may require additional variables. For example, the GitHub MCP server needs `GITHUB_PERSONAL_ACCESS_TOKEN`. These are passed to tools via the `env` field in your config:
46+
47+
```yaml
48+
toolsets:
49+
- type: mcp
50+
ref: docker:github-official
51+
env:
52+
GITHUB_PERSONAL_ACCESS_TOKEN: $GITHUB_PERSONAL_ACCESS_TOKEN
53+
```
54+
55+
## Env Files
56+
57+
For convenience, you can store secrets in a `.env` file and pass it to docker-agent with `--env-from-file`:
58+
59+
```bash
60+
# .env
61+
OPENAI_API_KEY=sk-...
62+
ANTHROPIC_API_KEY=sk-ant-...
63+
GITHUB_PERSONAL_ACCESS_TOKEN=ghp_...
64+
```
65+
66+
```bash
67+
docker agent run agent.yaml --env-from-file .env
68+
```
69+
70+
The file format supports:
71+
72+
- `KEY=VALUE` pairs, one per line
73+
- Comments starting with `#`
74+
- Quoted values: `KEY="value with spaces"`
75+
- Blank lines are ignored
76+
77+
<div class="callout callout-warning">
78+
<div class="callout-title">⚠️ Important</div>
79+
<p>Add <code>.env</code> to your <code>.gitignore</code> to avoid committing secrets to version control.</p>
80+
</div>
81+
82+
## Docker Compose Secrets
83+
84+
When running docker-agent in a container with Docker Compose, you can use [Compose secrets](https://docs.docker.com/compose/how-tos/use-secrets/) to inject credentials securely. Compose mounts secrets as files under `/run/secrets/`, and docker-agent reads from this location automatically.
85+
86+
### From a file
87+
88+
Store each secret in its own file, then reference it in `compose.yaml`:
89+
90+
```bash
91+
echo -n "sk-ant-your-key-here" > .anthropic_api_key
92+
```
93+
94+
```yaml
95+
# compose.yaml
96+
services:
97+
agent:
98+
image: docker/docker-agent
99+
command: run --exec /app/agent.yaml "Hello!"
100+
secrets:
101+
- ANTHROPIC_API_KEY
102+
volumes:
103+
- ./agent.yaml:/app/agent.yaml:ro
104+
105+
secrets:
106+
ANTHROPIC_API_KEY:
107+
file: ./.anthropic_api_key
108+
```
109+
110+
Docker Compose mounts the file as `/run/secrets/ANTHROPIC_API_KEY`. docker-agent picks it up with no extra configuration.
111+
112+
### From a host environment variable
113+
114+
In CI/CD pipelines, secrets are often injected as environment variables. Compose can forward these to `/run/secrets/`:
115+
116+
```yaml
117+
secrets:
118+
ANTHROPIC_API_KEY:
119+
environment: "ANTHROPIC_API_KEY"
120+
```
121+
122+
### Multiple secrets
123+
124+
```yaml
125+
services:
126+
agent:
127+
image: docker/docker-agent
128+
command: run --exec /app/agent.yaml "Summarize my GitHub issues"
129+
secrets:
130+
- ANTHROPIC_API_KEY
131+
- GITHUB_PERSONAL_ACCESS_TOKEN
132+
volumes:
133+
- ./agent.yaml:/app/agent.yaml:ro
134+
135+
secrets:
136+
ANTHROPIC_API_KEY:
137+
file: ./.anthropic_api_key
138+
GITHUB_PERSONAL_ACCESS_TOKEN:
139+
file: ./.github_token
140+
```
141+
142+
### Why use Compose secrets over environment variables?
143+
144+
| Aspect | Environment Variables | Compose Secrets |
145+
| --- | --- | --- |
146+
| Storage | In memory, visible via `docker inspect` | Mounted as tmpfs files under `/run/secrets/` |
147+
| Visibility | Shown in process list and inspect output | Not exposed in `docker inspect` |
148+
| Best for | Development | Production and CI/CD |
149+
150+
## `pass` Password Manager
151+
152+
docker-agent integrates with [`pass`](https://www.passwordstore.org/), the standard Unix password manager. Secrets are stored as GPG-encrypted files in `~/.password-store/`.
153+
154+
### Store a secret
155+
156+
```bash
157+
pass insert ANTHROPIC_API_KEY
158+
```
159+
160+
The entry name must match the environment variable name that docker-agent expects.
161+
162+
### Verify it works
163+
164+
```bash
165+
pass show ANTHROPIC_API_KEY
166+
```
167+
168+
Once `pass` is set up, docker-agent resolves secrets from it automatically.
169+
170+
## macOS Keychain
171+
172+
On macOS, docker-agent can read secrets from the system Keychain. This is useful for local development — you store the key once and it's available across all your projects.
173+
174+
### Store a secret
175+
176+
```bash
177+
security add-generic-password -a "$USER" -s ANTHROPIC_API_KEY -w "sk-ant-your-key-here"
178+
```
179+
180+
The `-s` (service name) must match the environment variable name that docker-agent expects.
181+
182+
### Verify it works
183+
184+
```bash
185+
security find-generic-password -s ANTHROPIC_API_KEY -w
186+
```
187+
188+
### Delete a secret
189+
190+
```bash
191+
security delete-generic-password -s ANTHROPIC_API_KEY
192+
```
193+
194+
Once stored, docker-agent finds the secret automatically — no flags or config needed.
195+
196+
## Choosing a Method
197+
198+
| Method | Best for | Setup effort |
199+
| --- | --- | --- |
200+
| Environment variables | Quick local development, scripts | Low |
201+
| Env files | Team projects, multiple keys | Low |
202+
| Docker Compose secrets | Containerized deployments, CI/CD | Medium |
203+
| `pass` | Linux/macOS, GPG-based workflows | Medium |
204+
| macOS Keychain | macOS local development | Low |
205+
206+
You can combine methods. For example, store long-lived provider keys in macOS Keychain and pass project-specific MCP tokens via env files.

examples/compose-secrets.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/docker-agent/main/agent-schema.json
2+
#
3+
# Example: Using Docker Compose secrets with docker-agent
4+
#
5+
# Docker Compose mounts secrets as files under /run/secrets/, and
6+
# docker-agent reads from this location automatically.
7+
#
8+
# See the full guide: https://docker.github.io/docker-agent/guides/secrets/
9+
#
10+
# To run this example:
11+
#
12+
# echo -n "sk-ant-..." > .anthropic_api_key
13+
# docker compose up
14+
#
15+
# compose.yaml:
16+
#
17+
# services:
18+
# agent:
19+
# image: docker/docker-agent
20+
# command: run --exec /app/agent.yaml "Hello!"
21+
# secrets:
22+
# - ANTHROPIC_API_KEY
23+
# volumes:
24+
# - ./agent.yaml:/app/agent.yaml:ro
25+
#
26+
# secrets:
27+
# ANTHROPIC_API_KEY:
28+
# file: ./.anthropic_api_key
29+
30+
agents:
31+
root:
32+
model: anthropic/claude-sonnet-4-0
33+
description: A helpful assistant running with Docker Compose secrets
34+
instruction: |
35+
You are a helpful assistant. Your API key was securely provided
36+
via Docker Compose secrets mounted at /run/secrets/.

0 commit comments

Comments
 (0)