VELA — RBAC Policy
Status: every control below is DESIGNED / ROADMAPPED unless marked IMPLEMENTED. A baseline role model (viewer / operator / approver) is IMPLEMENTED in the console and enforced at the API service boundary; the fuller policy in this document — fine-grained permissions, external IdP/SSO group mapping, per-tenant role scoping, and audited role changes — is DESIGNED/ROADMAPPED. Implemented ≠ independently audited. Last reviewed: (owner to date)
Owner: SKOPAQ AI Pvt Ltd. Scope: VELA ground-segment advisory software (production Python stack — LangGraph agents + Neo4j KG + Qdrant + 3 FastMCP servers + FastAPI). Sibling docs: SECURITY.md, DATA-HANDLING.md, docs/policies/audit-log-retention.md, docs/policies/incident-response-citation-integrity.md, docs/design/02-ARCHITECTURE.md, docs/design/04-MCP-SERVERS.md.
1. Purpose & scope
This policy defines the three VELA access roles — operator, reviewer, admin — and what each may do. It exists to make one property enforceable and auditable: a human, not the agent, releases every recovery procedure, and no role, ever, can command a spacecraft.
In scope: who may view telemetry, run investigations, read cited reports, satisfy the LangGraph interrupt() approval gate that releases a procedure draft, edit knowledge-graph bindings, read the audit log, manage tenants/users, and configure model routing / airgap mode.
Out of scope entirely: commanding a spacecraft. VELA is ground-segment, advisory-only software with zero commanding authority in v1. No role in this matrix grants command capability, because the capability does not exist in the product — Architecture Invariant 3 (no code path constructs or transmits telecommands, grep-guarded in CI) makes it un-grantable, not merely un-permitted. A human operator executes procedures in their own MOC tooling, outside VELA.
2. Roles
| Role | Intended holder | One-line summary |
|---|---|---|
| operator | Satellite operations engineer / on-console analyst | Runs investigations and reads cited reports. Cannot release a procedure draft. |
| reviewer | Senior operations engineer / anomaly-review authority | Everything operator can do, plus satisfies the interrupt() approval gate to release a procedure draft, and edits KG bindings. |
| admin | SKOPAQ deployment owner / customer-side platform admin | Everything reviewer can do, plus tenant/user management and model-routing / airgap configuration. |
Roles are cumulative in practice but enforced per-capability, not by rank — see the matrix. A user holds exactly one role per tenant (§4).
3. Capability matrix
Legend: A = allow, D = deny. All rows DESIGNED (pre-build; nothing IMPLEMENTED).
| Capability | operator | reviewer | admin | Notes |
|---|---|---|---|---|
| View telemetry (windowed MCP query) | A | A | A | Scoped to caller’s tenant_id + authorized satellite_ids. |
| Run investigation (start LangGraph run) | A | A | A | Advisory only; produces hypotheses + draft, releases nothing. |
| View cited report | A | A | A | Read-only; citations resolvable against KG/Qdrant. |
APPROVE / release procedure draft (interrupt() gate) |
D | A | A | The load-bearing control. Operator may run and read but never release. |
| Edit knowledge-graph bindings | D | A | A | Overlay writes via typed invertible operators; audited (§6). |
| View audit log | A* | A | A | *operator: own-investigation records within tenant only; reviewer/admin: full tenant scope. |
| Manage tenants / users (assign roles) | D | D | A | Cross-tenant user admin is a SKOPAQ-platform-admin function, not customer admin. |
| Configure model routing / airgap mode | D | D | A | The cloud-vs-airgap config flag and model endpoints are admin-only. |
| Command a spacecraft | D | D | D | Out of scope for the product. Not grantable to any role (Invariant 3). |
4. Tenant isolation
Every role is scoped to a single tenant_id. There is no cross-tenant role and no global operator/reviewer.
tenant_id+satellite_idare mandatory in every contract, key, MCP request, and audit record from day one (see03-DATA-SPEC.md,02-ARCHITECTURE.md). An authorization check that cannot resolve atenant_idfails closed.- A grant is a
(user, role, tenant_id)triple. The same human may holdoperatorin tenant A andreviewerin tenant B; these are independent grants. - The only role that spans tenants is a SKOPAQ-internal platform-admin variant of
adminused for provisioning; it is out of the per-tenant model and governed bySECURITY.md, not this matrix. Customer-sideadminis tenant-scoped like every other role. - Per-customer encrypted volumes and contractual zero-copy-post-pilot (
DATA-HANDLING.md) are the storage-layer complement to this role-layer isolation.
5. The interrupt() approval gate (load-bearing)
Procedure-draft release is not a UI button — it is a first-class LangGraph interrupt() checkpoint in the investigation graph (02-ARCHITECTURE.md). The graph pauses at the interrupt and resumes from that exact checkpoint only on an approval.
- Who can resume it:
revieweroradminonly. Anoperator’s attempt is denied at the authorization boundary and recorded as a denied approval attempt in the audit log. - What approval means: a human has read the cited draft and authorizes VELA to mark it released to the operator for out-of-band execution. It does not send anything to a spacecraft. Execution happens in the customer’s MOC tooling, by a human, outside VELA.
- Segregation of duties (DESIGNED, roadmapped policy option): deployments may require the approving
reviewerto be a different identity than theoperatorwho ran the investigation. Enforcement is a per-tenant config toggle; default is off for solo-console pilots, recommended on for anomaly-review-board operation. - Low-confidence KG-binding escalations use the same
interrupt()mechanism and the same reviewer/admin gate.
6. Enforcement points (all DESIGNED)
| # | Where enforced | Mechanism |
|---|---|---|
| 1 | FastAPI request layer | Session → (role, tenant_id); every route declares required capability. Fail-closed on missing tenant. |
| 2 | MCP servers (sole data-access boundary) | Agents never touch stores directly (import-linted). MCP requests carry tenant_id/satellite_id; server rejects out-of-scope reads. |
| 3 | LangGraph interrupt() resume |
Resume authorized against reviewer/admin capability before the checkpoint continues. |
| 4 | Audit log | Every tool call, hypothesis transition, KG write, and approval/denial persisted per investigation (Invariant 4). Backed by OpenTelemetry traces. |
RBAC decisions themselves are audit events. A denied operator approval attempt, a role change, and a model-routing change are all logged with actor, tenant, and timestamp — see docs/policies/audit-log-retention.md.
7. What this policy deliberately does NOT do
- It does not grant, gate, or describe spacecraft commanding — that capability is absent by design, not merely restricted.
- It does not borrow flight-software access regimes (e.g. ECSS operational-role schemes). VELA is ground-segment advisory software; those don’t bind it. In spirit we borrow only segregation of duties and audited approval (§5–6).
- It makes no certification claim. RBAC here is designed to support future SOC 2 / ISO 27001 readiness (
COMPLIANCE-ROADMAP.md); nothing is audited or certified today.
8. Implementation status & first checks to build
| Item | Status |
|---|---|
| Three roles + capability matrix | DESIGNED |
(user, role, tenant_id) grant model |
DESIGNED |
interrupt() reviewer/admin gate |
DESIGNED |
| Fail-closed tenant scoping at MCP boundary | DESIGNED |
| RBAC events in audit log | DESIGNED |
| Segregation-of-duties toggle | ROADMAPPED |
| Anything enforced in running code | NOT IMPLEMENTED |
First tests to write when the stack is built (map to 06-TEST-PLAN.md):
operatorcannot resume a procedure-releaseinterrupt()(denied + audited).- Any MCP request without a resolvable
tenant_idis rejected. - A
reviewerin tenant A cannot read tenant B telemetry or audit records. - No role exposes a command-construction path (reuses Invariant-3 grep guard).
