diff --git a/.chloggen/audit-logging-semconv.yaml b/.chloggen/audit-logging-semconv.yaml
new file mode 100644
index 0000000000..a3f56e50b9
--- /dev/null
+++ b/.chloggen/audit-logging-semconv.yaml
@@ -0,0 +1,17 @@
+change_type: new_component
+
+component: audit
+
+note: Add `audit.*` semantic conventions for the OpenTelemetry Audit Logging signal (OTEP 0267).
+
+issues: [7]
+
+subtext: |
+ Introduces a dedicated `audit.*` attribute namespace for compliance-critical,
+ lossless audit logging (ISO 27001, SOC 2, PCI-DSS, HIPAA). Attribute groups
+ cover actor identity (`audit.actor.*`), action and outcome (`audit.action`,
+ `audit.outcome`), target resource (`audit.target.*`), network source
+ (`audit.source.*`), per-record cryptographic integrity (`audit.integrity.value`),
+ and resource-level signing metadata (`audit.integrity.algorithm`,
+ `audit.integrity.certificate`). An append-only hash-chain is supported via
+ `audit.sequence.number` and `audit.prev.hash`.
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yaml b/.github/ISSUE_TEMPLATE/bug_report.yaml
index 05a426e838..f0356caf7b 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yaml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yaml
@@ -26,6 +26,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
+ - area:audit
- area:aws
- area:azure
- area:browser
diff --git a/.github/ISSUE_TEMPLATE/change_proposal.yaml b/.github/ISSUE_TEMPLATE/change_proposal.yaml
index c5d1ab80da..6587d15731 100644
--- a/.github/ISSUE_TEMPLATE/change_proposal.yaml
+++ b/.github/ISSUE_TEMPLATE/change_proposal.yaml
@@ -18,6 +18,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
+ - area:audit
- area:aws
- area:azure
- area:browser
diff --git a/.github/ISSUE_TEMPLATE/new-conventions.yaml b/.github/ISSUE_TEMPLATE/new-conventions.yaml
index 1f84a59d5b..77669e30df 100644
--- a/.github/ISSUE_TEMPLATE/new-conventions.yaml
+++ b/.github/ISSUE_TEMPLATE/new-conventions.yaml
@@ -29,6 +29,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
+ - area:audit
- area:aws
- area:azure
- area:browser
diff --git a/docs/audit/audit-logs.md b/docs/audit/audit-logs.md
new file mode 100644
index 0000000000..0a43c260f4
--- /dev/null
+++ b/docs/audit/audit-logs.md
@@ -0,0 +1,419 @@
+
+
+# Semantic Conventions for Audit Logs
+
+**Status**: [Development][DocumentStatus]
+
+
+
+- [Motivation and compliance context](#motivation-and-compliance-context)
+- [Signal separation](#signal-separation)
+- [Recording an audit record](#recording-an-audit-record)
+ - [LogRecord fields](#logrecord-fields)
+ - [Event name](#event-name)
+ - [Attributes](#attributes)
+- [Mandatory attributes](#mandatory-attributes)
+- [Optional attribute groups](#optional-attribute-groups)
+ - [Actor enrichment](#actor-enrichment)
+ - [Target](#target)
+ - [Source / origin](#source--origin)
+ - [Integrity and tamper-evidence](#integrity-and-tamper-evidence)
+ - [Hash-chain ordering](#hash-chain-ordering)
+- [AuditReceipt](#auditreceipt)
+- [SDK invariants](#sdk-invariants)
+- [Compliance mapping](#compliance-mapping)
+- [Examples](#examples)
+ - [Successful login](#successful-login)
+ - [Privileged resource deletion with integrity](#privileged-resource-deletion-with-integrity)
+
+
+
+## Motivation and compliance context
+
+Compliance frameworks (ISO 27001, SOC 2, PCI-DSS, HIPAA) mandate that
+security-relevant events are captured completely, without loss, and in a
+tamper-evident form. The standard OpenTelemetry Log signal is intentionally
+designed to allow sampling, back-pressure shedding, and record transformation
+— behaviours that are incompatible with these requirements.
+
+The **Audit Logging signal** is a dedicated pipeline that provides:
+
+- Guaranteed delivery with at-least-once semantics.
+- An `AuditReceipt` returned synchronously once the sink acknowledges.
+- Cryptographic integrity via per-record HMAC or digital signature.
+- An append-only hash chain that makes retroactive tampering detectable.
+- Complete separation from the observability log pipeline.
+
+> [!IMPORTANT]
+>
+> **Do NOT** use the standard `Logger` API to emit audit records.
+> Audit records MUST be emitted through the dedicated `AuditLogger` obtained
+> from an `AuditProvider`. Routing audit records through the observability
+> pipeline risks silent loss, sampling, and transformation — any of which
+> constitutes a compliance violation.
+
+## Signal separation
+
+The audit signal uses the same `LogRecord` data structure as the standard log
+signal, but travels through a completely separate pipeline:
+
+```
+Application code
+ │
+ ▼
+AuditLogger.emit(AuditRecord) ──► returns AuditReceipt
+ │ (via AuditProvider)
+ ▼
+AuditRecordProcessor chain (additive-only; enrichment, no filtering)
+ │
+ ▼
+AuditRecordExporter ──POST /v1/audit──► Audit sink / Tier-2 Collector
+```
+
+The exporter uses the OTLP `ExportLogsServiceRequest` payload with an
+`audit: true` flag on the `ResourceLogs` message to distinguish audit traffic
+from `/v1/logs` observability traffic.
+
+## Recording an audit record
+
+### LogRecord fields
+
+The following `LogRecord` fields are used by audit records:
+
+| Field | Requirement | Notes |
+| --- | --- | --- |
+| `Timestamp` | MUST | Time the auditable action occurred (nanoseconds UTC). |
+| `ObservedTimestamp` | MUST | SDK sets this to the current wall-clock time if omitted by the caller. |
+| `EventName` | MUST | Dot-separated, lowercase name (see [Event name](#event-name)). |
+| `Body` | MAY | Free-form human-readable summary. MUST NOT duplicate mandatory attributes. |
+| `SeverityNumber` | SHOULD NOT | Not meaningful for audit records. |
+| `InstrumentationScope` | MUST NOT | Leave empty (or SDK name/version as a technical marker only). |
+
+### Event name
+
+The event name MUST follow the
+[naming conventions](/docs/general/naming.md) and use the prefix `audit.`
+followed by a dot-separated, lowercase description of the auditable action.
+
+Examples: `audit.user.login`, `audit.config.change`, `audit.resource.delete`,
+`audit.permission.grant`.
+
+### Attributes
+
+All audit-specific data is carried as `LogRecord` attributes in the `audit.*`
+namespace.
+
+
+
+
+
+
+**Attributes:**
+
+| Key | Stability | [Requirement Level](https://opentelemetry.io/docs/specs/semconv/general/attribute-requirement-level/) | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- | --- |
+| [`audit.action`](/docs/registry/attributes/audit.md) |  | `Required` | string | The auditable operation that was performed. [1] | `LOGIN`; `DELETE`; `GRANT`; `CONFIG_CHANGE` |
+| [`audit.actor.id`](/docs/registry/attributes/audit.md) |  | `Required` | string | The stable identifier of the actor that performed the action. [2] | `u8472`; `svc-deployer`; `arn:aws:iam::123456789012:role/DeployRole` |
+| [`audit.actor.type`](/docs/registry/attributes/audit.md) |  | `Required` | string | The category of principal that performed the action. | `user`; `service`; `system` |
+| [`audit.outcome`](/docs/registry/attributes/audit.md) |  | `Required` | string | The result of the auditable action. | `success`; `failure`; `unknown` |
+| [`audit.record.id`](/docs/registry/attributes/audit.md) |  | `Required` | string | A stable, globally unique identifier for this audit record. [3] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
+| [`audit.integrity.algorithm`](/docs/registry/attributes/audit.md) |  | `Conditionally Required` [4] | string | The algorithm used to compute `audit.integrity.value`. [5] | `ES256`; `EdDSA`; `HMAC-SHA256` |
+| [`audit.integrity.canonicalization`](/docs/registry/attributes/audit.md) |  | `Conditionally Required` [6] | string | The canonicalization scheme applied to the record before signing or MACing. [7] | `jcs` |
+| [`audit.integrity.certificate`](/docs/registry/attributes/audit.md) |  | `Conditionally Required` [8] | string | A reference to the key or certificate used for `audit.integrity.value`. [9] | `key-2024-01`; `SHA256:ab12cd34...` |
+| [`audit.sequence.end`](/docs/registry/attributes/audit.md) |  | `Conditionally Required` [10] | boolean | Set to `true` on the last record of a gracefully closed audit stream. [11] | `true` |
+| [`audit.integrity.signer`](/docs/registry/attributes/audit.md) |  | `Recommended` When `audit.integrity.value` is present. | string | Identifies which tier produced the integrity proof in `audit.integrity.value`. [12] | `producer`; `collector` |
+| [`audit.sequence.number`](/docs/registry/attributes/audit.md) |  | `Recommended` [13] | int | A monotonically increasing counter assigned to each record within a single audit stream. [14] | `1`; `42`; `1000001` |
+| [`audit.sequence.previous_hash`](/docs/registry/attributes/audit.md) |  | `Recommended` [15] | string | SHA-256 hex digest of the `IntegrityHash` field of the immediately preceding record in the same audit stream. [16] | `a3f1c2e4b5d6a7f8e9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2` |
+| [`audit.sequence.previous_record_id`](/docs/registry/attributes/audit.md) |  | `Recommended` [17] | string | The `audit.record.id` of the immediately preceding record in the same audit stream. [18] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
+| [`audit.sequence.stream_id`](/docs/registry/attributes/audit.md) |  | `Recommended` [19] | string | An opaque identifier that scopes the hash chain to a single audit stream. [20] | `7c9e6679-7425-40de-944b-e07fc1f90ae7` |
+| [`audit.source.id`](/docs/registry/attributes/audit.md) |  | `Recommended` [21] | string | A stable identifier for the source system or network endpoint that originated the action. [22] | `192.0.2.42`; `device-uuid-abcd1234` |
+| [`audit.source.type`](/docs/registry/attributes/audit.md) |  | `Recommended` When `audit.source.id` is present. | string | The category of origin that initiated the action. [23] | `IPv4`; `IPv6`; `hostname` |
+| [`audit.target.id`](/docs/registry/attributes/audit.md) |  | `Recommended` [24] | string | The stable identifier of the resource that was the target of the action. [25] | `document-42`; `arn:aws:s3:::my-bucket/key`; `/api/v1/users/9f81` |
+| [`audit.target.type`](/docs/registry/attributes/audit.md) |  | `Recommended` [26] | string | The type or resource kind of the target. [27] | `User`; `apps/v1/Deployment`; `finance.invoice` |
+| [`audit.actor.name`](/docs/registry/attributes/audit.md) |  | `Opt-In` | string | A human-readable display name or username of the actor. [28] | `alice`; `alice@example.com`; `Alice Smith` |
+| [`audit.integrity.value`](/docs/registry/attributes/audit.md) |  | `Opt-In` | string | base64-encoded cryptographic signature or MAC covering this record. [29] | `SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c` |
+| [`audit.schema.version`](/docs/registry/attributes/audit.md) |  | `Opt-In` | string | The version of the audit semantic conventions schema used by this record. [30] | `1.0.0`; `1.2.0` |
+| [`audit.target.name`](/docs/registry/attributes/audit.md) |  | `Opt-In` | string | A human-readable name or label of the target resource. [31] | `production-deploy`; `Q1-invoice-7734` |
+
+**[1] `audit.action`:** SHOULD be an uppercase verb from a controlled vocabulary where possible. Well-known values include `LOGIN`, `LOGOUT`, `READ`, `CREATE`, `UPDATE`, `DELETE`, `GRANT`, `REVOKE`, `EXPORT`, `IMPORT`, `EXECUTE`, `APPROVE`, `REJECT`. Custom values MAY be used when none of the well-known values applies, but SHOULD be documented in the producing service's changelog.
+
+**[2] `audit.actor.id`:** This SHOULD be an opaque, durable identifier (e.g. a user-UUID, service account name, or IAM principal ARN) that remains stable across sessions. Avoid using mutable display names or email addresses as the primary ID.
+
+**[3] `audit.record.id`:** The SDK MUST auto-generate a UUID v4 when the caller omits this field. The value MUST remain identical across all retries of the same record. Records with the same `audit.record.id` and identical payload hash are treated as idempotent duplicates by compliant sinks.
+
+**[4] `audit.integrity.algorithm`:** Required (as a Resource attribute) when `audit.integrity.value` is present on any record emitted from this resource.
+
+**[5] `audit.integrity.algorithm`:** MUST be set as a Resource attribute whenever `audit.integrity.value` is present on any record emitted by this resource. Use a JWA identifier (RFC 7518) for asymmetric signatures (e.g. `ES256`, `RS256`, `EdDSA`) or an IANA MAC Algorithm identifier for symmetric MACs (e.g. `HMAC-SHA256`).
+
+**[6] `audit.integrity.canonicalization`:** Required when a canonicalization scheme other than `jcs` (RFC 8785) is used. Omit when `jcs` is used.
+
+**[7] `audit.integrity.canonicalization`:** Defaults to `jcs` (RFC 8785 JSON Canonicalization Scheme). Set explicitly when any other canonicalization is used so that verifiers can reproduce the exact byte sequence that was signed. MUST be omitted when `jcs` is used.
+
+**[8] `audit.integrity.certificate`:** Required (as a Resource attribute, together with `audit.integrity.algorithm`) when `audit.integrity.value` is present on any record emitted from this resource.
+
+**[9] `audit.integrity.certificate`:** MUST be set as a Resource attribute (together with `audit.integrity.algorithm`) whenever `audit.integrity.value` is present on any record emitted by this resource. Because a service instance uses a single signing key for its entire lifetime, both `audit.integrity.algorithm` and `audit.integrity.certificate` are constant across all records from the same resource and therefore belong on the Resource, not on individual records.
+Acceptable forms (in order of preference): a Key ID / `kid` (JOSE header parameter), a DER-encoded X.509 certificate base64-encoded, an X.509 certificate fingerprint (SHA-256 hex), or an Issuer + Serial Number pair. Receivers MUST NOT use this field alone for trust decisions; key validation MUST be performed out-of-band.
+
+**[10] `audit.sequence.end`:** Required on the final record of a gracefully closed stream (emitted during `ForceFlush` or `Shutdown`). Omit on all other records.
+
+**[11] `audit.sequence.end`:** Emitted by the SDK during `ForceFlush` or `Shutdown` to mark the terminal record of a stream. Absence is normal for all intermediate records — do not treat absence as an error.
+
+**[12] `audit.integrity.signer`:** `producer` means the SDK computed the value before export. `collector` means a Tier-2 Collector signed or re-signed the record after receiving it. When absent, `producer` SHOULD be assumed.
+
+**[13] `audit.sequence.number`:** When the emitting service maintains a monotonic per-stream counter. Required when `audit.sequence.previous_hash` is present.
+
+**[14] `audit.sequence.number`:** Compliant sinks and Tier-2 Collectors MUST verify that consecutive records within the same stream have strictly increasing sequence numbers. Gaps MUST trigger a gap-detection warning and a security event log entry. The counter SHOULD start at 1 and increment by 1 per emitted record, but implementations MAY use a larger step if records can be emitted concurrently from multiple threads.
+
+**[15] `audit.sequence.previous_hash`:** When the emitting service implements a hash chain for tamper detection. Requires `audit.sequence.number` to be present. MUST be omitted on the genesis record of a stream.
+
+**[16] `audit.sequence.previous_hash`:** Including the previous record's sink-acknowledged hash in the current record creates an append-only hash chain. Any retroactive modification of a record is detectable by re-verifying the chain. MUST be omitted on the genesis (first) record of a stream — absence is the normative signal; no magic sentinel constant is required.
+
+**[17] `audit.sequence.previous_record_id`:** When `audit.sequence.previous_hash` is present. Provides a resolvable locator for the predecessor record across storage boundaries. MUST be omitted on the genesis record of a stream.
+
+**[18] `audit.sequence.previous_record_id`:** Provides a resolvable locator for the predecessor across shards, storage systems, and retention boundaries, complementing `audit.sequence.previous_hash`. MUST be omitted on the genesis (first) record of a stream.
+
+**[19] `audit.sequence.stream_id`:** When the emitting service uses hash-chain ordering. Scopes the chain to a single `AuditLogger` instance.
+
+**[20] `audit.sequence.stream_id`:** The SDK SHOULD generate a UUID v4 once per `AuditLogger` instance and include it on every record emitted by that logger.
+
+**[21] `audit.source.id`:** When the network origin or calling device of the action is known and meaningful for compliance review (e.g. PCI-DSS access logging).
+
+**[22] `audit.source.id`:** MAY be an IP address, a device UUID, or a service mesh endpoint ID. Prefer stable identifiers (device UUID) over ephemeral ones (IP address) when both are available.
+
+**[23] `audit.source.type`:** Well-known values: `ipv4`, `ipv6`, `hostname`. Custom values MAY be used.
+
+**[24] `audit.target.id`:** When the action is performed on a specific, identifiable resource.
+
+**[25] `audit.target.id`:** SHOULD be the primary key, ARN, URI, or equivalent durable identifier of the resource. When acting on a collection rather than a single resource, this MAY contain the collection identifier.
+
+**[26] `audit.target.type`:** When `audit.target.id` is present and the resource kind adds meaningful context for audit review.
+
+**[27] `audit.target.type`:** SHOULD use a fully-qualified type where available (e.g. a Kubernetes GroupVersionResource or an IAM resource type). For domain-specific types a short qualified name MAY be used (e.g. `finance.invoice`).
+
+**[28] `audit.actor.name`:** MAY be a login name, email address, or display name. This value is informational only; use `audit.actor.id` for stable identity correlation.
+
+**[29] `audit.integrity.value`:** The input to the signing / MAC operation MUST be the canonical serialization of the `AuditRecord` with all `audit.integrity.*` attributes excluded. The default canonicalization is JCS (RFC 8785); set `audit.integrity.canonicalization` when a different scheme is used. `audit.integrity.algorithm` MUST be set on the emitting Resource whenever this attribute is present.
+
+**[30] `audit.schema.version`:** Follows semantic versioning (MAJOR.MINOR.PATCH). Receivers MAY use this value to select the matching validation schema for the record's attribute vocabulary.
+
+**[31] `audit.target.name`:** Informational only. Use `audit.target.id` for stable identity correlation.
+
+---
+
+`audit.actor.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `service` | An automated service or daemon acting on its own behalf. |  |
+| `system` | An internal system component (scheduler, GC, background job) that is not externally authenticated. |  |
+| `user` | A human user authenticated to the system. |  |
+
+---
+
+`audit.outcome` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `failure` | The action was attempted but did not complete successfully (e.g. authorization denied, validation error, resource not found). |  |
+| `success` | The action completed successfully and produced its intended effect. |  |
+| `unknown` | The outcome could not be determined at the time the event was emitted, for example because the operation is async. |  |
+
+
+
+
+
+---
+
+`audit.actor.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `service` | An automated service or daemon acting on its own behalf. |  |
+| `system` | An internal system component that is not externally authenticated. |  |
+| `user` | A human user authenticated to the system. |  |
+
+---
+
+`audit.outcome` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `failure` | The action was attempted but did not complete successfully. |  |
+| `success` | The action completed successfully and produced its intended effect. |  |
+| `unknown` | The outcome could not be determined at emit time (e.g. async operation). |  |
+
+## Mandatory attributes
+
+The five mandatory attributes MUST be present on every audit record.
+Missing any of them is a hard error; the SDK MUST NOT silently drop the record.
+
+| Attribute | Auto-generated? |
+| --- | --- |
+| `audit.record.id` | Yes — SDK generates UUID v4 if absent. |
+| `audit.actor.id` | No — caller MUST provide. |
+| `audit.actor.type` | No — caller MUST provide. |
+| `audit.action` | No — caller MUST provide. |
+| `audit.outcome` | No — caller MUST provide. |
+
+## Optional attribute groups
+
+### Actor enrichment
+
+`audit.actor.name` provides a human-readable label for the actor, useful for
+display in audit review UIs. It MUST NOT be used as the primary identifier;
+use `audit.actor.id` for stable correlation.
+
+### Target
+
+`audit.target.id` and `audit.target.type` describe the resource acted upon.
+Include them whenever the action has a specific, identifiable resource object.
+For bulk operations, `audit.target.id` MAY hold a collection identifier.
+
+### Source / origin
+
+`audit.source.id` and `audit.source.type` record the network endpoint or
+device from which the action originated. PCI-DSS Requirement 10 mandates
+capturing the originating IP for all access to cardholder data environments;
+use these attributes to satisfy that requirement.
+
+### Integrity and tamper-evidence
+
+The integrity triplet (`audit.integrity.value`, `audit.integrity.algorithm`,
+`audit.integrity.certificate`) enables the audit sink to verify that a record
+was not altered in transit.
+
+- `audit.integrity.algorithm` and `audit.integrity.certificate` are both
+ **Resource attributes**. A service instance uses a single signing key for
+ its entire lifetime, so both values are constant across all records emitted
+ by the same resource. They MUST NOT be placed on individual records.
+- `audit.integrity.value` is the per-record base64-encoded signature/MAC
+ over the canonical serialization of the record (with `audit.integrity.value`
+ itself absent from the input).
+- On acknowledgement, the sink returns an `AuditReceipt` containing an
+ `IntegrityHash` (SHA-256 of the persisted record). The emitter SHOULD
+ compute the same hash locally and compare; a mismatch MUST be treated as
+ a hard error.
+
+Compliant implementations SHOULD use asymmetric signing (`ES256` or `EdDSA`)
+to allow the sink to verify without possessing the signing key.
+
+### Hash-chain ordering
+
+`audit.sequence.number` and `audit.sequence.previous_hash` together form an append-only
+hash chain:
+
+```
+Record N: sequence.number=N, sequence.previous_hash=IntegrityHash(Record N-1)
+Record N+1: sequence.number=N+1, sequence.previous_hash=IntegrityHash(Record N)
+```
+
+Any retroactive modification of Record N causes the `audit.sequence.previous_hash` of Record N+1
+to become invalid, making the tampering detectable without re-signing.
+The genesis (first) record of a stream MUST omit `audit.sequence.previous_hash` — absence is the normative signal.
+
+## AuditReceipt
+
+`emit()` blocks until the audit sink acknowledges the record, then returns
+an `AuditReceipt`:
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `RecordId` | string | Echoes the caller's `audit.record.id`. |
+| `IntegrityHash` | string | SHA-256 hex digest of the record as persisted by the sink. |
+| `SinkTimestamp` | uint64 | Nanoseconds since UNIX epoch when the sink wrote the record. |
+
+The emitter SHOULD compute `SHA-256(canonical_record)` locally and compare to
+`IntegrityHash`. A mismatch means the record was altered after transmission
+and MUST be treated as a hard error.
+
+`emit()` MUST raise a hard error if the sink does not respond within the
+configured timeout. It MUST NOT return successfully without a valid receipt.
+
+## SDK invariants
+
+The following invariants MUST be respected by every SDK implementation:
+
+| # | Invariant |
+|----|------------------------------------------------------------------------------------------------------------------------------------------------|
+| 1 | `AuditProvider` MUST NOT accept sampler or sampling-rate configuration. |
+| 2 | `emit()` MUST block until the sink acknowledges, or raise a hard error. |
+| 3 | `emit()` MUST return a valid `AuditReceipt`. |
+| 4 | The queue MUST be disk-backed or unbounded in-memory — **never** silently drops. |
+| 5 | Processors are additive-only: MAY enrich; MUST NOT delete, filter, or transform. |
+| 6 | Transport: `POST /v1/audit` with `audit: true` on `ResourceLogs`. |
+| 7 | `partial_success` in a sink response MUST be treated as a hard `Failure`. |
+| 8 | `InstrumentationScope` MUST be left empty. |
+| 9 | SDK exposes metrics: `audit.records.emitted`, `audit.records.exported`, `audit.records.dropped`, `audit.queue.depth`, `audit.export.duration`. |
+| 10 | Non-zero `audit.records.dropped` MUST trigger an operational alert. |
+| 11 | `emit()` called on a mandatory attribute missing or empty MUST raise a hard error — MUST NOT silently drop the record. |
+| 12 | `emit()` called after `Shutdown` MUST raise a hard error — MUST NOT silently drop the record. |
+
+## Compliance mapping
+
+| Requirement | Audit signal feature |
+|-------------------------------------|---------------------------------------------------------------------------|
+| ISO 27001 A.8.15 — Logging | All actions recorded; logs protected via integrity attributes. |
+| ISO 27001 A.8.17 — Clock sync | SDK warns when `\|Timestamp − ObservedTimestamp\|` > 5 s. |
+| SOC 2 CC7.2 — Anomaly detection | `audit.records.dropped` metric + operational alert. |
+| PCI-DSS Req. 10.2 — Audit trails | Mandatory attributes cover all required fields; `audit.source.id` for IP. |
+| PCI-DSS Req. 10.5 — Log protection | `audit.integrity.value` + `audit.sequence.previous_hash` hash chain. |
+| HIPAA § 164.312(b) — Audit controls | `audit.actor.*` + `audit.target.*` cover ePHI access logging. |
+
+## Examples
+
+### Successful login
+
+```json
+{
+ "Timestamp": "2026-06-03T10:00:00.000000000Z",
+ "ObservedTimestamp": "2026-06-03T10:00:00.000100000Z",
+ "EventName": "audit.user.login",
+ "Attributes": {
+ "audit.record.id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
+ "audit.actor.id": "u8472",
+ "audit.actor.type": "user",
+ "audit.actor.name": "alice",
+ "audit.action": "LOGIN",
+ "audit.outcome": "success",
+ "audit.source.id": "192.0.2.42",
+ "audit.source.type": "ipv4"
+ }
+}
+```
+
+### Privileged resource deletion with integrity
+
+```json
+{
+ "Timestamp": "2026-06-03T10:05:00.000000000Z",
+ "ObservedTimestamp": "2026-06-03T10:05:00.000050000Z",
+ "EventName": "audit.resource.delete",
+ "Resource": {
+ "service.name": "billing-service",
+ "service.version": "3.1.0",
+ "audit.integrity.algorithm": "ES256",
+ "audit.integrity.certificate": "key-2024-01"
+ },
+ "Attributes": {
+ "audit.record.id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
+ "audit.actor.id": "svc-deployer",
+ "audit.actor.type": "service",
+ "audit.action": "DELETE",
+ "audit.outcome": "success",
+ "audit.target.id": "invoice-8819",
+ "audit.target.type": "finance.invoice",
+ "audit.source.id": "192.0.2.99",
+ "audit.source.type": "ipv4",
+ "audit.sequence.stream_id": "b1d2e3f4-a5b6-7c8d-9e0f-a1b2c3d4e5f6",
+ "audit.sequence.number": 42,
+ "audit.sequence.previous_hash": "a3f1c2e4b5d6a7f8e9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2",
+ "audit.integrity.value": "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV+adQssw5c",
+ "audit.integrity.signer": "producer",
+ "audit.schema.version": "1.0.0"
+ }
+}
+```
+
+[DocumentStatus]: https://opentelemetry.io/docs/specs/otel/document-status/
diff --git a/docs/registry/attributes/README.md b/docs/registry/attributes/README.md
index 64c71e2869..80c0928acd 100644
--- a/docs/registry/attributes/README.md
+++ b/docs/registry/attributes/README.md
@@ -35,6 +35,7 @@ Currently, the following namespaces exist:
- [App](app.md)
- [Artifact](artifact.md)
- [Aspnetcore](aspnetcore.md)
+- [Audit](audit.md)
- [AWS](aws.md)
- [Azure](azure.md)
- [Browser](browser.md)
diff --git a/docs/registry/attributes/audit.md b/docs/registry/attributes/audit.md
new file mode 100644
index 0000000000..0faa6237d0
--- /dev/null
+++ b/docs/registry/attributes/audit.md
@@ -0,0 +1,158 @@
+
+
+
+# Audit
+
+- [Audit Action Attributes](#audit-action-attributes)
+- [Audit Actor Attributes](#audit-actor-attributes)
+- [Audit Integrity Attributes](#audit-integrity-attributes)
+- [Audit Record Attributes](#audit-record-attributes)
+- [Audit Sequence Attributes](#audit-sequence-attributes)
+- [Audit Source Attributes](#audit-source-attributes)
+- [Audit Target Attributes](#audit-target-attributes)
+
+## Audit Action Attributes
+
+Attributes that describe the operation performed by the actor.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.action` |  | string | The auditable operation that was performed. [1] | `LOGIN`; `DELETE`; `GRANT`; `CONFIG_CHANGE` |
+| `audit.outcome` |  | string | The result of the auditable action. | `success`; `failure`; `unknown` |
+
+**[1] `audit.action`:** SHOULD be an uppercase verb from a controlled vocabulary where possible. Well-known values include `LOGIN`, `LOGOUT`, `READ`, `CREATE`, `UPDATE`, `DELETE`, `GRANT`, `REVOKE`, `EXPORT`, `IMPORT`, `EXECUTE`, `APPROVE`, `REJECT`. Custom values MAY be used when none of the well-known values applies, but SHOULD be documented in the producing service's changelog.
+
+---
+
+`audit.outcome` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `failure` | The action was attempted but did not complete successfully (e.g. authorization denied, validation error, resource not found). |  |
+| `success` | The action completed successfully and produced its intended effect. |  |
+| `unknown` | The outcome could not be determined at the time the event was emitted, for example because the operation is async. |  |
+
+## Audit Actor Attributes
+
+Attributes that identify the principal (human user, service, or automated system component) that initiated the auditable action.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.actor.id` |  | string | The stable identifier of the actor that performed the action. [2] | `u8472`; `svc-deployer`; `arn:aws:iam::123456789012:role/DeployRole` |
+| `audit.actor.name` |  | string | A human-readable display name or username of the actor. [3] | `alice`; `alice@example.com`; `Alice Smith` |
+| `audit.actor.type` |  | string | The category of principal that performed the action. | `user`; `service`; `system` |
+
+**[2] `audit.actor.id`:** This SHOULD be an opaque, durable identifier (e.g. a user-UUID, service account name, or IAM principal ARN) that remains stable across sessions. Avoid using mutable display names or email addresses as the primary ID.
+
+**[3] `audit.actor.name`:** MAY be a login name, email address, or display name. This value is informational only; use `audit.actor.id` for stable identity correlation.
+
+---
+
+`audit.actor.type` has the following list of well-known values. If one of them applies, then the respective value MUST be used; otherwise, a custom value MAY be used.
+
+| Value | Description | Stability |
+| --- | --- | --- |
+| `service` | An automated service or daemon acting on its own behalf. |  |
+| `system` | An internal system component (scheduler, GC, background job) that is not externally authenticated. |  |
+| `user` | A human user authenticated to the system. |  |
+
+## Audit Integrity Attributes
+
+Attributes that provide cryptographic evidence that the audit record has not been tampered with since it was emitted.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.integrity.algorithm` |  | string | The algorithm used to compute `audit.integrity.value`. [4] | `ES256`; `EdDSA`; `HMAC-SHA256` |
+| `audit.integrity.canonicalization` |  | string | The canonicalization scheme applied to the record before signing or MACing. [5] | `jcs` |
+| `audit.integrity.certificate` |  | string | A reference to the key or certificate used for `audit.integrity.value`. [6] | `key-2024-01`; `SHA256:ab12cd34...` |
+| `audit.integrity.signer` |  | string | Identifies which tier produced the integrity proof in `audit.integrity.value`. [7] | `producer`; `collector` |
+| `audit.integrity.value` |  | string | base64-encoded cryptographic signature or MAC covering this record. [8] | `SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c` |
+
+**[4] `audit.integrity.algorithm`:** MUST be set as a Resource attribute whenever `audit.integrity.value` is present on any record emitted by this resource. Use a JWA identifier (RFC 7518) for asymmetric signatures (e.g. `ES256`, `RS256`, `EdDSA`) or an IANA MAC Algorithm identifier for symmetric MACs (e.g. `HMAC-SHA256`).
+
+**[5] `audit.integrity.canonicalization`:** Defaults to `jcs` (RFC 8785 JSON Canonicalization Scheme). Set explicitly when any other canonicalization is used so that verifiers can reproduce the exact byte sequence that was signed. MUST be omitted when `jcs` is used.
+
+**[6] `audit.integrity.certificate`:** MUST be set as a Resource attribute (together with `audit.integrity.algorithm`) whenever `audit.integrity.value` is present on any record emitted by this resource. Because a service instance uses a single signing key for its entire lifetime, both `audit.integrity.algorithm` and `audit.integrity.certificate` are constant across all records from the same resource and therefore belong on the Resource, not on individual records.
+Acceptable forms (in order of preference): a Key ID / `kid` (JOSE header parameter), a DER-encoded X.509 certificate base64-encoded, an X.509 certificate fingerprint (SHA-256 hex), or an Issuer + Serial Number pair. Receivers MUST NOT use this field alone for trust decisions; key validation MUST be performed out-of-band.
+
+**[7] `audit.integrity.signer`:** `producer` means the SDK computed the value before export. `collector` means a Tier-2 Collector signed or re-signed the record after receiving it. When absent, `producer` SHOULD be assumed.
+
+**[8] `audit.integrity.value`:** The input to the signing / MAC operation MUST be the canonical serialization of the `AuditRecord` with all `audit.integrity.*` attributes excluded. The default canonicalization is JCS (RFC 8785); set `audit.integrity.canonicalization` when a different scheme is used. `audit.integrity.algorithm` MUST be set on the emitting Resource whenever this attribute is present.
+
+## Audit Record Attributes
+
+Attributes that uniquely identify and version an audit record.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.record.id` |  | string | A stable, globally unique identifier for this audit record. [9] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
+| `audit.schema.version` |  | string | The version of the audit semantic conventions schema used by this record. [10] | `1.0.0`; `1.2.0` |
+
+**[9] `audit.record.id`:** The SDK MUST auto-generate a UUID v4 when the caller omits this field. The value MUST remain identical across all retries of the same record. Records with the same `audit.record.id` and identical payload hash are treated as idempotent duplicates by compliant sinks.
+
+**[10] `audit.schema.version`:** Follows semantic versioning (MAJOR.MINOR.PATCH). Receivers MAY use this value to select the matching validation schema for the record's attribute vocabulary.
+
+## Audit Sequence Attributes
+
+Attributes that link audit records into an ordered, tamper-evident chain within a single stream.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.sequence.end` |  | boolean | Set to `true` on the last record of a gracefully closed audit stream. [11] | `true` |
+| `audit.sequence.number` |  | int | A monotonically increasing counter assigned to each record within a single audit stream. [12] | `1`; `42`; `1000001` |
+| `audit.sequence.previous_hash` |  | string | SHA-256 hex digest of the `IntegrityHash` field of the immediately preceding record in the same audit stream. [13] | `a3f1c2e4b5d6a7f8e9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2` |
+| `audit.sequence.previous_record_id` |  | string | The `audit.record.id` of the immediately preceding record in the same audit stream. [14] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
+| `audit.sequence.stream_id` |  | string | An opaque identifier that scopes the hash chain to a single audit stream. [15] | `7c9e6679-7425-40de-944b-e07fc1f90ae7` |
+
+**[11] `audit.sequence.end`:** Emitted by the SDK during `ForceFlush` or `Shutdown` to mark the terminal record of a stream. Absence is normal for all intermediate records — do not treat absence as an error.
+
+**[12] `audit.sequence.number`:** Compliant sinks and Tier-2 Collectors MUST verify that consecutive records within the same stream have strictly increasing sequence numbers. Gaps MUST trigger a gap-detection warning and a security event log entry. The counter SHOULD start at 1 and increment by 1 per emitted record, but implementations MAY use a larger step if records can be emitted concurrently from multiple threads.
+
+**[13] `audit.sequence.previous_hash`:** Including the previous record's sink-acknowledged hash in the current record creates an append-only hash chain. Any retroactive modification of a record is detectable by re-verifying the chain. MUST be omitted on the genesis (first) record of a stream — absence is the normative signal; no magic sentinel constant is required.
+
+**[14] `audit.sequence.previous_record_id`:** Provides a resolvable locator for the predecessor across shards, storage systems, and retention boundaries, complementing `audit.sequence.previous_hash`. MUST be omitted on the genesis (first) record of a stream.
+
+**[15] `audit.sequence.stream_id`:** The SDK SHOULD generate a UUID v4 once per `AuditLogger` instance and include it on every record emitted by that logger.
+
+## Audit Source Attributes
+
+Attributes that describe the network origin or calling context of the action.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.source.id` |  | string | A stable identifier for the source system or network endpoint that originated the action. [16] | `192.0.2.42`; `device-uuid-abcd1234` |
+| `audit.source.type` |  | string | The category of origin that initiated the action. [17] | `IPv4`; `IPv6`; `hostname` |
+
+**[16] `audit.source.id`:** MAY be an IP address, a device UUID, or a service mesh endpoint ID. Prefer stable identifiers (device UUID) over ephemeral ones (IP address) when both are available.
+
+**[17] `audit.source.type`:** Well-known values: `ipv4`, `ipv6`, `hostname`. Custom values MAY be used.
+
+## Audit Target Attributes
+
+Attributes that describe the resource or object that was acted upon.
+
+**Attributes:**
+
+| Key | Stability | Value Type | Description | Example Values |
+| --- | --- | --- | --- | --- |
+| `audit.target.id` |  | string | The stable identifier of the resource that was the target of the action. [18] | `document-42`; `arn:aws:s3:::my-bucket/key`; `/api/v1/users/9f81` |
+| `audit.target.name` |  | string | A human-readable name or label of the target resource. [19] | `production-deploy`; `Q1-invoice-7734` |
+| `audit.target.type` |  | string | The type or resource kind of the target. [20] | `User`; `apps/v1/Deployment`; `finance.invoice` |
+
+**[18] `audit.target.id`:** SHOULD be the primary key, ARN, URI, or equivalent durable identifier of the resource. When acting on a collection rather than a single resource, this MAY contain the collection identifier.
+
+**[19] `audit.target.name`:** Informational only. Use `audit.target.id` for stable identity correlation.
+
+**[20] `audit.target.type`:** SHOULD use a fully-qualified type where available (e.g. a Kubernetes GroupVersionResource or an IAM resource type). For domain-specific types a short qualified name MAY be used (e.g. `finance.invoice`).
diff --git a/model/audit/logs.yaml b/model/audit/logs.yaml
new file mode 100644
index 0000000000..625505c4dd
--- /dev/null
+++ b/model/audit/logs.yaml
@@ -0,0 +1,126 @@
+groups:
+ # ---------------------------------------------------------------------------
+ # Base audit record attribute group — shared mandatory + optional attributes
+ # referenced by all audit event definitions.
+ # ---------------------------------------------------------------------------
+ - id: audit.record
+ type: attribute_group
+ brief: >
+ Attributes for an audit record emitted through the OTel Audit Logging
+ signal. An AuditRecord IS a LogRecord; all audit-specific data is carried
+ as attributes in the `audit.*` namespace.
+ note: >
+ The five mandatory attributes (`audit.record.id`, `audit.actor.id`,
+ `audit.actor.type`, `audit.action`, `audit.outcome`) MUST be present on
+ every audit record. The SDK MUST auto-generate `audit.record.id` if the
+ caller omits it. Absence of any other mandatory attribute is a hard error;
+ the SDK MUST NOT silently drop the record.
+
+ The LogRecord fields used by audit records are:
+
+ * `Timestamp` (MUST) — time the auditable action occurred.
+ * `ObservedTimestamp` (MUST) — set by SDK if omitted.
+ * `EventName` (MUST) — e.g. `audit.user.login`, `audit.config.change`.
+ * `Body` (MAY) — free-form human-readable description; MUST NOT duplicate
+ mandatory attributes.
+ * `SeverityNumber` (SHOULD NOT) — audit records are compliance evidence, not
+ operational diagnostics. Severity implies triage priority, which has no
+ meaning for records that MUST all be delivered regardless of their outcome.
+ Receivers MUST NOT use `SeverityNumber` to filter or prioritize audit records.
+ Use `audit.outcome` to distinguish success from failure.
+ * `InstrumentationScope` (MUST be left empty).
+ attributes:
+ # --- mandatory ---
+ - ref: audit.record.id
+ requirement_level: required
+ - ref: audit.actor.id
+ requirement_level: required
+ - ref: audit.actor.type
+ requirement_level: required
+ - ref: audit.action
+ requirement_level: required
+ - ref: audit.outcome
+ requirement_level: required
+
+ # --- actor (optional enrichment) ---
+ - ref: audit.actor.name
+ requirement_level: opt_in
+
+ # --- target ---
+ - ref: audit.target.id
+ requirement_level:
+ recommended: >
+ When the action is performed on a specific, identifiable resource.
+ - ref: audit.target.type
+ requirement_level:
+ recommended: >
+ When `audit.target.id` is present and the resource kind adds
+ meaningful context for audit review.
+ - ref: audit.target.name
+ requirement_level: opt_in
+
+ # --- source / origin ---
+ - ref: audit.source.id
+ requirement_level:
+ recommended: >
+ When the network origin or calling device of the action is known
+ and meaningful for compliance review (e.g. PCI-DSS access logging).
+ - ref: audit.source.type
+ requirement_level:
+ recommended: When `audit.source.id` is present.
+
+ # --- integrity (tamper-evidence) ---
+ - ref: audit.integrity.value
+ requirement_level: opt_in
+ - ref: audit.integrity.signer
+ requirement_level:
+ recommended: When `audit.integrity.value` is present.
+ - ref: audit.integrity.canonicalization
+ requirement_level:
+ conditionally_required: >
+ Required when a canonicalization scheme other than `jcs` (RFC 8785)
+ is used. Omit when `jcs` is used.
+ - ref: audit.integrity.algorithm
+ requirement_level:
+ conditionally_required: >
+ Required (as a Resource attribute) when `audit.integrity.value` is
+ present on any record emitted from this resource.
+ - ref: audit.integrity.certificate
+ requirement_level:
+ conditionally_required: >
+ Required (as a Resource attribute, together with
+ `audit.integrity.algorithm`) when `audit.integrity.value` is present
+ on any record emitted from this resource.
+
+ # --- hash-chain ordering ---
+ - ref: audit.sequence.stream_id
+ requirement_level:
+ recommended: >
+ When the emitting service uses hash-chain ordering. Scopes the chain
+ to a single `AuditLogger` instance.
+ - ref: audit.sequence.number
+ requirement_level:
+ recommended: >
+ When the emitting service maintains a monotonic per-stream counter.
+ Required when `audit.sequence.previous_hash` is present.
+ - ref: audit.sequence.previous_hash
+ requirement_level:
+ recommended: >
+ When the emitting service implements a hash chain for tamper
+ detection. Requires `audit.sequence.number` to be present.
+ MUST be omitted on the genesis record of a stream.
+ - ref: audit.sequence.previous_record_id
+ requirement_level:
+ recommended: >
+ When `audit.sequence.previous_hash` is present. Provides a resolvable
+ locator for the predecessor record across storage boundaries.
+ MUST be omitted on the genesis record of a stream.
+ - ref: audit.sequence.end
+ requirement_level:
+ conditionally_required: >
+ Required on the final record of a gracefully closed stream
+ (emitted during `ForceFlush` or `Shutdown`). Omit on all other records.
+
+ # --- schema versioning ---
+ - ref: audit.schema.version
+ requirement_level: opt_in
diff --git a/model/audit/registry.yaml b/model/audit/registry.yaml
new file mode 100644
index 0000000000..132d859c53
--- /dev/null
+++ b/model/audit/registry.yaml
@@ -0,0 +1,383 @@
+groups:
+ # ---------------------------------------------------------------------------
+ # audit.record — identity and deduplication
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.record
+ type: attribute_group
+ display_name: Audit Record Attributes
+ brief: >
+ Attributes that uniquely identify and version an audit record.
+ attributes:
+ - id: audit.record.id
+ type: string
+ stability: development
+ brief: >
+ A stable, globally unique identifier for this audit record.
+ note: >
+ The SDK MUST auto-generate a UUID v4 when the caller omits this field.
+ The value MUST remain identical across all retries of the same record.
+ Records with the same `audit.record.id` and identical payload hash are
+ treated as idempotent duplicates by compliant sinks.
+ examples:
+ - "3fa85f64-5717-4562-b3fc-2c963f66afa6"
+
+ - id: audit.schema.version
+ type: string
+ stability: development
+ brief: >
+ The version of the audit semantic conventions schema used by this record.
+ note: >
+ Follows semantic versioning (MAJOR.MINOR.PATCH). Receivers MAY use this
+ value to select the matching validation schema for the record's attribute
+ vocabulary.
+ examples: ["1.0.0", "1.2.0"]
+
+ # ---------------------------------------------------------------------------
+ # audit.actor — who performed the action
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.actor
+ type: attribute_group
+ display_name: Audit Actor Attributes
+ brief: >
+ Attributes that identify the principal (human user, service, or automated
+ system component) that initiated the auditable action.
+ attributes:
+ - id: audit.actor.id
+ type: string
+ stability: development
+ brief: >
+ The stable identifier of the actor that performed the action.
+ note: >
+ This SHOULD be an opaque, durable identifier (e.g. a user-UUID, service
+ account name, or IAM principal ARN) that remains stable across sessions.
+ Avoid using mutable display names or email addresses as the primary ID.
+ examples:
+ - "u8472"
+ - "svc-deployer"
+ - "arn:aws:iam::123456789012:role/DeployRole"
+
+ - id: audit.actor.type
+ type:
+ members:
+ - id: user
+ value: "user"
+ brief: A human user authenticated to the system.
+ stability: development
+ - id: service
+ value: "service"
+ brief: An automated service or daemon acting on its own behalf.
+ stability: development
+ - id: system
+ value: "system"
+ brief: >
+ An internal system component (scheduler, GC, background job) that
+ is not externally authenticated.
+ stability: development
+ stability: development
+ brief: >
+ The category of principal that performed the action.
+ examples: ["user", "service", "system"]
+
+ - id: audit.actor.name
+ type: string
+ stability: development
+ brief: >
+ A human-readable display name or username of the actor.
+ note: >
+ MAY be a login name, email address, or display name. This value is
+ informational only; use `audit.actor.id` for stable identity correlation.
+ examples: ["alice", "alice@example.com", "Alice Smith"]
+
+ # ---------------------------------------------------------------------------
+ # audit.action — what was done
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.action
+ type: attribute_group
+ display_name: Audit Action Attributes
+ brief: >
+ Attributes that describe the operation performed by the actor.
+ attributes:
+ - id: audit.action
+ type: string
+ stability: development
+ brief: >
+ The auditable operation that was performed.
+ note: >
+ SHOULD be an uppercase verb from a controlled vocabulary where possible.
+ Well-known values include `LOGIN`, `LOGOUT`, `READ`, `CREATE`, `UPDATE`,
+ `DELETE`, `GRANT`, `REVOKE`, `EXPORT`, `IMPORT`, `EXECUTE`, `APPROVE`,
+ `REJECT`. Custom values MAY be used when none of the well-known values
+ applies, but SHOULD be documented in the producing service's changelog.
+ examples:
+ - "LOGIN"
+ - "DELETE"
+ - "GRANT"
+ - "CONFIG_CHANGE"
+
+ - id: audit.outcome
+ type:
+ members:
+ - id: success
+ value: "success"
+ brief: >
+ The action completed successfully and produced its intended effect.
+ stability: development
+ - id: failure
+ value: "failure"
+ brief: >
+ The action was attempted but did not complete successfully (e.g.
+ authorization denied, validation error, resource not found).
+ stability: development
+ - id: unknown
+ value: "unknown"
+ brief: >
+ The outcome could not be determined at the time the event was
+ emitted, for example because the operation is async.
+ stability: development
+ stability: development
+ brief: >
+ The result of the auditable action.
+ examples: ["success", "failure", "unknown"]
+
+ # ---------------------------------------------------------------------------
+ # audit.target — the resource acted upon
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.target
+ type: attribute_group
+ display_name: Audit Target Attributes
+ brief: >
+ Attributes that describe the resource or object that was acted upon.
+ attributes:
+ - id: audit.target.id
+ type: string
+ stability: development
+ brief: >
+ The stable identifier of the resource that was the target of the action.
+ note: >
+ SHOULD be the primary key, ARN, URI, or equivalent durable identifier
+ of the resource. When acting on a collection rather than a single
+ resource, this MAY contain the collection identifier.
+ examples:
+ - "document-42"
+ - "arn:aws:s3:::my-bucket/key"
+ - "/api/v1/users/9f81"
+
+ - id: audit.target.type
+ type: string
+ stability: development
+ brief: >
+ The type or resource kind of the target.
+ note: >
+ SHOULD use a fully-qualified type where available (e.g. a Kubernetes
+ GroupVersionResource or an IAM resource type). For domain-specific types
+ a short qualified name MAY be used (e.g. `finance.invoice`).
+ examples:
+ - "User"
+ - "apps/v1/Deployment"
+ - "finance.invoice"
+
+ - id: audit.target.name
+ type: string
+ stability: development
+ brief: >
+ A human-readable name or label of the target resource.
+ note: >
+ Informational only. Use `audit.target.id` for stable identity correlation.
+ examples:
+ - "production-deploy"
+ - "Q1-invoice-7734"
+
+ # ---------------------------------------------------------------------------
+ # audit.source — network / origin of the action
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.source
+ type: attribute_group
+ display_name: Audit Source Attributes
+ brief: >
+ Attributes that describe the network origin or calling context of the action.
+ attributes:
+ - id: audit.source.id
+ type: string
+ stability: development
+ brief: >
+ A stable identifier for the source system or network endpoint that
+ originated the action.
+ note: >
+ MAY be an IP address, a device UUID, or a service mesh endpoint ID.
+ Prefer stable identifiers (device UUID) over ephemeral ones (IP address)
+ when both are available.
+ examples:
+ - "192.0.2.42"
+ - "device-uuid-abcd1234"
+
+ - id: audit.source.type
+ type: string
+ stability: development
+ brief: >
+ The category of origin that initiated the action.
+ note: >
+ Well-known values: `ipv4`, `ipv6`, `hostname`.
+ Custom values MAY be used.
+ examples:
+ - "IPv4"
+ - "IPv6"
+ - "hostname"
+
+ # ---------------------------------------------------------------------------
+ # audit.integrity — cryptographic tamper-evidence
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.integrity
+ type: attribute_group
+ display_name: Audit Integrity Attributes
+ brief: >
+ Attributes that provide cryptographic evidence that the audit record has
+ not been tampered with since it was emitted.
+ attributes:
+ - id: audit.integrity.value
+ type: string
+ stability: development
+ brief: >
+ base64-encoded cryptographic signature or MAC covering this record.
+ note: >
+ The input to the signing / MAC operation MUST be the canonical
+ serialization of the `AuditRecord` with all `audit.integrity.*`
+ attributes excluded. The default canonicalization is JCS (RFC 8785);
+ set `audit.integrity.canonicalization` when a different scheme is used.
+ `audit.integrity.algorithm` MUST be set on the emitting Resource
+ whenever this attribute is present.
+ examples:
+ - "SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"
+
+ - id: audit.integrity.signer
+ type: string
+ stability: development
+ brief: >
+ Identifies which tier produced the integrity proof in `audit.integrity.value`.
+ note: >
+ `producer` means the SDK computed the value before export. `collector`
+ means a Tier-2 Collector signed or re-signed the record after receiving it.
+ When absent, `producer` SHOULD be assumed.
+ examples: ["producer", "collector"]
+
+ - id: audit.integrity.canonicalization
+ type: string
+ stability: development
+ brief: >
+ The canonicalization scheme applied to the record before signing or MACing.
+ note: >
+ Defaults to `jcs` (RFC 8785 JSON Canonicalization Scheme). Set explicitly
+ when any other canonicalization is used so that verifiers can reproduce the
+ exact byte sequence that was signed. MUST be omitted when `jcs` is used.
+ examples: ["jcs"]
+
+ - id: audit.integrity.algorithm
+ type: string
+ stability: development
+ brief: >
+ The algorithm used to compute `audit.integrity.value`.
+ note: >
+ MUST be set as a Resource attribute whenever `audit.integrity.value` is
+ present on any record emitted by this resource. Use a JWA identifier
+ (RFC 7518) for asymmetric signatures (e.g. `ES256`, `RS256`, `EdDSA`) or
+ an IANA MAC Algorithm identifier for symmetric MACs (e.g. `HMAC-SHA256`).
+ examples:
+ - "ES256"
+ - "EdDSA"
+ - "HMAC-SHA256"
+
+ - id: audit.integrity.certificate
+ type: string
+ stability: development
+ brief: >
+ A reference to the key or certificate used for `audit.integrity.value`.
+ note: >
+ MUST be set as a Resource attribute (together with
+ `audit.integrity.algorithm`) whenever `audit.integrity.value` is present
+ on any record emitted by this resource. Because a service instance uses a
+ single signing key for its entire lifetime, both `audit.integrity.algorithm`
+ and `audit.integrity.certificate` are constant across all records from the
+ same resource and therefore belong on the Resource, not on individual records.
+
+ Acceptable forms (in order of preference): a Key ID / `kid` (JOSE header
+ parameter), a DER-encoded X.509 certificate base64-encoded, an X.509
+ certificate fingerprint (SHA-256 hex), or an Issuer + Serial Number pair.
+ Receivers MUST NOT use this field alone for trust decisions; key
+ validation MUST be performed out-of-band.
+ examples:
+ - "key-2024-01"
+ - "SHA256:ab12cd34..."
+
+ # ---------------------------------------------------------------------------
+ # audit.sequence — hash-chain ordering
+ # ---------------------------------------------------------------------------
+ - id: registry.audit.sequence
+ type: attribute_group
+ display_name: Audit Sequence Attributes
+ brief: >
+ Attributes that link audit records into an ordered, tamper-evident chain
+ within a single stream.
+ attributes:
+ - id: audit.sequence.number
+ type: int
+ stability: development
+ brief: >
+ A monotonically increasing counter assigned to each record within a
+ single audit stream.
+ note: >
+ Compliant sinks and Tier-2 Collectors MUST verify that consecutive
+ records within the same stream have strictly increasing sequence numbers.
+ Gaps MUST trigger a gap-detection warning and a security event log entry.
+ The counter SHOULD start at 1 and increment by 1 per emitted record, but
+ implementations MAY use a larger step if records can be emitted
+ concurrently from multiple threads.
+ examples: [1, 42, 1000001]
+
+ - id: audit.sequence.previous_hash
+ type: string
+ stability: development
+ brief: >
+ SHA-256 hex digest of the `IntegrityHash` field of the immediately
+ preceding record in the same audit stream.
+ note: >
+ Including the previous record's sink-acknowledged hash in the current
+ record creates an append-only hash chain. Any retroactive modification
+ of a record is detectable by re-verifying the chain. MUST be omitted on
+ the genesis (first) record of a stream — absence is the normative signal;
+ no magic sentinel constant is required.
+ examples:
+ - "a3f1c2e4b5d6a7f8e9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2"
+
+ - id: audit.sequence.previous_record_id
+ type: string
+ stability: development
+ brief: >
+ The `audit.record.id` of the immediately preceding record in the same
+ audit stream.
+ note: >
+ Provides a resolvable locator for the predecessor across shards, storage
+ systems, and retention boundaries, complementing `audit.sequence.previous_hash`.
+ MUST be omitted on the genesis (first) record of a stream.
+ examples:
+ - "3fa85f64-5717-4562-b3fc-2c963f66afa6"
+
+ - id: audit.sequence.end
+ type: boolean
+ stability: development
+ brief: >
+ Set to `true` on the last record of a gracefully closed audit stream.
+ note: >
+ Emitted by the SDK during `ForceFlush` or `Shutdown` to mark the terminal
+ record of a stream. Absence is normal for all intermediate records — do not
+ treat absence as an error.
+ examples: [true]
+
+ - id: audit.sequence.stream_id
+ type: string
+ stability: development
+ brief: >
+ An opaque identifier that scopes the hash chain to a single audit stream.
+ note: >
+ The SDK SHOULD generate a UUID v4 once per `AuditLogger` instance and
+ include it on every record emitted by that logger.
+ examples:
+ - "7c9e6679-7425-40de-944b-e07fc1f90ae7"