Skip to content

AuditService

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Bounded context BC-19 Audit
Platform / plane Governance / Trust & Operations
Deployment granularity module of host · host GovernanceHost
Status target · ConnectSoft.Factory.Governance.Audit
Built from connectsoft-microservice · libraries: connectsoft-extensions-audit-net, connectsoft-extensions-compliance, connectsoft-extensions-saas-abstractions, connectsoft-extensions-messaging-model, connectsoft-extensions-persistence-model-nhibernate, connectsoft-extensions-data-storage-abstractions
Decisions ADR-0014, ADR-0019
Traceability FR-06 FR-08 FUX-05 FUX-06 NFR-03 NFR-04 NFR-10 XL-05 XL-13 XL-14

Purpose and responsibilities

Every autonomous action must be observable (original handoff §3.8). AuditService turns the events of every platform into evidence: append-only entries (audit-evidence-v1) with actor, scope, action, target version or hash, reason and outcome, chained by hash per tenant, mirrored to the immutable store, head-signed daily and verified on a schedule; a broken chain is a Critical finding. It also owns the classification registry (data classes with retention, redaction rules and residency) that context assembly, artifacts, ingestion and the model gateway obey (D31), and the findings that evidence raises (chain breaks, prohibited attempts, unresolved uncertain effects, overdue rotations). Tenants export their evidence with chain proofs in open formats.

It absorbs DataClassificationService, MemoryClassificationService and MemoryRedactionService; ComplianceReportService, RiskScoringService and SecurityFindingService stay later rows.

Context and boundaries

flowchart LR
    S["AuditService"]
    ContextBuilderService["ContextBuilderService"] -->|grpc| S
    ArtifactService["ArtifactService"] -->|grpc| S
    StudioBff["StudioBff"] -->|sync-http| S
    S -->|grpc| ArtifactService["ArtifactService"]
    S -->|sync-http| ext_key_vault["ext-key-vault"]
    S -. "AuditEntryRecorded" .-> E_AuditEntryRecorded(("event"))
    S -. "AuditChainVerified" .-> E_AuditChainVerified(("event"))
    S -. "ClassificationChanged" .-> E_ClassificationChanged(("event"))
    S -. "FindingRaised" .-> E_FindingRaised(("event"))
    S -. "FindingResolved" .-> E_FindingResolved(("event"))
Hold "Alt" / "Option" to enable pan & zoom

Domain model

AuditEntry — One immutable evidence record (audit-evidence-v1) — kind, actor, scope, action, target with version or hash, reason, outcome, correlation ids and the hash of the previous entry in the tenant's chain. (catalog entry)

Field Type Required Description
entryId guid yes
tenantId string yes
projectId string no
sequence long yes Monotonic per tenant.
kind enum:EvidenceKind yes
actor json yes Identity kind and id, roles, delegation, break-glass flag
action string yes
target json yes Type, id, version or hash
reason string no
outcome string yes
correlationId guid yes
causationId guid no
runId guid no
sourceEvent string yes Producing service and event name.
previousHash hash yes
entryHash hash yes
recordedAt datetime yes

Invariants:

  • Entries are append-only and hash-chained per tenant; the chain head is signed daily and verified on a schedule; a broken chain is a Critical finding.
  • Evidence never contains prompt text, payloads or secret values; it references hashes and artifact ids.
  • Retention is 7 years (D31); personal identifiers are redacted after the project's retention window while the chain stays verifiable.

Events: AuditEntryRecorded, AuditChainVerified · Tables: AuditEntries, ChainHeads · Repository: AuditEntryRepository

ClassificationLabel — The registry entry that classifies a resource type or instance (source, artifact kind, connection, profile) and binds retention, redaction and routing rules to the class. (catalog entry)

Field Type Required Description
labelId guid yes
tenantId string yes
resourceType string yes
resourceId string no Null for a type-level default.
dataClass enum:DataClass yes
retentionDays int yes
redactionRuleIds list:string yes
residency string yes Region constraint.
setBy string yes
setAt datetime yes

Invariants:

  • An instance label may only be stricter than its type default; Restricted never leaves its region and is never promoted to Shared memory.
  • Changing a label emits an event that retention sweepers, context assembly and the model gateway honour from the next operation on.

Events: ClassificationChanged · Tables: Classifications, RedactionRules · Repository: ClassificationLabelRepository

Finding — A compliance or security finding raised from evidence (chain break, policy prohibited attempts, uncertain effects unresolved, rotation overdue) with severity, owner and resolution. (catalog entry)

Field Type Required Description
findingId guid yes
tenantId string yes
severity enum:FindingSeverity yes
category string yes
evidenceEntryIds list:guid yes
owner string no
state string yes open
raisedAt datetime yes
resolvedAt datetime no

Invariants:

  • A finding references the evidence entries that justify it; resolution is itself evidence.

Events: FindingRaised, FindingResolved · Tables: Findings · Repository: FindingRepository

erDiagram
    AuditEntry {
        guid entryId PK
        string tenantId
        string projectId
        long sequence
        enum_EvidenceKind kind
        json actor
        string action
        json target
        string reason
        string outcome
        guid correlationId
        guid causationId
        guid runId
        string sourceEvent
        hash previousHash
        hash entryHash
        datetime recordedAt
    }
    ClassificationLabel {
        guid labelId PK
        string tenantId
        string resourceType
        string resourceId
        enum_DataClass dataClass
        int retentionDays
        list_string redactionRuleIds
        string residency
        string setBy
        datetime setAt
    }
    Finding {
        guid findingId PK
        string tenantId
        enum_FindingSeverity severity
        string category
        list_guid evidenceEntryIds
        string owner
        string state
        datetime raisedAt
        datetime resolvedAt
    }
    RedactionRule {
        string ruleId

        string detector

        string action

        list_string appliesTo

    }
    ClassificationLabel ||--o{ RedactionRule : contains
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

RedactionRule (entity, in ClassificationLabel) — A redaction pattern or detector bound to a data class (ConnectSoft.Extensions.Compliance).

Field Type Required Description
ruleId string yes
detector string yes regex
action string yes mask
appliesTo list:string yes prompt

Data model and storage

Store Role Engine / profile Tables
Governance store primary azure-sql / nhibernate-sqlserver AuditEntries, ChainHeads, Classifications, RedactionRules, Findings
Immutable audit store blob blob / azure-blob-immutable —
Table Owner Columns Indexes
dbo.AuditEntries AuditEntry 17 3
dbo.ChainHeads AuditEntry 5 0
dbo.Classifications ClassificationLabel 10 1
dbo.RedactionRules RedactionRule 5 0
dbo.Findings Finding 9 1

Full DDL: appendix.

Entries are written to governance-sql for query and mirrored to audit-immutable (write-once blob) for integrity; the chain head is signed with a Key Vault key. Personal identifiers are redacted after the project's retention window while the chain stays verifiable.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
GET /factory/audit SearchAudit factory.audit.read read natural GW-03 Evidence by scope, kind, actor, run and time; verifiable chain positions.
POST /factory/projects/{projectId}/audit/export ExportAudit factory.audit.export external key-header GW-03 Export a project's evidence in open formats with chain proofs (D31
GET /factory/classifications ListClassifications factory.audit.read read natural GW-03 Classification labels and redaction rules per resource type.
PUT /factory/classifications/{resourceType} SetClassification factory.audit.admin production natural GW-03 Set the data class
GET /factory/findings ListFindings factory.audit.read read natural GW-03 Open and resolved findings by severity and category.
POST /factory/findings/{findingId}/resolve ResolveFinding factory.audit.admin shared-write natural GW-03 Resolve or accept the risk of a finding with a reason (evidence).
gRPC service Method Streaming Visibility Side effects Summary
Audit Record none internal shared-write Append evidence directly (for commands that are not events).
Audit Classify none internal read Resolve the data class
Audit Redact none internal shared-write Apply redaction rules of a class to a content reference and return the redacted artifact reference.

Messages

Event Topic Scope / v Aggregate Consumers Summary
AuditEntryRecorded audit.evidence.v1.audit-entry-recorded integration / 1 AuditEntry DashboardService Evidence appended to the chain.
AuditChainVerified audit.evidence.v1.audit-chain-verified integration / 1 AuditEntry DashboardService The tenant chain was verified and its head signed.
ClassificationChanged audit.classification.v1.classification-changed integration / 1 ClassificationLabel ContextBuilderService, ArtifactService, KnowledgeIngestionService, ModelRouterService, StudioBff A label changed; retention
FindingRaised audit.findings.v1.finding-raised integration / 1 Finding AlertRuleService, StudioBff, StudioNotificationService, DashboardService A finding was raised from evidence.
FindingResolved audit.findings.v1.finding-resolved integration / 1 Finding StudioBff, DashboardService A finding was resolved or its risk accepted.

AuditEntryRecorded payload:

Field Type Required Description
entryId guid yes
tenantId string yes
sequence long yes
kind enum:EvidenceKind yes
action string yes
runId guid no

AuditChainVerified payload:

Field Type Required Description
tenantId string yes
headSequence long yes
valid bool yes

ClassificationChanged payload:

Field Type Required Description
labelId guid yes
tenantId string yes
resourceType string yes
resourceId string no
dataClass enum:DataClass yes
retentionDays int yes

FindingRaised payload:

Field Type Required Description
findingId guid yes
tenantId string yes
severity enum:FindingSeverity yes
category string yes

FindingResolved payload:

Field Type Required Description
findingId guid yes
tenantId string yes
state string yes
Command Handled by Result events Summary
Record AuditEntry AuditEntryRecorded
SetClassification ClassificationLabel ClassificationChanged
ResolveFinding Finding FindingResolved
Event Producer Handler Purpose
ApprovalRequested RunControlService RecordEvidence Approval requests as evidence.
ApprovalDecided RunControlService RecordEvidence Approval decisions as evidence.
ProjectStateChanged ProjectService RecordEvidence Project lifecycle
MembershipChanged ProjectService RecordEvidence Access changes.
DelegationChanged ProjectService RecordEvidence Delegations (D18).
AssetReleasePublished AgentRegistryService RecordEvidence Publications.
AssetReleaseRevoked AgentRegistryService RecordEvidence Revocations.
PolicyDecisionRecorded PolicyEngineService RecordEvidence Policy decisions.
ApprovalDecisionValidated ApprovalPolicyService RecordEvidence Decision validity incl. break-glass.
ToolInvoked ToolAdapterService RecordEvidence Tool effects.
ToolEffectUncertain ToolAdapterService RaiseUncertainFinding Unresolved uncertain effects become findings after the operator window.
CredentialIssued SecretBrokerService RecordEvidence Credential issuances.
SourceDeleted KnowledgeIngestionService RecordEvidence Data lifecycle.
ArtifactDeleted ArtifactService RecordEvidence Data lifecycle.
MemoryPromoted MemoryPromotionService RecordEvidence Promotions.
ConnectionStateChanged IntegrationService RecordEvidence Connection lifecycle incl. revocation.

Workers and jobs

Worker Trigger Output events Retry Idempotency key Summary
EvidenceWriter event AuditEntryRecorded exponential sourceEvent + eventId Appends consumed events as evidence entries in tenant sequence with the hash chain and mirrors them to the immutable store.
ChainVerifier schedule 0 1 * * * AuditChainVerified, FindingRaised fixed tenantId + day Re-computes and verifies each tenant's hash chain since the last signed head, signs the new head and raises a Critical finding on a break.
RetentionAndRedactionSweeper schedule 0 3 * * * — fixed entryId Redacts personal identifiers in evidence past the project retention window while keeping the chain verifiable; enforces classification retention across stores by emitting lifecycle tasks.
ExportWorker manual on ExportAudit AuditEntryRecorded exponential projectId + exportRequestId Produces an export package of a project's evidence with chain proofs in open formats.

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

None modelled

No sagas are modelled for this item yet.

Options and configuration

Section Key Type Default Reloadable Secret Summary
Governance:Audit ChainSigningKeyId string `` no yes Key Vault key for daily head signatures.
Governance:Audit UncertainFindingAfterHours int 24 yes no Unresolved uncertain tool effects become findings after this window.
Governance:Classification DefaultClass enum Internal yes no Class of resources without a label.

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.audit.entries counter {entry} tenant, kind Evidence appended.
connectsoft.factory.audit.chain_lag gauge s tenant Age of the oldest consumed event not yet appended.
connectsoft.factory.audit.chain_valid gauge 1 tenant 1 when the last verification passed.
connectsoft.factory.audit.findings_open updown {finding} tenant, severity Open findings.

Security

Authentication client-credentials
Scopes factory.audit.read (Read evidence); factory.audit.export (Export evidence (Platform admin); factory.audit.admin (Classifications and finding resolution (Platform admin).)
Roles Reviewer, Operator, WorkspaceAdmin, PlatformAdmin, Observer
Tenant isolation row-filter
Data classification restricted
Max side-effect class production
Secrets audit-chain-key (key-vault, rotate 365 d)

Dependencies

Outbound

Target Kind Purpose Failure mode Required
ArtifactService grpc Redacted artifacts and export packages. fail-fast yes
ext-key-vault sync-http Chain signing. fail-fast yes

Inbound

Target Kind Purpose Failure mode Required
ContextBuilderService grpc Classify and Redact. — yes
ArtifactService grpc Classify on store and preview. — yes
StudioBff sync-http Audit search — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Chain break detected ChainVerifier mismatch Critical finding; evidence writing continues on a new segment anchored to the last valid head; investigation from the immutable mirror integrity question on the segment 60
Evidence backlog chain_lag above threshold writer scales per tenant partition; no event is dropped (inbox) delayed evidence 60

NFR targets

Target Class value (pilot-interactive) Override
latency_p95_ms 2000 —
availability_pct 99.5 —
throughput_rps 50 —
rpo_minutes 15 —
rto_minutes 240 —
cost_class low —

Deployment

Granularity module of host · host GovernanceHost
Topologies saas-default, hybrid, on-prem, hybrid-compute
Runtime —; replicas —–—
Ports —

Current implementation

ConnectSoft.Extensions.AuditNet integrates Audit.NET for application audit trails and ConnectSoft.Extensions.Compliance standardizes classification and redaction; no evidence chain, immutable mirror, classification registry or findings exist.

Later capabilities

Compliance reports (later row); risk scoring from evidence; security findings from scanners; evidence attestations for customers' auditors.

Decisions and traceability

Family Ids
FR FR-06, FR-08
FUX FUX-05, FUX-06
NFR NFR-03, NFR-04, NFR-10
XL XL-05, XL-13, XL-14