Skip to content

Bundle — Citizenship Bundle & Signed Bundle

An agent does not operate in a vacuum: it operates with an identity, a declared intent, a policy decision, and an auditable record. The Citizenship Bundle is the portable packet that brings all of that together. The Signed Bundle makes it cryptographically verifiable.

Citizenship Bundle (L3 Bundle)

A Citizenship Bundle is a JSON object containing exactly:

  • responsible_principal_record — DCP-01 (RPR)
  • agent_passport — DCP-01 (AP)
  • intent — DCP-02
  • policy_decision — DCP-02
  • audit_entries — DCP-03 (array, at least one element)

Normative schema: schemas/v1/citizenship_bundle.schema.json
$id: https://dcp-ai.org/schemas/v1/citizenship_bundle.schema.json

Validation:

dcp validate-bundle <bundle.json>

Or validate the object against the bundle schema directly:

dcp validate schemas/v1/citizenship_bundle.schema.json <bundle.json>

Example: tests/conformance/examples/citizenship_bundle.json


Signed Bundle

A Signed Bundle wraps a Citizenship Bundle with an Ed25519 signature and deterministic hashes:

  • bundle — the full Citizenship Bundle object
  • signature — object with:
  • alg: "ed25519"
  • created_at: ISO 8601 date-time
  • signer: { type: "human"|"organization", id, public_key_b64 }
  • bundle_hash: sha256:<hex> — SHA-256 of the canonicalized JSON of the bundle
  • merkle_root: sha256:<hex> or null — Merkle root of audit_entries (optional)
  • sig_b64: signature in Base64

Normative schema: schemas/v1/signed_bundle.schema.json
$id: https://dcp-ai.org/schemas/v1/signed_bundle.schema.json

Validation (schema + signature):

dcp verify-bundle <bundle.signed.json> <public_key.txt>

Auxiliary commands:

dcp bundle-hash <bundle.json>        # Prints bundle_hash (sha256:...)
dcp merkle-root <bundle.json>       # Prints merkle_root of audit_entries or null
dcp sign-bundle <bundle.json> <secret_key.txt> [out.json]
dcp keygen [out_dir]

Example: tests/conformance/examples/citizenship_bundle.signed.json

V2 bundles (bundle.dcp_bundle_version: "2.0") use schemas/v2/signed_bundle.schema.json: every artifact is a SignedPayload, and the composite Ed25519 + ML-DSA-65 signature covers the bundle manifest. See the V2 checklist in VERIFICATION.md.

dcp sign-bundle --composite <bundle_v2.json> <ed25519_secret_key.txt> <ml_dsa_65_secret_key.txt> [out.json]
dcp verify-bundle [--policy <mode>] <signed_bundle_v2.json> [public_key.txt]   # key pins the classical signer

Verification checklist

For a normative, step-by-step verification checklist (schema, signature, expiry, revocation, intent_hash, audit chain, merkle, optional anchor), see VERIFICATION.md. All steps are local; no server call is required.

Implementation notes (informative)

Added 25/10/2026. Not normative. These notes add no requirement and change nothing above: they describe how the reference code on main relates to this text. Where they differ, the normative text above stands.

  • In V2 only the four primary artifacts (RPR, passport, intent and policy decision) are SignedPayload envelopes; the audit entries are plain objects, committed by the manifest's Merkle root and covered by the bundle signature over the manifest, not signed one by one.
  • A V1 Citizenship Bundle needs at least one audit entry; a V2 bundle may have an empty audit trail (its Merkle root is 64 zeros), as VERIFICATION.md allows.
  • A bundle that verifies is consistent and signed by the keys it lists; that alone does not establish who the principal is, admit the bundle or authorize an action (docs/ADMISSION.md).
  • <bundle.json> and the other names in angle brackets are placeholders for your own files.