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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All notable changes to Agent Manifest are documented here. Format follows [Keep

## [Unreleased]

### Added

**[SPEC]** **`agent_id` is now the normative correlation key for OCSF `ai_agent.instance_uid`** (section 3.1), and verification results carry it back as `runtime_correlation_key` (section 5.2). Closes #269. Section 5.3.1 already bound `agent_id` to "the authenticated workload subject for the current session" for gateway runtime binding; this extends the same scope to OCSF-emitting runtime-evidence producers (e.g. the `agent-state` KV-fingerprint chain, `rabbidave/ws4-secure-design-agentic-systems@1e35ab5`) so a verifier can join runtime evidence to a manifest without a second identity mechanism. Does not change `fields_verified`, which stays boot-time-only per section 7.2; does not split `agent_id` into separate stable/instance fields, though a future revision may if the current overload proves to be a problem in practice.

### Changed

**[SPEC][SDK] BREAKING: the `@context` URI moves to `https://manifest.agentrust-io.com/v0.2/context.json`**, and the specification is republished as v0.2 ([`spec/agent-manifest-spec-v0.2.md`](spec/agent-manifest-spec-v0.2.md), [ADR-0012](docs/adr/0012-context-uri-moved-to-controlled-domain.md)). The v0.1 URI `https://agentmanifest.agentrust.io/v0.1/context.json` named `agentrust.io`, a domain this project has never controlled: registered to a third party behind Domains By Proxy, paid through mid-2027, and it has never resolved. Every manifest issued to date was therefore identified under somebody else's name, which is untenable in an identity specification.
Expand Down
64 changes: 64 additions & 0 deletions spec/agent-manifest-spec-v0.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,11 @@ All fields annotated as UUID v7 MUST conform to RFC 9562 Section 5.7. The string
<!-- CHANGED: F-01 - SPIFFE URI path note -->
The `agent_id` path structure `/agent/<name>/<instance>` shown in examples is a convention, not a requirement. Trust domain must be lowercase `[a-z0-9._-]`; path segments may use `[a-zA-Z0-9._-]`. UUID v7 instance identifiers (hyphens permitted in path segments) are valid. Example: `spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001`.

<!-- CHANGED: #269 - normative agent_id / OCSF ai_agent.instance_uid correlation -->
`agent_id` already serves as the runtime-session subject-binding value in section 5.3.1 item 3 ("the authenticated workload subject for the current session equals the manifest `agent_id`"). This section makes that same binding explicit for OCSF-emitting runtime-evidence producers: when such a producer emits an `ai_agent`-bearing OCSF event (e.g. `Agent Inventory Info [5050]`) for a session governed by this manifest, the value populated into `ai_agent.instance_uid` MUST equal this manifest's `agent_id`. `ai_agent.instance_uid` is scoped to "a specific running instance or session" (OCSF `objects/ai_agent.json`) — the same scope `agent_id` already carries per 5.3.1, not a new concept. `ai_agent.version`/`ai_agent.charter`, if present, are not part of this binding: both are static across a session and are not suitable join keys for per-event correlation.

This section does not require `agent_id`'s optional `/agent/<name>/<instance>` path segment (above) to itself carry the instance scope — only that the resolved `agent_id` string, however structured, equals the emitted `instance_uid`. A future revision MAY split `agent_id` into a stable and an instance-scoped field if implementation experience shows the overload is a problem; this section does not propose that split.

<!-- CHANGED: SCHEMA F-15/@context - normative note on provisional URL -->
The `@context` URL `https://manifest.agentrust-io.com/v0.2/context.json` is provisional for the v0.2 draft period. The CoSAI WS4 working stream will assign the canonical URL prior to v1.0 ratification, and implementations MUST support the canonical CoSAI-assigned URL when it is assigned.

Expand Down Expand Up @@ -1147,6 +1152,7 @@ Conformance level requirements:
"pack_hash": "sha256:<64-hex-chars>",
"pack_uri": "<URI to full evidence pack>"
},
"runtime_correlation_key": "<string, equals manifest agent_id -- OPTIONAL, see section 3.1>",
"verification_signature": "<Ed25519 | ML-DSA-65 signature by the attestation service>"
}
```
Expand All @@ -1161,6 +1167,64 @@ Conformance level requirements:

`INCOMPATIBLE_VERSION` is returned when the verifier does not support the manifest's declared `version`. See section 2.2 for version negotiation rules.

<!-- CHANGED: #269 - runtime_correlation_key -->
`runtime_correlation_key` echoes `agent_id` back in the verification result so a runtime-evidence consumer does not need to re-parse the manifest just to obtain the join key defined in section 3.1. It is set whenever `agent_id` is present (i.e. always, since `agent_id` is REQUIRED) and is otherwise informational — it does not affect `result` or any `fields_verified` entry, since runtime evidence is out of scope for what this verification call attests (section 7.2). A verifier that has no runtime-evidence consumers MAY omit populating downstream consumption of this field, but the field itself is always present given `agent_id` always is.

Worked example — a manifest, the OCSF runtime evidence a producer emits against it (per the correlation rule in section 3.1), and the resulting verification result:

```jsonc
// Manifest excerpt (section 3.1)
{
"manifest_id": "01926b4c-79a0-7f3e-9c21-4e0f0a1b2c3d",
"agent_id": "spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001",
"version": "0.1",
"issuer": "spiffe://trust.example/manifest-authority",
"issued_at": "2026-08-03T14:00:00Z",
"expires_at": "2026-11-01T14:00:00Z"
}

// Runtime evidence: an OCSF Agent Inventory Info [5050] event, unmodified
// output of the reference implementation at
// rabbidave/ws4-secure-design-agentic-systems@1e35ab5 (ocsf_mapping.to_ocsf_event)
{
"class_uid": 5050,
"class_name": "Agent Inventory Info",
"ai_agent": {
"uid": "spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001",
"instance_uid": "spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001",
// ^ MUST equal manifest.agent_id above -- the binding section 3.1 defines.
"version": "2.3.1",
"charter": null,
"token_fingerprint": {
"algorithm_id": 3, "algorithm": "SHA-256",
"value": "e7a0585389f573fcfc3b744a81cb791b2a325240066731cd8a8c10fb710c28ea"
}
},
"session_uid": "spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001",
"context": {
"kv_state_fingerprint": {
"algorithm_id": 3, "algorithm": "SHA-256",
"value": "c96021ce1c548d3723ffe318e1167d5b85d9901f0a3dd4439eed090ba75ddc08"
}
},
"prev_inventory": { "algorithm_id": 3, "algorithm": "SHA-256", "value": "00...00" },
"inventory": { "algorithm_id": 3, "algorithm": "SHA-256", "value": "a877499302eef959999656c486b081a5a5f977c03d6876a295de0e89b15dce72" }
}

// Verification result (section 5.2), with the correlation key surfaced
{
"verification_id": "01926b4d-0001-7000-8000-000000000001",
"manifest_id": "01926b4c-79a0-7f3e-9c21-4e0f0a1b2c3d",
"result": "VALID",
"attestation_verified": false,
"fields_verified": { "...": "unchanged -- boot-time artifacts only, per section 7.2" },
"runtime_correlation_key": "spiffe://trust.example/agent/payments-processor/01926b4c-1234-7abc-9def-000000000001"
// A runtime-evidence consumer joins this manifest's evidence stream by
// matching Agent Inventory Info events where ai_agent.instance_uid
// equals this value -- no re-derivation from the manifest needed.
}
```

##### 5.2.1 Evidence Pack Format <!-- CHANGED: SPEC-12 - new normative subsection -->

An evidence pack is a JSON document with the following structure:
Expand Down
Loading