Where this is
Console origin · API · RP id .
Served from barycenters.ai. CORS limits which browser origins can read the API response;
the real guarantee is server-side — every assertion is refused unless its signed clientData.origin
and RP id match this console. So this page must stay served here, and your key is registered against this exact RP id.
1 · Register a hardware key
Enroll each YubiKey (primary, then a backup). Backup-eligible / synced passkeys are refused server-side — hardware only.
Re-tapping an already-enrolled key is rejected, so a "backup" can't secretly be the same device.
The first key is one tap. Each backup is two taps: the new key, then an
already-enrolled key to authorize it — a stranger who reaches this page still cannot enroll their own key.
A charter maps kid → one credential: enroll the backup under a distinct kid
(e.g. steward-dami-2). Re-enrolling as a second kid adds a row — it does not
remove the old same-kid enrollment. Unenroll the stale row here (tap a remaining key to
authorize). Two keys sharing steward-dami cannot both be stewards.
ready.
loading enrolled keys…
2 · Sign a packet — legacy provenance (grants no release authority)
This grants NO release authority — do not tap it expecting to arm a release.
A valid tap here proves a steward key was physically present over this exact packet and that the encoding
verifies — provenance, nothing more. The resulting afterburner_trust_root_v1.json stays
HOLD and never opens V1 or V2 (afterburner_trust_root_provisioner_v1 says so in its
own docstring). Real release-signing is a separate, raw-byte-pinned V2 registry, and that gate is deliberately
fail-closed (HOLD) today — so release authority is not armed on any path.
Paste a provisioning request produced offline by
app/afterburner_trust_root_provisioner_v1.build_provisioning_packet(...) — shape
{"keys":{kid:pubkey}, "packet":{...}}. The packet's keys_hash is computed in Python
(canon-v1 authoritative); this page never re-hashes it. You'll see exactly what the tap grants before
you tap. The output is the exact proofs/afterburner_trust_root_v1.json — a provenance record,
committable but non-authoritative.
Confirm before you tap — this is what your key will authorize
ready.
Before committing the output: set AFTERBURNER_STEWARD_WEBAUTHN_ANCHOR to your pinned
steward credential and run python -c "from pathlib import Path; from app.afterburner_envelope_verifier_v1
import load_trust_root; print(load_trust_root(Path('.')))" — it must return your keys, not {}.
That closes the loop this page cannot: it proves the encoding verifies.
3 · Sign a governance boundary — a real hardware signature, then submit it
A pack is law text. POST /v1/packs/{id}/instantiate returns unsigned
candidates — prep, not a bind. This tap is the gavel: it produces a genuine
SignedQuorumBinding, then this page POSTs it to
/v1/boundaries and shows the live detail. Instantiating does not
mark a pack proven_in_production. Default packet A is
barycenters.ci.merge_to_main. Both Option B kids are named (quorum 1 — either
key). A packet listing only steward-dami refuses a steward-dami-2 tap.
Confirm before you tap — this is the boundary your key will bind
ready.
The signed output binds nothing on its own (authority_effect = 0).
This page submits it: POST /v1/boundaries persists a hardware-signed binding for
an already-chartered namespace. Fail-closed stays fail-closed — unsigned, forged, or a packet
whose steward set is not the charter's kids is refused, and the live detail is
shown here. After a successful bind, GET /v1/namespaces/{ns} lists the binding in
bound_boundaries. A pack instantiate is not that list.
4 · Charter a namespace — genesis (your enrolled keys become its stewards)
This is the authority root. Name a namespace to claim; the server composes a genesis charter
from every enrolled hardware key with a distinct kid — it reads the enrolled
keys directly (the browser has no read path to the cose_key, by design), so the charter embeds
exactly the keys that may tap. Quorum 1 means either key governs; losing one is survivable.
Two keys under the same kid are refused: unenroll the stale same-kid row in Section 1
(do not guess, do not drop a key). An explicit credentialId still charters a single
key — tonight's fallback if the collision is still live. Your tap self-signs the genesis;
submitting it to POST /v1/namespaces is the one human authority act. The registrar
enforces embedded == enrolled.
Confirm before you tap — this genesis binds the namespace to your key
ready.
Register keys in step 1 first (backup = a second kid). The charter is composed
from your ENROLLED keys and self-signed by one tap (quorum 1); it binds only when you submit it
here (authority_effect = 0 until then). Quorum 1 with two distinct-kid keys is
resilient governance — either key can still move the namespace if the other is lost. Raise the
quorum when you want a boundary no single hand can shift.