From 2f9ac840c1c4d42a66a61c8061c11bb30a8dc1ff Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:14:16 +0000 Subject: [PATCH 1/3] docs: document dynamic sandbox secrets The sandbox credential guides only covered literal stored values and obsolete host-environment workflows. Document reference and command sources, refresh and verification controls, and provider-specific workflows for GitHub, 1Password, and AWS Secrets Manager. Co-authored-by: Codex --- .../manuals/ai/sandboxes/agents/copilot.md | 2 +- content/manuals/ai/sandboxes/get-started.md | 2 +- .../ai/sandboxes/security/credentials.md | 86 ++++++++++++++++--- content/manuals/ai/sandboxes/workflows.md | 75 +++++++++------- 4 files changed, 121 insertions(+), 44 deletions(-) diff --git a/content/manuals/ai/sandboxes/agents/copilot.md b/content/manuals/ai/sandboxes/agents/copilot.md index 29b62f603029..7bc20a81e177 100644 --- a/content/manuals/ai/sandboxes/agents/copilot.md +++ b/content/manuals/ai/sandboxes/agents/copilot.md @@ -33,7 +33,7 @@ Copilot requires a GitHub token with Copilot access. Store your token using [stored secrets](../security/credentials.md#stored-secrets): ```console -$ echo "$(gh auth token)" | sbx secret set github +$ sbx secret set github --command 'gh auth token' ``` ## Configuration diff --git a/content/manuals/ai/sandboxes/get-started.md b/content/manuals/ai/sandboxes/get-started.md index 7a709b1f8c09..a991b909db5b 100644 --- a/content/manuals/ai/sandboxes/get-started.md +++ b/content/manuals/ai/sandboxes/get-started.md @@ -128,7 +128,7 @@ To give the agent access to GitHub for creating pull requests or interacting with repositories: ```console -$ sbx secret set github -t "$(gh auth token)" +$ sbx secret set github --command 'gh auth token' ``` ## Run your first sandbox diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index c8d4489f8d07..59c0eb2c1163 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -31,7 +31,7 @@ value for the same service, the stored secret takes precedence. | Form | What it is | Use it when | | --------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------- | -| [Stored secrets](#stored-secrets) (`sbx secret set`) | A value in your OS keychain, keyed by service | The default for any built-in or kit-declared service | +| [Stored secrets](#stored-secrets) (`sbx secret set`) | A value or dynamic source in your OS keychain, keyed by service | The default for any built-in or kit-declared service | | [Custom secrets](#custom-secrets) (`sbx secret set-custom`) | A value keyed to a domain and environment variable | The service model doesn't fit — the agent validates the variable's format, or the secret rides in a request body | | OAuth | A host-side sign-in flow; the token never enters the sandbox | The agent supports it, such as Claude Code, Codex, Cursor, or Droid | | [Credential bindings](#credential-bindings) (`credentials.yaml`) | Per-service mechanism and domain approval | Required for third-party `schemaVersion: "2"` kits | @@ -43,9 +43,10 @@ credentials based on the API endpoint being called. See individual ## Stored secrets -`sbx secret set` stores credentials in your OS keychain, keyed on a service -identifier. Built-in agents declare a fixed set of services. Custom kits can -declare their own. The same `sbx secret set` flow works for both. +`sbx secret set` stores credential values or dynamic secret sources in your OS +keychain, keyed on a service identifier. Built-in agents declare a fixed set of +services. Custom kits can declare their own. The same `sbx secret set` flow +works for both. ### Where secrets are stored @@ -97,6 +98,55 @@ $ sbx secret set openai --sandbox my-sandbox > you set or change a global secret while a sandbox is running, recreate the > sandbox for the new value to take effect. +### Use a dynamic secret source + +Dynamic secret sources let `sbx` retrieve a credential from an authenticated +host tool when the proxy needs it. The secret store contains the reference or +command instead of the credential value. Resolution and caching happen on the +host, and the sandbox still receives only the proxy-managed placeholder. + +Use `--ref` with a 1Password secret reference or an AWS Secrets Manager ARN: + +```console +$ sbx secret set anthropic --ref 'op://Work/Anthropic/credential' +$ sbx secret set openai \ + --ref 'arn:aws:secretsmanager:us-west-2:123456789012:secret:openai-api-key' +``` + +The corresponding `op` or `aws` CLI must be installed and authenticated on the +host. When you register a reference, `sbx` records supported provider settings, +such as `OP_ACCOUNT`, `AWS_PROFILE`, and AWS config paths, so the daemon uses +the same account or profile when it resolves the reference. + +Use `--command` for another host tool that prints a secret to standard output: + +```console +$ sbx secret set github --command 'gh auth token' +``` + +`sbx` runs the command through the host shell and trims its output. The command +text is stored and replayed by the daemon. Don't embed a secret directly in the +command because the text can appear in shell history and process listings. + +By default, `sbx` verifies the source when you register it and reports an error +without exposing the resolver's standard error. Use `--no-verify` to store a +source that can't be resolved during registration. To troubleshoot an initial +verification failure, use `--show-error`; provider error output can contain +sensitive information. You can't combine `--show-error` with `--no-verify`. + +Resolved service secrets are cached for 55 minutes by default. Set another +duration or resolve the source for every credential use with `--refresh`: + +```console +$ sbx secret set anthropic \ + --ref 'op://Work/Anthropic/credential' \ + --refresh 30m +$ sbx secret set github --command 'gh auth token' --refresh on-demand +``` + +`--ref` and `--command` are mutually exclusive. They can't be combined with +`--token`, `--oauth`, or `--registry`. + ### Import from environment variables If you already have API keys set in your shell, `sbx secret import` reads them @@ -201,14 +251,15 @@ $ sbx secret rm github ### GitHub token The `github` service gives the agent access to the `gh` CLI inside the -sandbox. Pass your existing GitHub CLI token: +sandbox. Resolve your existing GitHub CLI token on the host: ```console -$ echo "$(gh auth token)" | sbx secret set github +$ sbx secret set github --command 'gh auth token' ``` -This is useful for agents that create pull requests, open issues, or interact -with GitHub APIs on your behalf. +The daemon refreshes the token from the host command after the default cache +period. This is useful for agents that create pull requests, open issues, or +interact with GitHub APIs on your behalf. ### SSH agent @@ -262,6 +313,21 @@ A `--host` value can also use wildcards, with the same syntax as single label (`*.example.com` covers `api.example.com`) and `**` matches any number (`**.example.com` covers `api.example.com` and `v2.api.example.com`). +Custom secrets also accept [dynamic secret sources](#use-a-dynamic-secret-source). +Replace `--value` with either `--ref` or `--command`: + +```console +$ sbx secret set-custom \ + --host api.example.com \ + --env API_KEY \ + --ref 'op://Work/Example/credential' +``` + +Dynamic custom secrets resolve on demand by default. Pass `--refresh` with a +duration to cache the resolved value. The verification and error-output flags +work the same as they do for service secrets. `--ref` and `--command` can't be +combined with `--value` or `--token`. + > [!WARNING] > Passing the secret as `--value ` records it in your shell history > and exposes it to other processes running as your user. Avoid pasting @@ -453,9 +519,9 @@ $ sbx secret rm --sandbox my-sandbox --registry ghcr.io -f Code; Cursor and Droid have no ahead-of-time option, so their sign-in prompt appears when the agent starts. See the individual [agent pages](../agents/) for each agent's flow. -- If you store credentials in 1Password, see +- If you store credentials in 1Password or AWS Secrets Manager, see [Sourcing credentials from 1Password](../workflows.md#sourcing-credentials-from-1password) - for how to use `op read` and `op run` with `sbx`. + and [Sourcing credentials from AWS Secrets Manager](../workflows.md#sourcing-credentials-from-aws-secrets-manager). ## Custom templates and placeholder values diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index a6548de97f40..3bb388691a6a 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -423,9 +423,10 @@ For troubleshooting, see The sandbox proxy handles API credentials for model providers automatically, but agents often also need credentials for tools like `gh`, `docker`, or a -secrets manager. The pattern is the same in each case: configure the -credential on your host once, and the sandbox either forwards it via the -proxy or via SSH agent forwarding. +secrets manager. Configure the credential source on your host, and the proxy +injects the resolved value into matching requests from the sandbox. Dynamic +secret sources can retrieve a value from an authenticated host CLI without +copying the value into the secret store. > [!NOTE] > Service secrets are global by default, so all future sandboxes can use them. @@ -440,9 +441,14 @@ outbound requests, so `gh` works inside the sandbox without any additional configuration: ```console -$ echo "$(gh auth token)" | sbx secret set github +$ sbx secret set github --command 'gh auth token' ``` +The daemon runs `gh auth token` on the host and caches its output for 55 minutes +by default. After the cache expires, it runs the command again, so token updates +from `gh` don't need to be copied into `sbx` manually. Use `--refresh on-demand` +to run the command for every credential use. + The agent can then create pull requests, open issues, comment on PRs, and interact with the GitHub API the same way it would from your host: @@ -484,50 +490,55 @@ per-registry username requirements, and all-sandbox versus per-sandbox scoping, ### Sourcing credentials from 1Password -#### Populating stored secrets with `op read` - -Use `op read` to populate stored secrets without pasting values manually. Store -the value once and it's available to all future sandboxes: +Install the 1Password CLI, sign in on the host, and pass an `op://` reference to +`sbx secret set`. The secret store records the reference, and the daemon uses +`op read` on the host when the proxy needs the credential: ```console -$ op read "op://Work/GitHub/token" | sbx secret set github -$ op read "op://Work/Anthropic/credential" | sbx secret set anthropic +$ sbx secret set github --ref 'op://Work/GitHub/token' +$ sbx secret set anthropic --ref 'op://Work/Anthropic/credential' ``` -The real value stays on your host; the sandbox sees the proxy-managed -placeholder as usual. +The real value stays on your host, and the sandbox sees the proxy-managed +placeholder. Service secrets are cached for 55 minutes by default. To retrieve +the value from 1Password for every credential use, set the refresh policy: -#### Per-launch injection with `op run` +```console +$ sbx secret set anthropic \ + --ref 'op://Work/Anthropic/credential' \ + --refresh on-demand +``` -To resolve credentials fresh from your vault on each launch without storing -them via `sbx secret set`, use `op run`: +When more than one 1Password account is configured, set `OP_ACCOUNT` while +registering the reference. `sbx` records the account selector for later +resolution: ```console -$ ANTHROPIC_API_KEY="op://Work/Anthropic/credential" op run -- sbx run claude -$ OPENAI_API_KEY="op://Work/OpenAI/key" op run -- sbx run codex -$ GEMINI_API_KEY="op://Work/Google/key" op run -- sbx run gemini +$ OP_ACCOUNT=work sbx secret set anthropic \ + --ref 'op://Work/Anthropic/credential' ``` -`op run` resolves each `op://` reference in the environment before executing -`sbx`. The sandbox reads the -[built-in service environment variables](security/credentials.md#built-in-services) -at launch and routes them through its proxy — the credential is never stored in -sbx's state and never appears inside the sandbox container. - -This only applies to those specific credential variables. The sandbox does not -forward arbitrary environment variables from the host into the sandbox. +### Sourcing credentials from AWS Secrets Manager -For multiple credentials at once, use `--env-file` with a file of `op://` -references: +Install and authenticate the AWS CLI on the host, then register the secret's +ARN. The daemon calls AWS Secrets Manager when the proxy needs the value: ```console -$ cat .sbx-secrets.env -ANTHROPIC_API_KEY=op://Work/Anthropic/credential -GITHUB_TOKEN=op://Work/GitHub/token +$ sbx secret set anthropic \ + --ref 'arn:aws:secretsmanager:us-west-2:123456789012:secret:anthropic-api-key' +``` + +If you use a named AWS profile, set `AWS_PROFILE` while registering the +reference. `sbx` records the profile for daemon-side resolution: -$ op run --env-file=.sbx-secrets.env -- sbx run claude +```console +$ AWS_PROFILE=development sbx secret set anthropic \ + --ref 'arn:aws:secretsmanager:us-west-2:123456789012:secret:anthropic-api-key' ``` +See [Use a dynamic secret source](security/credentials.md#use-a-dynamic-secret-source) +for refresh policies, verification options, and custom secrets. + ## CI and headless use For CI environments and scripts where a browser isn't available, authenticate From 8163b46febc950427d8c6bbaf8397f430810240c Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:26:21 +0000 Subject: [PATCH 2/3] docs: demote provider selector details The initial workflow gave OP_ACCOUNT and AWS_PROFILE more prominence than their optional role warranted. Move provider selector support into a note and keep the primary 1Password and AWS flows focused on registering references. Co-authored-by: Codex --- .../ai/sandboxes/security/credentials.md | 10 +++++++--- content/manuals/ai/sandboxes/workflows.md | 20 ++----------------- 2 files changed, 9 insertions(+), 21 deletions(-) diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index 59c0eb2c1163..866bf087dcf5 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -114,9 +114,13 @@ $ sbx secret set openai \ ``` The corresponding `op` or `aws` CLI must be installed and authenticated on the -host. When you register a reference, `sbx` records supported provider settings, -such as `OP_ACCOUNT`, `AWS_PROFILE`, and AWS config paths, so the daemon uses -the same account or profile when it resolves the reference. +host. + +> [!NOTE] +> If provider settings such as `OP_ACCOUNT`, `AWS_PROFILE`, or supported AWS +> region and config variables are set when you register a reference, `sbx` +> records them for later daemon-side resolution. Otherwise, the provider CLI +> uses its default account or profile. Use `--command` for another host tool that prints a secret to standard output: diff --git a/content/manuals/ai/sandboxes/workflows.md b/content/manuals/ai/sandboxes/workflows.md index 3bb388691a6a..9e0aafd8a675 100644 --- a/content/manuals/ai/sandboxes/workflows.md +++ b/content/manuals/ai/sandboxes/workflows.md @@ -509,15 +509,6 @@ $ sbx secret set anthropic \ --refresh on-demand ``` -When more than one 1Password account is configured, set `OP_ACCOUNT` while -registering the reference. `sbx` records the account selector for later -resolution: - -```console -$ OP_ACCOUNT=work sbx secret set anthropic \ - --ref 'op://Work/Anthropic/credential' -``` - ### Sourcing credentials from AWS Secrets Manager Install and authenticate the AWS CLI on the host, then register the secret's @@ -528,16 +519,9 @@ $ sbx secret set anthropic \ --ref 'arn:aws:secretsmanager:us-west-2:123456789012:secret:anthropic-api-key' ``` -If you use a named AWS profile, set `AWS_PROFILE` while registering the -reference. `sbx` records the profile for daemon-side resolution: - -```console -$ AWS_PROFILE=development sbx secret set anthropic \ - --ref 'arn:aws:secretsmanager:us-west-2:123456789012:secret:anthropic-api-key' -``` - See [Use a dynamic secret source](security/credentials.md#use-a-dynamic-secret-source) -for refresh policies, verification options, and custom secrets. +for refresh policies, verification options, custom secrets, and provider +account or profile selection. ## CI and headless use From bb90e69ee6ffdf36e804931edb7cd5880752f771 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Tue, 11 Aug 2026 14:56:48 +0000 Subject: [PATCH 3/3] docs: clarify dynamic secret options The refresh guidance conflated cache durations with on-demand resolution, and the provider-selection note described implementation rather than purpose. Separate the refresh modes, explain account and profile selection directly, and remove the semicolon flagged by review. Co-authored-by: Codex --- .../manuals/ai/sandboxes/security/credentials.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index 866bf087dcf5..67c5fb69cda1 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -117,10 +117,10 @@ The corresponding `op` or `aws` CLI must be installed and authenticated on the host. > [!NOTE] -> If provider settings such as `OP_ACCOUNT`, `AWS_PROFILE`, or supported AWS -> region and config variables are set when you register a reference, `sbx` -> records them for later daemon-side resolution. Otherwise, the provider CLI -> uses its default account or profile. +> To resolve a reference with a specific 1Password account or AWS profile, set +> `OP_ACCOUNT` or `AWS_PROFILE` when you run `sbx secret set`. `sbx` uses that +> account or profile whenever it resolves the secret. If neither variable is +> set, the provider CLI uses its default. Use `--command` for another host tool that prints a secret to standard output: @@ -135,11 +135,12 @@ command because the text can appear in shell history and process listings. By default, `sbx` verifies the source when you register it and reports an error without exposing the resolver's standard error. Use `--no-verify` to store a source that can't be resolved during registration. To troubleshoot an initial -verification failure, use `--show-error`; provider error output can contain +verification failure, use `--show-error`. Provider error output can contain sensitive information. You can't combine `--show-error` with `--no-verify`. -Resolved service secrets are cached for 55 minutes by default. Set another -duration or resolve the source for every credential use with `--refresh`: +Resolved service secrets are cached for 55 minutes by default. To change the +cache duration, use `--refresh `. To resolve the source for every +credential use instead of caching it, pass `--refresh on-demand`: ```console $ sbx secret set anthropic \