Events¶
Target Architecture — Final-State Design
This page describes the final-state event model of the Governance, Security & Compliance Platform. All messages travel in the canonical Event Envelope on Azure Service Bus via MassTransit. Events are NounVerbPastTense; commands are VerbNoun, per Naming Conventions.
Commands¶
Commands express intent and are handled by exactly one aggregate. They are not part of the public event stream.
| Command | Target Aggregate | Result Event |
|---|---|---|
DefinePolicy |
PolicyDefinition |
PolicyDefined |
EvaluatePolicy |
PolicyDecision |
PolicyDecisionRecorded |
RequestApproval |
ApprovalRequest |
ApprovalRequested |
GrantApproval |
ApprovalDecision |
ApprovalGranted |
RejectApproval |
ApprovalDecision |
ApprovalRejected |
RecordAuditEntry |
AuditEntry |
AuditEntryRecorded |
GenerateComplianceReport |
ComplianceReport |
ComplianceReportGenerated |
RaiseSecurityFinding |
SecurityFinding |
SecurityFindingRaised |
ClassifyData |
DataClassification |
DataClassified |
ScoreRisk |
RiskScore |
RiskScored |
Domain Events¶
Domain events are facts emitted by an aggregate after a state change, published within the owning context.
| Event | Emitting Service | Meaning |
|---|---|---|
PolicyDefined |
PolicyDefinitionService |
A policy definition (with rules) was created or versioned and published. |
PolicyDecisionRecorded |
PolicyEngineService / PolicyEvaluationService |
A policy was evaluated; an Allow / Deny / RequiresApproval decision was recorded. |
ApprovalRequested |
ApprovalService |
A human approval gate was opened and routed to approvers. |
ApprovalGranted |
ApprovalService |
An authorized approver granted a pending request. |
ApprovalRejected |
ApprovalService |
A request was rejected by an approver or auto-rejected on timeout. |
AuditEntryRecorded |
AuditService |
An immutable audit entry was appended (hash-chained). |
ComplianceReportGenerated |
ComplianceReportService |
A compliance report/evidence bundle finished generating. |
SecurityFindingRaised |
SecurityFindingService / SecretGovernanceService |
A security finding (incl. leaked-secret) was raised or re-opened. |
DataClassified |
DataClassificationService |
A data/artifact classification label was assigned or changed. |
RiskScored |
RiskScoringService |
A composite risk score was (re)computed for a subject. |
Integration Events¶
Domain events promoted to cross-platform contracts (versioned, in the Event Catalog). These are the events other platforms subscribe to:
| Integration Event | Primary Consumers | Why |
|---|---|---|
PolicyDecisionRecorded |
Control Plane, DevOps & GitOps, Observability & Feedback | Drives workflow gating and deployment promotion; feeds dashboards. |
ApprovalRequested / ApprovalGranted / ApprovalRejected |
Factory Studio, Control Plane | Surfaces approval queues; unblocks/blocks workflows. |
SecurityFindingRaised |
Observability & Feedback, Control Plane | Alerting, risk-adaptive gating, remediation tasks. |
DataClassified |
Knowledge Platform | Classification-driven redaction and memory-access enforcement. |
RiskScored |
Control Plane, Policy context | Risk-adaptive gates and prioritisation. |
ComplianceReportGenerated |
Factory Studio, Observability & Feedback | Evidence availability notifications. |
AuditEntryRecorded |
Observability & Feedback | Real-time governance activity stream. |
Canonical Envelope¶
Every governance event uses the platform-wide envelope. Example PolicyDecisionRecorded:
{
"eventId": "evt-4d21ab9c",
"eventType": "PolicyDecisionRecorded",
"tenantId": "connectsoft",
"projectId": "proj-booking-saas",
"moduleId": "module-reservations-api",
"traceId": "trace-9f1c2b7d",
"correlationId": "corr-3a6e1d40",
"causationId": "evt-deployrequested-7c",
"occurredAt": "2026-06-11T09:00:01Z",
"payload": {
"policyDecisionId": "dec-4d21ab",
"decision": "RequiresApproval",
"policyDefinitionId": "pol-7b3c1f9a",
"policyVersion": "3",
"action": "Promote",
"subject": { "agentId": "agent-release-01", "role": "ReleaseAgent" },
"resource": { "type": "Deployment", "artifactId": "art-api-7c", "classification": "Restricted", "environment": "prod" },
"riskScore": 82,
"approvalRequestId": "apr-91c2"
}
}
The identity fields are a strict superset of the Metadata Schema; domain-specific dimensions live in payload. Selected fields are mirrored into Service Bus application properties (cs-event-type, cs-tenant-id, cs-trace-id, cs-correlation-id, cs-schema-version) for subscription filtering.
Topics¶
Events are published to per-context Azure Service Bus topics; consumers subscribe with tenant- and type-scoped rules.
| Topic | Events | Notable Subscribers |
|---|---|---|
governance.policy |
PolicyDefined, PolicyDecisionRecorded |
Control Plane, DevOps & GitOps, Observability |
governance.approval |
ApprovalRequested, ApprovalGranted, ApprovalRejected |
Factory Studio, Control Plane, Observability |
governance.audit |
AuditEntryRecorded |
Observability, AuditExportWorker |
governance.compliance |
ComplianceReportGenerated |
Factory Studio, Observability |
governance.security |
SecurityFindingRaised |
Observability, Control Plane, RiskScoreWorker |
governance.classification |
DataClassified |
Knowledge Platform, RiskScoreWorker |
governance.risk |
RiskScored |
Policy context, Control Plane |
End-to-End Event Flow¶
flowchart LR
Define["DefinePolicy"] --> Defined["PolicyDefined"]
Evaluate["EvaluatePolicy"] --> Decision["PolicyDecisionRecorded"]
Decision -->|gate| ApprReq["ApprovalRequested"]
ApprReq --> Granted["ApprovalGranted"]
ApprReq --> Rejected["ApprovalRejected"]
Decision --> Audit["AuditEntryRecorded"]
Granted --> Audit
Rejected --> Audit
Class["DataClassified"] --> Risk["RiskScored"]
Finding["SecurityFindingRaised"] --> Risk
Risk --> Evaluate
Audit --> Report["ComplianceReportGenerated"]
Finding --> Report
Versioning & Consumer Rules¶
eventTypenames never change meaning; breaking changes append a version suffix (PolicyDecisionRecordedV2) or add fields with a bumpedcs-schema-version.- Consumers tolerate unknown
payloadfields (forward compatibility) and unknown event types (ignore-and-log). - Consumers deduplicate on
eventId, asserttenantId, and propagatetraceId/correlationId, per the Event Envelope consumer rules.
Related¶
- Workers · Microservices · Aggregate Roots · Workflows
- Reference: Event Envelope · Naming Conventions · Metadata Schema