Permissions & Policy
Scion implements a robust, principal-based access control system to manage resources across distributed projects and teams. The system is built on the Permissions Foundation architecture, providing deterministic authorization evaluation, declarative route guards, and comprehensive auditing.
For a detailed technical specification of the permissions model, role definitions, access constraints, and agent identity claims, see the Permissions & Access Constraints Reference.
Core Concepts
Section titled “Core Concepts”Unified Authorization
Section titled “Unified Authorization”Scion uses a UnifiedAuthMiddleware to enforce declarative route guards across the Hub. Every request undergoes deterministic authorization evaluation via a Decide path before reaching the handler, ensuring no resource can be accessed without explicit permission. Engine internals, settings handlers, User Access Token (UAT) endpoints, user management, integrations, and operations have all been converted to explicit permission-based checks, deprecating the legacy requireAdmin fallback.
Roles and Bindings
Section titled “Roles and Bindings”Access is granted through explicit role assignments:
- RoleDefinition: A named collection of permissions (e.g.,
developer,viewer,admin). - RoleBinding: A grant of a
RoleDefinitionto a principal (user, group, or agent) within a specific scope (Hub or Project). - Project Membership: Users gain access to project resources by being bound to a role within that project.
Delegation and Revocation
Section titled “Delegation and Revocation”- CanDelegate Admission Gate: Prevents lateral privilege escalation by ensuring a principal can only grant roles or permissions they themselves possess.
- Credential Revocation: Agent credentials and User Access Tokens can be instantly revoked, terminating access system-wide.
Observability
Section titled “Observability”- Decision & Mutation Audit: All authorization decisions and role mutations are captured in a structured audit log.
- Explain API: Administrators can use the Explain API to query why a specific permission was granted or denied for a principal on a given resource.
Principals
Section titled “Principals”A Principal is an identity that can be granted permissions.
- Users: Identified by their email address.
- Groups: Collections of users or other groups, allowing for hierarchical team structures.
Resources
Section titled “Resources”Permissions are granted on specific resource types:
hub: The global Scion Hub instance.project: A project-level workspace.agent: An individual agent instance.template: An agent configuration blueprint.scheduled_event: A time-based recurring schedule or scheduled event.
Actions
Section titled “Actions”Scion uses a standardized set of actions:
- CRUD:
create,read,update,delete,list. - Administrative:
manage. - Resource-Specific:
lifecycle(start, stop, suspend, restart, restore),attach(terminal, exec, env, reset-auth),port_access,message.
Access Control & Authorization
Section titled “Access Control & Authorization”Scion enforces strict role-binding-based authorization for all agent operations:
- Agent Creation: Requires active membership in the target project.
- Agent Interaction: Interacting with an agent (e.g., via PTY/terminal or structured messaging) is restricted to the agent’s owner (the creator), users in the agent’s ancestry chain, or system administrators. The default project-member role does not grant the
agent:messagepermission — messaging authorization is aligned with the terminal attach permission gate. - Lifecycle vs. Attach: Lifecycle operations (start, stop, suspend, restart, restore, reincarnate) are gated by
agent.lifecycle, separately fromagent.attach(terminal, exec, env, reset-auth) andagent.port_access. Because an agent runs with its creator’s user-scoped secrets, the built-inproject-ownerandproject-adminroles grantagent.lifecycleand messaging but notagent.attachoragent.port_access. Owners and admins can start, stop, and message other members’ agents, but cannot open a terminal on them or reach their forwarded ports. They keep full access to their own agents and descendants through the resource-owner and ancestry grants. - Agent Deletion: Only the agent’s owner, a system administrator, or authorized agent callers can delete an agent. For an agent caller to perform a deletion, it must have
project:agent:lifecycle(associated with thefullrole) and must target an agent within its own project (which closes a cross-project agent deletion vulnerability).
Membership-Based Project Access (Visibility Eradication)
Section titled “Membership-Based Project Access (Visibility Eradication)”The legacy, non-functional project Visibility field (e.g., private, team, or public) has been completely eradicated. Instead, access control is governed entirely by membership-based policies. The same applies to agents, templates, harness configs, and skills: their visibility field has been removed from the API (including the agent SSE payload), and access depends only on scope and grants. User- and project-scoped templates, harness configs, and skills are readable only by their owner, project members, and Hub admins; Hub-wide member and viewer grants cover only hub- and global-scoped records (see Security).
- Project Scope Governance: Access to a project and its associated resources is restricted to principals belonging to the project’s member group (i.e.
project:<slug>:members). This group is bound to per-project read and access roles using Project-scoped RoleBindings (such asproject:<slug>:member-read-projectandproject:<slug>:member-read-agentmappings). - Fail-Closed Retrieval (404 Gate): Project read access is verified via a
CheckAccessgate on retrieval. If a caller is not authorized to read the project, the API responds with a standard404 Not Found(rather than a403 Forbidden) to prevent callers from probing the existence of private projects.
Scheduler Authorization & Owner-Based Access Control
Section titled “Scheduler Authorization & Owner-Based Access Control”Scheduled events and recurring schedules are strictly protected using an Owner-Based Access Control model, combined with dedicated permissions and dynamic RoleBindings:
- Owner-Based Protection: Only the creator (the owner) of a schedule/event, or a system-wide administrator, has the authority to view, update, delete, or otherwise manage a scheduled event or recurring schedule. This is enforced via creator/owner ID validation at the API handlers layer.
- Project Member Bindings: During project creation or template synchronization, Scion backfills/seeds project-scoped scheduled event RoleBindings bound to the project’s members group. This grants members the capability to schedule events within their project space.
- Scheduler Permissions: A set of 7 dedicated permissions are enforced across scheduler endpoints:
scheduled_event.read: Permission to read a scheduled event or recurring schedule.scheduled_event.list: Permission to list scheduled events and recurring schedules.scheduled_event.create: Permission to create a scheduled event or recurring schedule.scheduled_event.update: Permission to update a recurring schedule (including pausing/resuming).scheduled_event.delete: Permission to cancel a scheduled event or delete a schedule.hub.scheduler.read: Permission to read hub-wide scheduler configurations.hub.scheduler.update: Permission to update hub-wide scheduler configurations.
Positive Authority & Monotonic Restrictions
Section titled “Positive Authority & Monotonic Restrictions”Scion operates on a single positive-authority model using RoleBindings to grant permissions, supplemented by AccessConstraints to enforce maximum boundaries.
Positive-Authority (RoleBindings)
Section titled “Positive-Authority (RoleBindings)”All permissions in Scion are additive and must be explicitly granted via a RoleBinding.
- RoleDefinition: A named set of allowed permissions (e.g.,
project:viewer,project:developer,hub-admin). - RoleBinding: Connects a principal (User, Agent, or Group) to a RoleDefinition.
- Scope: RoleBindings exist at either
systemscope (system-wide permissions across the entire Hub) orprojectscope (permissions restricted to a single project space).
Monotonic Restrictions (AccessConstraints)
Section titled “Monotonic Restrictions (AccessConstraints)”An AccessConstraint is a maximum-permissions boundary that can only reduce (never widen) a principal’s granted authority. It acts as an absolute ceiling.
- Ceiling Enforcement: If a RoleBinding grants a principal 10 permissions, but an AccessConstraint limits that principal to a maximum of 3 specific permissions, the principal will only have those 3 permissions.
- Targeting: AccessConstraints can target specific principals, entire group closures (a group and all its subgroups), or all principals (
all_principals). - Offline Recovery: Under
disabled: true, an AccessConstraint is deactivated. This is used in offline recovery to restore administrator access in the event of a lockout.
Resolution & Evaluation Logic
Section titled “Resolution & Evaluation Logic”On any authorization request (evaluated via the Hub’s Decide endpoint):
- Load Bindings: The engine loads all active RoleBindings for the principal (including group memberships and synthetic agent scopes).
- Resolve Allowed Set: The union of all permissions from these RoleBindings is compiled into an “allowed permissions” set.
- Apply AccessConstraints: The engine queries and loads all non-disabled AccessConstraints that apply to the principal (matching on direct principal ID, group memberships, or
all_principals). - Calculate Intersection: The effective permission set is the intersection of the resolved allowed set and the AccessConstraints’
maximum_permissionsceilings. If no positive RoleBinding grants the permission, or if an AccessConstraint excludes it, access is denied (fail-closed).
Capability-Based Access Control
Section titled “Capability-Based Access Control”The Hub API and Web UI utilize a capability gating system. Resource responses from the API include _capabilities annotations. These annotations explicitly state the actions the authenticated user is permitted to perform on that specific resource. This ensures granular UI controls (e.g., disabling the “Delete” button if the user lacks permission) and provides a secondary layer of API-level enforcement.
GCP Service Account Assignment Gates
Section titled “GCP Service Account Assignment Gates”To prevent lateral privilege escalation—where an agent with low privileges creates a child agent with high privileges, or a user assigns a highly privileged GCP service account they shouldn’t have access to—Scion implements a secure, two-layer gate for binding a GCP service account to any agent:
- Layer 1: Scion Hub Authorization: The Hub’s built-in authorization engine verifies the caller has the
ActionAssignpermission on the GCP service account resource within Scion. For project-scoped service accounts, theproject-owner,project-adminandproject-memberroles holdgcp_service_account.assign, so every owner, admin and member of a project passes this layer for any project-scoped service account in that project. - Layer 2: GCP IAM Policy (
actAs): This layer runs only whengcp_iam_check_modeis set toenforce; in the defaultoffmode, Layer 1 alone decides project-scoped assignment.enforceis strongly recommended, see the caution under GCP IAM Check Mode. Underenforce, the Hub evaluates Google Cloud’s IAM delegation model via the GCP Policy Troubleshooter v3 API. It verifies that the caller’s GCP principal possessesiam.serviceAccounts.actAspermission on the target service account.
The actAs Validation Gate
Section titled “The actAs Validation Gate”The actAs (impersonation) check is critical because binding a service account to an agent grants that agent real cloud authority.
| Layer | Checked Authority | Action | Checked Principal |
|---|---|---|---|
| Hub Authorization | Inside Scion | ActionAssign |
Scion User/Agent |
| GCP IAM | Inside Google Cloud | iam.serviceAccounts.actAs |
Caller’s GCP Principal |
Note: The Hub’s own roles/iam.serviceAccountTokenCreator permission is used to perform impersonated credential probes. It is NOT the permission checked on the caller. The permission evaluated on the caller is iam.serviceAccounts.actAs (typically granted via roles/iam.serviceAccountUser).
Fail-Closed Resolution
Section titled “Fail-Closed Resolution”If Policy Troubleshooter returns an indeterminate or unknown status (e.g., ACCESS_STATE_UNKNOWN_CONDITIONAL due to IAM conditions, or ACCESS_STATE_UNKNOWN_INFO_DENIED due to insufficient Hub reviewer permissions), Scion fails closed and denies the assignment immediately. There is no fallback to getIamPolicy, which can easily fail open or miss complex project-level, group-level, or org-level bindings.
Asymmetric Cache TTLs
Section titled “Asymmetric Cache TTLs”To maintain high API performance without violating security constraints, assignment decisions are cached using asymmetric TTLs:
- Allow TTL: 60 seconds
- Deny TTL: 10 seconds
- Indeterminate / Error States: Never cached. Transient failures are retried immediately on the next request to prevent short outages from becoming fixed-length service blocks.
The cache is automatically invalidated for a target service account when that service account is deleted, or when a Hub-initiated IAM mutation occurs.
IAM Prerequisites for Enforcement
Section titled “IAM Prerequisites for Enforcement”For Policy Troubleshooter to evaluate a caller’s IAM permission across the organization, the Scion Hub’s own GCP service account must be granted the IAM Security Reviewer role (roles/iam.securityReviewer) at either the Google Cloud project or organization level.
Hub-Scoped Service Accounts
Section titled “Hub-Scoped Service Accounts”Hub-scoped service accounts are defined globally at the Hub level rather than being restricted to a single project. This allows Platform Ops to make shared service accounts available for selection across multiple project-level workspaces.
To prevent unauthorized assignment of global resources, Scion applies specialized security logic:
- Enforcement Mode Dependency: Assignment of a hub-scoped service account is unconditionally denied if
gcp_iam_check_modeis set tooff. Because “off” mode disables the GCP IAM validation layer, letting users assign global service accounts without anactAscheck would create a massive security risk. Hub-scoped service accounts requiregcp_iam_check_mode: enforceto be assigned. - Dynamic Membership Checks: Only current, active members of the Hub or project who possess
ActionAssignon the resource and pass the Policy TroubleshooteractAscheck can bind the service account. - Former-Member Denial: If a user is removed from a project or leaves the organization, they immediately lose the ability to assign those service accounts—even if they were the user who originally created or registered the service account record in Scion. Ownership-based bypasses do not apply to hub-scoped service accounts.
Project-Default Service Accounts
Section titled “Project-Default Service Accounts”To streamline the agent creation workflow, project administrators can configure a project-default GCP service account that is automatically applied to newly created agents. However, to prevent privilege-escalation bypasses, this assignment is strictly gated:
- Enforced at Creation and Selection: The Policy Troubleshooter
actAsevaluation is automatically triggered whenever an agent is created using the project’s default service account, or when a user selects the default service account option. - Unauthorized Bypass Prevention: If a user does not possess
iam.serviceAccounts.actAspermission on the project’s default service account, they are barred from creating agents under that project with the default identity, even if they have full project access.
Hub-Default GCP Identity
Section titled “Hub-Default GCP Identity”Hub administrators can set a hub-wide default GCP identity in Admin > Server Config > Agent Defaults > General (agent_defaults.default_gcp_identity_mode and default_gcp_identity_service_account_id). The Hub picks the identity for a new agent from the first of these that is set:
- The GCP identity in the agent create request. Not applicable to an agent dispatched by a schedule, which carries no explicit identity.
- The project’s default GCP identity. An explicit project Block counts as set, so the hub default is not consulted.
- The hub default.
- Block.
This ladder applies the same way whether the agent is created interactively/via the API or dispatched by a schedule (ptone/scion#1927): a scheduled dispatch starts at rung 2, and a hub default with no project-level override reaches it exactly as it would an interactive create.
The hub default does not bypass the existing gates:
- Assign: the service account must be verified and hub-scoped, and
gcp_iam_check_modemust beenforce. These are checked when the setting is saved. Each agent creation also runs the same creatoractAsauthorization as project-default assignment, recorded under the audit surfacehub-default. For a scheduled dispatch, the “creator” is the schedule’s immediate creator (the user or agent that created the schedule), the same principal the project-default rung already authorizes against on that path. - Passthrough: applies only when the agent is dispatched to the Hub’s embedded (co-located) broker. The Hub identifies that broker by the ID it records when it starts its embedded broker, not by the
scion.io/broker-rolelabel, because a broker’s owner can set its labels. During startup the Hub API can accept requests before the embedded broker has registered. An agent created in that window waits up to 15 seconds for registration instead of immediately getting Block. If registration fails, the Hub has no embedded broker until it restarts, and the Hub log says so on each affected create. This covers the single-node deployment. On any other broker the agent gets Block, and the Hub logs why. Without this limit, a hub-wide default would expose every registered broker’s host identity to every agent creator. It would also skip the broker-owner and host-SA checks that explicit passthrough requests go through.
Passthrough Mode Security & PATCH Parity
Section titled “Passthrough Mode Security & PATCH Parity”In Passthrough Mode, an agent bypasses explicit service account binding and directly assumes the GCP identity of its GKE/GCE broker host. To prevent unauthorized access to host-level authority:
- Broker-Owner Restriction: The caller must have permission to use that specific broker in passthrough mode.
- Host SA check: The caller’s GCP principal is checked via Policy Troubleshooter to confirm they hold
iam.serviceAccounts.actAspermission on the broker’s underlying host service account.
To enforce this boundary reliably, Scion implements strict PATCH Parity across its API:
- Previously, the
actAscheck only ran on agent creation (POST /api/v1/agents). - Now, the exact same validation function gates the update path (
PATCH /api/v1/agents/{id}). This prevents users from sneaking past the delegation gates by creating a low-privilege or no-auth agent and then PATCHing it to use passthrough mode.
Service Account Minting Permissions
Section titled “Service Account Minting Permissions”Minting is the process where Scion Hub automatically provisions a brand-new GCP service account in the Hub’s own project and registers it to the database on behalf of the user. Because minting creates new GCP authority and project IAM bindings, it operates under a highly secure flow:
- Enforced Regardless of Mode: Unlike assignment checks (which can be toggled via
gcp_iam_check_mode), minting checks are always active. SAs cannot be minted unless the requester passes GCP IAM checks, even ifgcp_iam_check_modeis set tooff. Skipping mint checks would create an instant privilege-creation bypass. - Required GCP Permissions: To mint a service account, the requester’s GCP principal must have:
iam.serviceAccounts.createon the Hub’s GCP project (to create the service account).aiplatform.endpoints.predicton the target project (to authorize the minted SA to access the GCP Vertex AI Platform).
- Fail-Closed Minting Flow: A minted service account is stored as
Verifiedin Scion only if all required downstream GCP IAM mutations succeed—specifically, granting the Hub SAroles/iam.serviceAccountTokenCreatoron the minted SA, and granting the requesterroles/iam.serviceAccountUseron the minted SA. If any mutation fails, the status is recorded as failed and the service account remains unverified.
Web UI Integration & Identity Cards
Section titled “Web UI Integration & Identity Cards”To make the service account lifecycle transparent and auditable for users and administrators, the Web Dashboard includes the following enhancements:
- Tiered Role Badges: The agents list and agent detail pages display visible role badges (
none,readonly,baseline, orfull) highlighting the active execution role of each running container. - GCP Identity Card: The agent detail view features an interactive GCP Identity Card. In all authentication modes, it displays the bound service account email, verification status (e.g.
verifiedorfailed), and the corresponding GCP project ID. - Service Account Status Manager: Within project settings, owners can view registered service accounts, check their live Policy Troubleshooter verification status, and manually trigger verification probes.
- Zero-Reload Service Account Dropdown Sync: The UI dispatches custom events (
sa-list-changed) across components upon SA registration, verification, minting, or deletion, instantly updating default service account selection dropdowns without a full-page reload, and automatically clears the default SA selection if the selected SA is deleted.
Quotas and Limits
Section titled “Quotas and Limits”The Scion Hub enforces resource consumption through a strict Quota System (Permissions Phase 2). This system operates at both the project and agent creation layers:
- Enforcement Mechanics: Quotas are evaluated via advisory-lock-based enforcement with fail-closed semantics to ensure hard limits are respected and reservation leaks are prevented.
- Data Model: The quota system uses
LimitDefinition,EntitlementBinding, andUsageReservationschemas backed by a dedicatedQuotaStore. - System Limits: Several seeded system limit definitions provide out-of-the-box safe bounds on resource usage.
- Quota API: A suite of 13 quota API endpoints is available for inspecting and managing quotas. These endpoints feature strict route guard read/write permission splits and built-in protection against arbitrary system limit modification.
To simplify management, Scion separates roles into User Roles (for human operators) and Agent Roles (for running agents).
User Roles
Section titled “User Roles”These built-in roles bundle common permissions for human users:
| Role | Description |
|---|---|
super-admin |
Full platform administrator with all permissions (System Role). |
hub-admin |
Hub administrator with scopeable admin permissions (System Role). |
hub-member |
Standard user; read access to directory resources and can create their own projects (System Role). |
hub-viewer |
Read-only access to directory resources (System Role). |
global-catalog-author |
Non-admin global skill authoring; grants only skill.create_global (System Role). |
project-owner |
Full project permissions, including agent lifecycle and messaging. Does not include agent.attach or agent.port_access on other members’ agents. |
project-admin |
Like project-owner, but without agent.delete or agent.set_message_mode. |
project-member |
Basic project permissions. |
Hub Roles
Section titled “Hub Roles”Every user has one hub role: admin, member or viewer. It is shown in Admin > Users and as a badge on the user’s own profile page. The hub role decides what a user can do across the whole hub. The hub grants it through the system roles above:
| Hub role | Granted through | What it allows |
|---|---|---|
admin |
A system-scope super-admin binding |
Full administrative access to the hub. |
member |
Membership of the hub-members group, which holds the hub-member role |
Read the hub directory and catalogs (users, groups, templates, harness configs, brokers, skills, and so on) and create projects. |
viewer |
A system-scope hub-viewer binding |
The same as member, but cannot create projects. This includes cloning a project. |
- Project roles are independent of the hub role. A viewer can still be added to a project, and then works in it according to their project role (
project-member,project-adminorproject-owner). The hub role only controls hub-level actions, such as creating a project. - New users get the hub role set by
server.auth.default_user_role(memberunless configured otherwise). It is applied when the account is first created or activated, which includes the first sign-in of an invited or allow-listed user. Invites and allow-list entries carry no role of their own. Users listed inadmin_emailsare always admins. - Changing the default does not change existing users. To change an individual user’s role, use Change role in the actions menu on Admin > Users, or
PATCH /api/v1/users/{id}with{"role": "viewer"}(admin,memberorviewer). A pending invite has no role yet, so its role cannot be changed until the user has signed in. - Role changes take effect immediately. The hub updates the user’s group membership and role bindings when the role changes, whether an admin changes it or it changes at sign-in. No hub restart is needed.
- The UI hides controls the user’s hub role does not allow. For example, a viewer does not see Create Project.
server.auth.default_user_role is not the same setting as server.federation.trusted_issuers[].default_role, which sets the role for users who authenticate with federated OIDC tokens.
Tiered Agent Authorization Roles
Section titled “Tiered Agent Authorization Roles”Scion implements a dedicated, tiered authorization model for agents. This ensures that running agents only possess the specific permissions they need to interact with the Hub API.
Agents are assigned one of four named roles, each mapping to a fixed set of JWT scopes:
| Agent Role | Granted Scopes | Description |
|---|---|---|
none |
None | No access to the Hub API (runs with no authorization claims). |
readonly |
project:read |
Can view and query project state, but cannot report status, register port forwards, or manage other agents. |
baseline |
project:readagent:status:updateagent:token:refreshproject:agent:notifyagent:port:forward |
Standard execution permissions. Allows the agent to report progress, refresh its token, register reverse-proxied port forwards, send notifications, and manage its own notification subscriptions. |
full |
All baseline scopes +project:agent:createproject:agent:lifecycleproject:secret:read |
Complete agent control. Allows spawning child (sub) agents, managing their lifecycles, and reading project-scoped secrets from the secret backend. |
Creation-Time Role Ceilings
Section titled “Creation-Time Role Ceilings”The effective role granted to an agent at creation depends on the caller:
$$\text{user dispatch} = \min(\text{requestedRole}, \text{projectMax})$$
$$\text{sub-agent dispatch} = \min(\text{requestedRole}, \text{parentRole}, \text{projectMax})$$
- Requested Role: The role requested during agent dispatch (e.g., using the
--roleflag in the CLI). For user dispatches, an omitted role defaults to the project-level or Hub-leveldefault_agent_role. For sub-agent dispatches, it inherits the parent agent’s role.- Default Role Update: For better usability, the default fallback role has been changed from
baselinetofull. - Configuration Options: You can specify
default_agent_roleglobally underagent_defaultsin the Hub settings (via settings/admin UI) or customize it per-project using the admin UI dropdown or the project settingscion.io/default-agent-role.
- Default Role Update: For better usability, the default fallback role has been changed from
- Project Max: Set by the project’s
max_agent_rolesetting, which defaults to the global Hub configuration (default_max_agent_roleunderagent_defaults). - Parent Role: For sub-agent dispatches, the child cannot exceed the parent agent’s stored role. Explicit over-requests are rejected with
403 Forbidden.
The live delegation check separately requires the caller to hold agent-creation authority in the target project.
Fallback and Fail-Closed Security
Section titled “Fallback and Fail-Closed Security”To guard against unauthorized escalations, the role fallback chain and parent lookup enforce fail-closed behavior:
- Parent Agent Lookup Failure: If parent agent lookup fails (e.g., due to transient database issues or invalid parent ID) when spawning a sub-agent, the sub-agent role ceiling defaults to
baselineinstead of failing open. - Corrupted Stored Roles: If a parent agent’s stored role is corrupted or invalid, it is treated as
baselinefor sub-agent creations to ensure robust security.
Sub-Agent No-Escalation Enforcement
Section titled “Sub-Agent No-Escalation Enforcement”To prevent security bypasses via sub-agent creation, Scion enforces strict no-escalation rules:
- When a parent agent spawns a child (sub-agent), the parent agent acts as the requester.
- A parent agent cannot grant a child agent a higher role than its own.
- Any attempt by an agent to spawn a child with elevated permissions will result in a loud, immediate
403 ForbiddenAPI rejection.
Token Refresh & Scope Re-derivation
Section titled “Token Refresh & Scope Re-derivation”To ensure security policies stay up-to-date and to support legacy agents created prior to the tiered role rollout, the Hub re-derives permissions from the agent’s stored role during token refresh (RefreshAgentToken), rather than copying old JWT scopes verbatim.
- Legacy Agent Compatibility: Legacy agents that do not have a stored role default to the
fullrole. This prevents production regressions where standing agents lose modern required scopes (such asproject:read,project:agent:lifecycle, or secret access) after a token refresh.
Deprecation of Raw Template Scopes
Section titled “Deprecation of Raw Template Scopes”With the introduction of tiered agent roles, the raw template field hubAccess.scopes has been deprecated. Agent permissions must be configured via the named roles.
Implementation Status
Section titled “Implementation Status”The permissions system features:
- Identity Resolution: Core identity and domain-based authorization.
- Capability Gating: UI and API enforcement via
_capabilities. - Policy Enforcement: Strict authorization for agent creation, interaction, and deletion based on project membership and ownership.
- Agent Identity & Ancestry: Strict scoping of agent names, ancestry chains, and transitive access control.
- Group & Policy Management: Full support for group and policy schemas in the database, manageable via the Web Dashboard.
Agent Ancestry & Transitive Access
Section titled “Agent Ancestry & Transitive Access”Scion enforces a robust security model for agent-to-agent interactions (progeny) through Ancestry Chains and Transitive Access Control.
When an agent creates a child agent (for example, to delegate a sub-task), the system records an ancestry chain (root → parent → child). This chain is used to enforce strict identity scoping and transitive access permissions.
- Transitive Access: Any principal (human user or agent) that exists in an agent’s creation chain automatically gains access to manage that agent. If a user owns the root agent, they inherently have access to all of its descendants.
- Strict Scoping: Agent identities are strictly scoped by their project using a specific naming convention (e.g.,
project--agent). This prevents name collisions across different workspaces and ensures that progeny agents cannot impersonate or interfere with agents in other projects. - Granular Secret Access: Progeny agents inherit granular secret access controls from their parents, ensuring they only have the credentials necessary to perform their specific tasks.
Managing Access and Infrastructure
Section titled “Managing Access and Infrastructure”The Scion Web Dashboard includes a centralized Admin Management Suite (accessible to users with appropriate administrative capabilities) that provides dedicated views for access control and infrastructure management:
- Server Configuration Editor: A full-featured settings editor at
/admin/server-config. This allows administrators to view and modify the globalsettings.yamlthrough the Web UI with support for tabbed navigation, sensitive field masking, and hot-reloading of key settings like log levels, telemetry defaults, and admin emails. - Users List: View all authenticated users, search for specific accounts, track “Last Seen” timestamps, and manage their system-wide roles (e.g., granting
hub-adminaccess). Administrators can also revoke all active sessions for a user, forcing immediate re-authentication across all devices (see Session Revocation below). - Groups Management: Full-featured admin UI/UX for creating and managing custom membership groups. Administrators can easily define hierarchical collections of users and manage their membership using a human-friendly editor with user search autocomplete. Group creation is strictly authorized, and the
project:prefix is a reserved slug. To prevent slug collisions, colliding group identifiers require a system marker combined with theProjectID. Membership lookups rely on canonical identity resolution. This enables policy-based authorization where permissions can be granted to an entire team at once, while strictly enforcing group ownership and authorization rules. - Access Boundaries: Full-featured administrative suite for defining and managing monotonic permission ceilings (AccessConstraints) via the Hub Admin UI.
- Inventory Page: Provides a centralized view of all active and disabled access boundaries configured on the Hub.
- Guided Authoring Workflow: A step-by-step UI workflow for creating and editing boundaries, including targeting individual principals, group closures, or all principals, and specifying allowed maximum permissions.
- Preview Engine: An interactive evaluation sandbox enabling administrators to simulate, dry-run, and verify the impact of an access boundary on a principal’s effective permissions prior to committing. Backed by the Provenance/Explain API, it details exactly which positive permissions are restricted and why.
- Transactional Governance & Atomic Audit: Built-in backend security guarantees that all access boundary operations are transactionally secure and recorded in the atomic mutation audit log.
- Role & Binding Management: Full CRUD interfaces for Role Definitions and Role Bindings. Administrators can define custom roles, map permissions, and bind them to users, groups, or agents at the Hub or Project scope, while the system enforces
CanDelegatechecks to prevent privilege escalation. - Quota Management: Dedicated admin view to manage the Quota System. Administrators can view, create, and update
LimitDefinitionthresholds and monitorEntitlementBindingstatus across projects. - Admin Security & Navigation: The dashboard uses a Per-Resource Permission-Gated Admin UI to render and restrict access to the Admin Suite. Instead of a binary
role===admincheck:- Nav and route guards use granular, per-item permission checks.
- The admin status API endpoint returns a per-resource permissions array that determines what elements are active and visible in the Admin UI.
- Settings page tabs are gated by the caller’s actual resource-level permissions. For example, a role with template-only permissions (like
template.*) sees only the Templates tab, while other administrative tabs are hidden.
- Broker Visibility: Comprehensive broker detail pages provide a grouped view of all active agents by their respective projects, helping administrators understand resource distribution.
- Maintenance Mode: Administrators can toggle maintenance mode for the Hub and Web servers directly from the UI to facilitate safe infrastructure updates.
By leveraging these administrative views, Platform Ops can efficiently map their organization’s structure directly into Scion’s Principal and Policy hierarchy.
Per-User Session Revocation
Section titled “Per-User Session Revocation”Administrators can force any user to re-authenticate by revoking all of their active sessions. This is useful when a user’s credentials may be compromised, when an account needs to be immediately locked out, or after a security incident.
How It Works
Section titled “How It Works”Each user record carries a session_generation counter. When an admin revokes a user’s sessions, the counter is incremented. On every subsequent web request, the Hub middleware compares the counter stored in the user’s session cookie against the database value. If the database value is higher, the session is invalidated immediately and the user is redirected to re-authenticate.
- Web Dashboard: On the Admin Users page, open the actions menu for a user and select Revoke Sessions. A confirmation dialog appears; on confirmation the revocation takes effect immediately.
- API:
POST /api/v1/users/:id/revoke-sessions(requires admin privileges).
Session revocation affects cookie-based web sessions only. Agent tokens and User Access Tokens (UATs) are managed through their own revocation mechanisms.
Break-Glass Admin Recovery
Section titled “Break-Glass Admin Recovery”If all admin users have been removed or an organization has lost administrative access to the Hub, the scion admin promote CLI command provides an emergency recovery path. This command connects directly to the database — bypassing the running Hub server — and promotes an existing user to the admin role.
scion admin promote --email user@example.comThe target user must already exist in the database. See the CLI Reference for the full command syntax and flags.
AdminEmails and UI-Promoted Admins
Section titled “AdminEmails and UI-Promoted Admins”Users listed in the admin_emails server setting are always admins: they are promoted to admin when they sign in. When the list is non-empty, removing an email from it demotes that admin to the hub’s default role for new users (server.auth.default_user_role) at the next hub restart or their next sign-in, whichever comes first. Their permissions change at once. At restart, both admin_emails and the default role come from settings.yaml or the environment, so a change made only in the Admin UI (Postgres mode) takes effect at the user’s next sign-in. If the default role was set only in the Admin UI, a user demoted at restart becomes Member.
There are two exceptions:
- UI-promoted admins keep admin. A user promoted to admin through the Web Dashboard (the Users list) or the users API holds admin because of that explicit action, not because of
admin_emails. Removing their email fromadmin_emailsdoes not demote them. To remove their admin role, change it on Admin > Users. - The startup safety check must have passed. When the hub starts, it checks that the
admin_emailsfrom its startup configuration (settings.yamlor the environment) matches at least one existing user, or that at least one UI-promoted admin exists. If not, the hub refuses all demotions, both at startup and at sign-in, until the configuration is fixed and the hub is restarted. This stops a configuration mistake from removing every administrator.