Secret & Environment Management
Scion’s hosted architecture provides a centralized way to manage configuration and sensitive data across your team. Instead of sharing .env files or hardcoding credentials, you can use the Scion Hub to store and inject environment variables and secrets into your agents.
Variables vs. Secrets
Section titled “Variables vs. Secrets”Scion distinguishes between regular environment variables and secure secrets:
| Feature | Environment Variables (env) |
Secrets (secret) |
|---|---|---|
| Visibility | Read/Write (via API and CLI) | Write-only (cannot be read back) |
| Storage | Plaintext in database | Encrypted at rest / Externally stored |
| Use Case | API URLs, log levels, feature flags | API keys, passwords, private keys |
| Injection | Environment variables only | Environment, files, or JSON variables |
Scoping
Section titled “Scoping”Both variables and secrets can be scoped to different levels. Scion resolves these hierarchically when an agent starts:
- User Scope: Personal secrets for a specific user. Applied to all agents owned by that user.
- Project Scope: Project-level secrets. Available to all agents running in a specific Project.
- Broker Scope: Infrastructure-level secrets. Available only to agents running on a specific Runtime Broker (e.g., for hardware-specific config).
Resolution Priority: When multiple scopes define the same secret key, the more specific scope wins. Broker scope has the highest priority, followed by Project, then User, then Hub. Template env blocks and CLI --env flags are layered on top of resolved secrets.
Injection Modes
Section titled “Injection Modes”Both environment variables and secrets support Injection Modes, which control how they are delivered to the agent container:
- As Needed (Default): The variable or secret is only injected if it is explicitly requested in the agent’s template (
scion-agent.yaml) or harness configuration. This is the recommended mode for most credentials to minimize the attack surface. - Always: The variable or secret is injected into every agent started within that scope, regardless of whether it is explicitly requested.
You can set the injection mode via the CLI using the --always flag:
# Set a variable to be always injected in a projectscion hub env set --project --always LOG_LEVEL=debug
# Set a secret to be always injected for a userscion hub secret set --always MY_GLOBAL_TOKEN secret-valueManaging Environment Variables
Section titled “Managing Environment Variables”Use the scion hub env command suite to manage non-sensitive configuration.
Setting Variables
Section titled “Setting Variables”# Set a user-scoped variablescion hub env set API_URL=https://api.example.com
# Set a project-scoped variable (inferred from current directory)scion hub env set --project LOG_LEVEL=debug
# Set a variable only for a specific brokerscion hub env set --broker=my-gpu-node CUDA_VISIBLE_DEVICES=0Managing Secrets
Section titled “Managing Secrets”Secrets are write-only from host-level CLI commands and the Web Dashboard. Once set, their values cannot be read back by users. However, authorized agents running inside their containers can securely retrieve project-scoped secrets at runtime via the Hub API or the sciontool utility.
Setting Secrets
Section titled “Setting Secrets”Secrets can be set manually via the CLI or Web Dashboard, or gathered interactively during agent creation.
# Set a user-scoped secretscion hub secret set ANTHROPIC_API_KEY sk-ant-api01-...
# Set a project-scoped secretscion hub secret set --project DB_PASSWORD my-secure-passwordStreamlined Project Secrets via scion secret
Section titled “Streamlined Project Secrets via scion secret”While scion hub secret manages secrets at any scope (user, project, broker, hub), you can use the streamlined, top-level scion secret command group on your host to manage project-scoped secrets directly within your current project context:
# Set a project-scoped secret (inferred from current directory context)scion secret set ANTHROPIC_API_KEY sk-ant-api01-...
# List all project secrets (metadata only)scion secret list
# Get metadata for a specific project secretscion secret get ANTHROPIC_API_KEYInteractive Secrets-Gather:
If a template requires specific secrets (defined in scion-agent.yaml), Scion utilizes an interactive secrets-gather pipeline during agent creation. It will automatically prompt you to securely input any missing values and store them in the backend, ensuring sensitive credentials are never written to plain text configuration files.
Secret Types
Section titled “Secret Types”Secrets can be projected into the agent container in three ways:
- Environment (Default): Injected as a standard environment variable.
- File: Written to a specific path on the agent’s filesystem.
- Variable: Added to a JSON file at
~/.scion/secrets.jsonfor programmatic access by the harness.
Mounting Files as Secrets
Section titled “Mounting Files as Secrets”You can use the @ prefix to read a secret’s value from a local file. This is particularly useful for SSH keys or service account JSONs.
# Upload an SSH private key and mount it to the standard location in the agentscion hub secret set --type file --target ~/.ssh/id_rsa SSH_KEY @~/.ssh/id_rsaWell-Known Secrets
Section titled “Well-Known Secrets”Scion recognizes certain secret names and uses them for built-in platform features. Using the correct name causes the broker to perform additional setup automatically.
| Secret Name | Type | Target Path | Effect |
|---|---|---|---|
scion-telemetry-gcp-credentials |
file |
~/.scion/telemetry-gcp-credentials.json |
Sets SCION_OTEL_GCP_CREDENTIALS, auto-enables GCP-native telemetry export, and reads project_id from the file if SCION_GCP_PROJECT_ID is not set. |
Example — provisioning GCP telemetry credentials:
scion hub secret set \ --type file \ --target ~/.scion/telemetry-gcp-credentials.json \ scion-telemetry-gcp-credentials @/path/to/sa-key.jsonOnce set, every agent that starts will have the credential file mounted at ~/.scion/telemetry-gcp-credentials.json and GCP-native telemetry will be enabled automatically — no additional environment variable configuration required. See Metrics & OpenTelemetry for the full setup guide.
Agent Runtime Secret Retrieval
Section titled “Agent Runtime Secret Retrieval”While environment and file-based injection deliver secrets at agent startup, Scion also supports dynamic runtime secret retrieval from inside the agent container. This enables harnesses or scripts to request project-scoped secrets programmatically as-needed, reducing initial environment exposure.
This runtime retrieval is accessible either via the sciontool helper utility or directly through the Hub API.
Using sciontool
Section titled “Using sciontool”From inside an agent container, use the sciontool secret command suite:
-
List Available Secrets: Lists metadata (keys, types, and injection targets) for all secrets in the agent’s project. Sensitive values are omitted.
Terminal window sciontool secret listOutput:
KEY TYPE TARGET--- ---- ------MY_API_KEY environment MY_API_KEYCLAUDE_AUTH file ~/.claude/.credentials.json -
Retrieve a Secret Value: Decodes and outputs the raw bytes of a specific secret to stdout (ideal for piping or scripting).
Terminal window sciontool secret get MY_API_KEYExample script usage:
Terminal window export API_KEY=$(sciontool secret get MY_API_KEY) -
Set a Project Secret: You can also write/update secrets from inside the container to persist credentials discovered or generated at runtime:
Terminal window sciontool secret set NEW_TOKEN "secret-value"
Using the Hub API Directly
Section titled “Using the Hub API Directly”Under the hood, sciontool interacts with the Hub’s agent-specific secrets API:
GET /api/v1/agents/{agentID}/secrets: Lists available secret metadata in the agent’s project.GET /api/v1/agents/{agentID}/secrets/{key}: Retrieves a single secret’s metadata and its base64-encoded value.PUT /api/v1/agents/{agentID}/secrets/{key}: Stores or updates a secret.
Security & Audit Logging
Section titled “Security & Audit Logging”- Authentication: API access is restricted to the running agent container. The agent must include its unique Hub-issued JWT (loaded from
SCION_HUB_TOKEN) in theAuthorization: Bearer <token>header of every request. - Authorization: Agents are strictly bounded to their own project’s secrets. They cannot access secrets in other projects, user-scoped secrets, or global Hub secrets unless explicitly shared via progeny policies (descendant access).
- Audit Trail: To ensure accountability, every runtime read and write operation is fully audited on the Hub. Successful and failed retrieval attempts log an audit event (
agent_secret_read) identifying the calling agent, requested key, and status.
GitHub Multi-Repo Credentials
Section titled “GitHub Multi-Repo Credentials”When Scion resolves gh:// URIs in template skill lists, it authenticates with the default GITHUB_TOKEN — typically a GitHub App installation token scoped to the project’s own repository. This works for skills in public repos and the workspace repo itself, but fails with 404 when a gh:// URI references a skill in a different private repository.
To solve this, Scion supports convention-based project secrets that automatically provide the right credential for each gh:// URI based on the GitHub owner and repository name. No template changes are needed — the resolver derives a secret name from the URI and looks it up in your project secrets.
Naming Convention
Section titled “Naming Convention”Create a project secret with one of these naming patterns:
| Pattern | Scope | Example |
|---|---|---|
GH_{OWNER}__{REPO} |
One specific repo | GH_ACME_CORP__PRIVATE_SKILLS |
GH_{OWNER} |
All repos under an owner/org | GH_ACME_CORP |
Normalization rules: uppercase the name, replace hyphens (-) and dots (.) with underscores (_). The double underscore (__) separates owner from repo. Note: Because of this normalization, names that differ only by hyphens, dots, or underscores (e.g., acme-corp and acme_corp) will resolve to the same secret name.
Examples:
| GitHub Repository | Secret Name |
|---|---|
acme-corp/private-skills |
GH_ACME_CORP__PRIVATE_SKILLS |
my-org/my.special.repo |
GH_MY_ORG__MY_SPECIAL_REPO |
All repos under acme-corp |
GH_ACME_CORP |
# Repo-specific credential (fine-grained PAT or classic PAT with repo access)scion hub secret set --project GH_ACME_CORP__PRIVATE_SKILLS github_pat_...
# Or cover all repos under an owner with one tokenscion hub secret set --project GH_ACME_CORP github_pat_...Once set, template URIs resolve automatically — no ?token= annotation needed:
skills: - uri: "gh://acme-corp/private-skills/my-skill" # auto-uses GH_ACME_CORP__PRIVATE_SKILLSAn explicit ?token=SECRET_NAME parameter on the URI still works as an override when disambiguation is needed.
Credential Resolution Order
Section titled “Credential Resolution Order”When resolving a gh://owner/repo/... URI, Scion checks credentials in this order:
| Priority | Source | Description |
|---|---|---|
| 1 | ?token=SECRET_NAME on the URI |
Explicit override — bypasses convention lookup |
| 2 | GH_{OWNER}__{REPO} |
Repo-specific convention secret |
| 3 | GH_{OWNER} |
Owner-level convention secret |
| 4 | Default GITHUB_TOKEN |
App token, environment, or provision secret cascade |
| 5 | Unauthenticated | No credential found; works for public repos only |
The first match wins. If no convention secret exists, behavior is identical to the default single-token resolution.
Note: Credentials resolved for private gh:// URIs are preserved end-to-end through the entire download sequence, preventing unauthenticated fallback or 404 errors during multi-file resolution.
Injection Mode Behavior
Section titled “Injection Mode Behavior”Convention-keyed GitHub secrets support the standard injection modes:
-
As Needed (recommended): The credential is used at provision time to fetch skills and templates but is not exposed inside the agent container. This is the minimum-privilege posture.
Terminal window scion hub secret set --project GH_ACME_CORP__PRIVATE_SKILLS github_pat_... -
Always: The credential is also injected into the agent container as an environment variable (
GH_ACME_CORP__PRIVATE_SKILLS). Use this when agents need runtime access to the same private repo.Terminal window scion hub secret set --project --always GH_ACME_CORP__PRIVATE_SKILLS github_pat_...
For more on injection modes, see Injection Modes above.
Administrator Configuration (Hub)
Section titled “Administrator Configuration (Hub)”To use secrets in production, the Hub must be configured with a production-grade secrets backend.
Secrets Backend (Required)
Section titled “Secrets Backend (Required)”Scion requires a secrets backend to store secret values. The recommended backend is GCP Secret Manager.
Configuring GCP Secret Manager
Section titled “Configuring GCP Secret Manager”Set the backend in your settings.yaml:
server: secrets: backend: gcpsm gcp_project_id: "my-gcp-project" gcp_credentials: "/path/to/service-account.json" # Optional if using ADCOr via environment variables:
export SCION_SERVER_SECRETS_BACKEND=gcpsmexport SCION_SERVER_SECRETS_GCP_PROJECT_ID=my-gcp-projectexport SCION_SERVER_SECRETS_GCP_CREDENTIALS=/path/to/service-account.jsonWhen GCP Secret Manager is configured, Scion uses a hybrid storage model:
- Metadata (name, type, scope) is stored in the Hub database.
- Secret values are stored in GCP Secret Manager with automatic versioning.
Technical Details
Section titled “Technical Details”Automatic Plugin Secret Migration & Safety (Hub Integrations)
Section titled “Automatic Plugin Secret Migration & Safety (Hub Integrations)”For external messaging integrations (such as Discord, Telegram, or Google Chat) that run as Hub-level message broker plugins, Scion implements an automatic, secure secret migration and stripping pipeline to keep sensitive bot tokens and API keys out of plaintext configuration files:
- Automatic One-Shot Migration: When starting up or activating a plugin (e.g., via the runtime activation path in
activateInstalledIntegration), the Hub automatically scans the integration’s configuration—including per-plugin external configuration files and inline config blocks. Any discovered secret keys are automatically migrated into the configured secure Secrets Backend (such as GCP Secret Manager). - Copy-Before-Strip Safety: After migrating the secrets, Scion strips the raw values in-place from the integration’s file-based and inline configurations (
stripSecretKeysInPlace) using a secure copy-before-strip helper to avoid any risk of partial writes or configuration corruption, while deduplicating warning logs. - Boot and Activation Consistency: This migration-and-strip sequence runs consistently during both the Hub’s boot-up routine and dynamic runtime integration activation, ensuring that secrets are never stored or exposed in plaintext configs.
Resolution Hierarchy
Section titled “Resolution Hierarchy”When an agent starts, the Runtime Broker requests a “Resolved Environment” from the Hub. The Hub merges secret values in this order (last one wins for the same key):
- Hub Secrets (global defaults)
- User Secrets
- Project Secrets
- Broker Secrets
- Template
envblock - CLI
--envflags
Security
Section titled “Security”Secrets are transmitted over TLS between the Hub and Runtime Brokers. They are only decrypted by the Hub during the dispatch process and sent over an encrypted channel to the Runtime Broker. The Broker then injects them directly into the container’s memory space. Brokers never persist agent secrets to disk.
For a detailed overview of the security architecture, see the Security Architecture Reference.