Merge pull request #25132 from dvdksn/sbx/registry-secrets

sandboxes: document sbx secret set --registry for private OCI pulls
This commit is contained in:
David Karlsson
2026-05-29 22:28:00 +02:00
committed by GitHub
3 changed files with 113 additions and 14 deletions
+17 -4
View File
@@ -412,10 +412,17 @@ For Docker Hub, include the full `docker.io` prefix. See
[Packaging and distribution](#packaging-and-distribution) for publishing.
> [!IMPORTANT]
> Private kits are only supported on Docker Hub. `sbx` reuses your
> `sbx login` session to pull private artifacts from Docker Hub. Other
> registries are pulled anonymously, so private kits hosted on
> registries other than Docker Hub fail to pull.
> For Docker Hub, `sbx` reuses your `sbx login` session to pull private
> kits. For other registries, store pull credentials with
> [`sbx secret set --registry`](../security/credentials.md#registry-credentials)
> before running the sandbox:
>
> ```console
> $ gh auth token | sbx secret set --registry ghcr.io --password-stdin
> ```
>
> Without stored credentials, pulls from non-Docker Hub registries are
> anonymous and private kits fail to pull.
## Packaging and distribution
@@ -435,6 +442,12 @@ The `sbx kit` subcommands validate, inspect, and publish kits:
For Docker Hub, include the full `docker.io` prefix — `sbx` doesn't add it
automatically.
`sbx kit pull` prefers credentials stored with
[`sbx secret set --registry`](../security/credentials.md#registry-credentials),
falling back to the Docker credential store. `sbx kit push` only uses the
Docker credential store, so pushing to a private registry requires a prior
`docker login`.
## Spec reference
A kit directory has a required `spec.yaml` and an optional `files/` tree:
@@ -118,15 +118,21 @@ $ docker build -t my-org/my-template:v1 --push .
> daemon on the host.
> [!IMPORTANT]
> Private templates are only supported on Docker Hub. `sbx` reuses your
> `sbx login` session to pull private images from Docker Hub. Other
> registries (such as GitHub Container Registry, ECR, or a self-hosted
> registry like Nexus) are pulled anonymously, so private images on those
> registries fail to pull.
> For Docker Hub, `sbx` reuses your `sbx login` session to pull private
> images. For other registries (GitHub Container Registry, ECR, ACR, a
> self-hosted Nexus, and so on), store pull credentials with
> [`sbx secret set --registry`](../security/credentials.md#registry-credentials)
> before running the sandbox:
>
> ```console
> $ gh auth token | sbx secret set --registry ghcr.io --password-stdin
> ```
>
> Without stored credentials, pulls from non-Docker Hub registries are
> anonymous and private images fail to pull.
For locally-built images or private images on registries that `sbx`
can't authenticate against, save the image to a tar and load it
directly into the sandbox runtime instead of pulling from a registry:
For locally-built images, save the image to a tar and load it directly
into the sandbox runtime instead of pulling from a registry:
```console
$ docker image save my-org/my-template:v1 -o my-template.tar
@@ -44,6 +44,11 @@ There are two host-side stores, plus a host shell fallback:
and visible to other processes running as your user. See
[Environment variables](#environment-variables).
Registry credentials are a separate store with a different purpose. They
authenticate the `sbx` CLI (and optionally the sandbox itself) to private
OCI registries for template and kit pulls, and are not used by the
credential-injection proxy. See [Registry credentials](#registry-credentials).
If both a stored secret and a host environment variable are set for the same
service, the stored secret takes precedence. For multi-provider agents
(OpenCode, Docker Agent), the proxy selects credentials based on the API
@@ -125,8 +130,8 @@ List all stored secrets:
```console
$ sbx secret ls
SCOPE SERVICE SECRET
(global) github gho_GCaw4o****...****43qy
SCOPE TYPE NAME SECRET
(global) service github gho_GCaw4o****...****43qy
```
Remove a secret:
@@ -201,6 +206,81 @@ proxy replaces it with the real value. The agent never sees the real secret.
Prefer the [service-based flow](#stored-secrets) whenever it's an option —
the kit handles the wiring; you only provide the value.
## Registry credentials
Registry credentials authenticate to private OCI registries when pulling
[templates](../customize/templates.md) or [kits](../customize/kits.md). Use
`sbx secret set --registry <host>` to store them. They are independent from
service secrets: the proxy doesn't touch them, and they're used directly by
the `sbx` CLI when resolving image references.
For Docker Hub, `sbx` reuses your `sbx login` session — no registry secret
needed. For other registries (GitHub Container Registry, ECR, ACR,
self-hosted Nexus, and so on), store credentials with `sbx secret set
--registry`.
### Store registry credentials
Pipe a token from stdin and target the registry hostname:
```console
$ gh auth token | sbx secret set --registry ghcr.io --password-stdin
```
For registries that require a username (for example, ACR with an admin
account), add `--username`:
```console
$ echo "$ACR_PASSWORD" | sbx secret set \
--registry myregistry.azurecr.io \
--username myuser \
--password-stdin
```
Three scopes control where the credential is used:
- Host-only (no `-g`, no sandbox name): the `sbx` CLI uses it to pull
templates and kits when creating a sandbox. The credential is not
injected into the sandbox itself, so processes inside the sandbox can't
use it.
- Global (`-g`): same as host-only, plus written into `~/.docker/config.json`
in every new sandbox. Use this when agents need to pull or push from
inside the sandbox — for example, when an agent builds and publishes
container images.
- Sandbox-scoped (positional `SANDBOX` argument): credential applies only
to that named sandbox. Useful when only one sandbox needs access to a
private registry.
```console
$ gh auth token | sbx secret set -g --registry ghcr.io --password-stdin
$ gh auth token | sbx secret set my-sandbox --registry ghcr.io --password-stdin
```
`sbx kit pull` also uses these credentials, with the Docker credential
store as a fallback. `sbx kit push` uses only the Docker credential store —
push targets still require a prior `docker login`.
### Remove registry credentials
Remove both the host-only and global entries for a registry:
```console
$ sbx secret rm --registry ghcr.io -f
```
To remove only the global (sandbox-injected) entry and leave the
host-only credential in place, pass `-g`:
```console
$ sbx secret rm -g --registry ghcr.io -f
```
To remove a sandbox-scoped credential, pass the sandbox name:
```console
$ sbx secret rm my-sandbox --registry ghcr.io -f
```
## Environment variables
As an alternative to stored secrets, export the relevant environment variable