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
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.
{
"_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.
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:
{
"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. Resolve the workflow receipt root. Open the workflow receipt under
https://in-toto.io/attestation/chio-workflow-receipt/v1and read the per-step records. Each record carries the SHA-256 of the corresponding step’s bilateral-cosign-invocation Statement payload. - 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. Validate Statement and predicate schema. Decode
payloadbase64, parse as in-toto Statement v1, validate against the schema. Confirmsubject[0].digest.sha256equals 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. Confirm pinned passport keys. Look up both kernel ids in the verifier’s peer set. Check that each declared
passport_key_fingerprintequals 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. Verify both signatures over PAE. Compute
pae = "DSSEv1" SP LEN(payloadType) SP payloadType SP LEN(payload) SP payload. Verify exactly one signature whosekeyidequals 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. Verify policy agreement, capability, anchor. Confirm
server_a_verdict.verdict == server_b_verdict.verdictand thatjoint_dispositionagrees. Resolvecapability_lease_ref, confirm issuer match and non-expiry. Fortotally-orderedsteps, reconcile the consistency anchor (parent-hash chain or chio-anchor epoch) with the auditor’s view; forquorum-requiredsteps, 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.