Skip to content

R5: relay enrolment — 'beacon gen-csr' (CSR-over-SSH)#4

Merged
bodaay merged 2 commits into
mainfrom
feat/r5-relay-enrollment
May 19, 2026
Merged

R5: relay enrolment — 'beacon gen-csr' (CSR-over-SSH)#4
bodaay merged 2 commits into
mainfrom
feat/r5-relay-enrollment

Conversation

@bodaay

@bodaay bodaay commented May 19, 2026

Copy link
Copy Markdown
Contributor

beacon milestone R5 — relay enrolment

Implements beacon's side of helm's published relay-enrolment contract
(helm/BUILD.md, "Relay enrollment contract"; DESIGN §5, decision 14 —
CSR-over-SSH, no bootstrap token). Mirrors buoy's node onboarding.

beacon gen-csr

  • internal/pki.GenerateCSR generates the relay's ECDSA P-256 keypair
    on the host — the private key is written 0600 to relay.key
    and never leaves the host. Idempotent: a retried enrolment reuses the
    existing key rather than orphaning it.
  • Emits a plain PKCS#10 CSR — public key only. It asserts no
    Organization and no SANs: helm is the sole authority on relay
    identity and overrides them when it signs off the Fleet CA
    (O="PharosVPN Relay", dual ServerAuth+ClientAuth EKU, public-endpoint
    DNS SAN). A relay host must not self-assert the delegation marker.
  • CSR → stdout (helm captures it over SSH); diagnostics → stderr.

Command surface (helm's relay-deploy invokes these)

Command Behaviour
beacon gen-csr [--config-dir] generate the keypair, print a CSR
beacon run --config-dir /etc/beacon run the relay (systemd ExecStart)
beacon version print the version

After signing, helm pushes back relay.crt, fleet-ca.crt and
device-ca.crt — exactly the files beacon run already loads from the
config dir, alongside the gen-csr-written relay.key.

Also

  • Corrects beacon/BUILD.md's stale R5 line ("bootstrap token" →
    CSR-over-SSH, decision 14) and updates the README status.

Quality

gofmt / go vet / go test -race / golangci-lint all clean; new
unit tests cover key generation, idempotency, the plain-subject
guarantee, and corrupt-key handling. Zero origin-project trace.

Next and last: R6 — static-binary packaging + deploy docs.

bodaay added 2 commits May 19, 2026 23:40
Implements beacon R5 against helm's published relay-enrolment contract
(helm/BUILD.md, "Relay enrollment contract"; DESIGN §5, decision 14 —
CSR-over-SSH, no bootstrap token). Mirrors buoy's node onboarding.

- internal/pki.GenerateCSR generates the relay's ECDSA P-256 keypair
  on the host (key written 0600, never leaves the host) and emits a
  plain PKCS#10 CSR carrying only the public key. Idempotent — an
  existing key is reused so a retried enrolment never orphans it.
- The CSR deliberately asserts no Organization and no SANs: helm is the
  sole authority on relay identity and overrides them at signing time
  (O="PharosVPN Relay", dual ServerAuth+ClientAuth EKU, public-endpoint
  DNS SAN). A relay host must not self-assert the delegation marker.
- `beacon gen-csr [--config-dir]` prints the CSR to stdout (helm
  captures it over SSH) and diagnostics to stderr.

helm then pushes back relay.crt, fleet-ca.crt and device-ca.crt — the
files `beacon run` already loads from the config dir.

Signed-off-by: Khalefa <Khalefa@alahmad.org>
beacon/BUILD.md R5 still described a "bootstrap token" — superseded by
DESIGN decision 14 (CSR-over-SSH, no token). Correct the milestone line
and update the README status now that gen-csr enrolment is built.

Signed-off-by: Khalefa <Khalefa@alahmad.org>
@bodaay bodaay merged commit ec17968 into main May 19, 2026
1 of 2 checks passed
@bodaay bodaay deleted the feat/r5-relay-enrollment branch May 19, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant