Skip to content

feat(plugins): add ocsf-audit — OCSF API Activity emitter with attestation chain#128

Open
Levaj2000 wants to merge 2 commits into
contextforge-org:devfrom
Levaj2000:feat/ocsf-audit-plugin
Open

feat(plugins): add ocsf-audit — OCSF API Activity emitter with attestation chain#128
Levaj2000 wants to merge 2 commits into
contextforge-org:devfrom
Levaj2000:feat/ocsf-audit-plugin

Conversation

@Levaj2000

Copy link
Copy Markdown

Adds builtins/plugins/ocsf-audit — a CMF audit plugin that emits each dispatched
request as an OCSF API Activity event (class 6003, ai_operation +
security_control profiles) instead of a free-form JSON line. Near-twin of
audit-logger: same observation-only, always-allow contract, same factory + hook
wiring; only the record shape differs.

What it does

  • Maps CMF Message + Extensions onto OCSF: ai_agent, ai_model,
    message_context, delegation, actor/user, tool/resource coordinates.
  • Activity ids follow API Activity's real enum (readOnlyHint: true tools,
    resources, prompts → 2 Read; other tool calls → 99 + "Invoke Tool";
    completions → 99 + "Completion"). The passive post-hook stream carries
    action_id: 3 (Observed) / disposition_id: 17 (Logged).
  • Optional tamper-evident attestation chain with predecessor binding —
    entry_hash = sha256(canonical{chain_uid, event, prev_entry_hash}) over JCS-style
    canonical bytes — independently recomputable from the emitted JSON, no shared
    secret. DSSE signing is a seam (stub) consuming the same binding bytes.
  • CMF fields with no OCSF home yet (stop_reason, mcp.*, framework.*, monotonic
    labels, workload identity) ride under OCSF unmapped, so the open schema gaps stay
    self-documenting; upstream OCSF issues for them are being filed.

Scope / deliberate limits

  • Registered as a feature-gated builtin (ocsf-audit), not in default features.
  • Deny/modify records (action_id 2/4) need the framework to surface its decision
    to a plugin — per the production-readiness plan, not attempted here.
  • Chain head is in-process (one chain per instance, reset on restart); durable /
    replica-safe chaining and checkpoint signing are follow-on work.

Validation: cargo build/test -p cpex-plugin-ocsf-audit (13 tests),
cargo clippy --all-targets clean against the workspace lint wall, cargo fmt
clean, cargo build -p cpex-builtins --features ocsf-audit clean.
SAMPLE-OUTPUT.md holds the deterministic example output.

Follows the plan in ocsf-plugin-production-plan.md (P0 schema-validity items are
in; P1+ tracked there).

…ation chain

New builtin CMF plugin (audit/ocsf), a near-twin of audit-logger that
serializes each dispatched request as an OCSF API Activity event
(class 6003, ai_operation + security_control profiles) instead of a
free-form JSON line.

- Activity ids follow API Activity's real enum: resources/prompts and
  readOnlyHint tools -> 2 (Read); other tool calls -> 99 (Other) +
  activity_name; completions -> 99. Passive post-hook stream carries
  action_id 3 (Observed) / disposition_id 17 (Logged); deny/modify
  mapping waits on the framework decision event.
- Optional tamper-evident attestation chain with predecessor binding:
  entry_hash = sha256(canonical{chain_uid, event, prev_entry_hash})
  over JCS-style canonical bytes — independently recomputable from the
  emitted JSON, no shared secret. DSSE signing is a seam (stub) that
  consumes the same binding bytes.
- CMF gap fields (stop_reason, mcp.*, framework.*, monotonic labels,
  workload identity) ride under OCSF unmapped, keeping the open schema
  gaps self-documenting; upstream OCSF issues are being filed.
- Registered as feature-gated builtin (not in default features);
  13 unit tests + deterministic emit_sample example.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant