Documentation embedded in this build.
A machine for a mission
In short
For a team that needs somewhere to work for the length of a mission. Pick a server type on the mission, and the controller stands up a machine only that mission's members can log in to, through the front door, with the card's key. When the mission ends, the machine goes.
What it is for
A mission already says who is in it and for how long. This scenario adds one field to it: a server. Pick devbox on the mission's form and a moment later there is a Linux machine with a shell and the usual tools. Pick transfer and it is the same machine with file transfer only. Nobody writes an account, a key or a firewall rule. The members log in with the certificate the box issues for their card's key, and nobody else gets past the front door. When the mission is closed or its end date passes, the machine is stopped at once and removed.
The mission's files are not on the machine. They live on the mission's shelf in the object store, and the machine keeps a read-only copy at /srv/mission, fetched with its own credential through the same door. Lose the machine and nothing is lost. On a shelf at a sealed level the copy is ciphertext beside a sidecar naming its marking: the machine cannot read it, and a member opens it on their own computer with their own credential.
A website, not a shell
Two more types are reached in a browser rather than over SSH. Pick site and the mission gets a cover site: an ordinary small business's pages, fictional and saying so, with a Contact us form. Anyone can visit it without a certificate. Each message sent through the form lands on the mission's shelf, sealed at the mission's level the moment it arrives, so the site that received it cannot read it. At /desk, a member presenting their certificate sees the messages and downloads each one to open with their own credential; anybody else at that address sees the same page as any address that does not exist.
Pick records and the mission gets the classified-records application, unchanged, behind the front door: a member is handed each record their standing covers and refused the rest, and a person outside the mission is refused at the door. Both kinds of server get their certificates from the box when they start, and are gone with the mission.
Four more server types
Pick service and the mission gets a small workload whose certificate comes from the box and renews itself, with one page showing the certificate it is serving and when it renews next. Pick stream and a source writes labeled records down one connection to the front door, which hands each record to the two destinations allowed it and to no other; the page shows which destination got which record. Pick jump and the mission gets its own bastion with two machines behind it, reached with plain ssh -J. Pick range:box and a whole evaluation box stands up as the mission's practice deployment, its console reached through the door. Each is for the mission's members alone, and each is gone with the mission.
The topology
The box, the front door, the store, the controller that stands servers up, and the member's own computer.
MEMBER'S COMPUTER DOOR SERVERS
card's key --- ssh, by name ---> <slug>.ssh.<domain> -----> <slug>.servers.<domain>:22
ssh certificate admits the mission's sshd: account member,
(the mission's slug) members, refuses the rest principal <slug>
with a receipt ^
AUTHBOX (writer) -- signed bundle --> CONTROLLER -- Docker -----------+
issues the certificates reads the missions,
and the server's identity stands up and removes
Stand it up
The controller is a companion like the store: chosen on the first boot's Choose step, its file written beside the others, its image authboxus/authbox-controller and the server image authboxus/authbox-server-devbox. It needs the Docker socket on the host it runs on.
$ docker compose up -d controller
$ ssh -o ProxyCommand='authboxclient ssh-proxy -door door.example:8443 -sni %h' \
member@ops-red-cell.ssh.example
Between the two lines, author the mission on the console's missions desk and pick devbox under Server, or send the same mission to PUT /admin/v1/missions/{id} with "server": {"type": "devbox"}. The mission's page in the console shows the server's address and the line to type. The first boot writes the two profiles the servers need into the box's file.
On Kubernetes, choose the Kubernetes shape on the first boot. Its manifests add the controller's Deployment, a service account and a Role over four kinds in its own namespace, and nothing cluster-wide. Each server is then a pod, reached by the door inside the cluster.
$ kubectl apply -f authbox-controller-k8s.yaml
$ kubectl -n authbox get deployments -l authbox.managed-by=authbox-controller
The controller's runbook says what the Role allows and how a server is named in the cluster.
What the smoke proves
The administrator authors three missions through the admin API: a devbox and a cover site at SECRET, and a records box at CONFIDENTIAL. The controller writes each server's entity and its single-use invitations, and the containers come up; the devbox spends its invitations on its host certificate and its own credential and holds none afterwards. A member files three documents into the sealed shelf and one into an unsealed one, which reads back in the clear; the store's disk holds the sealed ones as ciphertext beside their sidecars.
The member's agent gets an SSH certificate for the card's key by possession, carrying the mission's slug, and the member logs in through the door with no prompt. On the server the documents are ciphertext beside sidecars naming SECRET, and authboxclient open says the machine holds no credential; on the member's own computer, after scp through the door, it opens the document with the key access service's grant on its chain, and a person cleared to CONFIDENTIAL is refused with that refusal on the chain too.
The cover site answers a visitor with no certificate on a certificate the box issued by ACME, and a message sent through its form lands sealed on its mission's shelf. Its desk is an unknown page to a visitor with no certificate, is refused at the door with a receipt for the devbox mission's member, and lists the message for its own member as ciphertext. The records box releases a CONFIDENTIAL record to its member, refuses a SECRET one, and refuses an outsider at the door.
The devbox mission is closed: the controller stops and removes the container, the member's next login is refused at the door, and the controller's chain, handed up to the box, holds the ensure, stop and remove rows.
The same on kind
The same mission stands up a Deployment, a Secret and the shared Service; the Secret is gone once the pod is ready, the server's credential is on the box's ledger, the member logs in through the door to the pod, a stranger is refused, and the close removes both. The workload and the records box are proved on kind too, each pod's certificate from the box for its own name. The shelf, the cover site, the feed, the bastion and the range are proved on compose only.
The four more types
Four more missions follow. The workload's page shows a certificate the box issued for its name and, after the box restarts, a renewed serial on the same account. The feed's two destinations are given different records, each decided on its own label, and a source outside the mission is refused at the door. The member jumps through the bastion to both machines with one certificate, and a person from another mission is refused there. The range's console answers the member and refuses a stranger. All four close, and every machine goes with them.
Read on
- The controller's runbook: the catalog, the two drivers, the socket and the Role, the web types, the grace, and the failures that happen.
- Store files by mission: opening a sealed file with
authboxclient open. - SSH with AuthBox: the address and the one line a member types.
- Your computer's credential as a card: the card the member logs in with.