Skip to content
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
45 changes: 45 additions & 0 deletions docs/configuration/agents/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ agents:
add_environment_info: boolean # Optional: add env info to context
add_prompt_files: [list] # Optional: include additional prompt files
add_description_parameter: bool # Optional: add description to tool schema
redact_secrets: boolean # Optional: scrub detected secrets out of tool args and outgoing chat messages
code_mode_tools: boolean # Optional: enable code mode tool format
max_iterations: int # Optional: max tool-calling loops
max_consecutive_tool_calls: int # Optional: max identical consecutive tool calls
Expand Down Expand Up @@ -76,6 +77,7 @@ agents:
| `add_environment_info` | boolean | ✗ | When `true`, injects working directory, OS, CPU architecture, and git info into context. |
| `add_prompt_files` | array | ✗ | List of file paths whose contents are appended to the system prompt. Useful for including coding standards, guidelines, or additional context. |
| `add_description_parameter` | boolean | ✗ | When `true`, adds agent descriptions as a parameter in tool schemas. Helps with tool selection in multi-agent scenarios. |
| `redact_secrets` | boolean | ✗ | When `true`, scrubs detected secrets (API keys, tokens, private keys, etc.) out of tool-call arguments and outgoing chat messages before they reach a tool or the model. See [Redacting Secrets](#redacting-secrets) below. |
| `code_mode_tools` | boolean | ✗ | When `true`, formats tool responses in a code-optimized format with structured output schemas. Useful for MCP gateway and programmatic access. |
| `max_iterations` | int | ✗ | Maximum number of tool-calling loops. Default: unlimited (0). Set this to prevent infinite loops. |
| `max_consecutive_tool_calls` | int | ✗ | Maximum consecutive identical tool calls before the agent is terminated, preventing degenerate loops. Default: `5`. |
Expand Down Expand Up @@ -138,6 +140,49 @@ Multiple processes can share the same `path:` cache file safely. Every `Store` t

`Lookup` watches the file's modification time and reloads the in-memory map when the file has advanced since its last load, so writes from a sibling process become visible without a restart. The `<path>.lock` sentinel file is created on first write and never deleted: removing it would let two processes lock different inodes and lose mutual exclusion.

## Redacting Secrets

The `redact_secrets` flag is a single agent-level switch that scrubs accidentally leaked credentials, tokens, and private keys out of an agent's I/O. It wires up two complementary defenses:

1. A `pre_tool_use` built-in hook that scrubs detected secrets from the **arguments of every tool call**, before the tool sees them.
2. A `before_llm_call` message transform that scrubs the same patterns from **outgoing chat messages** — message content, multi-part text content, prior reasoning content, and the JSON-encoded arguments of any tool call still in the conversation — before they reach the model provider.

```yaml
agents:
root:
model: openai/gpt-5-mini
description: A helpful assistant that scrubs secrets before they leak
instruction: |
You are a helpful assistant. If the user accidentally pastes a token,
do your best work without echoing the secret back.
redact_secrets: true
toolsets:
- type: shell
```

Detection uses the docker-agent `secretsscan` ruleset, which recognises common secret patterns including:

- GitHub Personal Access Tokens (`ghp_*`, `gho_*`, `ghu_*`, `ghs_*`, `ghr_*`, fine-grained `github_pat_*`)
- AWS access keys (`AKIA*`, `ASIA*`, …) and secret access keys
- GitLab PATs (`glpat-*`), Hugging Face tokens (`hf_*`)
- Stripe (`sk_live_*`, `pk_test_*`, …), Slack (`xoxb-*`, …), Shopify, Twilio, Discord, Atlassian, Mailchimp, SendGrid, and many more
- JWTs, GCP service-account JSON, Heroku keys, Docker Hub PATs (`dckr_pat_*`)
- PEM-encoded private keys (`-----BEGIN … PRIVATE KEY-----` blocks)

Each detected span is replaced with the literal string `[REDACTED]`; the surrounding text is preserved so a redacted argument still looks like a legitimate flag (e.g. `--token=[REDACTED]`). Redaction is idempotent — applying it twice yields the same result.

<div class="callout callout-info" markdown="1">
<div class="callout-title">ℹ️ False positives vs. false negatives
</div>
<p>False positives are extremely rare: every rule pairs a regex with a discriminating keyword, so plain English never trips detection. <strong>False negatives are possible</strong> — only patterns the ruleset recognises are scrubbed, so this is a defense-in-depth feature, not a substitute for keeping secrets out of the conversation in the first place. Pair it with a proper <a href="{{ '/guides/secrets/' | relative_url }}">secret manager</a> for the credentials your agent actually needs.</p>
</div>

<div class="callout callout-info" markdown="1">
<div class="callout-title">ℹ️ Equivalent hook entry
</div>
<p>Setting <code>redact_secrets: true</code> on the agent is shorthand for auto-registering both halves of the feature. The tool-side scrubber is a normal built-in hook (<code>type: builtin</code>, <code>command: redact_secrets</code> on <code>pre_tool_use</code>), so you can also configure it manually — see the <a href="{{ '/configuration/hooks/#available-built-ins' | relative_url }}">Hooks reference</a>. The chat-side message transform is only enabled by the agent flag.</p>
</div>

## Welcome Message

Display a message when users start a session:
Expand Down
3 changes: 2 additions & 1 deletion docs/configuration/hooks/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ Built-ins are typically zero-config and faster than equivalent shell hooks becau
| `add_user_info` | `session_start` | _none_ | Adds the current OS user (username and full name) and the hostname. |
| `add_recent_commits` | `session_start` | _none_, or `["<N>"]` | Adds `git log --oneline -n N`. `N` defaults to 10; pass a positive integer to override. |
| `max_iterations` | `before_llm_call` | `["<N>"]` (required) | Hard-stops the agent after `N` model calls. State is per-session and reset at `session_end`. |
| `redact_secrets` | `pre_tool_use` | _none_ | Scrubs detected secrets (API keys, tokens, private keys, …) out of every tool call's arguments. Auto-registered by `redact_secrets: true` on the agent. |

<div class="callout callout-info" markdown="1">
<div class="callout-title">ℹ️ Per-turn vs. per-session
Expand All @@ -162,7 +163,7 @@ Built-ins are typically zero-config and faster than equivalent shell hooks becau
<div class="callout callout-info" markdown="1">
<div class="callout-title">ℹ️ Auto-injected built-ins
</div>
<p>The agent flags <code>add_date: true</code>, <code>add_environment_info: true</code>, and <code>add_prompt_files: [...]</code> are shorthands that auto-register the matching built-in hook. You don't need to repeat them under <code>hooks:</code> — set the flag <em>or</em> the hook entry, not both.</p>
<p>The agent flags <code>add_date: true</code>, <code>add_environment_info: true</code>, <code>add_prompt_files: [...]</code>, and <code>redact_secrets: true</code> are shorthands that auto-register the matching built-in hook. You don't need to repeat them under <code>hooks:</code> — set the flag <em>or</em> the hook entry, not both. <code>redact_secrets</code> is a special case: the agent flag <em>also</em> enables a runtime <code>before_llm_call</code> message transform that scrubs outgoing chat content; the hook entry on its own only covers tool arguments.</p>
</div>

<div class="callout callout-warning" markdown="1">
Expand Down
22 changes: 22 additions & 0 deletions docs/guides/secrets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,25 @@ Once stored, docker-agent finds the secret automatically — no flags or config
| macOS Keychain | macOS local development | Low |

You can combine methods. For example, store long-lived provider keys in macOS Keychain and pass project-specific MCP tokens via env files.

## Preventing Secret Leaks

Provider keys live in the secret store and are passed to docker-agent through the chain above — the agent itself never receives them as input. But the **content of a conversation** can still leak credentials: a user pasting a token, a tool returning a config file with embedded keys, a transcript dumped into a prompt.

For that defense-in-depth case, set `redact_secrets: true` on an agent. It scrubs detected secrets out of:

- the arguments of every outgoing tool call (before the tool sees them), and
- every outgoing chat message (before the model provider sees them).

```yaml
agents:
root:
model: openai/gpt-5-mini
description: A helpful assistant
instruction: You are a helpful assistant.
redact_secrets: true
toolsets:
- type: shell
```

The ruleset covers GitHub PATs, AWS / GCP / Azure credentials, Stripe / Slack / GitLab / Hugging Face tokens, JWTs, PEM-encoded private keys, Docker Hub PATs, and many others. Each detected span is replaced with the literal `[REDACTED]`. See the [Redacting Secrets]({{ '/configuration/agents/#redacting-secrets' | relative_url }}) section in the agent configuration reference for the full picture and important caveats about false negatives.
Loading