AEP-0005: Bridge Annexes (CloudEvents, OTLP, and OCSF)
Defines the lossless, mechanical, reversible mapping between AEP Events and CloudEvents 1.0 (JSON format, structured mode), the export of AEP Events to OpenTelemetry as OTLP LogRecords, and the projection of AEP's security-relevant event families onto OCSF (Open Cybersecurity Schema Framework) class
Draft: the AEP suite is pre-v0.1; each document's status lives in its header table. This page is rendered from the canonical spec/AEP-0005-bridges.md, which is the normative text.
| Field | Value |
|---|---|
| AEP | 0005 |
| Title | Bridge Annexes: CloudEvents Mapping, OTLP Export, and OCSF Projection |
| Type | Standards Track — Annex (normative) |
| Status | Draft |
| Sponsor | AEP maintainers |
| Created | 2026-07-03 |
| Requires | AEP-0001, AEP-0002 |
| Supersedes / Superseded-by | n/a |
Provenance (non-normative): the bridges are normative, day-one deliverables: the mapping tables are specification text, the reference implementations are conformance-tested, and both are versioned and released with the specification; this is the standing answer to "adopters would rather ingest CE/OTLP".
Abstract
Defines the lossless, mechanical, reversible mapping between AEP Events and CloudEvents 1.0 (JSON format, structured mode), the export of AEP Events to OpenTelemetry as OTLP LogRecords, and the projection of AEP's security-relevant event families onto OCSF (Open Cybersecurity Schema Framework) classes for security-analytics consumers.
Losslessness is a design property (the AEP envelope is deliberately CE-isomorphic), so the CE mapping is five rules and one table, and round-trip identity is a conformance requirement, not an aspiration. The OCSF projection is deliberately partial by scope, not by loss: it carries the security signal (sessions, tool activity, human-attention outcomes), and every record embeds the complete source envelope.
1. CloudEvents mapping: forward (AEP → CE)
Output: a valid CloudEvents 1.0 event, JSON format, structured mode.
Rules:
- B1 (constants). Set
specversion: "1.0"; setdatacontenttype: "application/json"whendatais present. - B2 (pass-through).
id,source,subject,time,datacopy verbatim. - B3 (type).
type := "dev.aep." + type(reverse-DNS root; placeholder frozen at the naming decision). Vendor types map under the same root:x.acme.foo.bar → dev.aep.x.acme.foo.bar. - B4 (attributes). Each remaining envelope attribute maps to its prefixed CE extension attribute per the table below. AEP envelope values are CE-legal extension scalars (string/integer/boolean) by design; there is no encoding step. AEP extension attributes (AEP-0001 §5.4) pass through verbatim (their naming rule is CE's).
- B5 (trace context).
traceparentmaps to the CE Distributed Tracing extension attributetraceparent, unprefixed (CE already standardizes it).
| AEP attribute | CE attribute |
|---|---|
aep |
aepversion |
agent |
aepagentid |
session |
aepsessionid |
run |
aeprunid |
step |
aepstep |
seq |
aepsequence |
epoch |
aepepoch |
cause |
aepcausationid |
severity |
aepseverity |
capture |
aepcapture |
traceparent |
traceparent |
Absent OPTIONAL AEP attributes produce no CE attribute (defaults are not materialized).
2. CloudEvents mapping: inverse (CE → AEP), and scope
For CE events whose
typebegins with the frozen root: drop the B1 constants, strip the B3 prefix, reverse the B4/B5 table, pass B2 through. The result MUST be the original AEP Event, bit-for-bit modulo JSON member order.Unknown
aep*-prefixed extension attributes on inbound events MUST be preserved when their names are legal AEP extension names (AEP-0001 §5.4). They may be from a newer minor version, and any attribute a conformant newer-minor bridge mints satisfies the grammar by construction, since the extension grammar is version-stable. A name violating the shared grammar cannot ride the envelope (the envelope schema rejects it) and is dropped with a diagnostic like any other illegal name.Other unknown CE extension attributes SHOULD be preserved as AEP extension attributes when their names are legal (AEP-0001 §5.4), otherwise dropped with a diagnostic.
Foreign CE events (any other
type) are out of scope: the bridge is an AEP-to-CE profile carrier, not a universal CE ingester. Lifting foreign CE traffic into AEP is an adapter's job (custom/x.*), like any other source.
3. OTLP export (AEP → OpenTelemetry)
3.1 Signal
AEP Events export as OTLP LogRecords (the OTel Events model: LogRecord +
event_name), not synthesized spans. Span synthesis (session/run/step spans from
start/finish pairs via cause) is a possible future exporter mode: additive,
deferred (an open question for a future revision).
3.2 Field mapping
| AEP | OTLP LogRecord | Note |
|---|---|---|
time |
time_unix_nano |
RFC 3339 → epoch nanos |
type |
event_name = "dev.aep." + type |
same string as the CE bridge: one exported identity everywhere |
severity |
severity_text + severity_number |
table §3.4 |
traceparent |
trace_id, span_id, flags |
parsed W3C fields; Events land on existing traces |
agent |
resource attribute service.name (default) + attribute aep.agent_id |
resource = the emitting agent process; override for shared relays |
session / run / step |
attributes aep.session_id, aep.run_id, aep.step |
|
id / seq / epoch / cause / capture |
attributes aep.event_id, aep.sequence, aep.epoch, aep.causation_id, aep.capture |
|
subject / source |
attributes aep.subject, aep.source |
|
data members named gen_ai.* |
top-level LogRecord attributes, verbatim | the OTel-mirror rule's payoff: token counts, model names light up in backends with zero mapping code |
remaining data |
body (AnyValue map) |
preserved wholesale |
3.3 Capture enforcement at the exporter
The exporter takes a max_capture setting (default metadata). Events above it are
down-leveled per AEP-0001 §8.2 / AEP-0002 §5.1 before export; capture: none
Events export envelope-derived attributes only (no body). Backends never see what
the operator did not opt into.
3.4 Severity mapping
| AEP | severity_text |
severity_number |
|---|---|---|
debug |
DEBUG | 5 |
info |
INFO | 9 |
notice |
INFO2 | 10 |
warning |
WARN | 13 |
error |
ERROR | 17 |
critical |
FATAL | 21 |
The inverse buckets OTLP ranges back to the six AEP levels
(1-8 to debug, 9 to info, 10-12 to notice, 13-16 to warning, 17-20 to
error, 21-24 to critical).
3.5 Exporter shape
aep-bridge-otlp is an ordinary AEP consumer: it subscribes with attr-match
filters (operator-scoped), batches, and emits OTLP/HTTP. It is an ecosystem
consumer, never normative infrastructure.
4. OCSF projection (AEP → OCSF)
4.1 Signal and scope
AEP's security-relevant event families project onto OCSF (Open Cybersecurity Schema Framework) event classes, so security-analytics backends that ingest OCSF natively (SIEM and security-lake deployments) can consume AEP fleets with zero mapping code. The projection targets OCSF version 1.8.0 (pinned; re-checked per AEP release, §5).
Three AEP families project; every other event (the control plane, progress,
presence, messages, vendor x.* traffic) deliberately produces no OCSF
record. This is a scope decision, not a loss: the OTLP export (§3) is the
full-fidelity telemetry channel, the OCSF projection is the security-signal
channel, and flooding a security pipeline with non-security agent chatter under
classes that do not mean it would be a mis-mapping.
Like the OTLP exporter (§3.5), an OCSF forwarder is an ordinary AEP consumer; the mapping below is normative independent of any runtime.
4.2 Class mapping
| AEP event | OCSF class | activity_id |
status_id |
disposition_id |
|---|---|---|---|---|
session.started |
Authentication (3002) | 1 Logon | 1 Success | n/a |
session.ended |
Authentication (3002) | 2 Logoff | 1 Success | n/a |
tool.requested |
Process Activity (1007) | 1 Launch | n/a | n/a |
tool.completed |
Process Activity (1007) | 2 Terminate | 1 Success | n/a |
tool.failed |
Process Activity (1007) | 2 Terminate | 2 Failure | n/a |
tool.denied |
Process Activity (1007) | 1 Launch | 2 Failure | 2 Blocked |
attention.requested |
Detection Finding (2004) | 1 Create | 1 New | n/a |
attention.answered |
Detection Finding (2004) | 2 Update | 2 In Progress | n/a |
attention.resolved |
Detection Finding (2004) | 3 Close | 4 Resolved | see §4.5 |
attention.timeout |
Detection Finding (2004) | 3 Close | n/a | 16 No Action |
category_uid is the class's OCSF category (3 IAM, 1 System Activity,
2 Findings); type_uid := class_uid * 100 + activity_id. All Detection Finding
records of one attention lifecycle share one finding identity:
finding_info.uid is the attention.requested Event's id, its own id on
the request, the subject on every later lifecycle Event (the stable
correlation AEP-0002 §5 guarantees).
4.3 Record construction
Every projected record is derived from the envelope plus the capture-surviving payload, and nothing else:
time:=timeas epoch milliseconds;metadata:={version:the pinned OCSF version,uid: id, original_time: time, product: {name: agent}}, pluscorrelation_uid := causewhen present. When the record asserts adisposition_idit declaresmetadata.profiles: ["security_control"](the disposition attribute rides that OCSF profile).severity_idper the §4.4 table;message := type.- Authentication:
user := {name: agent},session := {uid: session}. - Process Activity:
actor := {app_name: agent};process := {name: subject}plusuid :=the tool call id when the surviving payload carries it;device := {type_id: 0}plushostname :=thesourceURI authority when it has one, elsename := sourceverbatim. - Detection Finding:
finding_info := {uid:the request id (§4.2), title: type}. - Fidelity carrier:
unmapped.aep:= the complete envelope verbatim (every attribute exceptdata, extension attributes included);unmapped.data:= the capture-surviving payload verbatim (omitted when empty). A consumer can always recover the full AEP identity from the record.
Records satisfy the base-class required attributes of the pinned OCSF version
by construction. One documented edge: when a tool Event's payload does not
survive the ceiling (capture: none, or a level above max_capture), the
process object carries only the tool name and cannot satisfy OCSF's
at-least-one-of pid/uid/cpid object constraint; the record still ships,
and the projection never invents an identifier to green a constraint.
4.4 Severity mapping
| AEP | OCSF severity_id |
|---|---|
debug |
1 Informational |
info |
1 Informational |
notice |
2 Low |
warning |
3 Medium |
error |
4 High |
critical |
5 Critical |
Monotone, and lossy only at debug/info (OCSF has no debug severity); the
original severity string always rides unmapped.aep.severity. The mapping is
one-way: there is no OCSF-inbound direction.
4.5 Dispositions assert only what the wire asserts
A disposition is claimed exactly where an AEP Event itself asserts the
outcome: tool.denied → 2 Blocked, attention.resolved with
resolution: dismissed → 16 No Action, attention.timeout → 16 No Action
(the request expired unanswered; AEP-0002 §5 makes it terminal). An
attention.resolved with resolution: answered closes its finding with no
disposition_id: the decision content lives in the answer payload and its
interpretation is vendor-scoped (AEP-0008); a projection claiming
Allowed or Blocked there would assert knowledge the wire does not carry.
4.6 Capture enforcement
The §3.3 rule applies unchanged: a max_capture setting (default metadata)
down-levels Events before projection, and unmapped.data carries only what
survives. Because attention.requested defaults to capture: redacted, at
the default ceiling a finding is created from the envelope alone: prompt
text, options, and form fields never reach a security backend the operator
did not opt into.
5. Conformance
- Round-trip identity: for every golden fixture Event
e,ce_inverse(ce_forward(e)) ≡ e(canonical-JSON comparison). This fixture class MUST stay green in CI for any release. - Validity:
ce_forward(e)MUST validate as CloudEvents 1.0 JSON format (attribute-name/type legality included). - OTLP mapping: golden Events have pinned expected LogRecord projections
(JSON encoding of the OTLP data model); severity and
gen_ai.*hoisting are asserted exactly;max_capturedown-leveling is asserted. - Bridge mappings and fixtures MUST ship with v0.1 (implementations may be
labelled beta; the mappings and fixtures may not). The bridge annexes are
versioned with the specification; the external pins, namely OTel severity/name
and the OCSF class subset (
conformance/fixtures/ocsf/ocsf-classes.json: attribute-name sets and the activity/status/disposition/severity value sets at the pinned OCSF version), are re-checked per AEP release. - Inbound preserve-path: hand-authored inbound CE events pin §2 rule 2
directly: a grammar-legal
aep*-prefixed extension attribute is preserved, a plain legal extension name is preserved, and a name violating AEP-0001 §5.4's grammar is dropped while the rest maps (conformance/fixtures/ce-roundtrip/inbound-cases.json; both runners feed their inverse implementation directly: the golden-derived round-trip fixtures cannot exercise an attribute the golden corpus does not carry). - OCSF projection: golden Events in the §4.2 families have pinned
expected records (
conformance/fixtures/ocsf/ocsf-expected.json); the severity table, the §4.5 disposition rules (including the answered-carries-no-disposition rule), and capture enforcement are asserted exactly, and every pinned record is checked against the pinned OCSF class subset: only class attributes, enum-legal ids, derivedtype_uid.
6. Security considerations
This section is informative; every rule it mentions is defined where cited.
Bridges are the egress boundary of the capture model. Everything exported lands in systems with their own retention, indexing, and access-control regimes that AEP's
capturesemantics no longer govern. For OTLP and OCSF the control point is normative: the exporter'smax_capture(defaultmetadata) down-levels before export, so backends never see what the operator did not opt into (§3.3, §4.6).A CloudEvents forwarder has no section of its own here because it needs none. It is an ordinary re-emitting hop, and the down-level rule of AEP-0001 §8.2 applies to it like any hop; a deployment configures a ceiling there with the same care as at the OTLP exporter.
Envelope metadata travels as broker-visible attributes. The B4 mapping puts session identifiers, agent identity, sequence positions, and causation links into CE extension attributes (§1): exactly the part of a message that broker ecosystems most freely log, index, route on, and hand to middleware. The same holds for the OTLP attribute projection (§3.2).
Operators for whom activity structure is sensitive (who ran what, when, how much; visible even at
capture: metadata, AEP-0001 §12) treataep*attributes as data when configuring broker ACLs and telemetry pipelines, not as mere routing surface.Severity crosses the bridge with emitter trust attached. The §3.4 mapping is monotone and adds no interpretation: downstream alerting fires on the severity the emitter asserted (AEP-0002 §8). The inverse direction buckets OTLP's 24 levels into six (order-preserving but lossy within a bucket), so round-tripped severity is a coarser claim than the original.
Payload members surface as top-level attributes. The
gen_ai.*hoisting rule (§3.2) deliberately promotes those payload fields to LogRecord attributes so backends index them without mapping code. They aremetadata-level by schema (AEP-0002 §5.2): token counts and model names, not free text. But they are payload-derived and producer-controlled, and inherit the untrusted-input posture of AEP-0001 §12 wherever attributes feed queries or dashboards.OCSF records feed detection pipelines: dispositions are claims. A disposition in a security backend reads as an enforcement fact, which is why §4.5 claims one only where the AEP wire itself asserts the outcome and never interprets an answered decision. The projection carries the emitter's severity and outcome assertions with the emitter's trust attached, exactly like the OTLP direction;
unmapped.aeppreserves the evidence trail back to the source Event.
References
- AEP-0001, AEP-0002.
- CloudEvents 1.0 core + JSON format + Distributed Tracing extension.
- OTLP
logs/v1protobuf (LogRecord). - OTel Logs Data Model severity ranges.
- W3C Trace Context.
- OTel GenAI semantic conventions (mirrored names).
- OCSF 1.8.0 (Authentication 3002, Process Activity 1007, Detection Finding
2004, the
security_controlprofile).