Signed Tickets
A signed ticket is an OpenSSH-signed authorization payload that ASF50 uses to gate high-stakes production operations. The design is offline-friendly: the owner signs on their workstation, the orchestrator verifies, and the private key never enters the ASF50 repository, runtime, evidence, chat, or documentation.
Deterministic payload
A signed ticket payload has the following canonical fields:
{
"ticket_id": "<uuid>",
"gate_id": "<uuid>",
"goal_id": "<GOAL_ID>",
"subject_sha": "<40-char commit SHA>",
"production_target": "<environment name or identifier>",
"issuer": "<human principal name>",
"namespace": "<namespace>",
"payload_digest": "<hex digest of the payload being authorized>",
"created_at": "<UTC ISO-8601>"
}
The payload_digest binds the ticket to the exact bytes of the operation payload (e.g., the production manifest). Changing a single byte invalidates the signature.
Trust model
The owner maintains an owner public trust file at agent-harness/governance/allowed_signers (one line per principal). The matching owner private key lives only on the owner's workstation — never in the repo. The orchestrator verifies with ssh-keygen -Y verify:
ssh-keygen -Y verify \
-f agent-harness/governance/allowed_signers \
-I <issuer> \
-n <namespace> \
-s <signature-file>
If verification succeeds against the principal in allowed_signers, the ticket is considered authentic.
Replay protection
Tickets are single-use. After the orchestrator consumes a ticket, the gate transitions to APPROVED. A second submission of the same ticket_id is rejected with a replay error.
Subject binding
The ticket's subject_sha must match the runtime's observed HEAD. A ticket signed for SHA abc123 is rejected if the runtime is at def456. This is the canonical stale-subject rejection.
What the private key is NOT
- It is not in the ASF50 repo.
- It is not in the runtime DB or
evidence/. - It is not in chat history.
- It is not in this documentation.
If you see a private key anywhere in the canonical ASF50 repository, that is a security incident. Open a REPAIR_GOAL and revoke the key immediately.
See Signed-Ticket Guide for the operator walkthrough.