Chio/Docs

Bilateral Co-Sign

The default joint-commit primitive across organisational kernels. Both sides independently evaluate the same canonical body and sign it. Either party can verify retrospectively from its own receipt store; neither can rewrite the joint history.

Forward-looking concept

Bilateral co-signing primitives exist in chio-federation::bilateral today. The cross-vendor invocation predicate (proposed as the in-toto attestation type https://in-toto.io/attestation/bilateral-cosign-invocation/v1, chio-namespaced fallback chio.bilateral-cosign-invocation.v1) and the workflow composition surface that builds on top are research-stage.

Why bilateral, not BFT

The earlier framing reached for Tendermint-style BFT for joint decisions. The current framing prefers bilateral co-signing trees that compose, with FROST quorum as an opt-in special case. Legitimacy comes from evidence-referential cases that any third party can replay, not from internal voting. There is no roster to capture and no quorum threshold for routine action.

What a co-signed receipt commits to

  • The canonical body of the action (parameters, target, timestamp).
  • The agent passport on whose authority it ran.
  • The treaty scope that authorised the cross-org link.
  • A reference to the workflow receipt if the action sits inside a multi-step plan.
  • An anchor reference for action classes whose consistency model is totally-ordered.

Canonical cosigned receipt body

The shape below is the in-toto Statement v1 with the proposed bilateral-cosign-invocation/v1 predicate. Both kernels sign the same DSSE PAE bytes ("DSSEv1" SP LEN(type) SP type SP LEN(body) SP body). The subject[0].digest.sha256 is the SHA-256 of the canonical-JSON of the underlying chio receipt body, so the predicate refers to a precise invocation event independent of where the receipt is stored.

cosigned-receipt.json
{
  "_type": "https://in-toto.io/Statement/v1",
  "subject": [
    {
      "name": "chio-receipt:rcpt_a1b2c3d4e5f6",
      "digest": {
        "sha256": "5b41362bc82b7f3d56edc5a306db22105707d01ff4819e26faef9724a2d406c9"
      }
    }
  ],
  "predicateType": "https://in-toto.io/attestation/bilateral-cosign-invocation/v1",
  "predicate": {
    "invocation_id": "inv_8f3a2c1d-7e4b-4a92-b1d5-2f9a8c6e1b04",
    "tool_server_a": {
      "kernel_id": "did:chio:blueteam-soc",
      "passport_key_fingerprint": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
      "alg": "ed25519"
    },
    "tool_server_b": {
      "kernel_id": "did:chio:treasury-cfo",
      "passport_key_fingerprint": "4d5a92e0b1c8f7a392d4e6f8b2a1c5d7e9f0a3b4c5d6e7f8a9b0c1d2e3f4a5b6",
      "alg": "ed25519"
    },
    "tool_name": "credentials.revoke_passport",
    "tool_args_hash": {
      "alg": "sha256",
      "value": "7e2b1f3a4d8c9e0b2f1d5a8c6e3b9f7a2d4c1e0b8f3a5d7c9e1b2f4a6d8c0e2b"
    },
    "capability_lease_ref": {
      "lease_id": "lease_4d2a1b8e",
      "issuer": "did:chio:blueteam-soc",
      "expires_at_unix_ms": 1746717600000,
      "scope_digest": {
        "alg": "sha256",
        "value": "b2c58e91a0d4c7f3e6a9b1d8c2f5a0e3d7b4c1f8a5e2d9c6b3a0f7e4d1c8b5a2"
      }
    },
    "policy_evaluation_summary": {
      "server_a_verdict": {
        "verdict": "allow",
        "policy_id": "blueteam.policy.revoke",
        "policy_version": "2.4.1",
        "rationale_code": "passport_compromise_confirmed"
      },
      "server_b_verdict": {
        "verdict": "allow",
        "policy_id": "treasury.policy.revoke",
        "policy_version": "1.7.0",
        "rationale_code": "settlement_freeze_aligned"
      },
      "joint_disposition": "allow"
    },
    "governance_receipt_ref": {
      "receipt_id": "gov_rcpt_3a8f1e2c",
      "kernel_id": "did:chio:blueteam-soc",
      "digest": {
        "alg": "sha256",
        "value": "c104a8b2d5e9f1c3a7b0e4d8f2a5c9e1b4d7f0a3c6e9b2d5f8a1c4e7b0d3f6a9"
      }
    },
    "consistency_model": "totally-ordered",
    "consistency_anchor": "chio-anchor",
    "cross_org_visibility": "federated",
    "co_sign": "bilateral_required",
    "timestamp_unix_ms": 1746710400000
  },
  "signatures": [
    {
      "keyid": "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08",
      "sig": "MEUCIQDxK8b3...A=="
    },
    {
      "keyid": "4d5a92e0b1c8f7a392d4e6f8b2a1c5d7e9f0a3b4c5d6e7f8a9b0c1d2e3f4a5b6",
      "sig": "MEUCIQDz9Lw1...B=="
    }
  ]
}

The keyid of each signature MUST equal the SHA-256 of that kernel’s passport public key, and MUST equal the passport_key_fingerprint declared inside the predicate. This binding is what distinguishes a bilateral-cosign-invocation envelope from two independent signers that happen to sign the same Statement: the predicate body itself names which two keys MUST appear in the envelope.

Multi-party and the path-cover predicate

Bilateral trees with a path-cover predicate are the recommended default for more than two parties. The smallest validating shape ships in crates/chio-federation/tests/: a 3-party fixture reusing InProcessCoSigner drives A-B over R1 and B-C over a parent R2 that references R1’s hash, with verify_joint_commit(set, root) walking the DAG. The predicate “every party in the set participated in some path that leads to the root” is the composition rule.

rendering…
Path-cover over a 3-party DAG: A and B co-sign R1; B and C co-sign R2 referencing R1's hash. The path-cover predicate verifies that every party in {A, B, C} sits on a co-signed path to the join.

The predicate fails closed if any party’s passport key does not appear on at least one co-signed edge that reaches the root, or if R2’s declared parent hash does not match the canonical-JSON SHA-256 of R1. Operators verify any subtree independently; a bilateral pair’s receipt remains valid even if its sibling edge later fails verification.

FROST quorum opt-in

FROST-aggregated Ed25519 over a canonical body is the opt-in for action classes declared quorum-required in the ladder manifest. The opt-in is per-class precisely so the operational overhead (signing-key custody and the pre-handshake key-share ceremony) is paid only where needed: cross-issuer credential revocation, multi-party settlement, treaty-wide sanctions.

The DSSE envelope still carries n signatures (one per signer participating in the quorum), but the verification contract requires that every signature in the envelope verify; DSSE threshold rejection falls back to the ladder, not to DSSE’s permissive default. A FROST-aggregated signature appears on the wire as a single Ed25519 over the canonical body, with consistency_anchor: "frost-quorum" in the predicate and the quorum scope echoed from co_sign_quorum:

frost-quorum-sketch.json
{
  "consistency_model": "quorum-required",
  "consistency_anchor": "frost-quorum",
  "co_sign": "n_of_m",
  "co_sign_quorum": { "n": 2, "m": 3, "scope": "treaty" },
  "frost_aggregate_sig": {
    "alg": "ed25519",
    "group_pub_fingerprint": "9c7b3f0d1e8a4b5c2f6d9e1a3b7c4d8e0f2a5b8c1d4e7f0a3b6c9d2e5f8a1b4c",
    "value": "MIIDsig...8c1f"
  },
  "frost_signers": [
    "did:chio:blueteam-soc",
    "did:chio:treasury-cfo"
  ]
}

Structurally only one quorum-aggregated signature can succeed per body hash within a quorum epoch, so there is no partition-divergent co-sign window for these classes. The Partition-contingency mode cannot apply to quorum-required classes, since FROST quorum cannot be assembled under partition by definition.

Verifying offline

A third-party auditor with no live access to either kernel can verify a workflow receipt months after the fact. The walk is deterministic; the only inputs are the receipt corpus, the pinned passport keys, and the chio-anchor epoch the action committed at.

  1. 1. Resolve the workflow receipt root. Open the workflow receipt under https://in-toto.io/attestation/chio-workflow-receipt/v1 and read the per-step records. Each record carries the SHA-256 of the corresponding step’s bilateral-cosign-invocation Statement payload.
  2. 2. Walk to each step receipt. For every step, fetch the DSSE envelope whose payload SHA-256 matches the recorded digest. Reject the workflow receipt if any step envelope is missing.
  3. 3. Validate Statement and predicate schema. Decode payload base64, parse as in-toto Statement v1, validate against the schema. Confirm subject[0].digest.sha256 equals the canonical-JSON SHA-256 of the underlying chio receipt body resolved from the audit store. Validate the predicate body against the section 5 schema.
  4. 4. Confirm pinned passport keys. Look up both kernel ids in the verifier’s peer set. Check that each declared passport_key_fingerprint equals the SHA-256 of the pinned passport public key, and that no passport is revoked at the predicate’s pinned epoch (consult the chio-revocation-oracle epoch root).
  5. 5. Verify both signatures over PAE. Compute pae = "DSSEv1" SP LEN(payloadType) SP payloadType SP LEN(payload) SP payload. Verify exactly one signature whose keyid equals server_a’s fingerprint under A’s passport key, and exactly one whose keyid equals server_b’s fingerprint under B’s passport key. Reject on missing or out-of-order keys.
  6. 6. Verify policy agreement, capability, anchor. Confirm server_a_verdict.verdict == server_b_verdict.verdict and that joint_disposition agrees. Resolve capability_lease_ref, confirm issuer match and non-expiry. For totally-ordered steps, reconcile the consistency anchor (parent-hash chain or chio-anchor epoch) with the auditor’s view; for quorum-required steps, confirm the envelope carries the declared FROST quorum signatures.

Failure at any step surfaces a stable error code (subject.digest_mismatch, peer.unpinned_or_keyid_mismatch, peer.revoked_at_epoch, signature.server_a_invalid, signature.server_b_invalid, policy.verdict_disagreement, capability.lease_expired_or_unknown, consistency.anchor_unverified, consistency.quorum_underpopulated) that maps to a fileable Dispute case. The composite assertion “every cross-org step jointly committed” is true exactly when every step-level predicate verifies; the workflow receipt signature itself does not certify that property, only its own roll-up.

vs. Sigstore + in-toto runtime extensions

The structural slice is durable, not temporal. Bilateral co-signed intent (both parties independently evaluated and signed the same canonical body), per-action attenuated capability scoping, workflow receipts as joint multi-party plans, and evidence-referential governance over a lineage DAG are different questions than transparency-log-anchored single-party signatures.

Co-signing on top of Rekor is possible (DSSE multi-sig + custom predicate), but the predicate, the verifier, the capability binding, and the dispute model are not what Sigstore ships. The pragmatic posture: write Chio receipt DSSE envelopes to Rekor v2 for public tamper-evidence as a free integration win, while leaning on the structural slice for the cross-vendor pitch.