SSH authentication

Guardian and co-guardian SSH keys are optional. They add a cryptographic signature to the accepted → roadmap transition.

The important distinction:

  • comparing a public key with a stored key is identification, not authentication;
  • a signature over a fresh nonce proves possession of the private key;
  • mdBoard stores only the public key and fingerprint; it never stores a private key.

When the gate is active

Configuration Roadmap transition
No guardian or co-guardian key Allowed; low-security hint
At least one key Requires a valid challenge signature
Malformed key Fails closed

First-time setup

The simplest path is during init:

mdboard init . --ssh-key ~/.ssh/id_ed25519.pub

Or add a key later:

mdboard --actor agent guardian ssh-add \
  --email guardian@example.com \
  --key ~/.ssh/id_ed25519.pub \
  --authorised-by guardian \
  --authorization "Add my guardian SSH key."

Show configured keys:

mdboard guardian ssh-show

Remove a key:

mdboard --actor agent guardian ssh-remove \
  --email guardian@example.com \
  --authorised-by guardian \
  --authorization "Remove the guardian SSH key."

Removing the last key disables the gate.

Sign a roadmap transition

Create a challenge for the card:

mdboard --actor agent guardian ssh-challenge '#0042'

It prints a nonce. Save the nonce exactly:

printf '%s' '<nonce>' > /tmp/mdboard-nonce

Sign it with the private key:

ssh-keygen -Y sign -f ~/.ssh/id_ed25519 -n mdboard /tmp/mdboard-nonce

Verify and record:

mdboard --actor agent guardian ssh-verify '#0042' \
  --nonce '<nonce>' \
  --signature /tmp/mdboard-nonce.sig \
  --email guardian@example.com

Then roadmap the card:

mdboard --actor agent roadmap '#0042' \
  --authorised-by guardian \
  --authorization "Roadmap with a signed guardian transition."

What is audited

  • Challenge creation.
  • Successful verification: signer e-mail, fingerprint and nonce.
  • Failed verification: the error is returned; no verification event is written.
  • Key changes: the config change and its owner authorisation.

Failure modes

Failure Result
No nonce or unknown nonce Rejected
Reused nonce Rejected
Invalid or missing signature Rejected
No key for the signer Rejected
Malformed configured key Fails closed
ssh-keygen unavailable Rejected with an error

Low-security mode

When no key is configured, the project still works. The agent should warn the guardian once per pitch session:

  • the roadmap commitment is authenticated only by chat authorisation;
  • adding an SSH key makes the transition require proof of private-key possession;
  • this is optional, not a gate that blocks existing projects.

Limits

  • One key per guardian or co-guardian; replacing it is rotation.
  • Keys live in mdboard.toml, which is owner-only.
  • A signature proves possession of the private key, not the human’s legal identity.
  • This is identification plus a fresh signature, layered on the existing human authorisation.