AuthBox

Documentation embedded in this build.

A federation across organizations

In short

Organizations that must work together without merging directories: each keeps its own authority and issues its own certificates. Records carry the origin they came from, trusting a partner's certificates for the handshake never means adopting its data, and an authority that goes quiet stops conferring anything.

What it is for

Headquarters, a region and a partner lab: three organizations that have to work together and cannot merge their directories, because none of them will hand the others the keys to its own people. Each keeps its own authority and issues its own certificates.

A chain of authorities: headquarters publishes a signed bundle to a region, which republishes to an enclave, and every bundle carries an origin mark; a side lab on the other diagonal keeps its own authority, with its root appended to the trust pool rather than its data adopted

Records carry the origin they came from, so nobody is asked to believe a record without knowing whose it is, and trusting a partner's certificates for the handshake never means adopting the partner's data. A lapse anywhere is visible rather than silent: when one authority goes quiet, what it published stops conferring anything past its budget, and the console names which authority went stale and when.

This is not one directory with tenants in it. Each authority is its own box.

The topology

A chain of authorities, and one peer beside it that is trusted for the handshake only.

   HQ  --signed bundle-->  REGION  --republished-->  ENCLAVE
   own authority           own authority            own authority
                           carries HQ's records     carries both,
                           with HQ's origin         origins intact

   SIDE LAB                (on the other diagonal)
   own authority  --root appended to the trust pool-->  the handshake only
                    its DATA is never adopted

Every bundle carries an origin mark that survives each hop, and every hop has a freshness budget of its own.

Stand it up

Two organizations that trust each other: each keeps its own authority, and a signed bundle carries one's people to the other, where they are decided.org Aorg Bdecided here
$ docker run --rm authboxus/authbox-eval -evaluate -scenario federation -print docker | sh
$ docker logs writer

Two organizations that trust each other, each with its own certificate authority and its own first boot, on one volume. The second (peer, its console on port 8453) publishes a signed authority bundle; the first (writer) adopts it, appends the second's root to its client trust, and decides for a person the second organization issued. With the evaluation image, import eval-peer-admin.p12 from the peer's credentials page and ask the writer who you are. The evaluation runbook says what each container is and how it ends.

What the smoke proves

The evaluation's own proof runs the printed recipe from the built image: the writer reports itself ready only once the adopted authority is fresh, names the peer synced, and answers a person the PEER issued as a person under the peer's root, cleared by the adopted record.

The worked federation's first smoke is the cascade, and it is the federation's whole claim in one act: a record made live at headquarters through a door with no published port is drawn by the proxied console two hops away, with its provenance. Then, in order: a partner's credential refused at an edge whose trust pool does not hold the partner's root; two hierarchy models; a revocation list that reaches a container and comes into force on restart, with the responder answering on its published port; the authority lens, naming every authority and how fresh it is; and the blast radius, which pauses one box and shows two readiness ports answering differently — the center reports itself stale, the edge stays ready. The narrowness is the point being proved. The same composition is translated to Kubernetes manifests, applied in waves, and run through the same phases, so the chain is not a property of compose.

Read on