Scopes & Policies
Role-based access control for memories.
Cortex uses a scope-based permission system. Every memory belongs to a scope, and every user has a role that determines which scopes they can access.
Scopes
A scope is a permission boundary. Common examples:
| Scope | Description |
|---|---|
engineering | Technical decisions, API docs, architecture |
public-docs | Public-facing documentation |
finance | Financial data, metrics, budgets |
hr | HR policies, team structure |
secret | Confidential information |
Roles (designations)
Members carry a designation that maps to a default clearance level and a starting set of scope access. The workspace owner can change any member's designation and edit the scope matrix at any time.
| Designation | Default clearance | Description |
|---|---|---|
CEO | Senior | Workspace owner — full access + admin (the single owner) |
Founder | Senior | Co-founder — full memory access like the CEO |
CxO | Senior | Senior executive — full memory access |
Manager | Senior | Access to their team's scopes |
Employee | Junior | Access to their team + public scopes (stored internally as IC) |
Intern | Contractor | Public scopes only (stored internally as Contractor) |
Employee and Intern are the human-readable labels for the internal role
keys IC and Contractor. Only the CEO is the workspace owner for
destructive/admin actions; Founder and CxO are senior-clearance but not
owners.
Custom designations
Beyond the built-ins, the CEO can define custom designations (e.g. "VP Engineering", "Head of Sales") from the Team page — each with a chosen default clearance (Senior / Junior / Restricted). A new designation is immediately assignable and is seeded with starting scope access matched to its clearance, so a member given the title has real access from the start; the CEO can then fine-tune its scopes in the Policy matrix like any built-in role.
Clearance Levels
Each user also has a clearance level that determines access to content:
| Level | Rank | Description |
|---|---|---|
Contractor | 1 | Basic access |
Junior | 2 | Standard access |
Senior | 3 | Extended access |
Staff | 4 | Broad access |
Principal | 5 | Near-full access |
CEO | 6 | Full access + admin |
Policy Matrix
Policies map roles to scopes with an allow/deny effect:
graph LR
subgraph "Policy Matrix"
R1[Role: CEO] --> S1[finance: allow]
R1 --> S2[engineering: allow]
R1 --> S3[secret: allow]
R2[Role: IC] --> S4[engineering: allow]
R2 --> S5[public-docs: allow]
R2 --> S6[finance: deny]
end
Resolution Rules
- Deny beats allow — If a role has both allow and deny for the same scope, deny wins
- No implicit access — Roles only access scopes explicitly granted
- Level check — Even with scope access, clearance level must match
Example Policy Configuration
{
"policies": [
{ "role": "CEO", "scope_key": "finance", "effect": "allow" },
{ "role": "CEO", "scope_key": "engineering", "effect": "allow" },
{ "role": "CEO", "scope_key": "secret", "effect": "allow" },
{ "role": "Manager", "scope_key": "engineering", "effect": "allow" },
{ "role": "Manager", "scope_key": "finance", "effect": "allow" },
{ "role": "IC", "scope_key": "engineering", "effect": "allow" },
{ "role": "IC", "scope_key": "public-docs", "effect": "allow" },
{ "role": "IC", "scope_key": "finance", "effect": "deny" },
{ "role": "Contractor", "scope_key": "engineering", "effect": "allow" }
]
}
Permission Flow
sequenceDiagram
participant Caller
participant Policy as Policy Engine
participant DB as Database
Caller->>Policy: resolveScopes(user)
Policy->>DB: Load policy matrix for org
DB-->>Policy: Policy rows
Policy->>Policy: computeScopes(role, rows)
Policy-->>Caller: Allowed scopes
Note over Caller,DB: For each memory...
Caller->>Policy: canRecallPure(user, memory, scopes)
Policy->>Policy: Check: org match
Policy->>Policy: Check: status = active
Policy->>Policy: Check: scope in allowed
Policy->>Policy: Check: clearance level
Policy->>Policy: Check: not expired
Policy-->>Caller: allowed / denied
Denials
Denials are explicit and logged. When a recall is denied:
{
"allowed": false,
"reason": "No memories cleared for your role within scopes [engineering]. Content may exist in scopes you are not cleared for.",
"allowed_scopes": ["public-docs"],
"audit_id": "uuid"
}
Denials are never silent. Every denied access is logged to the audit trail with full context.