Aggregate Roots¶
Target Architecture — Final-State Design
This page describes the final-state domain model of the Governance, Security & Compliance Platform: twelve aggregate roots across seven bounded contexts. Aggregates follow the Naming Conventions (singular PascalCase nouns) and persist via NHibernate to per-service Azure SQL / PostgreSQL databases. Every aggregate carries the cross-cutting Metadata Schema fields (tenantId, traceId, createdAt, etc.).
Aggregate Overview¶
flowchart TB
subgraph Policy["Policy Context"]
PolicyDefinition
PolicyRule
PolicyDecision
end
subgraph Approval["Approval Context"]
ApprovalRequest
ApprovalDecision
end
subgraph Audit["Audit Context"]
AuditEntry
end
subgraph Compliance["Compliance Context"]
ComplianceReport
end
subgraph Security["Security Context"]
SecurityFinding
SecretReference
end
subgraph Isolation["Isolation & Classification Context"]
TenantIsolationRule
DataClassification
end
subgraph Risk["Risk Context"]
RiskScore
end
PolicyDefinition -->|contains| PolicyRule
PolicyDecision -->|references| PolicyDefinition
PolicyDecision -->|may open| ApprovalRequest
ApprovalRequest -->|resolved by| ApprovalDecision
PolicyDefinition¶
Purpose — The versioned, published unit of policy-as-code (the policy administration point). Owns the rules that the policy decision point evaluates.
- Fields —
policyDefinitionId,name,domain(one of the ten governance domains),description,effect(Allow|Deny|RequiresApproval),version,status(Draft|Published|Deprecated),tenantId,createdAt,publishedAt. - Entities —
PolicyRule(composed; see below). - Value Objects —
PolicyDomain,PolicyEffect,PolicyVersion,PolicyScope(tenant/project/edition selector). - Invariants — a
Publisheddefinition is immutable (changes create a new version); at least one rule is required to publish;name+versionis unique per tenant;domainmust be one of the ten governance domains. - Domain Events —
PolicyDefined. - Repository —
PolicyDefinitionRepository. - Persistence —
PolicyDefinitionServiceDB (Azure SQL/PostgreSQL); rules stored in a child table; versions retained indefinitely for decision replay.
PolicyRule¶
Purpose — A single evaluable rule within a PolicyDefinition: when this subject performs this action on this resource under this condition, apply this effect/gate.
- Fields —
policyRuleId,policyDefinitionId,subjectSelector,resourceSelector,action,condition(ABAC expression),effect,gate(None|HumanApproval),priority,tenantId. - Entities — none (leaf within the
PolicyDefinitionaggregate boundary). - Value Objects —
SubjectSelector,ResourceSelector,RuleCondition,RulePriority. - Invariants —
conditionmust parse to a valid boolean ABAC expression;priorityis unique within a definition; a rule belongs to exactly one definition. - Domain Events — emitted via the parent
PolicyDefined. - Repository — managed through
PolicyDefinitionRepository(not independently loadable). - Persistence — child table of
PolicyDefinitionin thePolicyDefinitionServiceDB.
PolicyDecision¶
Purpose — The immutable record of a single policy evaluation — the auditable output of the policy decision point.
- Fields —
policyDecisionId,decision(Allow|Deny|RequiresApproval),policyDefinitionId,policyVersion,action,subject,resource,riskScore,reason,approvalRequestId?,tenantId,traceId,correlationId,evaluatedAt. - Entities —
MatchedRuleTrace(which rules fired, in order). - Value Objects —
DecisionOutcome,EvaluationContext,RiskSnapshot. - Invariants — immutable once recorded;
decision == RequiresApproval⇒approvalRequestIdset; references a specificpolicyVersion(never "latest") for deterministic replay. - Domain Events —
PolicyDecisionRecorded. - Repository —
PolicyDecisionRepository. - Persistence —
PolicyEngineServiceDB; append-only; indexed bytraceId,subject,action.
ApprovalRequest¶
Purpose — A human approval gate opened because a PolicyDecision required it (or by direct request). Tracks lifecycle from open to resolved.
- Fields —
approvalRequestId,status(Pending|Approved|Rejected|Expired|Escalated),subject,action,resource,policyDecisionId,requiredApprovers,expiresAt,escalationLevel,tenantId,traceId,createdAt. - Entities —
ApprovalDecision(the resolving decision; see below). - Value Objects —
ApproverSet,ApprovalStatus,TimeoutPolicy,EscalationPolicy. - Invariants — a request resolves to exactly one terminal state; the raising subject cannot be an approver (segregation of duties); only an authorized approver in
requiredApproversmay decide; cannot decide afterexpiresAtunless escalated. - Domain Events —
ApprovalRequested,ApprovalGranted,ApprovalRejected. - Repository —
ApprovalRequestRepository. - Persistence —
ApprovalServiceDB; open requests indexed byexpiresAtfor theApprovalTimeoutWorker.
ApprovalDecision¶
Purpose — The granular, attributable record of an approver's grant or rejection of an ApprovalRequest.
- Fields —
approvalDecisionId,approvalRequestId,approverId,outcome(Granted|Rejected),comment,justification,tenantId,decidedAt. - Entities — none.
- Value Objects —
ApprovalOutcome,Justification. - Invariants — immutable once recorded; belongs to exactly one request;
approverIdmust be authorized and distinct from the request's raising subject. - Domain Events — surfaces as
ApprovalGranted/ApprovalRejectedon the parent request. - Repository — managed through
ApprovalRequestRepository. - Persistence — child of
ApprovalRequestin theApprovalServiceDB.
AuditEntry¶
Purpose — A single immutable, tamper-evident record of a governance-relevant action — the atomic unit of the audit system of record.
- Fields —
auditEntryId,action,subject,resource,outcome,tenantId,traceId,correlationId,hash,previousHash,occurredAt,payloadDigest. - Entities — none.
- Value Objects —
AuditAction,HashChainLink(hash/previousHash),ActorRef. - Invariants — append-only and immutable;
hash = sha256(previousHash + canonical(entry))forms a per-tenant chain; no deletes (retention via export then archival only). - Domain Events —
AuditEntryRecorded. - Repository —
AuditEntryRepository(write-once; reads via indexed projections). - Persistence —
AuditServiceDB (append-only), backed byConnectSoft.Extensions.AuditNet; exported to Blob by theAuditExportWorker.
ComplianceReport¶
Purpose — A point-in-time evidence bundle mapping controls to a compliance framework over a scope and period.
- Fields —
complianceReportId,framework(e.g.SOC2,GDPR,HIPAA),scope,period,status(Generating|Generated|Failed),controlResults,evidenceLocation(Blob URI),tenantId,requestedAt,generatedAt. - Entities —
ControlResult(per-control pass/fail with evidence refs). - Value Objects —
ComplianceFramework,ReportPeriod,ReportScope,EvidenceReference. - Invariants — a
Generatedreport is immutable;evidenceLocationis set only whenGenerated;period.from <= period.to; control set determined byframeworkversion. - Domain Events —
ComplianceReportGenerated. - Repository —
ComplianceReportRepository. - Persistence —
ComplianceReportServiceDB (metadata) + Blob (evidence bundle).
SecurityFinding¶
Purpose — A tracked security issue (vulnerability, leaked secret, misconfiguration, policy violation) from a scanner or runtime detector.
- Fields —
securityFindingId,source,category,severity(Low|Medium|High|Critical),status(Open|Triaged|Resolved|Suppressed),resource,title,evidence,dedupKey,riskScore,tenantId,traceId,createdAt,resolvedAt?. - Entities —
FindingNote(triage history). - Value Objects —
Severity,FindingCategory,FindingStatus,EvidenceLocation,DedupKey. - Invariants —
dedupKeyis unique per tenant (duplicate ingests update, not duplicate);Resolved/Suppressedrequire a note; severity transitions are recorded. - Domain Events —
SecurityFindingRaised. - Repository —
SecurityFindingRepository. - Persistence —
SecurityFindingServiceDB; indexed bydedupKey,severity,status.
SecretReference¶
Purpose — A governed pointer to a secret in Azure Key Vault — metadata and rotation policy only, never the secret value.
- Fields —
secretReferenceId,vaultUri,secretName,secretVersion,owner,rotationPolicy,lastRotatedAt,nextRotationDueAt,status(Active|Pending Rotation|Compromised|Retired),tenantId,createdAt. - Entities — none.
- Value Objects —
VaultReference(vaultUri+secretName+secretVersion),RotationPolicy,SecretStatus. - Invariants — never stores secret material;
vaultUrimust resolve to a tenant-authorized Key Vault; aCompromisedreference forces rotation and raises aSecurityFinding;nextRotationDueAtderived fromrotationPolicy. - Domain Events —
SecurityFindingRaised(on leak/compromise detection). - Repository —
SecretReferenceRepository. - Persistence —
SecretGovernanceServiceDB (references); secret values live exclusively in Azure Key Vault.
TenantIsolationRule¶
Purpose — A declarative rule defining tenant isolation boundaries — cross-tenant access permissions and data residency constraints.
- Fields —
tenantIsolationRuleId,tenantId,scope(resource/data category),isolationMode(Strict|SharedRead|Delegated),residencyRegion,allowedCrossTenant,status,createdAt. - Entities — none.
- Value Objects —
IsolationMode,ResidencyConstraint,CrossTenantGrant. - Invariants — default mode is
Strict(deny cross-tenant); aDelegatedgrant requires an explicitCrossTenantGrantwith an owning approval; residency cannot be relaxed below the tenant's edition floor. - Domain Events — surfaces as
PolicyDecisionRecordedwhen consulted during evaluation. - Repository —
TenantIsolationRuleRepository. - Persistence —
TenantIsolationPolicyServiceDB; backed byConnectSoft.Extensions.Saas.*tenant context.
DataClassification¶
Purpose — A classification label assigned to data or an artifact that drives handling, redaction, and access policy.
- Fields —
dataClassificationId,subjectRef(artifact/data id),label(Public|Internal|Confidential|Restricted),categories(e.g. PII, PHI, secrets),contentHash,classifiedBy(worker/agent),tenantId,classifiedAt. - Entities — none.
- Value Objects —
ClassificationLabel,DataCategorySet,ContentHash. - Invariants — exactly one active label per
(subjectRef, contentHash); label can only be raised automatically (downgrade requires approval);Restrictedimplies handling constraints enforced by Knowledge Platform redaction. - Domain Events —
DataClassified. - Repository —
DataClassificationRepository. - Persistence —
DataClassificationServiceDB; indexed bysubjectRef,label,categories.
RiskScore¶
Purpose — A composite, recomputable risk score for an action, artifact, or tenant, feeding risk-adaptive policy gates.
- Fields —
riskScoreId,subjectType(Action|Artifact|Tenant|Agent),subjectId,score(0–100),band(Low|Medium|High|Critical),factors,version,tenantId,computedAt. - Entities —
RiskFactor(contributing signal with weight). - Value Objects —
RiskBand,RiskFactorWeight,ScoreVersion. - Invariants —
scorein [0,100];bandderived deterministically fromscorethresholds; latest version wins per(subjectType, subjectId); factors must reference real signals (findings, classifications, behaviour). - Domain Events —
RiskScored. - Repository —
RiskScoreRepository. - Persistence —
RiskScoringServiceDB; latest-per-subject projection plus version history.
Persistence Summary¶
| Aggregate | Owning Service | Store |
|---|---|---|
PolicyDefinition, PolicyRule |
PolicyDefinitionService |
Azure SQL / PostgreSQL |
PolicyDecision |
PolicyEngineService |
Azure SQL / PostgreSQL (append-only) |
ApprovalRequest, ApprovalDecision |
ApprovalService |
Azure SQL / PostgreSQL |
AuditEntry |
AuditService |
Azure SQL / PostgreSQL (append-only) + Blob export |
ComplianceReport |
ComplianceReportService |
Azure SQL / PostgreSQL + Blob evidence |
SecurityFinding |
SecurityFindingService |
Azure SQL / PostgreSQL |
SecretReference |
SecretGovernanceService |
Azure SQL / PostgreSQL + Azure Key Vault |
TenantIsolationRule |
TenantIsolationPolicyService |
Azure SQL / PostgreSQL |
DataClassification |
DataClassificationService |
Azure SQL / PostgreSQL |
RiskScore |
RiskScoringService |
Azure SQL / PostgreSQL |
Related¶
- Bounded Contexts · Microservices · Data Model · Events · Storage
- Reference: Naming Conventions · Metadata Schema