Skip to main content

Operating Layer Scope

Problem Statement

The platform analyzes access chains but has no structured operating loop for acting on findings. There are pieces of the puzzle in place — routing hints suggest which team should look at a finding, ownership assignment lets someone claim accountability, and mitigation actions track remediation work — but these pieces are disconnected from each other and from access chains.

Specifically:

  • Routing exists but stops at triage. owner_role (to be renamed routing_hint) maps finding types to team names, but it is a suggestion, not an assignment. Nobody is accountable.

  • Ownership exists but targets the wrong unit. OwnershipAssignmentDoc supports assigning owners to paths or entities, but access chains are the unit of risk. You cannot assign ownership to an access chain.

  • Mitigation exists but is fragmented. MitigationActionDoc tracks remediation per finding and per path. Sergey's feedback is explicit: one remediation object per access chain, not five path-level actions that happen to relate to the same identity.

  • No attestation mechanism. There is no way for an owner to formally acknowledge a risk, record that they have reviewed it, and accept or escalate it. Without attestation, there is no audit trail of conscious risk decisions.

The operating layer closes this gap: a structured workflow that takes access-chain analysis from "here is what we found" to "here is who owns it, what they are doing about it, and when they last confirmed it."

Current State

Routing Hints

DEFAULT_OWNER_ROLES in src/evaluator/evidence-classification.ts maps each finding type to a suggested team name (e.g., excessive_permissions maps to "IAM Team"). This value is attached to EvidenceClaim as owner_role.

Per the action plan, owner_role will be renamed to routing_hint and DEFAULT_OWNER_ROLES to DEFAULT_ROUTING_HINTS (Wave 3). The rename clarifies that this is a triage suggestion, not an ownership assignment.

Ownership Assignment

OwnershipAssignmentDoc in src/domain/ownership-assignments/types.ts:

  • Target types: path or entity
  • Statuses: active or revoked
  • Fields: owner_email, owner_name, owner_team, assigned_by, notes
  • API: Full CRUD at /api/v1/ownership-assignments

This is the correct mechanism for assigning accountability. It needs to extend to access chains.

Mitigation Tracking

MitigationActionDoc in src/domain/mitigation-actions/types.ts:

  • Statuses: proposedassignedin_progresscompletedverified (terminal), with rejected and deferred branches
  • Linkage: finding_id, path_id, entity_id, optional cluster_key and identity_id
  • Staleness detection: source_state_hash (SHA256 of evidence refs + path state at creation) with stale flag and stale_reason
  • Origin: auto_proposed (evaluator-generated) or manual
  • Lifecycle: Full status history with changed_by audit trail, valid transition enforcement, terminal states

The lifecycle and staleness tracking are solid. What is missing is access-chain-level linkage — the ability to create one mitigation that spans multiple findings within a single access chain.

Attestation

Nothing exists. No types, no API, no workflow.

Operating Layer Components

Four layers that build on each other. Each layer adds a capability; each depends on the one before it.

Layer 1: Routing (exists)

routing_hint provides an initial triage suggestion per finding type. It answers "who should probably look at this?" based on the category of finding.

Routing is not ownership. It is the starting point for triage — a default that helps findings land in the right team's queue before anyone has reviewed them. It is already implemented via DEFAULT_OWNER_ROLES (pending rename to DEFAULT_ROUTING_HINTS).

No changes needed to this layer beyond the Wave 3 rename.

Layer 2: Accountability (partially exists)

Ownership assignment is the mechanism for declaring "this person is accountable for the risk in this access chain." It differs from routing in that it is an explicit human decision, not an automatic default.

The current OwnershipAssignmentDoc works for paths and entities. To support access chains:

  • Add "access_chain" to OWNERSHIP_TARGET_TYPES
  • target_id references the access chain's stable ID (content-hash-based, like path_lineage_id)
  • Owner = the person accountable for reviewing and acting on the risk this chain represents
  • Existing assign/revoke lifecycle applies unchanged
  • API: extend GET /api/v1/ownership-assignments?target_type=access_chain

This is a narrow extension, not a redesign. The ownership model is already correct — it just needs a new target type.

Layer 3: Mitigation Tracking (partially exists)

Mitigation actions need access-chain-level remediation. Sergey's requirement: one remediation object per access chain, not five path-level actions.

Design:

  • Add optional access_chain_id to MitigationActionDoc
  • When access_chain_id is set, the mitigation applies to the chain as a whole, not to individual paths
  • A chain-level mitigation can reference multiple findings within that chain via a new finding_ids: string[] field (alongside the existing singular finding_id for backwards compatibility)
  • The action describes what to do about the chain — e.g., "Reduce svc-finance from 5 roles to 2, covering 3 destinations"
  • Staleness detection extends naturally: source_state_hash covers the chain's constituent paths, so if any path changes, the mitigation is flagged stale
  • Existing lifecycle (proposedassignedin_progresscompletedverified) applies unchanged

This preserves backwards compatibility. Path-level mitigations continue to work. Chain-level mitigations are a new capability layered on top.

Layer 4: Attestation (not started)

Attestation is the periodic confirmation that an access chain's risk has been reviewed and consciously accepted, escalated, or deferred. It creates an audit trail of risk decisions — not a rubber stamp, but a record of what was reviewed and why.

Design sketch:

interface AttestationDoc {
_id: string;
tenant_id: string;
access_chain_id: string;
attester_email: string;
attester_name: string;

// What the attester decided
status: "attested" | "escalated" | "deferred";
escalation_target?: string; // who it was escalated to
deferral_reason?: string;
deferral_until?: Date;

// What they reviewed
review_summary: string; // free-text: what the owner reviewed
risk_acceptance_rationale: string; // why they accept the risk (or don't)
chain_state_hash: string; // SHA256 of chain state at attestation time

// Validity
attested_at: Date;
valid_until: Date; // attestation expires after N days
expired: boolean; // computed: valid_until < now

created_at: Date;
updated_at: Date;
}

Key design decisions:

  • Expiry: Attestation is time-bounded. After valid_until, the chain returns to "needs attestation" state. The recurrence period is configurable per tenant (default: 90 days).

  • State hash: chain_state_hash captures the chain's state at attestation time. If the chain changes materially after attestation (new paths, new findings, severity increase), the attestation is invalidated regardless of expiry.

  • Not a rubber stamp: review_summary and risk_acceptance_rationale are required fields. The attester must document what they reviewed and why they accept the risk. This is the difference between compliance theater and actual risk management.

  • Escalation path: If an owner cannot accept the risk, they escalate. The attestation records who they escalated to, creating a chain of accountability.

What This Is NOT

The operating layer has an explicit scope boundary. It is NOT:

  • Posture management. The platform does not enforce security policies, gate deployments, or block configurations. It surfaces risk and enables humans to act on it.

  • Automated remediation. The platform does not execute fixes. Mitigation actions describe what should be done; humans or external systems do the work.

  • Compliance mapping. Mapping access chains to compliance frameworks (SOC 2, ISO 27001, etc.) is a separate feature. The operating layer provides the accountability data that compliance mapping would consume.

  • Platform RBAC. User management and role-based access control for the SecurityV0 platform itself is infrastructure, not the operating layer. The operating layer assumes authenticated users and focuses on who owns which access chains.

The operating layer is about enabling humans to act on access-chain analysis: route findings to the right team, assign accountability, track remediation, and create an audit trail of risk decisions.

Dependency on Access Chain Model

Layers 2-4 depend on access chains being first-class objects with stable IDs. Today, IdentityAccessSurface is a computed grouping assembled at query time — it has no persistent identity and no stable ID.

Before the operating layer can target access chains, the platform needs:

  1. Stable access chain IDs. Content-hash-based, following the same pattern as path_lineage_id. The hash should be deterministic from the chain's constituent paths so that the same chain produces the same ID across re-evaluations.

  2. AccessChain as a stored document. The chain must be persisted, not just computed on read. Ownership, mitigation, and attestation all reference chain IDs — those references must remain valid.

  3. API endpoint. GET /api/v1/access-chains/{id} to retrieve a chain by ID, with its constituent paths, findings, ownership, mitigations, and attestation status.

This materialization is the prerequisite. Without it, there is nothing for Layers 2-4 to target.

Implementation Phases

These are engineering proposals for sequencing the work. They are not founder-approved roadmap commitments. Phase ordering may change based on product priorities.

Phase 1: Extend ownership to access chains. Add "access_chain" to OWNERSHIP_TARGET_TYPES. Extend the ownership assignment API to accept target_type: "access_chain". UI: ownership panel on the access chain detail view.

Phase 2: Access-chain-level mitigation. Add access_chain_id and finding_ids to MitigationActionDoc. Create chain-level mitigation proposals in the evaluator. UI: mitigation panel on the access chain detail view, showing one action per chain instead of per-path fragments.

Phase 3: Attestation workflow. New AttestationDoc type, storage adapter, API endpoints. Attestation expiry and state-hash invalidation logic. UI: attestation form on the access chain detail view with required review summary and rationale fields.

Phase 4: Attestation dashboard. Aggregate view: chain attestation coverage (% of chains attested), overdue attestations, recently expired, escalation queue. This is the operating loop's feedback mechanism — it shows whether the organization is actually reviewing its access chains.

Next Action

Status: adopted

Decisions made:

  • Operating layer scope is routing, accountability, mitigation tracking, and attestation — four layers that build on each other.

  • This is NOT posture management. The platform enables humans to act on access-chain analysis; it does not enforce policies or execute remediations.

  • Phase ordering and API proposals are engineering proposals, not founder-approved roadmap.

Implementation:

  • Create GitHub issues in sv0-platform for each phase after access chain IDs are stable.

  • Phase 1-2 extend existing types (OwnershipAssignmentDoc, MitigationActionDoc) — narrow changes, not redesigns.

  • Phase 3-4 introduce a new type (AttestationDoc) — requires design review before implementation.

Dependency: Access chain materialization (storing chains as first-class documents with stable IDs) must happen first. This is not yet started.