AuthBox documentation — Scenarios

Documentation embedded in this build.

SSH access to your hosts and your cluster's nodes

What it is for

Who may log in to which machine, and as which account, is decided by the same policy as everything else here — the same people, the same groups, the same missions — and not by a list of keys copied onto each server. Nobody's key is ever copied anywhere: each person keeps one, and what they present is a certificate that expires in hours and is renewed while they work. A lost laptop is a non-event, because what was on it stops working this afternoon whether or not anyone reported it.

One person holding a single key asks AuthBox, which reads the same groups and missions as everything else and works out which accounts they may use; the certificate it returns expires in hours and is renewed while they work; it opens the deploy account on two servers and the node-admin account on a cluster node, each of which needed only two lines added to the configuration it already had, and the root account is refused

And the login that must not be possible is proven not to be possible: for every account a machine can offer, this repository generates the case of a person who does not qualify and proves the certificate they are issued does not name that account — and a subject who qualifies for nothing is issued nothing at all, never a certificate with an empty list. A worked scenario then has a real sshd refuse exactly that login.

Your servers need no software from us — two lines in the configuration they already have. Your cluster's nodes are included the same way, and proven on a real one: an administrator lands on the node as an ordinary account that can see it, and becoming the superuser is a separate grant with its own mission and its own course — never one account under two names.

And the session can come in through the same front door as everything else here: the door checks who is calling against the same policy before a byte of SSH is read, writes its decision down as a receipt, and passes the bytes through without opening them — the session stays under SSH's own keys, and the machine still decides the account from the certificate. Or the door is the jump host itself: the one flag every SSH client already has, with nothing of ours on the laptop, and each channel decided and receipted by name before it opens. Two decisions by two engines, and neither can grant what the other refused.

This is not a session recorder, or an agent on your servers. Nothing of ours runs there; and the door, as a path or as the jump host, never opens the session — it decides who may reach which host, writes that down, and carries the bytes.

The topology

One person, one key, and a certificate that names the accounts their standing earned.

   PERSON                AUTHBOX                     MACHINES
   one key   --asks-->   reads the same groups   --> deploy@server-1   (allowed)
                         and missions as             deploy@server-2   (allowed)
                         everything else             node-admin@node   (allowed)
                                                     superuser@server  (refused)
             <--cert--   expires in hours,
                         renewed while they work

   each machine: two lines added to the configuration it already had
   optionally:   the same front door in the path, or as the jump host itself

Stand it up

$ make scenario-ssh-fleet     # a real sshd, three people, one refused login — then the
                              # same fleet through the front door
$ make kind-node-access       # the same thing on a cluster's nodes

In your own deployment the client side is one of:

# in ssh_config: the session rides the door's mutual TLS
ProxyCommand authboxclient ssh-proxy -door door.example:8443 -sni ssh.%h

# or the door is the jump host, and no ssh_config line is needed
ssh -J door.example:2222 deploy@web-3

Two lines on each machine, one line in your ssh_config for the door or none with the jump flag, one revocation list, and nothing installed.

What the smoke proves

make scenario-ssh-fleet runs the Go twin TestSSHFleet against two machines running a stock sshd from a pinned upstream image, configured with nothing but the files AuthBox publishes, and three people: one who may log in as the deploy account, one who may log in as the superuser, and one who earns no login name at all. The unit tiers check the certificate's octets against fixtures OpenSSH itself produced, check that the names on an issued certificate are exactly what the engine allowed, and generate the subject who must not receive the superuser account. None of them runs an sshd. This scenario is what is left over: the published file is one a real sshd reads as its trusted authority list, a certificate this deployment signed authenticates as the name it carries and is refused as the name it does not.

The same scenario then runs the fleet through the front door and through the jump host: one caller refused at the door, one refused at the host — two engines, neither able to grant what the other refused.

make kind-node-access runs TestNodeAccessOnKind against a real cluster node: the administrator lands as an ordinary account, and becoming the superuser is its own grant.

Read on