Install the guard's key with its restriction attached, in one step #5

Merged
branderson merged 1 commits from install-key into main 2026-08-28 17:54:38 -07:00
Collaborator

Summary generated by LLM agent

Asked for as an ssh-copy-id call. It cannot be one, and the reason is the point of the whole step.

ssh-copy-id would undo the restriction

It copies the bare key, with no options. The line this needs is:

command="/usr/local/sbin/dejima-guard-shell",no-port-forwarding,no-agent-forwarding,no-pty,no-X11-forwarding ssh-ed25519 AAAA...

A bare key there is a shell on the devbox for whoever eventually takes this machine — which is the machine holding the baseline and the history of what changed, so it is a machine somebody wanting to erase that evidence would want. ssh-copy-id has no way to attach a forced command.

Doing it by hand is the alternative and has a gap in it: copy the key, then edit authorized_keys to add the restriction, with an unrestricted key live in between.

So: bin/dejima-guard-install-key

Does what ssh-copy-id does, with the restriction attached, in a single append. There is no moment where the file holds a bare key.

It connects as the operator, with their own credentials — the guard's key is what it installs, not what it uses.

Then it proves the restriction. The runbook previously asked for four commands to be run by hand and the results read. Most people run the two that should work. This runs all four and reports the two that matter, saying which side is broken: the guard cannot collect, or the key is worth more than it should be.

Idempotent, and it refuses rather than duplicating when the key is already present with different options. Two entries for one key is worse than either, because whichever ssh matches first wins and it will not be the one the operator expects.

Found while testing it

if ! cmd; then rc=$?

$? there is the status of the negation, which is zero whenever the branch is taken. So the specific "already there without the restriction" message could never fire, and every failure produced the same generic line. Fixed by capturing the status without inverting.

Tested

bats test/ — 41 passing, 8 new:

  • the installed line carries the forced command;
  • it strips port forwarding, agent forwarding, pty and X11;
  • the key is never written without its restriction — one line, not a bare key;
  • running twice adds no second entry;
  • a key already there unrestricted is refused, not duplicated;
  • .ssh is created 700;
  • a file that is not a public key is refused before anything connects;
  • the restriction still matches what dejima-devbox-hardener documents.

The ssh stub runs the remote script locally, so what is under test is the script this sends rather than whether this machine can reach a devbox.

Depends on

dejima-devbox-hardener#22, which ships dejima-guard-shell and the sudoers rule. Without those the four checks fail and say so — which is the right failure, but it means that branch has to be applied to the devbox first.

**Summary generated by LLM agent** Asked for as an `ssh-copy-id` call. It cannot be one, and the reason is the point of the whole step. ## `ssh-copy-id` would undo the restriction It copies the **bare** key, with no options. The line this needs is: ``` command="/usr/local/sbin/dejima-guard-shell",no-port-forwarding,no-agent-forwarding,no-pty,no-X11-forwarding ssh-ed25519 AAAA... ``` A bare key there is a shell on the devbox for whoever eventually takes *this* machine — which is the machine holding the baseline and the history of what changed, so it is a machine somebody wanting to erase that evidence would want. `ssh-copy-id` has no way to attach a forced command. Doing it by hand is the alternative and has a gap in it: copy the key, then edit `authorized_keys` to add the restriction, with an **unrestricted key live in between**. ## So: `bin/dejima-guard-install-key` Does what `ssh-copy-id` does, with the restriction attached, in a **single append**. There is no moment where the file holds a bare key. It connects **as the operator**, with their own credentials — the guard's key is what it installs, not what it uses. **Then it proves the restriction.** The runbook previously asked for four commands to be run by hand and the results read. Most people run the two that should work. This runs all four and reports the two that matter, saying which side is broken: the guard cannot collect, or the key is worth more than it should be. **Idempotent, and it refuses rather than duplicating** when the key is already present with different options. Two entries for one key is worse than either, because whichever ssh matches first wins and it will not be the one the operator expects. ## Found while testing it ```sh if ! cmd; then rc=$? ``` `$?` there is the status of the **negation**, which is zero whenever the branch is taken. So the specific "already there without the restriction" message could never fire, and every failure produced the same generic line. Fixed by capturing the status without inverting. ## Tested `bats test/` — 41 passing, 8 new: - the installed line carries the forced command; - it strips port forwarding, agent forwarding, pty and X11; - **the key is never written without its restriction** — one line, not a bare key; - running twice adds no second entry; - a key already there unrestricted is refused, not duplicated; - `.ssh` is created 700; - a file that is not a public key is refused before anything connects; - the restriction still matches what dejima-devbox-hardener documents. The `ssh` stub runs the remote script locally, so what is under test is the script this sends rather than whether this machine can reach a devbox. ## Depends on [dejima-devbox-hardener#22](https://gitbox.branderson.io/dejima/dejima-devbox-hardener/pulls/22), which ships `dejima-guard-shell` and the sudoers rule. Without those the four checks fail and say so — which is the right failure, but it means that branch has to be applied to the devbox first.
dejima-agent added 1 commit 2026-08-28 17:45:48 -07:00
Asked for as an ssh-copy-id call, and it cannot be one: ssh-copy-id copies
the bare key with no options. A bare key here is a shell on the devbox for
whoever eventually takes this machine - which is the machine holding the
evidence about that one.

Doing it by hand is the other option and has a gap in it: copy the key, then
edit authorized_keys to add the forced command, with an unrestricted key live
in between. dejima-guard-install-key writes the restricted line in a single
append, so there is no moment where the key exists without its restriction.

It connects as the operator, with their own credentials. The guard's key is
what it installs, not what it uses.

Then it proves the restriction, which the runbook previously asked the
operator to do by hand with four commands. Most people run the two that
should work. It runs all four and reports the two that matter - a restriction
nobody tried is a restriction nobody has - and says which side is broken:
whether the guard cannot collect, or the key is worth more than it should be.

Idempotent, and it REFUSES rather than duplicating when that key is already
present with different options. Two entries for one key is worse than either,
because whichever ssh matches first wins and it will not be the one the
operator expects.

Found while testing it: `if ! cmd; then rc=$?` reads the status of the
NEGATION, which is zero whenever the branch is taken - so the specific
"already there unrestricted" message could never fire and every failure
looked identical.

`bats test/` 41 passing, 8 new. The ssh stub runs the remote script locally,
so what is under test is the script this sends rather than whether this
machine can reach a devbox.
branderson approved these changes 2026-08-28 17:54:33 -07:00
branderson merged commit 28117389c6 into main 2026-08-28 17:54:38 -07:00
Sign in to join this conversation.