Skip to content

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
Hold "Alt" / "Option" to enable pan & zoom

PolicyDefinition

Purpose — The versioned, published unit of policy-as-code (the policy administration point). Owns the rules that the policy decision point evaluates.

  • FieldspolicyDefinitionId, name, domain (one of the ten governance domains), description, effect (Allow | Deny | RequiresApproval), version, status (Draft | Published | Deprecated), tenantId, createdAt, publishedAt.
  • EntitiesPolicyRule (composed; see below).
  • Value ObjectsPolicyDomain, PolicyEffect, PolicyVersion, PolicyScope (tenant/project/edition selector).
  • Invariants — a Published definition is immutable (changes create a new version); at least one rule is required to publish; name + version is unique per tenant; domain must be one of the ten governance domains.
  • Domain EventsPolicyDefined.
  • RepositoryPolicyDefinitionRepository.
  • PersistencePolicyDefinitionService DB (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.

  • FieldspolicyRuleId, policyDefinitionId, subjectSelector, resourceSelector, action, condition (ABAC expression), effect, gate (None | HumanApproval), priority, tenantId.
  • Entities — none (leaf within the PolicyDefinition aggregate boundary).
  • Value ObjectsSubjectSelector, ResourceSelector, RuleCondition, RulePriority.
  • Invariantscondition must parse to a valid boolean ABAC expression; priority is 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 PolicyDefinition in the PolicyDefinitionService DB.

PolicyDecision

Purpose — The immutable record of a single policy evaluation — the auditable output of the policy decision point.

  • FieldspolicyDecisionId, decision (Allow | Deny | RequiresApproval), policyDefinitionId, policyVersion, action, subject, resource, riskScore, reason, approvalRequestId?, tenantId, traceId, correlationId, evaluatedAt.
  • EntitiesMatchedRuleTrace (which rules fired, in order).
  • Value ObjectsDecisionOutcome, EvaluationContext, RiskSnapshot.
  • Invariants — immutable once recorded; decision == RequiresApprovalapprovalRequestId set; references a specific policyVersion (never "latest") for deterministic replay.
  • Domain EventsPolicyDecisionRecorded.
  • RepositoryPolicyDecisionRepository.
  • PersistencePolicyEngineService DB; append-only; indexed by traceId, subject, action.

ApprovalRequest

Purpose — A human approval gate opened because a PolicyDecision required it (or by direct request). Tracks lifecycle from open to resolved.

  • FieldsapprovalRequestId, status (Pending | Approved | Rejected | Expired | Escalated), subject, action, resource, policyDecisionId, requiredApprovers, expiresAt, escalationLevel, tenantId, traceId, createdAt.
  • EntitiesApprovalDecision (the resolving decision; see below).
  • Value ObjectsApproverSet, 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 requiredApprovers may decide; cannot decide after expiresAt unless escalated.
  • Domain EventsApprovalRequested, ApprovalGranted, ApprovalRejected.
  • RepositoryApprovalRequestRepository.
  • PersistenceApprovalService DB; open requests indexed by expiresAt for the ApprovalTimeoutWorker.

ApprovalDecision

Purpose — The granular, attributable record of an approver's grant or rejection of an ApprovalRequest.

  • FieldsapprovalDecisionId, approvalRequestId, approverId, outcome (Granted | Rejected), comment, justification, tenantId, decidedAt.
  • Entities — none.
  • Value ObjectsApprovalOutcome, Justification.
  • Invariants — immutable once recorded; belongs to exactly one request; approverId must be authorized and distinct from the request's raising subject.
  • Domain Events — surfaces as ApprovalGranted / ApprovalRejected on the parent request.
  • Repository — managed through ApprovalRequestRepository.
  • Persistence — child of ApprovalRequest in the ApprovalService DB.

AuditEntry

Purpose — A single immutable, tamper-evident record of a governance-relevant action — the atomic unit of the audit system of record.

  • FieldsauditEntryId, action, subject, resource, outcome, tenantId, traceId, correlationId, hash, previousHash, occurredAt, payloadDigest.
  • Entities — none.
  • Value ObjectsAuditAction, 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 EventsAuditEntryRecorded.
  • RepositoryAuditEntryRepository (write-once; reads via indexed projections).
  • PersistenceAuditService DB (append-only), backed by ConnectSoft.Extensions.AuditNet; exported to Blob by the AuditExportWorker.

ComplianceReport

Purpose — A point-in-time evidence bundle mapping controls to a compliance framework over a scope and period.

  • FieldscomplianceReportId, framework (e.g. SOC2, GDPR, HIPAA), scope, period, status (Generating | Generated | Failed), controlResults, evidenceLocation (Blob URI), tenantId, requestedAt, generatedAt.
  • EntitiesControlResult (per-control pass/fail with evidence refs).
  • Value ObjectsComplianceFramework, ReportPeriod, ReportScope, EvidenceReference.
  • Invariants — a Generated report is immutable; evidenceLocation is set only when Generated; period.from <= period.to; control set determined by framework version.
  • Domain EventsComplianceReportGenerated.
  • RepositoryComplianceReportRepository.
  • PersistenceComplianceReportService DB (metadata) + Blob (evidence bundle).

SecurityFinding

Purpose — A tracked security issue (vulnerability, leaked secret, misconfiguration, policy violation) from a scanner or runtime detector.

  • FieldssecurityFindingId, source, category, severity (Low | Medium | High | Critical), status (Open | Triaged | Resolved | Suppressed), resource, title, evidence, dedupKey, riskScore, tenantId, traceId, createdAt, resolvedAt?.
  • EntitiesFindingNote (triage history).
  • Value ObjectsSeverity, FindingCategory, FindingStatus, EvidenceLocation, DedupKey.
  • InvariantsdedupKey is unique per tenant (duplicate ingests update, not duplicate); Resolved/Suppressed require a note; severity transitions are recorded.
  • Domain EventsSecurityFindingRaised.
  • RepositorySecurityFindingRepository.
  • PersistenceSecurityFindingService DB; indexed by dedupKey, severity, status.

SecretReference

Purpose — A governed pointer to a secret in Azure Key Vault — metadata and rotation policy only, never the secret value.

  • FieldssecretReferenceId, vaultUri, secretName, secretVersion, owner, rotationPolicy, lastRotatedAt, nextRotationDueAt, status (Active | Pending Rotation | Compromised | Retired), tenantId, createdAt.
  • Entities — none.
  • Value ObjectsVaultReference (vaultUri + secretName + secretVersion), RotationPolicy, SecretStatus.
  • Invariants — never stores secret material; vaultUri must resolve to a tenant-authorized Key Vault; a Compromised reference forces rotation and raises a SecurityFinding; nextRotationDueAt derived from rotationPolicy.
  • Domain EventsSecurityFindingRaised (on leak/compromise detection).
  • RepositorySecretReferenceRepository.
  • PersistenceSecretGovernanceService DB (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.

  • FieldstenantIsolationRuleId, tenantId, scope (resource/data category), isolationMode (Strict | SharedRead | Delegated), residencyRegion, allowedCrossTenant, status, createdAt.
  • Entities — none.
  • Value ObjectsIsolationMode, ResidencyConstraint, CrossTenantGrant.
  • Invariants — default mode is Strict (deny cross-tenant); a Delegated grant requires an explicit CrossTenantGrant with an owning approval; residency cannot be relaxed below the tenant's edition floor.
  • Domain Events — surfaces as PolicyDecisionRecorded when consulted during evaluation.
  • RepositoryTenantIsolationRuleRepository.
  • PersistenceTenantIsolationPolicyService DB; backed by ConnectSoft.Extensions.Saas.* tenant context.

DataClassification

Purpose — A classification label assigned to data or an artifact that drives handling, redaction, and access policy.

  • FieldsdataClassificationId, subjectRef (artifact/data id), label (Public | Internal | Confidential | Restricted), categories (e.g. PII, PHI, secrets), contentHash, classifiedBy (worker/agent), tenantId, classifiedAt.
  • Entities — none.
  • Value ObjectsClassificationLabel, DataCategorySet, ContentHash.
  • Invariants — exactly one active label per (subjectRef, contentHash); label can only be raised automatically (downgrade requires approval); Restricted implies handling constraints enforced by Knowledge Platform redaction.
  • Domain EventsDataClassified.
  • RepositoryDataClassificationRepository.
  • PersistenceDataClassificationService DB; indexed by subjectRef, label, categories.

RiskScore

Purpose — A composite, recomputable risk score for an action, artifact, or tenant, feeding risk-adaptive policy gates.

  • FieldsriskScoreId, subjectType (Action | Artifact | Tenant | Agent), subjectId, score (0–100), band (Low | Medium | High | Critical), factors, version, tenantId, computedAt.
  • EntitiesRiskFactor (contributing signal with weight).
  • Value ObjectsRiskBand, RiskFactorWeight, ScoreVersion.
  • Invariantsscore in [0,100]; band derived deterministically from score thresholds; latest version wins per (subjectType, subjectId); factors must reference real signals (findings, classifications, behaviour).
  • Domain EventsRiskScored.
  • RepositoryRiskScoreRepository.
  • PersistenceRiskScoringService DB; 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