From c73f8eaf056b1553fff60f4323f5173d2fde572d Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 09:43:19 +0000 Subject: [PATCH 1/3] docs: warn about extended-agent OAuth (fixes #434) The Claude extension example implied that proxy-managed OAuth works for a third-party child kit. Document the working API-key setup, explain that sbx generates the binding during first-run approval, and warn that the prompt's OAuth option does not activate interception. Co-Authored-By: Claude --- .../ai/sandboxes/customize/kit-examples.md | 24 ++++++++++++++++- .../ai/sandboxes/security/credentials.md | 27 ++++++++++++------- 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index a3e06446bd6..43ef07a9a3e 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -364,6 +364,26 @@ the child kit's name: $ sbx run claude-sonnet --kit ./claude-sonnet ``` +Proxy-managed OAuth isn't supported for a third-party kit that extends the +built-in `claude` agent. Store an Anthropic API key on the host before the first +launch: + +```console +$ sbx secret set anthropic +``` + +When you launch the kit for the first time, `sbx` prompts you to approve its +inherited Anthropic credentials. Approve the API-key mechanism. Because this is +a third-party schema v2 kit, `sbx` records your approval as a +[credential binding](../security/credentials.md#credential-bindings). The +sandbox receives a sentinel value, and the proxy injects the real API key into +requests to the domains declared by the kit. + +> [!WARNING] +> The approval prompt also lists OAuth, but approving it doesn't activate OAuth +> interception for the extended agent. If you use Claude Code's `/login` +> command, Claude Code stores the real OAuth tokens inside the sandbox. + OpenCode supports an additional config file through `OPENCODE_CONFIG`. Keep the kit's config separate from the sandbox-managed `/home/agent/.config/opencode/opencode.json`, for example at @@ -431,7 +451,9 @@ sandbox: The child inherits the built-in image, credentials, network permissions, persistent volumes, settings, MCP integration, and agent instructions. Its -`sandbox.entrypoint` replaces the inherited entrypoint. +`sandbox.entrypoint` replaces the inherited entrypoint. Proxy-managed OAuth +isn't supported for the extended agent, so follow the +[Anthropic API-key setup](#customize-agent-settings) before launching it. Launch with the kit's `name:` as the agent argument to `sbx run`: diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index c8d4489f8d0..68deca738c3 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -317,14 +317,14 @@ bindings: A binding is only an approval record: the presence of `apiKey` or `oauth` authorizes that mechanism. Declining a credential writes no entry at all. +The real credential isn't stored in this file. ### First-run approval -When a third-party kit needs a credential that has no binding, `sbx` walks you -through approving one. For an API key, you can use a value already in the secret -store or enter one at the prompt. For OAuth, you approve the sign-in flow. In -both cases, you approve the domains declared by the kit. `sbx` writes the entry -to `credentials.yaml`. +When a third-party kit needs an API key that has no binding, `sbx` walks you +through approving one. You can use a value already in the secret store or enter +one at the prompt. You approve the domains declared by the kit, and `sbx` writes +the entry to `credentials.yaml`. In non-interactive contexts (CI or `--detached`), there's no one to answer the prompt. Without a binding, the sandbox starts with the credential withheld. If @@ -340,10 +340,19 @@ constrain which requests can carry the credential. Only third-party kits that declare `schemaVersion: "2"` require a binding. Built-in agents also use `schemaVersion: "2"`, but credentials declared only by -embedded kits are authorized by provenance and inject automatically. If a -third-party kit also declares the same service, that service requires approval. -Kits on `schemaVersion: "1"` inject their declared credentials without a -binding. +embedded kits are authorized by provenance and inject automatically. A +third-party kit that extends a built-in agent inherits its credentials, but not +its built-in provenance. The inherited credentials therefore require approval. +If a third-party kit declares the same service itself, that service also +requires approval. Kits on `schemaVersion: "1"` inject their declared +credentials without a binding. + +> [!WARNING] +> Proxy-managed OAuth isn't supported for a third-party kit that extends a +> built-in agent. Repeating the parent's OAuth declaration in the child kit +> doesn't activate OAuth interception. Use a stored API key when the service +> supports one. Otherwise, an OAuth login performed inside the sandbox stores +> the real token there. ## Registry credentials From 05ebfb3ec9a366dd87f749525cf69ab0199c58be Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 10:16:53 +0000 Subject: [PATCH 2/3] docs: clarify OAuth approval action Tell users to review credential mechanisms individually and decline unsupported OAuth. Clarify the first-run behavior for third-party sandbox agents without removing OAuth binding coverage from the general documentation. Co-Authored-By: Claude --- .../ai/sandboxes/customize/kit-examples.md | 11 ++++++----- .../manuals/ai/sandboxes/security/credentials.md | 15 ++++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 43ef07a9a3e..79a73769f97 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -373,16 +373,17 @@ $ sbx secret set anthropic ``` When you launch the kit for the first time, `sbx` prompts you to approve its -inherited Anthropic credentials. Approve the API-key mechanism. Because this is -a third-party schema v2 kit, `sbx` records your approval as a +inherited Anthropic credentials. Select **Review each**, approve the API-key +mechanism, and decline OAuth. Because this is a third-party schema v2 kit, +`sbx` records your approval as a [credential binding](../security/credentials.md#credential-bindings). The sandbox receives a sentinel value, and the proxy injects the real API key into requests to the domains declared by the kit. > [!WARNING] -> The approval prompt also lists OAuth, but approving it doesn't activate OAuth -> interception for the extended agent. If you use Claude Code's `/login` -> command, Claude Code stores the real OAuth tokens inside the sandbox. +> The approval prompt also lists OAuth, but approving it has no effect for the +> extended agent. If you use Claude Code's `/login` command, Claude Code stores +> the real OAuth tokens inside the sandbox. OpenCode supports an additional config file through `OPENCODE_CONFIG`. Keep the kit's config separate from the sandbox-managed diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index 68deca738c3..5237f19776f 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -326,6 +326,11 @@ through approving one. You can use a value already in the secret store or enter one at the prompt. You approve the domains declared by the kit, and `sbx` writes the entry to `credentials.yaml`. +The approval prompt can also offer OAuth when a third-party sandbox kit +declares it. Approving OAuth writes a binding, but doesn't activate OAuth +interception for a third-party sandbox agent. Decline OAuth unless the kit also +offers a working credential mechanism, such as an API key. + In non-interactive contexts (CI or `--detached`), there's no one to answer the prompt. Without a binding, the sandbox starts with the credential withheld. If the kit marks the credential as `required: true`, `sbx` also prints a warning. @@ -348,11 +353,11 @@ requires approval. Kits on `schemaVersion: "1"` inject their declared credentials without a binding. > [!WARNING] -> Proxy-managed OAuth isn't supported for a third-party kit that extends a -> built-in agent. Repeating the parent's OAuth declaration in the child kit -> doesn't activate OAuth interception. Use a stored API key when the service -> supports one. Otherwise, an OAuth login performed inside the sandbox stores -> the real token there. +> Proxy-managed OAuth isn't supported for third-party sandbox agents, including +> kits that extend a built-in agent. Repeating the parent's OAuth declaration in +> the child kit doesn't activate OAuth interception. Use a stored API key when +> the service supports one. Otherwise, an OAuth login performed inside the +> sandbox stores the real token there. ## Registry credentials From e39fd2ca5073433f802f425a1630d0fc5241aea4 Mon Sep 17 00:00:00 2001 From: David Karlsson <35727626+dvdksn@users.noreply.github.com> Date: Wed, 12 Aug 2026 10:18:03 +0000 Subject: [PATCH 3/3] docs: simplify OAuth limitation guidance Keep the credential approval flow unchanged and state only that OAuth is ineffective for the extended agent. Restore the general first-run explanation for both API-key and OAuth bindings. Co-Authored-By: Claude --- .../manuals/ai/sandboxes/customize/kit-examples.md | 9 ++++----- .../manuals/ai/sandboxes/security/credentials.md | 14 +++++--------- 2 files changed, 9 insertions(+), 14 deletions(-) diff --git a/content/manuals/ai/sandboxes/customize/kit-examples.md b/content/manuals/ai/sandboxes/customize/kit-examples.md index 79a73769f97..ebae4807705 100644 --- a/content/manuals/ai/sandboxes/customize/kit-examples.md +++ b/content/manuals/ai/sandboxes/customize/kit-examples.md @@ -373,17 +373,16 @@ $ sbx secret set anthropic ``` When you launch the kit for the first time, `sbx` prompts you to approve its -inherited Anthropic credentials. Select **Review each**, approve the API-key -mechanism, and decline OAuth. Because this is a third-party schema v2 kit, +inherited Anthropic credentials. Because this is a third-party schema v2 kit, `sbx` records your approval as a [credential binding](../security/credentials.md#credential-bindings). The sandbox receives a sentinel value, and the proxy injects the real API key into requests to the domains declared by the kit. > [!WARNING] -> The approval prompt also lists OAuth, but approving it has no effect for the -> extended agent. If you use Claude Code's `/login` command, Claude Code stores -> the real OAuth tokens inside the sandbox. +> The approval prompt also lists OAuth, but OAuth doesn't work for the extended +> agent. If you use Claude Code's `/login` command, Claude Code stores the real +> OAuth tokens inside the sandbox. OpenCode supports an additional config file through `OPENCODE_CONFIG`. Keep the kit's config separate from the sandbox-managed diff --git a/content/manuals/ai/sandboxes/security/credentials.md b/content/manuals/ai/sandboxes/security/credentials.md index 5237f19776f..9507522ac57 100644 --- a/content/manuals/ai/sandboxes/security/credentials.md +++ b/content/manuals/ai/sandboxes/security/credentials.md @@ -321,15 +321,11 @@ The real credential isn't stored in this file. ### First-run approval -When a third-party kit needs an API key that has no binding, `sbx` walks you -through approving one. You can use a value already in the secret store or enter -one at the prompt. You approve the domains declared by the kit, and `sbx` writes -the entry to `credentials.yaml`. - -The approval prompt can also offer OAuth when a third-party sandbox kit -declares it. Approving OAuth writes a binding, but doesn't activate OAuth -interception for a third-party sandbox agent. Decline OAuth unless the kit also -offers a working credential mechanism, such as an API key. +When a third-party kit needs a credential that has no binding, `sbx` walks you +through approving one. For an API key, you can use a value already in the secret +store or enter one at the prompt. For OAuth, you approve the sign-in flow. In +both cases, you approve the domains declared by the kit. `sbx` writes the entry +to `credentials.yaml`. In non-interactive contexts (CI or `--detached`), there's no one to answer the prompt. Without a binding, the sandbox starts with the credential withheld. If