Skip to content

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 19 Jun 17:57
fbf3ee4

Fixed

  • SSH_CA_VAULT_ALLOWED_USERS / SSH_CA_VAULT_ALLOWED_HOST_DOMAINS
    now actually take effect from .env.prod.
    The prod overlay
    hardcoded a small env block on bootstrap-substrate and didn't
    forward the SSH-CA role allowlists, so an operator extending
    SSH_CA_VAULT_ALLOWED_USERS to add a custom login account (e.g.
    justinfudally) saw their edit silently ignored — Compose's
    --env-file only loads values for YAML interpolation, not for
    container env. Vault then kept refusing to sign user certs with
    the new principal at client provision time
    (<user> is not a valid value for valid_principals).
    Adds the passthrough in docker-compose.prod.yml (mirroring the
    existing DEFAULT_SUBNET shape), the example entry in
    .env.prod.example, and a regression test in
    tests/test_compose_prod_bootstrap.py so a future env-block
    cleanup can't quietly regress this.

Changed

  • Register-server flow can now bootstrap the host in the same
    task.
    Replaces the standalone "Bootstrap host" dashboard action
    and POST /bootstrap-host endpoint that shipped in v0.3.x with
    a collapsible "Bootstrap this host first" section inside the
    Register-server form. When the operator pastes their OOB SSH
    private key there, provision_server_task opens one
    BootstrapSSHRunner session (TOFU + operator key) before the
    regular CA-mode provision session, laying down the SSH CA trust

    • signed host cert + sshd drop-in. One row, one task, one click
      for fresh boxes; same behaviour as today when the box was
      already bootstrapped (CLI path, baked AMI).
    • ServerCreate schema (src/wg_manager/schemas.py) gains
      optional bootstrap_ssh_key_pem + bootstrap_ssh_key_passphrase
      fields. POST /servers encrypts both via the crypto backend
      (Vault Transit in prod) before queueing and forwards the
      ciphertext to the task. Passphrase without PEM is rejected at
      the schema layer so the operator's intent isn't silently
      dropped.
    • provision_server_task (src/wg_manager/tasks.py) accepts
      the new encrypted-bootstrap kwargs, decrypts in worker memory,
      and runs bootstrap_host() before opening the CA-mode session.
      The bootstrap step is skipped entirely when no PEM was supplied;
      today's "you forgot to bootstrap" failure mode
      (host cert signed by an untrusted CA) is preserved verbatim.
    • Dashboard /servers (web/app/servers/page.tsx) drops the
      standalone "Bootstrap host" button; the bootstrap section now
      lives inside the Register form behind a <details> toggle,
      defaulting collapsed so the common (already-bootstrapped) case
      stays one click.
    • Removed: POST /bootstrap-host, bootstrap_host_task,
      BootstrapHostRequest / BootstrapHostResponse schemas,
      api.bootstrapHost() client method, and the matching tests.
      The CLI (wg-manager bootstrap-host) still exists for
      scripted/CI use that wants the install separate from
      registration.
    • Docs: docs/deploy/single-host-prod.md updates "Path A —
      Dashboard" to describe the combined Register-with-bootstrap
      flow; Path B (CLI) is unchanged.

Published images

  • ghcr.io/jfudally/wg_manager:v0.4.0 — API + worker
  • ghcr.io/jfudally/wg_manager-web:v0.4.0 — dashboard

Pull either with a granularity-appropriate tag (vX.Y.Z, vX.Y, vX, or latest).

Supply-chain attestation

Both images are signed via cosign keyless OIDC and carry an
in-toto CycloneDX SBOM attestation. Verify with:

cosign verify \
    --certificate-identity-regexp \
        'https://github.com/jfudally/wg_manager/.github/workflows/release.yml@.*' \
    --certificate-oidc-issuer \
        'https://token.actions.githubusercontent.com' \
    ghcr.io/jfudally/wg_manager:v0.4.0

The SBOMs are also attached as release assets:

  • sbom-api.cdx.json — CycloneDX SBOM of the API + worker image's Python deps
  • sbom-web.cdx.json — CycloneDX SBOM of the dashboard image's Node deps