Security Architecture
Scion is designed with a multi-layered security model to ensure the integrity and confidentiality of agent operations, user data, and system communications. This document outlines the authentication mechanisms, transport security protocols, and future authorization plans for the Scion platform.
1. Authentication Model
Section titled “1. Authentication Model”Scion operates in multiple contexts, each with specific security requirements. Authentication is managed centrally by the Scion Hub, which resolves identities for users, agents, and infrastructure components.
1.1 Authentication Contexts
Section titled “1.1 Authentication Contexts”| Context | Client Type | Auth Method | Token Storage |
|---|---|---|---|
| Web Dashboard | Browser | OAuth 2.0 + Session Cookie | HTTP-only cookie |
| CLI (Hub Commands) | Terminal | OAuth 2.0 + Device Flow | ~/.scion/credentials.json |
| Agent (sciontool) | Container | Hub-issued JWT | Env Var (SCION_HUB_TOKEN) |
| Runtime Broker | Compute Node | HMAC Signature | ~/.scion/broker-credentials.json |
| Development | Any | Developer Token (Bearer) | ~/.scion/dev-token |
1.2 User Authentication (OAuth 2.0)
Section titled “1.2 User Authentication (OAuth 2.0)”For both Web and CLI access, Scion relies on standard OAuth 2.0 providers (Google and GitHub).
- Web Flow: Standard Authorization Code flow. The embedded Go web server handles the callback and exchanges the provider token for a session-bound Hub access token.
- CLI Flow: Uses a localhost callback server (defaulting to port
18271). The CLI opens the user’s browser for authentication and receives the authorization code via the local server. - PKCE: The CLI uses Proof Key for Code Exchange (PKCE) to prevent authorization code injection attacks.
1.3 Agent Authentication (sciontool)
Section titled “1.3 Agent Authentication (sciontool)”Agents running inside containers must report status back to the Hub without possessing user-level credentials.
-
Hub-Issued JWT: During provisioning, the Hub generates a short-lived JWT scoped specifically to that agent instance.
-
Claims: The token includes the
agent_id(sub),project_id, andscopes. -
Role-Based Scopes: Instead of raw template scopes (which are deprecated), an agent’s scopes are governed by its assigned Tiered Agent Role (
none,readonly,baseline, orfull). An empty or unspecified agent role is securely enforced to resolve to the least-privilege role (AgentRoleNone) across all authorization paths. Scheduled dispatch children automatically persist this explicit role, and dispatches lacking a creator are refused.project:read(Readonly): Allows reading project state (agents, templates, etc.).agent:status:update,agent:token:refresh,project:agent:notify,agent:port:forward(Baseline): Standard operational scopes allowing the agent to report progress, refresh its token, and hold port tunnels.project:agent:create,project:agent:lifecycle,project:secret:read(Full): Complete programmatic control allowing the agent to spawn sub-agents, manage their phases, and retrieve project secrets dynamically.
-
Transmission: The token is injected into the container via the
SCION_HUB_TOKENenvironment variable and is used bysciontoolfor all API calls.
1.4 Runtime Broker Authentication (HMAC)
Section titled “1.4 Runtime Broker Authentication (HMAC)”Runtime Brokers represent high-trust infrastructure. They use HMAC-based request signing for bidirectional authentication with the Hub.
- Shared Secret: Established during initial registration via a short-lived
joinToken. - Signing: Every request includes headers for
X-Scion-Broker-ID,X-Scion-Timestamp,X-Scion-Nonce, andX-Scion-Signature. - Replay Protection: Nonce-based tracking and timestamp validation (5-minute clock skew tolerance) prevent replay attacks.
- NAT Traversal: Brokers establish a persistent WebSocket control channel. The initial upgrade request is HMAC-authenticated, establishing a trusted session for subsequent commands.
2. Transport Security
Section titled “2. Transport Security”2.1 TLS and HTTPS Enforcement
Section titled “2.1 TLS and HTTPS Enforcement”In production mode, Scion mandates the use of TLS for all network traffic.
- HTTPS Enforcement: The Hub server rejects non-HTTPS requests (unless configured for local development or behind a trusted TLS-terminating proxy).
- Security Headers: Standard headers such as
Strict-Transport-Security(HSTS),X-Frame-Options, andContent-Security-Policyare enforced. - mTLS (Future): Support for Mutual TLS between Hub and Runtime Brokers is planned for high-security environments.
2.2 WebSocket Security
Section titled “2.2 WebSocket Security”- CLI/Agents: Use standard
Authorizationheaders. - Browser/Web: Since browser WebSocket APIs cannot set custom headers, Scion uses a Ticket-Based Authentication system. The client requests a short-lived, single-use ticket via a POST request (authenticated by cookie) and provides it in the WebSocket query string (
?ticket=...).
3. Authorization and Access Control
Section titled “3. Authorization and Access Control”3.1 Domain Authorization
Section titled “3.1 Domain Authorization”Scion supports restricting authentication to specific email domains via the SCION_AUTHORIZED_DOMAINS configuration. This provides a first-line defense, ensuring only authorized organization members can access the Hub.
3.2 Permissions and Policy Model
Section titled “3.2 Permissions and Policy Model”Scion implements a robust, hierarchical RBAC (Role-Based Access Control) and policy system. For a detailed technical specification of the policy language and agent identity claims, see the Policy & Permissions Reference and Permissions & Policy Guide.
- Principal-Based: Permissions are granted to Users and Groups.
- Hierarchical Groups: Groups can contain other groups, allowing for complex team structures.
- Resource Scopes: Policies are attached to scopes (Hub, Project, or specific Resource) and follow a containment hierarchy.
- Override Model: Lower-level policies (e.g., at the Agent level) override higher-level ones (e.g., at the Project level), allowing for granular delegation of authority.
- Actions: Standardized CRUD actions (
create,read,update,delete,list) plus resource-specific actions (start,stop,attach,message). - Lattice-Based Agent Authorization: Agents are assigned tiered roles (
none,readonly,baseline,full) that restrict their JWT scopes via a two-gate authority lattice.
3.3 GCP Service Account Assignment Gates
Section titled “3.3 GCP Service Account Assignment Gates”To prevent lateral privilege escalation, Scion implements a strict two-layer delegation check when binding a GCP service account to any agent:
- Layer 1: Scion Hub Policy: The Hub’s policy engine checks if the caller holds the
ActionAssignpermission on the target GCP service account resource within Scion. - Layer 2: GCP IAM (
actAs): Whengcp_iam_check_modeis set to"enforce", the Hub performs an out-of-band call via Google’s Policy Troubleshooter v3 API to verify that the caller’s GCP principal possessesiam.serviceAccounts.actAspermission on the target service account.
Key security attributes of the GCP IAM check include:
- Fail-Closed Design: If the Policy Troubleshooter returns an indeterminate result (due to conditional bindings, or due to insufficient Hub reviewer permissions when configured to fail-closed), the check fails closed and assignment is blocked. There is no fallback to insecure alternatives like getIamPolicy.
- Asymmetric Caching: Approved assignments are cached for 60 seconds, and denials are cached for 10 seconds. Indeterminate or error states are never cached.
- Auditing: Every service account assignment check—both allowed and denied—generates a permanent audit log entry detailing the principal, target service account, and Policy Troubleshooter decision.
- Hub-Scoped SAs: Real hub-scoped service accounts can be assigned across projects. However, to prevent privilege bypasses, hub-scoped assignments are immediately rejected if
gcp_iam_check_modeis not set to"enforce".
3.4 Fail-Closed API Authorization and Resource Isolation
Section titled “3.4 Fail-Closed API Authorization and Resource Isolation”To guarantee that no API endpoints or handlers can be accessed without explicit authorization, the Scion Hub enforces a strict fail-closed authorization design:
- Explicit Fail-Closed Handlers (
s.authorize()): All API handlers route through fail-closed authorization checks (s.authorize()). This eliminates legacy fail-open bypass vectors (such as functions relying onGetUserIdentityFromContextwhich could returnnilfor agent or broker callers and silently bypass authorization). Under the fail-closed model, any context lacking a valid user identity, agent token, or broker credentials is automatically denied. - Fail-Closed Dispatch Access: The
checkBrokerDispatchAccessguard is strictly fail-closed, ensuring that no agent execution can be triggered on a runtime broker unless dispatch permissions have been verified. - Role Boundary Enforcement (
addGroupMember): Non-user callers (such as automated agents or system services) are strictly capped at the plainmemberrole when executingaddGroupMemberoperations, preventing elevation of privileges across organizational boundaries. - Strict Isolation Ordering (404-before-403): To prevent unauthorized users or agents from discovering the existence of sensitive resources via API probe responses, Scion enforces strict resource isolation ordering. If a caller requests a resource they are not authorized to view, the Hub performs resource existence checks and tenant bounds validation first. This ensures the Hub responds with a
404 Not Foundrather than a403 Forbiddenif the resource does not exist or belongs to another tenant/project, preventing side-channel resource enumeration. - Regression Checks in CI: To prevent future authorization regressions, an automated
authz-guardcheck is wired into the CI pipeline (via a dedicated Makefile target and GitHub Actions step) that statically analyzes and validates that all API handlers are protected by appropriate authorization helpers.
4. Secret Management
Section titled “4. Secret Management”Scion provides a typed, scope-aware secret management system. Secret values are never stored in plaintext in the Hub database. For a user-facing guide, see Secret Management.
4.1 Secrets Backend Architecture
Section titled “4.1 Secrets Backend Architecture”The Hub uses a pluggable SecretBackend interface for secret storage:
| Backend | Value Storage | Write Operations | Read Operations |
|---|---|---|---|
gcpsm (GCP Secret Manager) |
Encrypted in GCP SM | Supported | Supported |
local (default) |
Encrypted at rest (AES-256-GCM) in Hub DB | Supported | Supported |
When gcpsm is configured, a hybrid model is used:
- Metadata (name, type, scope, version) is stored in the Hub database.
- Secret values are stored in GCP Secret Manager with automatic versioning.
- GCP SM secret names follow the pattern:
scion-{scope}-{sha256(scopeID)[:12]}-{name}.
The local backend now encrypts secret values at rest using AES-256-GCM, with domain-separated key derivation from the hub signing secret. Legacy plaintext values are transparently readable and will be automatically re-encrypted upon the next write operation.
4.2 Secret Scopes and Resolution
Section titled “4.2 Secret Scopes and Resolution”Secrets are scoped and resolved hierarchically when an agent starts. The following scopes are merged in order (last one wins for the same key):
- Hub scope (lowest priority): Global defaults.
- User scope: Personal secrets for the agent’s owner.
- Project scope: Project-level secrets.
- Runtime Broker scope (highest priority): Infrastructure-level overrides.
This produces a merged set of secrets for each agent, where more specific scopes override broader ones.
4.3 Secret Types and Projection
Section titled “4.3 Secret Types and Projection”Secrets are typed to control how they reach the agent container:
environment: Injected as environment variables (default).variable: Written to~/.scion/secrets.jsoninside the container.file: Written to a specified filesystem path (max 64 KiB).
4.4 User Access Tokens (UATs)
Section titled “4.4 User Access Tokens (UATs)”For headless environments (CI/CD, automation), Scion supports user access tokens (UATs).
- Tokens are prefixed with
scion_pat_(a legacy artifact of the older “personal access token” name). - Only the SHA-256 hash of the token is stored in the database; the original value is never persisted.
- Tokens can be scoped to specific permissions and projects, and revoked instantly via the dashboard or CLI.
4.5 Credentials Propagation
Section titled “4.5 Credentials Propagation”Scion ensures that sensitive credentials (GCP Service Accounts, API keys for LLMs) are propagated into agent containers securely.
- Docker / Podman: Injected via environment variables or read-only bind mounts for file-type secrets. File secrets are written to a temporary directory and mounted into the container at the target path.
- Kubernetes: Propagated via Kubernetes Secrets or Secret Manager CSI drivers (e.g., GCP Secret Manager).
- Broker Mode Isolation: When agents are dispatched via the Hub, the credential pipeline only uses hub-resolved secrets and environment variables. The broker operator’s host environment and filesystem are never scanned, preventing credential leakage into hub-dispatched agents.
- Isolation: Agent home directories and non-git project data are isolated on the host filesystem and externalized from the workspace to prevent cross-agent data leakage and unauthorized traversal.
- Shadow Mounts: Scion uses
tmpfsshadow mounts to definitively block agents from accessing.scionconfiguration data or other agents’ workspaces within the same project. - Lifecycle: Secrets exist only in the agent container’s memory or transient mounts. When an agent is deleted, all projected secrets and transient volumes are purged.
4.6 Hub-Internal Keys
Section titled “4.6 Hub-Internal Keys”JWT signing keys used for agent and user token issuance are stored through the secret backend when GCP Secret Manager is configured. In development mode (local backend), signing keys fall back to direct database storage with a logged warning. These keys use the internal hub scope and are not accessible through the user-facing secrets API.
4.7 Broker Authentication Secrets
Section titled “4.7 Broker Authentication Secrets”The following broker-related secrets are stored in the Hub database and are not managed through the secrets backend:
- Join tokens: SHA-256 hashed before storage; single-use with 1-hour expiry.
- Shared secrets: Stored as binary BLOBs in the
broker_secretstable; used for HMAC-SHA256 request signing.
These are infrastructure-level secrets established during broker registration and are managed by the broker authentication subsystem rather than the user-facing secrets API.
5. Development Security
Section titled “5. Development Security”To facilitate local development, Scion provides a Development Authentication mode.
- Developer Token: A persistent token starting with
scion_dev_stored in~/.scion/dev-token. - Constraints: Dev mode is disabled by default and requires
localhostbinding if TLS is not used. - Warning: The server logs clear warnings when operating in Dev Mode.