Skip to main content

Architecture Documentation Update Plan

Date: 2026-02-13 Status: Active — updated with Round 3/4/5 decisions Supersedes: Previous version (Round 2 only). Now incorporates all 5 rounds of analysis.


1. What Changed (Rounds 3-5)

The original plan was written after Round 2, which concluded "keep entity_type: identity, fix labels in UI." Rounds 3-5 reversed this:

RoundDecisionImpact on Docs
Round 3New execution_chains collectionNew section in 03-database.md, new section in 01-data-model.md
Round 4OAA is export format, not internal modelNew section in 01-data-model.md (OAA mapping), new ADR
Round 5Reclassify entity types (9 types)Major rewrite of 01-data-model.md Entity Types section, 05-connectors.md, glossary.md

Key Reversals

TopicRound 2 PositionRound 5 Position
Entity type for BR/SI/FlowKeep as identityReclassify to automation
Entity type for OAuth ProfileKeep as identityReclassify to credential
Entity type for REST MessageKeep as resourceReclassify to connection
ADR-006 topic"identity subtype taxonomy""entity type reclassification"
human_identity typeKeepMap to internal owner (NormalizedNodeType stays human_identity)
Execution chainsNot consideredNew execution_chains collection
OAA alignmentNot consideredExport projection layer (deferred)

2. Documents to Update

2.1 architecture/01-data-model.md — Major Rewrite

A. Entity Types Section — Replace

Replace the current entity types table with the new 9-type system.

NormalizedNodeType vs Internal entity_type: Connectors emit human_identity as the NormalizedNodeType (per connector contract, 05-connectors.md line 334). The platform normalizer maps this to internal entity_type: "owner". All other types are 1:1 between NormalizedNodeType and entity_type. Also, during migration window, autonomous_identity is accepted and remapped to identity, automation, or credential based on subtype.

### Entity Types (Internal)

| Type | Purpose | Examples | NormalizedNodeType | Subtypes |
|------|---------|---------|-------------------|----------|
| `identity` | Authenticates and acts in systems | Service Principal, OAuth App, Machine Account | `identity` | IdentitySubtype |
| `automation` | Defines execution logic | Business Rule, Script Include, Flow, Scheduled Job | `automation` | AutomationSubtype |
| `connection` | Outbound integration configuration | REST Message, SOAP Message, HTTP Connection | `connection` | ConnectionSubtype |
| `credential` | Authentication material | OAuth Provider, OAuth Profile, API Key, Certificate | `credential` | CredentialSubtype |
| `owner` | Human user who owns/creates entities | Entra user, ServiceNow sys_user | `human_identity` (normalizer maps) ||
| `role` | Permission grouping | Entra role, ServiceNow role | `role` ||
| `permission` | Individual capability | ACL entry, Graph API scope | `permission` ||
| `resource` | Data object being acted upon | Table, API endpoint, Repository | `resource` ||
| `execution_evidence` | Proof of execution | Sign-in log, transaction log | `execution_evidence` ||

B. Entity Classification Decision Tree (new section)

C. Subtype Definitions (new section)

export type IdentitySubtype =
| "service_principal" | "oauth_app" | "machine_account"
| "integration_user" | "system_execution";

export type AutomationSubtype =
| "business_rule" | "script_include" | "flow_designer_flow"
| "scheduled_job" | "event_script" | "transform_map";

export type ConnectionSubtype =
| "rest_message" | "rest_method" | "soap_message" | "http_connection";

export type CredentialSubtype =
| "oauth_provider" | "oauth_profile" | "api_key"
| "certificate" | "client_secret";

D. Relationship Types — Update

Update the relationship table with new edge types:

#RelationshipFromToDescription
1OWNED_BYanyownerEntity owned by human
2CREATED_BYanyownerEntity created by human
3HAS_ROLEidentityroleIdentity has this role
4GRANTSrolepermissionRole grants permission
5APPLIES_TOpermissionresourcePermission applies to resource
6AUTHENTICATES_TOidentityidentityCross-system identity auth (SP→SP)
7RUNS_ASautomationidentity | ownerAutomation executes as identity or human user
8TRIGGERS_ONautomationresourceAutomation fires on resource events
9EXECUTES_ONautomationresourceAutomation reads/writes this resource
10CALLSautomationautomationAutomation invokes code (BR→SI)
11INVOKESautomationconnectionCode uses outbound connection
12USESconnectioncredentialConnection uses auth material
13AUTHENTICATES_AScredentialidentityCredential represents this identity

D.2 Edge Migration Mapping (Old → New)

Document the explicit mapping from legacy edge types:

Legacy EdgeLegacy UsageNew EdgeWhen
EXECUTES_ONautomation→REST messageINVOKESWhen target is connection type
EXECUTES_ONautomation→table/resourceEXECUTES_ON (kept)When target is resource type
AUTHENTICATES_VIAREST→OAuthUSESAlways (connection→credential)
(none)CALLSNew: automation→automation (BR→SI)
(none)AUTHENTICATES_ASNew: credential→identity (OAuth→SP)

During the migration window, the platform ingestion normalizer accepts legacy edge types and remaps them to new types based on source/target entity types.

E. Execution Chains (new section)

Add a new top-level section documenting:

  • What an execution chain is (ordered set of entities from trigger to destination)
  • Chain identity (anchored to entry point, survives entity rotation)
  • Chain composition fingerprint (SHA256 of sorted entity_id:role pairs)
  • Chain assembly (platform-side, BFS from entry points)
  • Chain lifecycle (created on first sync, versioned on structural change)

F. Execution Flow Provenance Diagram (new section)

G. OAA Mapping Reference (new section)

SecurityV0 TypeOAA Export EntityMapping Fidelity
identitylocal_userHIGH
automationresource (type: automation)HIGH
connectionresource (type: connection)HIGH
credentialcustom property on local_userMEDIUM
rolelocal_roleHIGH
permissioncustom_permissionHIGH
resourceresourceHIGH

Note: OAA is an export format, not the internal data model. SecurityV0's model is a superset of OAA. See ADR-009.

H. Security Relevance Decision Tree — Update

Update the existing decision tree (if present) with the sensitive-data promotion rule from Round 1 analysis.

I. Remove "The Identity Question" Section

The Round 2 doc plan included a section explaining "why everything is entity_type: identity." This is no longer needed — the types are now correct. Remove or replace with a brief note: "Prior to v2, all automation artifacts were classified as identity. See ADR-006 for the reclassification rationale."

2.2 architecture/03-database.md — Add execution_chains

A. New Collection: execution_chains

Add to the Collections section:

// execution_chains — platform-computed execution chain tracking
{
_id: "chain-uuid",
tenant_id: String,
name: String,
anchor_entity_id: String, // Entry point entity ID (stable root)
entity_refs: [{
entity_id: String,
entity_type: String, // automation | connection | credential | identity
role: String // entry_point | code_component | outbound_target | auth_credential | destination_identity
}],
summary: {
trigger: String,
destination: String,
egress_category: String,
blast_radius_domains: [String],
ownership_status: String,
total_roles: Number,
max_sensitivity: String,
canonical_permissions: {
reads: [String],
writes: [String]
}
},
composition_hash: String, // SHA256 fingerprint for change detection
first_detected_at: Date,
last_seen_at: Date,
sync_version: Number
}

// Indexes
{ tenant_id: 1, anchor_entity_id: 1 } // unique chain lookup
{ tenant_id: 1, "entity_refs.entity_id": 1 } // find chains containing entity
{ tenant_id: 1, "summary.ownership_status": 1 } // filter orphaned chains
{ tenant_id: 1, composition_hash: 1 } // change detection
{ tenant_id: 1, last_seen_at: 1 } // temporal queries

B. New Collection: execution_chain_versions (Phase 2)

Add to the Collections section (Phase 2 — temporal chain tracking):

// execution_chain_versions — chain state snapshots for temporal comparison
{
_id: "version-uuid",
chain_id: String, // FK to execution_chains._id
tenant_id: String,
version_number: Number,
entity_refs: [{ entity_id: String, entity_type: String, role: String }],
summary: { /* snapshot at this version */ },
composition_hash: String,
created_at: Date,
sync_version: Number,
diff_from_previous: {
entities_added: [{ entity_id: String, entity_type: String, role: String }],
entities_removed: [{ entity_id: String, entity_type: String, role: String }],
summary_changes: Object
}
}

// Indexes
{ chain_id: 1, version_number: -1 } // latest version per chain
{ tenant_id: 1, chain_id: 1, created_at: -1 } // temporal queries

C. New Collection: execution_chain_events (Phase 2)

// execution_chain_events — discrete events for chain lifecycle
{
_id: "event-uuid",
chain_id: String,
tenant_id: String,
event_type: String, // chain_created | chain_entity_added | chain_entity_removed
// | chain_blast_radius_changed | chain_ownership_changed
timestamp: Date,
details: Object,
sync_version: Number
}

// Indexes
{ tenant_id: 1, chain_id: 1, timestamp: -1 } // events per chain
{ tenant_id: 1, event_type: 1, timestamp: -1 } // events by type

Phasing: execution_chain_versions and execution_chain_events are Phase 2 deliverables (see implementation plan B.6). Document the schema in 03-database.md during Phase 2 implementation, but reserve the section headers during Phase 1.

D. Update Entity Types in entities collection

Update the entity_type field description to list all 9 types.

E. Update Indexes

Add indexes for new entity types (automation, connection, credential) if needed.

2.3 architecture/05-connectors.md — Update Connector Interface

A. NormalizedNode Type Changes

Update the NormalizedNode specification:

  • nodeType enum: add automation, connection, credential
  • Keep human_identity — do NOT rename to owner (connector contract prohibition at line 334 remains valid; platform normalizer handles mapping to internal owner type)
  • Remove autonomous_identity (replaced by identity, automation, credential)
  • Add subtype fields: automationSubtype, connectionSubtype, credentialSubtype
  • Document which artifacts map to which types

B. NormalizedEdge Type Changes

Update the NormalizedEdge specification:

  • Add CALLS, INVOKES, USES, AUTHENTICATES_AS
  • Mark AUTHENTICATES_VIA as deprecated (→ normalized to USES on ingest)
  • Mark EXECUTES_ON as narrowed (only for automation→resource; automation→connection should use INVOKES)
  • Document from/to type constraints for each edge

C. Chain Hints (Optional)

Document the optional chainMembership property on automation nodes:

properties["chainMembership"] = {
"role": "entry_point",
"anchorEntityId": br_sys_id,
"chainSemanticHash": "trigger-incident-dest-graph"
}

2.4 glossary.md — Term Updates

TermStatusDefinition
AutomationUpdateEntity that defines executable behavior. entity_type: "automation". Includes Business Rules, Script Includes, Flows, Scheduled Jobs. Does NOT authenticate — uses RUNS_AS to delegate to an identity.
ConnectionNewEntity that defines an outbound integration endpoint. entity_type: "connection". Includes REST Messages, SOAP Messages, HTTP Connections.
CredentialUpdateEntity that stores authentication material. entity_type: "credential". Includes OAuth Providers/Profiles, API Keys, Certificates.
IdentityUpdateEntity that authenticates and acts in systems. entity_type: "identity". Includes Service Principals, OAuth Apps, Machine Accounts. The only entity type that "can log in."
OwnerUpdate (clarify)Human user who owns or creates entities. Internal entity_type: "owner". Connectors emit as human_identity NormalizedNodeType; platform normalizer maps to owner.
Execution ChainNewPlatform-computed ordered set of entities from trigger to destination, stored in execution_chains collection. Has stable identity anchored to entry point. Survives entity rotation.
Chain Composition FingerprintNewSHA256 hash of sorted entity_id:role pairs. Detects structural changes between scans.
CALLSNewRelationship: automation invokes another automation (BR → SI).
INVOKESNewRelationship: automation uses outbound connection (SI → REST Message).
USESNewRelationship: connection uses credential (REST Message → OAuth Profile).
AUTHENTICATES_ASNewRelationship: credential represents an identity (OAuth Profile → Service Principal).
Code ArtifactRemoveSuperseded by automation entity type.
Trigger AutomationRemoveSuperseded by automation with entry-point subtypes (business_rule, scheduled_job, flow_designer_flow).

3. ADRs to Create

ADR-006: Entity Type Reclassification

File: architecture/decisions/adr-006-entity-type-reclassification.md

Status: Accepted Date: 2026-02-13

Context: The original data model classified all automation artifacts (Business Rules, Script Includes, Flows, Scheduled Jobs, OAuth Profiles) as entity_type: "identity" with different identitySubtype values. This was pragmatically convenient but semantically wrong:

  • Script Includes don't authenticate
  • OAuth Profiles are credentials, not identities
  • REST Messages are connection configurations
  • NHI count inflated 13-18x by non-authenticating artifacts
  • 0 of 8 OAA community connectors classify automation artifacts as identities

Decision: Split autonomous_identity into 4 types:

  • identity — entities that authenticate (SP, OAuth App, Machine Account)
  • automation — entities that define execution logic (BR, SI, Flow, Job)
  • connection — outbound integration configs (REST Message)
  • credential — authentication material (OAuth Profile)

Map human_identity to internal owner type via platform normalizer (NormalizedNodeType keeps human_identity per connector contract; platform stores as owner).

Consequences:

  • NHI count accurately reflects authenticating entities only
  • Clean governance categories (govern identities, monitor automations, rotate credentials)
  • OAA export becomes natural (identities → local_users, automations → resources)
  • All code that assumes identity = automation artifact must be updated
  • Connector contract preserved: connectors still emit human_identity, platform handles mapping

Analysis: Round 5 Synthesis — 6 agents, 7,844 lines, 5/6 majority

ADR-007: Execution Relationship Types

File: architecture/decisions/adr-007-execution-relationship-types.md

Status: Accepted Date: 2026-02-13

Context: With entity type reclassification, the execution chain traverses 4 different entity types. New edge types are needed to connect them.

Decision: Add 4 new relationship types:

  • CALLS — automation → automation (BR invokes SI)
  • INVOKES — automation → connection (SI uses REST Message)
  • USES — connection → credential (REST Message uses OAuth Profile)
  • AUTHENTICATES_AS — credential → identity (OAuth Profile represents SP)

Update existing relationship type constraints:

  • RUNS_AS — automation → identity | owner (covers both SP binding and flow run-as human user)
  • EXECUTES_ON — narrowed to automation → resource only (automation → connection now uses INVOKES)

Deprecate with migration:

  • AUTHENTICATES_VIA — deprecated, normalized to USES on ingest

Preserve AUTHENTICATES_TO for cross-system identity-to-identity auth.

Consequences:

  • Graph traversal follows typed edges through the execution chain
  • Each edge type has clear from/to type constraints
  • Path materializer must follow the new edge sequence
  • Migration window: platform accepts old + new edge types; ingestion normalizer remaps legacy edges

ADR-008: Execution Chains Collection

File: architecture/decisions/adr-008-execution-chains-collection.md

Status: Accepted Date: 2026-02-13

Context: The platform needs to track automation chains as durable, listable entities with stable identity across scans. The current model can reconstruct chains on the fly but cannot list, bookmark, diff, or version them.

Decision: New execution_chains collection. Chain identity anchored to entry point entity. Platform-side assembly via BFS during sync. Composition fingerprint for change detection.

Consequences:

  • CISO can list, filter, and search automations
  • Chain identity survives entity rotation (OAuth client_id change, SP credential rotation)
  • Chain-level findings become possible (aggregate ownership, blast radius expansion)
  • One more collection to manage (acceptable trade-off per 6/6 team consensus)

Analysis: Round 3 Synthesis — 5 agents, 5,760 lines, 6/6 unanimous (after Round 4 PO reversal)

ADR-009: OAA Export Projection (Deferred)

File: architecture/decisions/adr-009-oaa-export-projection.md

Status: Proposed (deferred until customer need) Date: 2026-02-13

Context: The founder asked whether automations should be modeled as OAA Applications or Resources. The team analyzed this across 6 perspectives.

Decision: OAA is an export projection layer, not the internal data model. SecurityV0's internal model (entities + execution_chains) is a superset of OAA. OAA export projects: identities → local_users, automations → resources, roles → local_roles, permissions → custom_permissions.

Consequences:

  • Internal model optimized for execution exposure analysis, not OAA compliance
  • OAA export is lossy but acceptable (documented limitations)
  • OAA implementation deferred until customer/sales need

Analysis: Round 4 Synthesis — 6 agents, 9,315 lines, 6/6 unanimous


4. Implementation Plan

Step 1: Create ADRs (3 hours)

ADRContent
adr-006Entity type reclassification (9 types)
adr-007Execution relationship types (4 new edges)
adr-008execution_chains collection
adr-009OAA export projection (stub — deferred)

Step 2: Update 01-data-model.md (5-6 hours)

SectionAction
Entity Types tableReplace with 9-type system
Classification Decision TreeAdd mermaid flowchart
Subtype DefinitionsAdd TypeScript enums
Relationship Types tableUpdate with 4 new edges + type constraints
Execution ChainsAdd new section (schema, identity, assembly, lifecycle)
Execution Flow ProvenanceAdd mermaid diagram
OAA Mapping ReferenceAdd mapping table + note
Security Relevance TreeUpdate with sensitive-data promotion
"The Identity Question"Remove (no longer needed)

Step 3: Update 03-database.md (2-3 hours)

SectionAction
CollectionsAdd execution_chains schema + indexes
Entity TypesUpdate to list 9 types

Step 4: Update 05-connectors.md (2-3 hours)

SectionAction
NormalizedNode specUpdate with new types + subtypes
NormalizedEdge specUpdate with 4 new edge types
Chain HintsAdd optional chainMembership property

Step 5: Update glossary.md (1-2 hours)

Add/update ~12 terms (see Section 2.4).

Step 6: Cross-reference analysis (30 min)

Add references from architecture docs to the analysis folder.

Total Effort: 14-17 hours

Effort reconciliation with implementation plan:

  • ADR creation (Step 1, 3h) is accounted for in implementation plan task A0.1
  • Doc updates (Steps 2-6, ~11-14h) are accounted for in implementation plan task A4.3 (12h)
  • These are the same work — this plan defines the content, the implementation plan schedules it
  • Do not double-count: total doc effort is 14-17h, not 14-17h + A0.1 + A4.3

5. Success Criteria

After these updates, a developer or AI agent should be able to:

  1. Look up the Entity Classification Decision Tree → Determine any artifact's correct entity type in 5 questions
  2. Look up the Execution Flow diagram → Understand the full chain with correct types: automation → connection → credential → identity
  3. Read the execution_chains section → Understand chain identity, composition fingerprint, assembly algorithm
  4. Find ADR-006 → Understand why BRs/SIs are automation, not identity
  5. Find ADR-008 → Understand why chains need their own collection
  6. Look up OAA mapping → Know how to project internal types to OAA format
  7. Look up the Relationship Types table → Know which edge types connect which entity types

No ambiguity. No need to read 35+ analysis files across 5 rounds.


6. Analysis References

Architecture Doc SectionAnalysis SourceRound
Entity Type System (9 types)Round 5 Synthesis5
Classification Decision TreeRound 5 Architect5
Execution Chains SchemaRound 3 Synthesis3
Chain Builder AlgorithmRound 3 Architect3
OAA Mapping ReferenceRound 4 Synthesis4
Security Relevance TiersRound 1 Synthesis1
CALLS RelationshipRound 2 Architect2
Execution Flow ProvenanceRound 2 Synthesis2
NHI Count InflationRound 5 CISO5
Compliance ImpactRound 4 CISO4