Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .chloggen/audit-logging-semconv.yaml
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
- area:audit
- area:aws
- area:azure
- area:browser
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/change_proposal.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
- area:audit
- area:aws
- area:azure
- area:browser
Expand Down
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/new-conventions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ body:
- area:app
- area:artifact
- area:aspnetcore
- area:audit
- area:aws
- area:azure
- area:browser
Expand Down
419 changes: 419 additions & 0 deletions docs/audit/audit-logs.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/registry/attributes/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
158 changes: 158 additions & 0 deletions docs/registry/attributes/audit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<!-- NOTE: THIS FILE IS AUTOGENERATED. DO NOT EDIT BY HAND. -->
<!-- see templates/registry/markdown/attribute_namespace.md.j2 -->

# 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-action" href="#audit-action">`audit.action`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | The auditable operation that was performed. [1] | `LOGIN`; `DELETE`; `GRANT`; `CONFIG_CHANGE` |
| <a id="audit-outcome" href="#audit-outcome">`audit.outcome`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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). | ![Development](https://img.shields.io/badge/-development-blue) |
| `success` | The action completed successfully and produced its intended effect. | ![Development](https://img.shields.io/badge/-development-blue) |
| `unknown` | The outcome could not be determined at the time the event was emitted, for example because the operation is async. | ![Development](https://img.shields.io/badge/-development-blue) |

## 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-actor-id" href="#audit-actor-id">`audit.actor.id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | The stable identifier of the actor that performed the action. [2] | `u8472`; `svc-deployer`; `arn:aws:iam::123456789012:role/DeployRole` |
| <a id="audit-actor-name" href="#audit-actor-name">`audit.actor.name`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | A human-readable display name or username of the actor. [3] | `alice`; `alice@example.com`; `Alice Smith` |
| <a id="audit-actor-type" href="#audit-actor-type">`audit.actor.type`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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. | ![Development](https://img.shields.io/badge/-development-blue) |
| `system` | An internal system component (scheduler, GC, background job) that is not externally authenticated. | ![Development](https://img.shields.io/badge/-development-blue) |
| `user` | A human user authenticated to the system. | ![Development](https://img.shields.io/badge/-development-blue) |

## 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-integrity-algorithm" href="#audit-integrity-algorithm">`audit.integrity.algorithm`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | The algorithm used to compute `audit.integrity.value`. [4] | `ES256`; `EdDSA`; `HMAC-SHA256` |
| <a id="audit-integrity-canonicalization" href="#audit-integrity-canonicalization">`audit.integrity.canonicalization`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | The canonicalization scheme applied to the record before signing or MACing. [5] | `jcs` |
| <a id="audit-integrity-certificate" href="#audit-integrity-certificate">`audit.integrity.certificate`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | A reference to the key or certificate used for `audit.integrity.value`. [6] | `key-2024-01`; `SHA256:ab12cd34...` |
| <a id="audit-integrity-signer" href="#audit-integrity-signer">`audit.integrity.signer`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | Identifies which tier produced the integrity proof in `audit.integrity.value`. [7] | `producer`; `collector` |
| <a id="audit-integrity-value" href="#audit-integrity-value">`audit.integrity.value`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-record-id" href="#audit-record-id">`audit.record.id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | A stable, globally unique identifier for this audit record. [9] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
| <a id="audit-schema-version" href="#audit-schema-version">`audit.schema.version`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-sequence-end" href="#audit-sequence-end">`audit.sequence.end`</a> | ![Development](https://img.shields.io/badge/-development-blue) | boolean | Set to `true` on the last record of a gracefully closed audit stream. [11] | `true` |
| <a id="audit-sequence-number" href="#audit-sequence-number">`audit.sequence.number`</a> | ![Development](https://img.shields.io/badge/-development-blue) | int | A monotonically increasing counter assigned to each record within a single audit stream. [12] | `1`; `42`; `1000001` |
| <a id="audit-sequence-previous-hash" href="#audit-sequence-previous-hash">`audit.sequence.previous_hash`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | SHA-256 hex digest of the `IntegrityHash` field of the immediately preceding record in the same audit stream. [13] | `a3f1c2e4b5d6a7f8e9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2` |
| <a id="audit-sequence-previous-record-id" href="#audit-sequence-previous-record-id">`audit.sequence.previous_record_id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | The `audit.record.id` of the immediately preceding record in the same audit stream. [14] | `3fa85f64-5717-4562-b3fc-2c963f66afa6` |
| <a id="audit-sequence-stream-id" href="#audit-sequence-stream-id">`audit.sequence.stream_id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-source-id" href="#audit-source-id">`audit.source.id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | A stable identifier for the source system or network endpoint that originated the action. [16] | `192.0.2.42`; `device-uuid-abcd1234` |
| <a id="audit-source-type" href="#audit-source-type">`audit.source.type`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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 |
| --- | --- | --- | --- | --- |
| <a id="audit-target-id" href="#audit-target-id">`audit.target.id`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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` |
| <a id="audit-target-name" href="#audit-target-name">`audit.target.name`</a> | ![Development](https://img.shields.io/badge/-development-blue) | string | A human-readable name or label of the target resource. [19] | `production-deploy`; `Q1-invoice-7734` |
| <a id="audit-target-type" href="#audit-target-type">`audit.target.type`</a> | ![Development](https://img.shields.io/badge/-development-blue) | 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`).
Loading
Loading