Harness Authentication
Scion automatically handles discovering and injecting LLM credentials into agent containers so that the underlying harnesses (Claude, Gemini, etc.) can authenticate with their respective model providers (Anthropic, Google, OpenAI).
Note: This documentation covers how harnesses gain access to LLM models, as well as how agents authenticate to Git repositories.
Workstation vs. Hosted Brokers
Section titled “Workstation vs. Hosted Brokers”Every agent is started by a Runtime Broker on behalf of a Hub. What the agent can pick up from your machine depends on where that broker runs:
- Workstation (the broker inside
scion server start, on your machine, with the Hub on loopback and dev auth): API keys exported in the shell you runscionfrom are sent with the start request. The harness login files in your home directory are given to the agent too; see Host credential files on a workstation. Your gcloud ADC file is given to agents only when you opt in withauto_inject_gcloud_adc: true(the onboarding wizard offers it). Hub secrets take precedence over all of these. - Hosted brokers: the agent’s environment is strictly isolated from the broker’s host machine. You must provide credentials explicitly via Hub Secrets or profile settings, which are then securely injected into the agent container at launch.
Host credential files on a workstation
Section titled “Host credential files on a workstation”On a workstation server, an agent gets the harness login files from your home directory, for
example ~/.claude/.credentials.json after you sign in to Claude Code on this machine, or
~/.gemini/oauth_creds.json after a Gemini CLI login. You do not need to upload them as
secrets. This is controlled by the global setting use_host_credentials:
use_host_credentials: false # default: true on a workstationor scion config set --global use_host_credentials false.
- When it applies. Only when the broker runs inside a workstation server (not hosted mode) with dev auth, the start request comes over that server’s own connection, and the Hub endpoint is loopback. Hosted brokers never read host credential files, whatever the setting says.
- Which files. Only the credential files declared by the harness configs that ship with
Scion (the paths in the table under
auth-file). A template-bundled, project or user-installed harness config cannot add paths. A file must be a regular file inside your home directory, after following symlinks, and at most 1 MiB. Copilot’s~/.copilot/config.jsonis used only when it holds sign-in data; a config file with only preferences is skipped. - Precedence. A Hub secret with the same name or the same target path wins over the host file.
- When it is read. On every start, restart and resume. Turning the setting off takes effect on the next start; the server does not need a restart. If the settings file cannot be read, no host files are given to agents.
- What it does not cover. Environment variables (API keys come from your shell through the
start request) and gcloud ADC (opt in with
auto_inject_gcloud_adc: true).
The broker logs the names of the files it gave to an agent, never their contents.
The Container-Script Provisioning Model
Section titled “The Container-Script Provisioning Model”All harnesses are provisioned by a container-script (provision.py) that runs inside the
agent container, backed by the shared scion_harness Python library. Credential resolution is a
two-part collaboration:
- Host-side gather (Go): Before the container starts, Scion collects candidate credentials from environment variables and well-known file paths. On a hosted broker this includes only the secrets and variables explicitly injected into the agent; direct Hub-secret access from inside the agent is blocked.
- In-container select (
provision.py): The harness’s provisioner evaluates the staged candidates against the harness’s declared auth methods (theauth:block in itsconfig.yaml), selects one, and writes the harness-native configuration (e.g.~/.claude.json,~/.gemini/settings.json,~/.hermes/.env).
The selection logic lives in each bundle’s provision.py via scion_harness.AuthSpec /
ctx.select_auth(...). The order of methods in that spec — not the config.yaml autodetect
map — determines which credential wins when several are present.
When Scion picks the auth type before provisioning (at agent start, and in
the broker’s preflight check, which use the same auto-detect), a file
credential normally wins over an environment variable. One exception: for harnesses whose
default auth type is api-key (Claude, Gemini CLI, Grok Build, Hermes), an API
key in the environment wins over a gcloud-adc file credential, matching their
provision.py order. Every other file credential still wins.
Source precedence
Section titled “Source precedence”For each credential key, the resolution order is:
- Staged candidate / secret file — credentials the Hub or CLI explicitly staged for the agent.
- Environment variable — a matching variable in the agent’s process environment.
- Well-known file — a native credential file at its conventional path (e.g.
~/.config/gcloud/application_default_credentials.json).
Staged candidates are matched across all keys before the process-environment fallback fires, so a user-provided secret is never shadowed by a stale container environment variable.
Vertex AI / GCP metadata is not a “source” gathered this way — it is an auth type
(vertex-ai) selected when a GCP service account is assigned to the agent. At runtime, tokens are
served by Scion’s in-container GCP metadata server.
The Three-Stage Auth Workflow
Section titled “The Three-Stage Auth Workflow”Beyond a plain API key, most harnesses authenticate through an interactive login. Scion supports this with a no-auth start → authenticate → capture workflow that lets you bring an agent up with no credentials, log in interactively, and then persist the resulting credentials so future agents start pre-authenticated.
- No-auth start — When no usable credentials are found, provisioning does not fail. The agent still starts and drops to an interactive shell, with a graceful warning explaining that it is running in no-auth mode. See No-Auth Fallback.
- Authenticate — Inside the agent (via
scion attachor the terminal page), you run the harness’s native login command (e.g.claude setup-token,codex login --device-auth,copilot login,agy). Each bundle’s no-auth message tells you exactly which command to run. - Capture — You run the bundle’s
capture_auth.py, which locates the credential files the harness just wrote and stores them as project secrets. On the next start, the host stages those secrets back into the agent and provisioning selects them automatically. See Capturing Credentials.
If you already have a plain API key (or a credential file) you can skip stages 1–3 entirely by providing it up front — see Credential Sources & Setup.
The per-harness login and capture details:
| Harness | No-auth login command | Captured secret(s) |
|---|---|---|
| Claude | claude setup-token |
CLAUDE_AUTH (file ~/.claude/.credentials.json); CLAUDE_CODE_OAUTH_TOKEN (extracted from the terminal scrollback after setup-token) |
| Gemini | native Gemini auth (e.g. OAuth login) | GEMINI_OAUTH_CREDS (file ~/.gemini/oauth_creds.json) |
| Codex | codex login --device-auth |
CODEX_AUTH (file ~/.codex/auth.json) |
| OpenCode | opencode auth login |
OPENCODE_AUTH (file ~/.local/share/opencode/auth.json) |
| Copilot | copilot login |
COPILOT_CONFIG (file ~/.copilot/config.json) |
| Hermes | hermes setup |
(none — Hermes is API-key only; provide the key up front) |
| Pi | pi, then /login |
PI_AUTH (file ~/.pi/agent/auth.json) |
| Antigravity | agy |
AGY_TOKEN (file ~/.gemini/antigravity-cli/antigravity-oauth-token, with a gnome-keyring fallback) |
Authentication Approaches
Section titled “Authentication Approaches”Scion supports two approaches to harness authentication: the Automatic (Implicit) Approach and the Explicit Path.
The Automatic (Implicit) Approach
Section titled “The Automatic (Implicit) Approach”By default, when an agent starts, the provisioner discovers and applies credentials automatically: it gathers the staged candidates and environment, selects the best method according to the harness’s declared priority order (usually preferring a direct API key over a credential file), validates the result, and writes the harness’s native settings. The decision is made right before the agent starts (late-binding), so the final strategy reflects whatever credentials are actually available at launch.
If no usable credentials are found, provisioning falls back to no-auth rather than failing (see No-Auth Fallback below).
The Explicit Path
Section titled “The Explicit Path”You can override the automatic detection by explicitly forcing a specific authentication method in your agent’s profile or template configuration (using the auth_selectedType field). You can also override this on the fly when starting an agent by using the --harness-auth flag (e.g., scion start my-agent --harness-auth vertex-ai).
When you configure the explicit path, the automatic fallback is disabled. The credentials required for your chosen method must be present (either gathered from the local environment or provided via Hub secrets), otherwise the agent will immediately fail to start.
The available explicit authentication types are:
- Provider API Key (
api-key): Direct API key authentication. - OAuth Token (
oauth-token): A raw OAuth token injected via an environment variable (e.g. Claude’sCLAUDE_CODE_OAUTH_TOKEN). - Vertex Model Garden (
vertex-ai): Google Cloud Vertex AI using Application Default Credentials (ADC). - Harness specific credential file (
auth-file): A credential file native to the harness, such as an OAuth credentials file.
Not every harness supports every type — see the auth capability matrix.
Credential Sources & Setup
Section titled “Credential Sources & Setup”The following sections detail the environment variables and files that Scion consults for each authentication method, and how to configure them locally or via the Scion Hub.
Provider API Key (api-key)
Section titled “Provider API Key (api-key)”This is the simplest method, relying on standard environment variables to provide a direct API key.
Required Sources:
- Claude:
ANTHROPIC_API_KEY - Gemini:
GEMINI_API_KEYorGOOGLE_API_KEY - Antigravity:
GEMINI_API_KEYorGOOGLE_API_KEY(lowest-priority fallback method) - OpenCode:
ANTHROPIC_API_KEYorOPENAI_API_KEY(Anthropic preferred) - Codex:
CODEX_API_KEYorOPENAI_API_KEY(Codex-specific key preferred) - Hermes:
ANTHROPIC_API_KEY,OPENAI_API_KEY, orGOOGLE_API_KEY(in that order) - Copilot: a GitHub token via
COPILOT_GITHUB_TOKEN,GH_TOKEN, orGITHUB_TOKEN
Local Setup:
export ANTHROPIC_API_KEY="sk-ant-api01-..."scion start --harness claude my-agentHub Setup: You can establish these secrets via the Scion Hub Web Interface by navigating to the Secrets section, or you can use the CLI:
scion hub secret set ANTHROPIC_API_KEY "sk-ant-api01-..."scion hub secret set GEMINI_API_KEY "AIza..."OAuth Token (oauth-token)
Section titled “OAuth Token (oauth-token)”Some harnesses accept a raw OAuth token through an environment variable instead of a full
credential file. This is distinct from the auth-file method (a file on disk) and from
Antigravity’s file-based OAuth token.
Required Sources:
- Claude:
CLAUDE_CODE_OAUTH_TOKEN(generate on your host withclaude setup-token).
Hub Setup:
scion hub secret set CLAUDE_CODE_OAUTH_TOKEN "sk-ant-oat01-..."This is also the token that Claude’s capture_auth.py stores automatically after an in-agent
claude setup-token login (see Capturing Credentials).
Vertex Model Garden (vertex-ai)
Section titled “Vertex Model Garden (vertex-ai)”Uses Google Cloud’s Vertex AI endpoints with Application Default Credentials (ADC). On a Hub, Scion supports two primary ways to authenticate: via an assigned GCP Identity (Service Account) or an injected ADC file secret. Supported by Claude, Gemini, OpenCode, and Antigravity (Codex, Copilot, and Hermes do not support Vertex AI).
Required Sources:
- Assigned GCP Identity: If the agent is assigned a Hub-managed GCP Service Account via metadata emulation, Vertex AI will automatically use it. This is the recommended and most secure approach.
- ADC JSON file: On a workstation, your host file at
~/.config/gcloud/application_default_credentials.jsonis used whenauto_inject_gcloud_adc: trueis set in your global settings. Otherwise, you can upload an ADC file via thegcloud-adcfile secret or specify theGOOGLE_APPLICATION_CREDENTIALSenvironment variable pointing to a custom credential file. GOOGLE_CLOUD_PROJECT: Your Google Cloud project ID.GOOGLE_CLOUD_REGION: The region (e.g.,us-east5). Required for Claude, optional but recommended for Gemini.GOOGLE_CLOUD_LOCATIONandCLOUD_ML_REGIONare accepted as alternatives. If more than one is set, Scion uses them in this order:GOOGLE_CLOUD_LOCATION, thenGOOGLE_CLOUD_REGION, thenCLOUD_ML_REGION. It prints a warning whenGOOGLE_CLOUD_LOCATIONandGOOGLE_CLOUD_REGIONare both set to different values. Hermes checksVERTEX_REGIONfirst. Hermes, Antigravity and OpenCode do not readCLOUD_ML_REGIONdirectly (OpenCode also acceptsVERTEX_LOCATION, last).
Workstation Setup:
# Assuming ADC is already generated via `gcloud auth application-default login`,# and ~/.scion/settings.yaml contains: auto_inject_gcloud_adc: trueexport GOOGLE_CLOUD_PROJECT="my-project"export GOOGLE_CLOUD_REGION="us-east5"scion start --harness claude my-agentHub Setup: On a shared Hub, the recommended approach is to assign a GCP Service Account to the agent at creation time.
Alternatively, to use an ADC file secret:
# 1. Upload the ADC credential file (written to ~/.config/gcloud/application_default_credentials.json in container)scion hub secret set --type file \ --target ~/.config/gcloud/application_default_credentials.json \ gcloud-adc @~/.config/gcloud/application_default_credentials.json
# 2. Set the environment variablesscion hub secret set GOOGLE_CLOUD_PROJECT "my-project"scion hub secret set GOOGLE_CLOUD_REGION "us-east5"Harness specific credential file (auth-file)
Section titled “Harness specific credential file (auth-file)”Some harnesses authenticate with their own credential files, such as OAuth credential files. Scion stages the file at the harness’s expected path inside the container. The file is provided either by uploading it as a file secret, or (on a workstation) by having it present at its conventional path in your home directory; see Host credential files on a workstation.
Well-known paths & file-secret keys:
| Harness | Container path | File-secret key |
|---|---|---|
| Gemini | ~/.gemini/oauth_creds.json |
GEMINI_OAUTH_CREDS |
| Claude | ~/.claude/.credentials.json |
CLAUDE_AUTH |
| Codex | ~/.codex/auth.json |
CODEX_AUTH |
| OpenCode | ~/.local/share/opencode/auth.json |
OPENCODE_AUTH |
| Copilot | ~/.copilot/config.json |
COPILOT_CONFIG |
| Antigravity | ~/.gemini/antigravity-cli/antigravity-oauth-token |
AGY_TOKEN |
Workstation Setup:
If you have run the harness’s native authentication command (e.g. an OAuth login on your host), the workstation broker gives the resulting credential file to the agent, as long as use_host_credentials is not turned off.
Hub Setup: Upload the credential file as a file secret via the Web Interface or CLI, targeting the harness’s expected path:
scion hub secret set --type file \ --target ~/.gemini/oauth_creds.json \ GEMINI_OAUTH_CREDS @~/.gemini/oauth_creds.jsonNo-Auth Fallback
Section titled “No-Auth Fallback”When automatic detection finds no usable credentials, and the harness permits it, provisioning does not abort — it falls back to a no-auth mode so the agent still starts (typically dropping to an interactive shell). A graceful warning is written to the agent’s logs explaining that no auth candidates were found, that it is running in no-auth mode, and which login command to run next.
This lets you launch an agent, log in to the harness interactively (e.g. claude setup-token,
copilot login, hermes setup, agy), and then capture the resulting credentials for reuse
(see below). Every bundle declares no_auth.behavior: drop-to-shell along with a message, and
optionally a login command to run first. Copilot runs no command: it starts a shell with sign-in
instructions. A harness-config can add environment variables for no-auth mode only, in a
no-auth-env.yaml file next to its config.yaml with one env map. Copilot’s sets
DBUS_SESSION_BUS_ADDRESS: unix:path=/home/scion/.scion/harness/no-session-bus, so in that mode
it runs with no session bus and keeps its sign-in in ~/.copilot/config.json. Starts with
credentials never get these variables.
The fallback applies only to automatic resolution. If you selected an auth type via the Explicit Path, the fallback is disabled — the required credentials must be present or the agent fails to start with an actionable error.
Runtime Broker check before the container starts. A Runtime Broker checks the staged auth
candidates before it creates the container, and fails the start at once when the harness’s
provisioner would certainly reject it: an explicitly selected auth type whose credentials are all
missing, or, for a harness that has no no-auth fallback, no satisfied auth type at all. The error
names the harness and the accepted auth types and, for a selected auth type, the environment
keys it looks for, never their values. An auth type that declares required_files is never
rejected by this check, because a credential file can reach the container by routes the Runtime
Broker cannot see (volumes, file secrets, a persistent home, pre-start hooks). All shipped harness
configs declare a no-auth fallback, so for them only an explicit auth type can fail this way.
Capturing Credentials from a Running Agent
Section titled “Capturing Credentials from a Running Agent”For harnesses that authenticate through an interactive login (rather than a plain API key), you can capture the credentials an agent produced and store them as a secret, so future agents start pre-authenticated instead of dropping to no-auth.
After logging in interactively inside the agent (via scion attach or the terminal page), you can run the credential capture process.
Secret Scope Selection
Section titled “Secret Scope Selection”Credential capture supports scoping captured credentials to either the project (visible to all agents in the project) or the user (personal secrets visible only to your own agents).
- In the Web UI: Clicking the Capture Auth button triggers an interactive dialog allowing you to choose between Project scope and User scope before executing the capture script.
- Via CLI/Script: The
capture_auth.pyscript defaults touserscope with progeny enabled. You can optionally override this with--scope projectto make the credential available to all users in the project:Terminal window # Capture credentials to the user scope (default)python3 ~/.scion/harness/capture_auth.py# Capture credentials to the project scopepython3 ~/.scion/harness/capture_auth.py --scope project
Hub admins can restrict this to user scope only. If the “Restrict agent-written secrets to
profile scope” setting is on (Admin > Server Config, agent_secrets.user_scope_only), the hub
rejects any project-scope write an agent attempts — capture included — with a 403, whatever
harness, flag, or --force is used. In the Web UI, the Project option in the Capture Auth dialog
is disabled with an explanation and Profile is preselected while the setting is on; retrying a
rejected capture with --scope user (or via the CLI/Script path above) still works. This does not
affect user-originated project writes made directly through the web UI or scion hub secret set --project.
How capture works
Section titled “How capture works”The host generates a capture manifest (inputs/capture-auth-config.json) from the harness’s
auth.types.*.required_files declarations — every credential file the harness can authenticate
with that has a well-known path. capture_auth.py reads that manifest, locates each file the
harness just wrote, and stores it as a secret by shelling out to
sciontool secret set <key> @<file> --type <type> --target <path> --scope <project|user> --allow-progeny.
By default, all capture paths use user scope with progeny enabled (--allow-progeny), meaning the credentials are kept private to your user identity but safely passed down to any child agents (progeny) your agent creates.
- What is captured — the harness’s credential file(s). For example, Codex captures
~/.codex/auth.jsonas theCODEX_AUTHfile secret; Gemini captures~/.gemini/oauth_creds.jsonasGEMINI_OAUTH_CREDS. See the table in The Three-Stage Auth Workflow. - Where it goes — into the secret store (the Hub’s secret store), scoped either to the project or the originating user. This is why captured credentials survive container restarts: the file lives in the store, not in the ephemeral container, and the host re-stages it on every subsequent start.
- Harness-specific extras — some bundles override the generic flow:
- Claude additionally scans the terminal scrollback for the
sk-ant-oat…token printed byclaude setup-tokenand stores it as theCLAUDE_CODE_OAUTH_TOKENenvironment secret. - Antigravity falls back to extracting
AGY_TOKENfrom the container’s gnome-keyring (viasecret-tool) when no token file is found on disk.
- Claude additionally scans the terminal scrollback for the
- API-key-only harnesses — Hermes declares no credential files, so there is nothing for
capture_auth.pyto capture; provide its API key up front instead.
Exit codes
Section titled “Exit codes”The script’s exit code distinguishes outcomes:
| Code | Meaning |
|---|---|
0 |
One or more credentials captured successfully. |
2 |
No credentials found to capture (nothing logged in yet, or the harness has no capturable files). |
3 |
A conflict — a secret with that key already exists. Re-run with --force to overwrite it. |
1 |
An error occurred while capturing. |
# Overwrite an existing captured secretpython3 ~/.scion/harness/capture_auth.py --forcePersistence Across Restarts
Section titled “Persistence Across Restarts”Once captured, credentials live in the project secret store rather than in the ephemeral agent container. On each subsequent start:
- The host-side gather stages the stored secret back into the agent (as a candidate or file secret).
provision.pyfinds it and selects the corresponding auth method automatically.- The agent starts pre-authenticated — no interactive login required.
This means the no-auth → authenticate → capture cycle is a one-time cost per credential. Restarting, stopping, or resuming the agent reuses the captured secret.
Clearing or replacing captured credentials
Section titled “Clearing or replacing captured credentials”Captured credentials are ordinary project secrets, so you manage them with the secret commands:
# Replace a captured credential: re-run capture with --force, or overwrite the secret directlyscion hub secret set CODEX_AUTH @~/.codex/auth.json --type file --target ~/.codex/auth.json
# Remove a captured credential entirelyscion hub secret clear CODEX_AUTHAfter clearing a captured secret, the next agent start reverts to no-auth (or whatever other credential is available), letting you re-run the login → capture cycle.
Repairing Auth on a Running Agent
Section titled “Repairing Auth on a Running Agent”If a long-running agent’s Hub token expires and it cannot self-refresh (for example after a Hub signing-key rotation), you can inject a fresh token without restarting the agent:
scion reset-auth <agent-name>This generates a new token on the Hub, pushes it into the running container, and signals the agent to restart its token-refresh loop. If the signal does not reach the agent, it still picks up the new token: the agent checks its token file every few seconds and adopts a new token the Hub accepts through the same reset. It requires Hub connectivity and only works on a running agent (a stopped agent gets a fresh token on its next start). The same action is available as a Reset Auth button in the web UI. See Diagnostics to identify when this is needed.
Diagnostics
Section titled “Diagnostics”Two diagnostic commands help troubleshoot auth and connectivity:
-
scion doctor(host-side): checks host prerequisites and, when a Hub is configured, the Hub and the platform it manages — Git, tmux, Hub reachability and authentication, where the Hub credential came from (hub-credential), the Hub’s Platform Health summary, and the active container runtime (Docker/Podman daemon or Kubernetes cluster access). Supports--format json, which emitsformatVersion: 2withgeneratedAt, ahubblock (endpoint, version, serving instance and credential source) andplatformHealth.state(ok,skippedorunavailable, with areasoncode when notok). Seescion doctor. -
sciontool doctor(in-container): checks the agent’s health from inside the container — required environment variables, the Hub token (presence, format, expiry), Hub reachability, token validity (a read-only check that leaves the agent’s token untouched), the GCP metadata server and token acquisition, and the GitHub App token. When the token check fails it prints a remediation hint pointing you atscion reset-auth. It also reports the credential held by the long-runningsciontool initprocess, which the other checks cannot see, because they read the token file. Doctor shows:- whether init holds the same credential as the token file (compared by credential ID and a short hash, never the value);
- init’s last heartbeat, refresh and start-up check results, with times;
- whether init’s credential has expired or is refused.
The check fails when init’s credential has expired or its requests are refused (401/403). When the credential has expired or the Hub refused it, doctor says how to reload the credential. In the 20 seconds after a new token file is written, init may still be switching to it, so doctor only warns and asks you to run it again. Init publishes this state in a root-owned file. When the state file is absent and
init(PID 1) is thesciontoolbinary running as a non-root user (such asscionon Kubernetes),sciontool doctorreports[INFO] Init credential check not applicable: init (PID 1) runs as a non-root user and does not publish its credential stateinstead of a warning; when PID 1 runs with effective UID0or its privilege cannot be determined, a missing state file is reported as[WARN] Init credential state unavailable .... When the Hub refuses a GCP credential request with HTTP403, the in-container metadata server opens a capped exponential back-off window with jitter (base 10 seconds, max 5 minutes), tracked separately for the access token and for identity tokens: during the window, token requests receive the cached403refusal (credential refused by hub; retry after ...) without calling the Hub and one log line is written per back-off step. A successful fetch resets the back-off, as does a change to the agent’s assignment (its service account or Hub credential), which is retried at once; any other error returns502with no back-off. Concurrent identity-token fetches are deduplicated per target audience.
Agent Progeny & Secret Access
Section titled “Agent Progeny & Secret Access”When an agent creates sub-agents (progeny), Scion enforces strict controls over which secrets those child agents can access.
By default, child agents operate under a granular secret access model. They do not automatically inherit all secrets from the project or their parent. Instead, they only have access to the credentials necessary to perform their specific tasks, maintaining a least-privilege security boundary across the agent ancestry chain.
Propagation of User-Scoped Secrets (--allow-progeny)
Section titled “Propagation of User-Scoped Secrets (--allow-progeny)”For user-scoped (personal) secrets, you can explicitly configure them to propagate down the agent ancestry chain (progeny) by setting the --allow-progeny flag upon creation:
scion hub secret set --allow-progeny MY_PERSONAL_TOKEN my-secret-valueWhen a child agent is created, started, or reads secrets at runtime, Scion walks the ancestry and delegation chain of the agent (from child to ancestors) to resolve secrets. If the secret’s creator is in the agent’s ancestry chain AND allow-progeny is enabled — and, when the agent’s delegation chain has recorded provenance, every hop on the chain allows secret.use, every agent delegator on the chain is live and holds project:secret:read, and the root user is active, admitted to the project, not restricted from secret.use, and the recorded author of the secret — the secret is safely inherited and projected into the descendant agent (at start, restart, and resume, progeny-shared owner secrets are decided once per request on the owner-material chain, and a legacy chain with no recorded ancestry is withheld; see Propagation to Descendant Agents). Under the hood, this dynamically manages implicit progeny policies (progeny-secret-access:<id>) on the Scion Hub.
Troubleshooting
Section titled “Troubleshooting”“no valid auth method found”
Section titled ““no valid auth method found””The harness couldn’t find any usable credentials through the automatic implicit approach. Check that you have exported the correct environment variables locally, or that your Hub secrets are properly assigned and available to the agent’s workspace. If you intend to log in interactively, the agent will have dropped to a shell in no-auth mode instead — follow the printed login command, then capture.
“auth type selected but…”
Section titled ““auth type selected but…””You have configured the Explicit Path (e.g., selecting vertex-ai) but the specific credentials required for that path (like GOOGLE_CLOUD_PROJECT) are missing. The explicit path disables fallback, so ensure all required sources for the chosen explicit type are provided.
“no auth method satisfied”
Section titled ““no auth method satisfied””The Runtime Broker refused the start before creating a container (see No-Auth Fallback). The message names the harness, the accepted auth types and, for a selected auth type, the credentials it looks for. Provide one of them as a Hub secret (scion hub secret set) or a Hub environment setting (scion hub env set), or select a different auth type with --harness-auth.
“agent secrets could not be resolved” or “agent environment settings could not be read”
Section titled ““agent secrets could not be resolved” or “agent environment settings could not be read””Create, start, restart, resume and waking an agent for a direct message fail closed with 503 when the Hub cannot resolve the agent’s configured secret metadata or read its stored environment settings, instead of starting the agent without them. A start leaves the agent as it was, a restart leaves it stopped (its stop leg has already run), and a failed create is rolled back. A provision-only create still succeeds; the agent’s later start fails closed. A reincarnation answers 202 and then fails at its start leg: it is recorded as failed with the same message and the previous config is restored. This points to a secret backend or database problem on the Hub, not a missing credential (an agent with no secrets or settings starts normally). Retry once the Hub’s backend is healthy; the Hub’s server log has the cause. When an individual secret’s metadata resolves but the secret store cannot return its value (access, not_found, or missing), the Hub skips that secret so the dispatch proceeds without it and returns a warning in warnings (secrets not delivered because the secret store could not return them: <items>; the agent was <started|restarted|created> without them; see Start-Time Authorization).
“the hub issued no agent token for this start”
Section titled ““the hub issued no agent token for this start””A Hub-dispatched create, start, or restart requires a Hub-issued agent token (StartOptions.HubIssuedToken). If the Hub issues none, the Runtime Broker removes any previous ~/.scion/scion-token file from the Agent home and fails the start with 500 runtime_error (the hub issued no agent token for this start; check the hub's agent token service) without starting a container; on a restart, the running container is stopped first, leaving the agent stopped. Check the Hub’s agent token signing configuration (server.keyring_file / JWT signing keys) and server logs. Setting SCION_AUTH_TOKEN in an agent’s or harness-config’s env does not satisfy this requirement: in Runtime Broker mode that variable is stripped and ignored with a start warning.
“unknown auth type”
Section titled ““unknown auth type””The value you passed to --harness-auth (or auth_selectedType) is not one this harness supports. Valid universal types are api-key, oauth-token, auth-file, and vertex-ai, but each harness only accepts a subset — see the auth capability matrix.
capture_auth.py reports “no credentials found to capture” (exit 2)
Section titled “capture_auth.py reports “no credentials found to capture” (exit 2)”Either you have not completed the interactive login yet, or the harness has no capturable credential file (e.g. Hermes is API-key only). Complete the login command printed in the no-auth message first, then re-run capture.
Vertex AI not activating
Section titled “Vertex AI not activating”For Claude, Vertex Model Garden requires all three variables: credentials, project, and region. If any are missing, it will not authenticate. For Gemini, both credentials and a project are required. Ensure these are set either in your local environment or as Hub secrets.
Git Authentication
Section titled “Git Authentication”Scion agents frequently need to interact with remote Git repositories to push changes, open PRs, or sync states. Authentication with GitHub is handled securely using native GitHub App integration or Personal Access Tokens (PATs).
GitHub App Integration (Recommended)
Section titled “GitHub App Integration (Recommended)”Scion provides deep integration with GitHub Apps to manage Git credentials automatically, eliminating the need to manage static PATs.
- Automated Token Refresh: The Scion Hub maintains a background refresh loop that constantly mints valid installation tokens for your GitHub App.
- Credential Helper: Scion injects
sciontoolas a Git credential helper into the agent container (git config --global credential.helper). - On-Demand Tokens: When the agent executes a
git clone,push, orpull, Git asks the credential helper for a password.sciontoolretrieves the fresh, short-lived token provided by the Hub, ensuring operations never fail due to token expiration—even for long-running agents.
This flow is enabled for a project whose GitHub App installation association is authorized (checked when the association is recorded and at every token mint): the project’s git remote must be on the configured GitHub host (github.com, or the host of github_app.api_base_url), the installation must be active and its account must match the remote’s owner, and either an active Hub admin bound the installation to that remote (PUT /api/v1/projects/{id}/github-installation, recorded in scion.dev/github-installation-binding with installation_id, remote, bound_by, and bound_at) or the project creator’s user-scope GITHUB_TOKEN secret has at least pull access to the repository on GitHub (pull-only proof caps the minted token to read-only, whereas push access allows write permissions). On agent create, start, restart, and token refresh, the Hub mints a GitHub App installation token from the agent’s own project, or, when the agent’s project has no installation configured, from the project named by the scion.dev/github-token-source-project label only when the agent’s authoritative source user is active and holds agent.create in that source project (and that source project’s installation association is authorized).
Personal Access Tokens (PATs)
Section titled “Personal Access Tokens (PATs)”If GitHub App integration is not available, you can use a Personal Access Token. When using a PAT:
- You create a fine-grained PAT on GitHub.
- You provide the PAT to the Hub as a secret named
GITHUB_TOKEN. - Scion injects this token into the agent container as an environment variable (
GITHUB_TOKEN), which Git uses for HTTPS authentication.
For detailed instructions on setting this up, see Git-Based Projects.
Multi-Repository (Convention-Based) Secrets
Section titled “Multi-Repository (Convention-Based) Secrets”When your templates reference skills or repositories across multiple GitHub owners or organizations, a single default GITHUB_TOKEN may not have the required permissions.
To address this, Scion supports convention-based multi-GitHub credential resolution using project secrets (e.g., GH_OWNER__REPO or GH_OWNER). For setup examples, precedence rules, and naming conventions, see the GitHub Multi-Repo Credentials section in the Secrets Guide.