Authentication & Identity
Scion implements a unified authentication system designed to secure communication between all components: the CLI, the Web Dashboard, the Hub, and individual Agents.
Identity Types
Section titled “Identity Types”Scion recognizes four primary identity types:
- Users: Humans interacting via the CLI or Web Dashboard. Authenticated via OAuth or Development tokens.
- Agents: Running LLM instances. Authenticated via short-lived JWTs issued by the Hub during provisioning.
- Runtime Brokers: Infrastructure nodes that execute agents. Authenticated via Broker tokens.
- Development User: A special identity used for local development and zero-config testing.
Authentication Methods
Section titled “Authentication Methods”Scion supports multiple authentication methods for different use cases:
- OAuth (Google/GitHub): For production web and CLI authentication.
- Development Auth: For local development and testing.
- User Access Tokens (UATs): For programmatic access and CI/CD pipelines.
Tenancy: single- vs multi-user
Section titled “Tenancy: single- vs multi-user”Tenancy is whether a deployment serves one identity or many. It is orthogonal to the availability tier — either hosted tier (Single-node or HA) can be single- or multi-user. Local and Workstation modes are single-user by construction.
- Single-user — one principal, with simple auth: a workstation developer token, or a single OAuth identity. There are no other users to isolate, so Groups and access policies are not needed.
- Multi-user — many principals authenticated through an OAuth identity provider (Google or GitHub). Access is governed by Hub Groups (named collections of users) and access policies that decide who can see and act on what.
Deciding to run multi-user is what turns on the rest of this page’s OAuth setup, domain authorization, and the RBAC model. For the authorization model itself — Groups, roles, and policy bindings — see Identity & Access (RBAC).
Who can sign in (user access mode)
Section titled “Who can sign in (user access mode)”server.auth.user_access_mode controls who can sign in:
| Mode | Who can sign in |
|---|---|
open (default) |
Any account the identity provider accepts, limited to authorized_domains when that list is set. |
domain_restricted |
Only accounts from authorized_domains. With an empty list, no one except admin_emails can sign in. |
invite_only |
Only users who were invited or already have an account, still limited to authorized_domains when set. |
Accounts in admin_emails can always sign in. On a single-node Hub, set the initial values in hub.env; an admin can change them later in Admin > Server Config:
SCION_SEED_SERVER_AUTH_USERACCESSMODE=invite_onlySCION_SEED_SERVER_AUTH_AUTHORIZEDDOMAINS=example.comOr in settings.yaml:
server: auth: user_access_mode: invite_only # open (default) | domain_restricted | invite_only authorized_domains: - example.comDefault role for new users
Section titled “Default role for new users”In a multi-user deployment, each user has a hub role: admin, member or viewer. Users listed in admin_emails are always admins. Everyone else gets the role set by server.auth.default_user_role (member by default) when their account is first created or activated. This includes the first sign-in of an invited or allow-listed user. Set it to viewer if new users should be able to work in projects they are added to, but not create projects of their own:
server: auth: default_user_role: viewer # member (default) | viewerTo pre-register a person before their first sign-in (for example, under invite_only), use Invite User on Admin > Users, scion hub users provision <email>, or POST /api/v1/users. All three create an invited record and require the user.invite permission, which hub admins hold. The CLI and API, and the dialog when a display name is given, require an interactive sign-in and are not available while the Hub runs with dev auth (see Development Authentication). An optional display name is stored with the record; at first sign-in, a name supplied by the sign-in provider replaces it. The role is assigned at first sign-in as described above. See the API reference and the CLI reference.
You can also set it from Admin > Server Config, or seed it with SCION_SEED_SERVER_AUTH_DEFAULTUSERROLE=viewer. Changing it does not affect existing users; change an individual user’s role on Admin > Users. See Hub roles for what each role allows and how demotion from admin_emails works, and the server configuration reference for the setting.
server.auth.default_user_role is a different setting from the federation default_role described under OIDC-Based Federation below, which only applies to users who authenticate with federated OIDC tokens.
Deleting users
Section titled “Deleting users”Deleting a user on Admin > Users (DELETE /api/v1/users/{id}) fails with 409 last_owner if the user is the only usable owner of any project (an owner is usable when their owner binding is in effect and their account exists and is active; suspended, invited and deleted owners do not count), or holds the last owner binding of any project, even an expired one. The error’s details.projects lists those projects. Transfer ownership or add another owner on each one, then delete the user again. If someone grants the user a role or changes one of their roles while the delete runs (for example, transfers a project to them) and that change commits first, the delete is aborted with 409 conflict and nothing is changed; retry it. A concurrent revoke of one of the user’s roles does not abort the delete. A grant that commits in the last moments before the delete itself commits is not detected and can leave a stale binding on the deleted user (ptone/scion#2769). It also fails with 409 conflict while any of the user’s agents has not been deleted, including a stopped one. The guard counts three kinds of agent as the user’s: the agents the user owns, the agents whose ancestry root is the user (agents started by the user’s agents, or by those agents’ child agents), and the agents started by the user’s own schedules. It does not count an agent started by a schedule that an agent created. The error’s details.agents lists each such agent’s id, slug and projectId, so delete those agents first, including agents started by the user’s agents. Deleting an agent does not delete the agents it started. An agent created for the user while the delete runs either finishes first, and the delete then fails with this error, or fails (409 conflict on the create API; a scheduled start fails and is logged) because the user or agent it belongs to no longer exists. A soft-deleted agent does not block the delete, but once the user is deleted, a soft-deleted agent of any of these three kinds cannot be restored: POST /api/v1/agents/{id}/restore fails with 409 conflict because the user or agent it belongs to no longer exists. The deprecated allow-list delete (DELETE /api/v1/admin/allow-list/{email}) applies the same rules.
When the deletion succeeds, Scion also removes all of the user’s role bindings (project, hub and system). It then removes the user’s user-scope secrets and environment variables; this step is best effort, and anything it cannot remove (for example while an external secret backend is unavailable) is removed by a startup sweep once the backend is reachable. The sweep runs in the background after the Hub starts, within a time limit, and does not delay startup. If no secret backend is configured (for example because it failed to start), secrets whose value is stored in the Hub database are still removed; a secret that only references an external backend (GCP Secret Manager) is kept until a sweep can also remove its external value. Bindings left behind by deletions made before this change are not cleaned up. To clear such a binding when it is a project’s only owner, add a real owner first, then remove the old binding from the project’s members.
After a user is deleted, that user’s tokens stop working immediately. Requests that present a web or CLI sign-in token get 401 with the error code user_not_found. Requests that present one of the user’s access tokens (scion_pat_) are also refused, with 401 and the error code unauthorized.
OAuth Authentication
Section titled “OAuth Authentication”Scion supports OAuth authentication via Google and GitHub. OAuth credentials are configured separately for web and CLI clients due to different redirect URI requirements.
Web OAuth Setup
Section titled “Web OAuth Setup”Configure web OAuth with these environment variables:
export SCION_SERVER_OAUTH_WEB_GOOGLE_CLIENTID="your-client-id"export SCION_SERVER_OAUTH_WEB_GOOGLE_CLIENTSECRET="your-client-secret"export SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTID="your-client-id"export SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTSECRET="your-client-secret"CLI OAuth Setup
Section titled “CLI OAuth Setup”Configure CLI OAuth with these environment variables:
export SCION_SERVER_OAUTH_CLI_GOOGLE_CLIENTID="your-client-id"export SCION_SERVER_OAUTH_CLI_GOOGLE_CLIENTSECRET="your-client-secret"export SCION_SERVER_OAUTH_CLI_GITHUB_CLIENTID="your-client-id"export SCION_SERVER_OAUTH_CLI_GITHUB_CLIENTSECRET="your-client-secret"External OIDC Login Provider Support
Section titled “External OIDC Login Provider Support”For enterprise SSO setups, Scion supports authenticating Web UI users via an external OpenID Connect (OIDC) identity provider (such as Okta, Keycloak, or Ping Identity) as an alternative to standard Google/GitHub OAuth.
How It Works
Section titled “How It Works”- OIDC Discovery: The Hub automatically discovers authorization and token endpoints by fetching the provider’s standard metadata configuration from
{issuer_url}/.well-known/openid-configurationwith a 1-hour TTL discovery cache to ensure high performance and zero-downtime key rotation. - Dynamic Login Button: When enabled, the Web Dashboard dynamically renders a custom login button using your configured
display_namealongside any active Google or GitHub OAuth buttons. - Public Client Support: For OIDC public clients (like Keycloak public clients), the Hub allows the
client_secretto be left empty or omitted, removing client secret validation from the token exchange workflow.
Redirect URI
Section titled “Redirect URI”When registering Scion as a client in your identity provider, set the redirect URI (sometimes called “callback URL”) to:
<hub-base-url>/auth/callback/oidcReplace <hub-base-url> with the Hub base URL, including the scheme, for example https://hub.example.com. The Hub base URL is set by the --base-url flag or, when the flag is not set, by SCION_SERVER_BASE_URL; without either, it defaults to http://localhost:<web port>. This is the endpoint the IdP redirects users to after authentication.
The Hub builds the redirect URI from its base URL, so a Hub served over plain HTTP uses an http:// redirect URI. The Hub does not require HTTPS for OIDC login, and it marks the session cookie Secure only when the base URL starts with https://. Whether an http:// redirect URI is accepted is up to your identity provider; many require HTTPS for production clients. The issuer_url is different: it must use https:// unless its host is localhost or 127.0.0.1, and the Hub does not start otherwise.
Configuration
Section titled “Configuration”To enable the external OIDC login provider, add the oidc_login section under server in your Hub’s static settings.yaml bootstrap file:
server: oidc_login: enabled: true display_name: "Corporate SSO" # Text shown on the login button issuer_url: "https://sso.example.com/auth/realms/main" # Base OIDC issuer URL client_id: "scion-client" # Client ID registered with the provider client_secret: "secret-value" # Client secret (can be empty for public clients) scopes: ["openid", "email", "profile"] # Custom scopes (defaults to openid, email, profile)Prefer settings.yaml for these keys. Underscored environment variables such as SCION_SERVER_OIDC_LOGIN_ENABLED are ignored, and the Hub logs a warning at startup for each one. The collapsed names (SCION_SERVER_OIDCLOGIN_ENABLED, SCION_SERVER_OIDCLOGIN_ISSUERURL, SCION_SERVER_OIDCLOGIN_CLIENTID, and so on) take effect only when settings.yaml has a server: section, as above. They are ignored on the legacy server.yaml path (ptone/scion#3038).
Verified Email Requirement
Section titled “Verified Email Requirement”Google, GitHub and external OIDC sign-in accept only an email address that the provider marks as verified. The Hub never falls back to an unverified address.
- Google and OIDC: the provider’s verified-email claim must be true.
- GitHub: the Hub always reads the account’s full email list (the
user:emailscope) rather than trusting the public profile email. It uses the profile email if the list marks it verified, otherwise the primary verified email, otherwise any verified email.
Domain Authorization
Section titled “Domain Authorization”You can restrict authentication to specific email domains using the server.auth.authorized_domains setting. This provides an additional layer of access control beyond OAuth authentication. See also Who can sign in.
Configuration
Section titled “Configuration”Set the environment variable with a comma-separated list of allowed domains:
# Allow only users from these domainsexport SCION_SEED_SERVER_AUTH_AUTHORIZEDDOMAINS="example.com,mycompany.org"Or configure in server.yaml:
auth: authorizedDomains: - example.com - mycompany.orgBehavior
Section titled “Behavior”- Empty list (default): All email domains are allowed.
- Non-empty list: Only emails from listed domains can authenticate.
- Case insensitive:
Example.COMmatchesexample.com. - Exact match: Subdomains must be listed explicitly.
OIDC Identity Provider (IdP)
Section titled “OIDC Identity Provider (IdP)”When enabled, the Scion Hub can act as a minimal OpenID Connect (OIDC) Identity Provider. This allows running agents inside containers to request short-lived, cryptographically signed OIDC tokens to prove their identity to external systems.
Configuration
Section titled “Configuration”Enable the OIDC IdP feature in settings.yaml:
server: oidc: enabled: true # IssuerURL defaults to the Hub's public endpoint if empty. # Must be valid HTTPS in hosted mode (HTTP allowed in workstation mode). issuer_url: "https://hub.scion.dev" token_lifetime: "15m"Endpoints
Section titled “Endpoints”When active, the Hub exposes standard OIDC discovery and key endpoints:
/.well-known/openid-configuration: Returns OIDC discovery metadata./.well-known/jwks.json: Publishes the public keys (JWKS) used to verify token signatures.POST /api/v1/agent/identity-token: Endpoint for agents to request tokens.
Token Issuance and Rotation
Section titled “Token Issuance and Rotation”- Token Signing: Tokens are RS256-signed using keys generated and managed by the Hub’s secrets backend.
- Key Rotation: The Hub rotates signing keys every 24 hours automatically, maintaining a key overlap period to ensure seamless token verification during transitions.
- Audience Scope: Tokens are minted targeting specific external audiences.
Agent Identity Token API
Section titled “Agent Identity Token API”For programmatic or custom integrations where sciontool is not available, agents can request OIDC identity tokens directly from the Hub’s token endpoint.
- Endpoint:
POST /api/v1/agent/identity-token - Authentication: Requires a valid Agent Token header (e.g.
X-Scion-Agent-Token: <scion JWT>). - Request Body: Must be JSON and include the mandatory
audienceparameter targeting the external service.
Example Request:
POST /api/v1/agent/identity-token HTTP/1.1Host: hub.scion.devX-Scion-Agent-Token: <agent_jwt_token>Content-Type: application/json
{ "audience": "https://vault.example.com"}Example Response (HTTP 200 OK):
{ "token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ii4uLiJ9...", "expires_at": "2026-08-11T12:15:00Z"}In-Agent Retrieval
Section titled “In-Agent Retrieval”From inside any authorized agent container, retrieve an OIDC identity token using sciontool:
sciontool identity-token --audience="https://vault.example.com"Use this token to authenticate agents to external services like HashiCorp Vault, AWS IAM Roles for Service Accounts (IRSA), or GCP Workload Identity Federation (WIF).
OIDC-Based Federation
Section titled “OIDC-Based Federation”Scion supports inbound OIDC-based federation authentication. This allows external identities (such as other Scion Hubs, Google Cloud Service Accounts, or Firebase/Google users) to authenticate against the Hub API using OIDC ID tokens from trusted issuers.
Configuration and Runtime Management
Section titled “Configuration and Runtime Management”Federation authentication is feature-gated. It can be configured initially at bootstrap via the server.federation block in settings.yaml, or managed dynamically at runtime via the Admin UI (using the opsettings pattern).
Runtime Administration (Admin UI)
Section titled “Runtime Administration (Admin UI)”When running in database mode, administrators can manage OIDC federation configuration directly in the Admin UI without restarting the Hub:
- Issuer CRUD: Create, read, update, and delete trusted OIDC issuers dynamically. The interface provides conditional input fields based on the selected identity/issuer type.
- Hot-Reloading: Changes saved in the UI are immediately applied cluster-wide. The backend utilizes an
atomic.Pointerto hot-reload theFederationAuthenticator, ensuring a zero-downtime, lock-free path for inbound federated requests. - Semantic Validation: The Admin API performs strict semantic validation on save, preventing malformed issuer rules or invalid URLs from reaching the live runtime.
Static Bootstrap Configuration (settings.yaml)
Section titled “Static Bootstrap Configuration (settings.yaml)”Alternatively, or for initial bootstrapping, you can configure federation statically in your configuration file.
server: federation: enabled: true trusted_issuers: - issuer_url: "https://hub.other-org.com" # Optional: Explicit JWKS URL (retrieved via discovery if omitted) jwks_url: "https://hub.other-org.com/.well-known/jwks.json" expected_audience: "https://hub.scion.dev" # Optional restriction lists allowed_projects: ["project-uuid-1", "project-uuid-2"] allowed_root_users: ["user@other-org.com"] # Default scopes/roles for identities from this issuer default_scopes: ["project:read", "agent:status:update"] issuer_type: "hub" # hub, service_account, or userHow It Works
Section titled “How It Works”- Multi-Issuer Support: The federation authenticator handles multiple external trust domains simultaneously.
- JWKS Caching: Public verification keys are cached locally with RS256-signature pinning and automatic refresh to eliminate per-request latency.
- Federation Access Middleware: Requests carrying external OIDC tokens pass through the
RequireFederationAccessscope-gated middleware, validating token authenticity, issuer rules, and matching scopes. - Identity Types:
hub: Identifies requests originating from federated partner Hubs. A partner Hub marks each credential it signs withscion_token_kind:agentfor agent identity tokens,userfor user access credentials. Agent identity tokens, and credentials without the claim from Hubs that predate it, are read as agents, as before. A user access credential is accepted only when the issuer hasaccept_user_tokens: trueand thefederation.project_visitorsexperiment is on; it must carry a verified email and no agent claims, and must passallowed_emailsandallowed_domains. Any otherscion_token_kindvalue is refused. A refused credential gets the same401as any other credential that fails verification.service_account: Authenticates automated workloads via GCP Service Accounts.user: Maps OIDC tokens to standard user identities, with configurabledefault_role(defaults toviewer; this is separate fromserver.auth.default_user_role, which applies to users who sign in through OAuth, OIDC login or an auth proxy) and domain restrictions using wildcards (e.g.allowed_emails: ["*@example.com"]).
- Write limits for federated callers: A federated caller keeps visitor rights on the resources it has been granted, but the Hub refuses its writes to profile and other non-agent resources: user-scope templates, skills and harness configs, imports, env vars and secrets, chat preferences, presence, and attachments outside a project. Federated callers also cannot redeem invites.
External Bearer Tokens (Google credential pass-through)
Section titled “External Bearer Tokens (Google credential pass-through)”An integration that sits in front of the Hub — for example the Gemini Enterprise A2A bridge — does not mint a Hub credential on the end user’s behalf. It forwards the caller’s own Google credential, verbatim, as the request’s Authorization: Bearer header, on every request. There is no exchange step and no separate Hub-issued token to cache, refresh, or revoke.
This path activates once a user-type trusted issuer for https://accounts.google.com is configured with a non-empty expected_audience. Two credential shapes and two principal kinds are accepted:
| Principal | Google OIDC ID token (JWT) | Google OAuth2 access token (opaque) |
|---|---|---|
| User | Accepted: aud in expected_audience, verified email, allowed_domains (if set), then the Hub sign-in policy |
Accepted: azp in expected_audience, verified email, allowed_domains (if set), then the Hub sign-in policy |
| Service account | Accepted: aud in expected_audience, verified email, GCP project (parsed from the email) in allowed_gcp_projects — unset admits none |
Always rejected |
server: federation: enabled: true trusted_issuers: - issuer_url: "https://accounts.google.com" jwks_url: "https://www.googleapis.com/oauth2/v3/certs" issuer_type: "user" # REQUIRED: the OAuth client ID whose tokens are accepted. Without # this, the path is disabled for this issuer, and a warning is # logged at startup and on reload. expected_audience: "1234567890-abc.apps.googleusercontent.com" # Optional: restrict USER principals to these email domains (exact, # case-insensitive, no wildcards, no subdomain matching). Each entry # must be a bare domain: no "@" or "*" (this is not the allowed_emails # pattern syntax), no "/" or ":" (not a URL), no whitespace, no # leading or trailing dot, and no ".." — config validation rejects # any entry that could never match. Omit to accept any verified # Google account that passes the Hub sign-in policy below. allowed_domains: ["example.com"] # Optional: admit SERVICE-ACCOUNT principals whose GCP project ID # (parsed from the service account's email) is listed (exact, # case-insensitive). Omitting this admits NO service accounts. allowed_gcp_projects: ["my-a2a-project"]A verified user identity is still resolved through the same sign-in policy as interactive login (admin_emails, authorized_domains, user_access_mode) after the allowed_domains check passes — a listed domain narrows which users reach that policy, it does not replace it. A verified service account identity skips the sign-in policy entirely: membership in allowed_gcp_projects is the authorization decision for first-time admission. A service account is never subject to allowed_domains, and a user is never subject to allowed_gcp_projects. Bypassing the sign-in policy does not extend to suspension: a service account that was already provisioned and is later suspended is refused on its next request exactly like a suspended user.
The A2A bridge forwards Google credentials under the hubBearer auth scheme (auth.scheme: hubBearer in scion-a2a-bridge.yaml): it admits a caller by presenting the same token to the Hub’s GET /api/v1/auth/me, then forwards that token verbatim on every downstream call. The Hub re-verifies the token on each request: a suspended user is refused on the next call. A revoked Google credential stops being accepted once the Hub’s verification cache entry expires (at most 5 minutes, and never beyond the credential’s own expiry).
Response codes:
| Condition | Status | Code |
|---|---|---|
| No Google trust configured, or the token isn’t a shape this path recognizes | Falls through unchanged to whichever other authentication check applies to that credential | — |
| Per-client-IP rate limit exceeded (checked only on a credential-cache miss) | 429, with Retry-After |
rate_limited |
| Verification failed, unverified email, a service account presented as an access token, or its project/domain isn’t listed | 401 | unauthorized (message invalid external bearer token; the specific reason is logged, never returned) |
| Google’s token-verification endpoints are unreachable | 503 | upstream_unavailable |
| An internal fault while resolving the verified identity to a Hub user (store error) | 503 | store_error |
| The resolved user is suspended | 403 | user_suspended |
| The Hub sign-in policy denies the user, or the identity fails auto-link checks | 403 | forbidden |
allowed_domains and allowed_gcp_projects are matched case-insensitively against the verified email; the configured lists themselves are kept exactly as written (not lower-cased or otherwise rewritten when the config loads).
Development Authentication (Dev Auth)
Section titled “Development Authentication (Dev Auth)”To minimize friction during local setup, Scion includes a “Dev Auth” mode. When enabled, the Hub auto-generates a token and creates a “Development User” identity.
Dev auth is for a single-user workstation Hub. Pre-registering other users (POST /api/v1/users, scion hub users provision) is not available while the Hub runs with dev auth, for any caller, and returns 403 with details.reason: dev_auth_not_supported.
Enabling Dev Auth
Section titled “Enabling Dev Auth”Start the server with the --dev-auth flag or set it in your server.yaml:
auth: devMode: trueOr via environment variable:
export SCION_SERVER_AUTH_DEVMODE=trueUsing the Developer Token
Section titled “Using the Developer Token”When the Hub starts with devMode: true, it writes the token to ~/.scion/dev-token.
- CLI: The
scionCLI automatically looks for this file. - Web: The Web Dashboard automatically uses this token for the “Development User” login when
SCION_DEV_AUTH_ENABLED=trueis set.
Alternatively, you can set the token in your environment:
export SCION_DEV_TOKEN=scion_dev_...Runtime Broker Security
Section titled “Runtime Broker Security”Runtime Brokers use a robust security model to ensure that only authorized Hubs can dispatch commands and that agents remain isolated.
HMAC-Based Authentication
Section titled “HMAC-Based Authentication”Communication between the Hub and a Runtime Broker (in both directions) is secured using HMAC-SHA256 request signing. This provides several security benefits:
- Mutual Authentication: Both parties prove they possess the shared secret.
- Payload Integrity: The request body is included in the signature, preventing tampering.
- Replay Protection: Every request includes a timestamp and a unique nonce.
A shared secret is established during the scion runtime-broker register flow and is stored locally in ~/.scion/hub-credentials/<name>.json, one file per Hub connection.
Provider Authorization
Section titled “Provider Authorization”The Hub enforces a “Provider” model for authorization. Even if a broker is authenticated, it will only receive agent dispatch requests for Projects that it has been explicitly registered to provide for. This prevents a compromised broker from accessing projects it shouldn’t have access to.
Secret Management
Section titled “Secret Management”Brokers never store agent secrets (like API keys) on disk.
- The Hub resolves secrets from all applicable scopes (user, project, broker) via the configured secrets backend (e.g., GCP Secret Manager).
- The Hub includes the resolved secrets in the
CreateAgentcommand sent to the Broker over the TLS-secured control channel. - The Broker projects secrets into the agent container based on their type (environment variable, JSON file, or filesystem path).
- When the agent is deleted, the secrets are purged from the host.
For details on configuring and managing secrets, see Secret Management.
GCP Identity & Metadata Emulation
Section titled “GCP Identity & Metadata Emulation”Scion provides a native mechanism to assign Google Cloud Platform (GCP) identities to agents, even when running on non-GCP infrastructure. This is achieved through an in-process metadata server emulator within sciontool that intercepts requests to the standard GCE metadata IP (169.254.169.254).
Metadata Modes
Section titled “Metadata Modes”When creating an agent, you can configure its GCP Identity Mode:
- Block (Default on every runtime except Kubernetes): All requests to the metadata server are intercepted and return a 403 Forbidden. This ensures agents cannot expose the host’s identity (e.g., when running on a GCE instance). On the Kubernetes runtime, Block is accepted but works differently: the agent pod runs as the runtime profile’s block Kubernetes ServiceAccount, or the namespace’s default ServiceAccount when none is configured, with no GCP credentials mounted. On Workload Identity nodes that ServiceAccount still receives a federated token, so the agent’s GCP access is whatever IAM grants that ServiceAccount holds. An agent with no GCP identity mode configured gets Passthrough on Kubernetes. See the Kubernetes runtime note in Permissions.
- Assign: Assigns a specific Google Service Account to the agent.
- The agent’s
sciontoolsidecar intercepts requests to the metadata server. - Token requests are proxied to the Scion Hub, which uses its own broad permissions to generate a short-lived access token for the requested Service Account (via the
iam.serviceAccounts.getAccessTokenpermission). - The token is then returned to the agent, allowing it to use standard GCP SDKs (Application Default Credentials) as that specific Service Account.
- The agent’s
- Passthrough: Requests are allowed to reach the actual host metadata server. Use with caution as this allows the agent to assume the identity of the underlying node. Security is tightened by restricting GCP identity passthrough to broker owners and admin-role users on embedded (co-located) brokers.
Management UI & Hub-Minted Service Accounts
Section titled “Management UI & Hub-Minted Service Accounts”Administrators can manage available Service Accounts through the Service Accounts section in the Admin dashboard.
- Registration: Register existing GCP Service Accounts by email. The system
accepts service accounts with
@<project>.iam.gserviceaccount.com,@developer.gserviceaccount.com, and@appspot.gserviceaccount.comsuffixes. - Hub-Minted Accounts: The Hub can directly manage and provision (mint) GCP service accounts based on your quota dashboard and capability controls.
- Validation: Scion auto-verifies that the Hub has the necessary permissions to act as the registered Service Account upon registration.
- Assignment & Defaults: Service Accounts can be assigned to agents during the creation flow. Projects also support default GCP identities that are automatically applied in the agent creation form.
Security & Auditing
Section titled “Security & Auditing”- Iptables Interception: Scion uses
iptables(whenNET_ADMINcapability is available) to redirect traffic from169.254.169.254:80to the local sidecar. - Authorization Checks: Administrative actions for GCP Service Account management require
project-owner(ActionManage) permissions to enforce strict authorization boundaries. - Rate Limiting: Token requests are rate-limited per-agent to prevent abuse.
- Audit Logging: All token issuance events are logged at the Hub level with the requesting
agent_idanduser_id.
GitHub App Integration
Section titled “GitHub App Integration”Scion supports native GitHub App integration for secure, automated agent authentication with GitHub repositories. This provides a robust alternative to static personal access tokens.
Features
Section titled “Features”- Native Auth: Uses JWT-based authentication and automated installation token minting.
- Automated Token Refresh: A background refresh loop ensures long-running agents always have valid git credentials.
- Git Credential Helper: The
sciontoolinjects a credential helper into the agent environment, providing fresh tokens togiton-demand. - Commit Attribution: Supports per-project git identity configuration to ensure commits are authored correctly.
- Admin Management: Global monitoring of installations, rate limits, and status via the “GitHub App” tab in the Admin Server Config UI.
Project Association
Section titled “Project Association”Projects can be linked to specific GitHub App installations. The system automatically associates GitHub App installations at project creation time, streamlining the authentication flow for private repositories. Project settings provide visual indicators and permission badges for real-time feedback on integration health.
Webhook Secret
Section titled “Webhook Secret”GitHub App webhook deliveries must be signed. Set the webhook secret in the “GitHub App” tab of the Admin Server Config UI; the Hub stores it as a hub-scoped secret. Use the same value as the webhook secret in your GitHub App’s settings. If no webhook secret is configured, the Hub rejects every webhook event with 503 Service Unavailable instead of processing it unsigned.
Session Revocation
Section titled “Session Revocation”Administrators can force any user to re-authenticate by revoking all of their active web sessions. This is useful for incident response, credential compromise, or when offboarding a user who is still logged in.
- Web Dashboard: On the Admin Users page, open the actions menu for a user and select Revoke Sessions.
- API:
POST /api/v1/users/:id/revoke-sessions(requires admin privileges).
Revocation takes effect immediately — the user is redirected to the login page on their next request. Agent tokens and User Access Tokens (UATs) are unaffected; revoke those through their own mechanisms (UATs, agent credential reset via scion reset-auth).
CLI Authentication
Section titled “CLI Authentication”Users can authenticate the CLI against a Scion Hub using the following flow:
- Login:
scion hub auth loginopens a browser to the dashboard login page. - Exchange: After successful login, the dashboard provides a token (or the CLI exchanges a code).
- Storage: The token is stored in
~/.scion/config.json.
Agent Authentication
Section titled “Agent Authentication”Agents are automatically authenticated. When the Hub dispatches an agent to a Runtime Broker, it includes a one-time-use Agent Token.
- The agent uses this token for all calls back to the Hub (e.g., updating status, streaming logs).
- Tokens are scoped to the specific agent and its project.
- Tokens have a default expiration (typically 24 hours), but Scion implements an automated token refresh mechanism to ensure long-running agents maintain valid authorization throughout extended tasks.
User Access Tokens
Section titled “User Access Tokens”For programmatic access (e.g., CI/CD pipelines), the Hub supports user access tokens (UATs).
- Tokens can be generated via the Web Dashboard or CLI (
scion hub token create). - Tokens are prefixed with
scion_pat_(a legacy artifact of the older “personal access token” name). - Use the
Authorization: Bearer <token>header in your requests.
See User Access Tokens for the full user-facing guide.