From 6ba5c96b9e3a0490dda45b4010f0e4d637872125 Mon Sep 17 00:00:00 2001 From: "warp-factories[bot]" <243557089+warp-factories[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 16:07:46 +0000 Subject: [PATCH] docs: document private image credentials (docker-registry secrets) Add create flow for oz secret create docker-registry and the web UI Private image credential type, plus runner/factory-as-code cross-links. --- .../docs/factories/factory-as-code.mdx | 2 +- src/content/docs/platform/runners.mdx | 2 + src/content/docs/platform/secrets.mdx | 58 ++++++++++++++++--- 3 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/content/docs/factories/factory-as-code.mdx b/src/content/docs/factories/factory-as-code.mdx index b0eb0f94e..86c23f001 100644 --- a/src/content/docs/factories/factory-as-code.mdx +++ b/src/content/docs/factories/factory-as-code.mdx @@ -471,7 +471,7 @@ Optional. The compute size, as `vcpus` and `memoryGb`. Omit it to take the works The operating system and architecture. `os` is `linux` (the default) or `macos`, and `arch` is `x86_64` (the default on Linux) or `aarch64` (the only option on macOS). Linux runners require `linux.dockerImage`, the container image the sandbox boots, so every Linux runner declares a `platform` section. macOS runners accept an optional `mac.version` (`"14"`, `"15"`, `"26"`, or `"27"`; quote it, and it defaults to `"26"`). -For a private Linux image, set `linux.registryCredentialSecretName` to the name of a managed `docker_registry` secret. The secret's registry host must match the host in `linux.dockerImage`. +For a private Linux image, set `linux.registryCredentialSecretName` to the name of a managed private image credential (`docker_registry` secret). Create one with `oz secret create docker-registry` or in the Secrets UI — see [Private image credentials](/platform/secrets/#private-image-credentials). The secret's registry host must match the host in `linux.dockerImage`. ## `benchmarks//suite.yaml` diff --git a/src/content/docs/platform/runners.mdx b/src/content/docs/platform/runners.mdx index 6692e4a06..6c13eaa85 100644 --- a/src/content/docs/platform/runners.mdx +++ b/src/content/docs/platform/runners.mdx @@ -45,6 +45,8 @@ Each environment has a default runner. Specifying a runner for a run overrides t Warp-hosted Linux runners support any public x86-64 or aarch64 image. By default, runners use [`warpdotdev/dev-base:latest`](https://hub.docker.com/r/warpdotdev/dev-base). Linux supports any combination of CPU and memory as long as both are a power of two and within your plan's maximum resource limit. + For a **private** image, create a [private image credential](/platform/secrets/#private-image-credentials) (CLI: `oz secret create docker-registry`) whose registry host matches the image host, then attach that secret by name when you configure the runner. In a [factory-as-code](/factories/factory-as-code/#platform) runner file, set `linux.registryCredentialSecretName` to the secret name. + Warp-hosted Linux runners can also run Docker containers and KVM-based virtual machines, such as the Android emulator. diff --git a/src/content/docs/platform/secrets.mdx b/src/content/docs/platform/secrets.mdx index e336eb55c..c949ae7c2 100644 --- a/src/content/docs/platform/secrets.mdx +++ b/src/content/docs/platform/secrets.mdx @@ -17,12 +17,14 @@ Warp-managed secrets are designed to work across [cloud agent](/platform/) and [ * A cloud agent needs to call an API or CLI that does not support OAuth * You are using [MCP servers](/platform/mcp/) that expect static tokens or keys * An agent needs credentials for tools like cloud CLIs, databases, monitoring systems, or internal services +* A [runner](/platform/runners/) or [environment](/platform/environments/) pulls its Linux sandbox image from a private container registry * You want centralized auditing and control over what credentials agents can access ### Common use cases * Run SQL queries against BigQuery or Metabase to answer questions like “what changed in last night’s pipeline run” or “how many users hit this error today,” using a read-only service account or API token. * Call cloud or infrastructure CLIs to take small, predefined remediation steps when an alert fires, such as restarting a service, scaling a deployment, or clearing a stuck job, using tightly scoped credentials. +* Store a private image credential so Warp-hosted Linux runners can pull `ghcr.io/acme/dev-base:latest` (or another private image) when the sandbox starts. * List and review all API keys, service accounts, and tokens that cloud agents can access to verify scopes, rotation policies, and ownership match internal security requirements. --- @@ -87,18 +89,34 @@ Personal secrets belong to an **individual user**. The [{VARS.WEB_APP}](/platform/oz-web-app/) provides a guided side pane for creating Warp-managed secrets. Use it when you want a point-and-click flow without leaving the browser; the CLI flow below remains available for scripting and automation. -To create a secret in the web app: +### Raw value secrets 1. In the {VARS.WEB_APP} ({VARS.WEB_APP_URL}), open the **Secrets** page. 2. Click **Add secret** to open the **Add secret** side pane. -3. Enter a **Name** (for example, `OPENAI_API_KEY`). This becomes the environment variable name injected into runs. -4. Enter the **Value**. The value is encrypted in your browser before it is sent to the server; Warp never sees the plaintext. -5. Optionally, enter a **Description** to help teammates identify the secret later. -6. Choose a **Scope** — **Team** to share the secret with everyone on the team, or **Personal** to keep it scoped to your user. -7. Click **Create secret**. +3. In the "Type" dropdown, choose **Raw value**. +4. Enter a **Name** (for example, `OPENAI_API_KEY`). This becomes the environment variable name injected into runs. +5. Enter the **Value**. The value is encrypted in your browser before it is sent to the server; Warp never sees the plaintext. +6. Optionally, enter a **Description** to help teammates identify the secret later. +7. Choose a **Scope** — **Team** to share the secret with everyone on the team, or **Personal** to keep it scoped to your user. +8. Click **Create secret**. The new secret appears in the Secrets list immediately. Its value is never readable from the UI after creation; to rotate the value, edit the secret and submit a new one. +### Private image credentials + +Use a **Private image credential** when a [runner](/platform/runners/) or [environment](/platform/environments/) needs to pull a Linux sandbox image from a private registry (for example GHCR, ECR, or a company registry). Warp uses the credential only to authenticate the image pull. It is not injected as an environment variable into the agent process. + +1. In the {VARS.WEB_APP} ({VARS.WEB_APP_URL}), open the **Secrets** page. +2. Click **Add secret** to open the **Add secret** side pane. +3. In the "Type" dropdown, choose **Private image credential**. +4. Enter a **Name** (for example, `GHCR_PULL`). Runners and environments reference the secret by this name. +5. Enter the **Registry host** as a bare hostname with no scheme or path — for example `ghcr.io`, not `https://ghcr.io/org`. +6. Enter the registry **Username** and **Password** (or access token). +7. Optionally, enter a **Description**. +8. Click **Create secret**. + +Private image credentials are team-scoped in the web app. After you create the secret, attach it by name when you configure a private Linux image on a runner, environment, or [factory runner definition](/factories/factory-as-code/#platform). The secret's registry host must match the host in the image reference. + --- ## Managing agent secrets with the CLI @@ -123,6 +141,30 @@ oz secret create --personal --value-file api_key.txt METABASE_API_KEY This is useful for long values such as JSON blobs or private keys. +#### Private image credentials (`docker-registry`) + +Create a typed private image credential with `oz secret create docker-registry`. Warp uses it to pull private Linux sandbox images; it is not injected as an environment variable. + +```bash +oz secret create docker-registry --team GHCR_PULL \ + --host ghcr.io \ + --username USERNAME \ + --password-file ./ghcr-token.txt +``` + +Flags: + +* `--host` — bare registry hostname with no scheme or path (for example `ghcr.io`). Required for non-interactive use; the CLI prompts when omitted. +* `--username` — registry username. Required for non-interactive use; the CLI prompts when omitted. +* `--password-file` — path to a file containing the registry password or access token. Prefer this over `--password` in scripts so the value does not appear in shell history or process listings. +* `--password` — registry password or access token on the command line. Conflicts with `--password-file`. Avoid in scripts. +* `--description` (`-d`) — optional description. +* `--team` / `--personal` — secret scope. + +If you omit `--host`, `--username`, or a password flag, the CLI prompts interactively. + +**Expected outcome.** `oz secret list` shows `GHCR_PULL` with type **Container Registry Credential**. Attach the secret by name on a runner, environment, or factory runner whose `linux.dockerImage` host matches `--host`. + #### Adding descriptions Descriptions help with auditing and rotation tracking. @@ -206,12 +248,14 @@ MY_MCP_SERVER_TOKEN personal 10:00am When a cloud agent starts, Warp determines which secrets are in scope and sets them as environment variables in the agent’s execution environment. -Today, secrets are provided as environment variables using the secret name as the variable name. For example: +Today, raw-value and most typed secrets are provided as environment variables using the secret name as the variable name. For example: ```bash METABASE_API_KEY=******** ``` +[Private image credentials](#private-image-credentials) are the exception: Warp uses them only to authenticate a private sandbox image pull. They are never injected into the agent process, even when named on a run or environment allowlist. + #### Secret size limit Because secrets are injected as environment variables, each resulting `NAME=value` entry has to fit inside the operating system's per-variable limit of 128 KiB (131,072 bytes), including the terminating null byte. The usable value length is 128 KiB minus that entry's environment-variable name, the `=` sign, and the terminating null byte.