A union type is better when the shared abstraction would only exist to satisfy the type system. If the entity classes share little more than an identifier, a forced interface can create fake commonality and spread changes across many classes. A union keeps the model aligned to reality while letting one logger handle all supported document types.
Why unions fit audit logging better than a forced interface
audit logging is usually a cross-entity workflow, but that does not mean the entities involved truly belong to one domain model. When the only stable shared property is that each object can be logged, a forced interface can blur real differences, make the codebase look more general than it is, and create brittle coupling whenever a new entity is added or an existing one changes shape. That matters because audit trails should preserve meaning, not hide it behind a convenience abstraction. For teams thinking about control quality, the relevant question is whether the model still describes the business event accurately, not whether it satisfies a compiler or framework expectation. In practice, many engineering teams discover the cost of a shared abstraction only after a supposedly small change starts rippling through unrelated classes.
For broader control context, auditability and change traceability are treated as core assurance concerns in the CIS Controls v8, which is one reason modelling choices that preserve event integrity tend to age better than abstract designs built for convenience.
How the workflow stays correct when the logger accepts a union
A union type works well when the logging component needs to accept several distinct entity types but does not need to pretend they behave identically. The logger can switch on the actual type, extract the fields that matter for the audit event, and write a record that reflects the entity’s real semantics. That keeps the shared workflow centralised while leaving each entity free to model its own lifecycle, invariants, and public API. The result is usually less accidental complexity: fewer placeholder methods, fewer default implementations that do nothing, and fewer awkward base-class decisions that exist only to support logging.
The practical benefit is not just cleanliness. It also improves change control. If a new entity joins the workflow, developers can add an explicit union member and handle it intentionally, rather than inheriting a contract that may not fit. That makes unsupported cases visible at compile time instead of being hidden behind a generic interface that appears complete but is only partially meaningful. A union also encourages the logger to depend on the minimal data it truly needs, which is often the right design for audit pipelines, export jobs, and similar cross-entity processes where the workflow is shared but the source objects remain distinct.
- Keep the logger focused on the fields required to produce a trustworthy event, not on the full behaviour of every source entity.
- Prefer explicit handling for each supported type so unsupported additions fail visibly during development.
- Use a shared interface only when the entities genuinely share behaviour that the broader domain model needs, not just the logging path.
If the logging process starts requiring many type-specific branches, enrichment rules, or entity-specific policy checks, the union is no longer the main design question and the workflow may need a dedicated event model instead.
Where the abstraction line breaks for real systems
Tighter typing often improves correctness, but it also increases the chance that a design is over-specified for the actual workflow, so teams need to balance type safety against model honesty. The main edge case is when the shared operation looks simple at first but later grows into common business behaviour, such as validation, authorisation, or lifecycle management. At that point, a true interface may become justified because the common contract is real, not synthetic. Guidance-vs-consensus is worth stating plainly here: there is no universal rule that unions are always better, only a strong preference for unions when the shared abstraction would be artificial.
Another edge case is audit logging across objects that differ in provenance or sensitivity. A logger that accepts a union should still preserve enough context to distinguish one entity class from another, because audit records that flatten important differences can weaken review, incident investigation, and compliance evidence. NIST’s security and privacy control catalogue treats audit and accountability as distinct control concerns, which is why the logging shape should follow the evidence requirement instead of forcing a prettier type hierarchy. Where the union begins to conceal material differences, the abstraction has gone too far.
For teams operating under assurance requirements, NIST Cybersecurity Framework 2.0 reinforces the broader expectation that logging support should improve visibility and governance rather than merely simplify code structure.
Risk and Threat Considerations
When a shared interface is forced onto loosely related entities, the main risk is not type aesthetics but audit integrity. Over-generalised models can hide important distinctions in event source, privilege context, or object state, which makes later review less reliable and can create gaps in accountability. In security-sensitive systems, those gaps matter because audit logging is only useful if the record still tells the truth about what happened.
Failure mechanism: A synthetic common contract encourages developers to route different entities through the same shape even when the underlying metadata differs. That can drop fields, flatten semantics, or push special cases into ad hoc conditionals, creating inconsistent records and weaker evidence for investigation or compliance review.
Impact: Reviewers may lose the ability to reconstruct who did what, on which object, and under which policy context. In regulated or high-assurance environments, that can undermine incident response, weaken non-repudiation evidence, and expose the organisation to avoidable control findings.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
CIS Controls v8 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| CIS Controls v8 | 6 — Access Control Management | Audit logging supports account and access accountability across entity workflows. |
| Recommendation — Preserve identity and event traceability in logging paths so access review remains actionable. | ||
| NIST CSF 2.0 | PR.AA-01 — Identity Management, Authentication, and Access Control | Accurate audit events depend on preserving source identity and action context. |
| DE.CM-08 — Anomalies and events are detected and logged | Union-based logging helps ensure supported events are captured consistently. | |
| GV.RM-03 — Risk management strategy is established and maintained | Designing truthful audit models is part of maintaining control and evidence quality. | |
| Recommendation — Retain entity-specific identity context in audit records so review and attribution stay reliable. Log supported entity events consistently so detection and investigation retain usable evidence. Align the logging model with evidence needs so abstraction choices do not weaken governance. | ||
Practitioner Guidance
What to prioritise: Treat the logging contract as an evidence problem first and a type-design problem second. If the logger needs only a narrow set of fields, model that explicitly and resist adding a broader interface just to reduce compiler friction.
Decision rule: Use a union when the entities remain semantically distinct and the workflow is shared only at the point of emission. Move to a shared interface only if the common behaviour becomes real business behaviour that multiple parts of the system depend on.
What to verify: Check that each union branch still preserves the audit fields required for traceability, including entity kind, source context, and any policy-relevant attributes. If those details disappear behind the abstraction, the design is too generic.
Practitioner takeaway: The best model is the one that keeps the audit record faithful to reality, even if that means accepting a less “unified” type shape.
Related resources from NHI Mgmt Group
- Why do shared mobile workflows often create identity risk in operations teams?
- How should security teams govern AI agent audit logging in MCP workflows?
- What breaks when access logging and audit reporting are missing for PHI in CRM workflows?
- Why do local security tools often get better developer adoption than container-only workflows?