From 11ce2a8672f350eb36ae1595f1591bebff48681f Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 30 Jun 2026 16:22:46 +0000 Subject: [PATCH] fix(bootstrap): define CODER_ADMIN_* on coder-init-admin, not coder.service Move the admin bootstrap credentials (CODER_ADMIN_EMAIL/USERNAME/PASSWORD) out of the long-running coder.service environment and onto the coder-init-admin.service (and its dependent coder-reset.service), so they are only present where the bootstrap actually needs them. coder-init-admin and coder-reset still inherit coder.service's environment for CODER_PG_CONNECTION_URL; the admin creds are merged in via systemd.services.coder-init-admin.environment in local.nix. GitHub OAuth vars remain on coder.service since the server reads them. Refs https://github.com/coder/box/issues/29 --- configuration.nix | 22 ++++++++++++++++------ hosts/incus-vm/README.md | 2 +- local.nix.example | 26 ++++++++++++++++---------- nixos/_images/box-turnkey.nix | 8 +++++--- 4 files changed, 38 insertions(+), 20 deletions(-) diff --git a/configuration.nix b/configuration.nix index b41136b..3b4fe14 100644 --- a/configuration.nix +++ b/configuration.nix @@ -489,8 +489,11 @@ in programs.git.config.safe.directory = [ "/etc/nixos-repo" ]; # ── Coder server ────────────────────────────────────────────────────────── - # Base env vars live here. Secrets (admin creds, OAuth, etc.) are merged in - # via systemd.services.coder.environment in hosts//local.nix; no EnvironmentFile. + # Base env vars live here. Server secrets (e.g. OAuth) are merged in via + # systemd.services.coder.environment in hosts//local.nix; no + # EnvironmentFile. Admin bootstrap creds (CODER_ADMIN_*) are NOT set here — + # they live on coder-init-admin.service so they stay off the long-running + # server's environment. systemd.services.coder = { description = "Coder Server"; wantedBy = [ "multi-user.target" ]; @@ -538,7 +541,9 @@ in }; # ── Admin user bootstrap ────────────────────────────────────────────────── - # Reads CODER_ADMIN_* from coder.service environment (set via local.nix). + # Reads CODER_ADMIN_* from this service's own environment (set via + # local.nix as systemd.services.coder-init-admin.environment), keeping the + # admin credentials off the long-running coder.service. # Creates a local admin account once; sentinel prevents re-running. # If CODER_ADMIN_EMAIL is unset, skips and directs user to the browser wizard. systemd.services.coder-init-admin = { @@ -547,8 +552,10 @@ in after = [ "coder.service" ]; requires = [ "coder.service" ]; - # Inherit the full coder.service environment so CODER_ADMIN_* and - # CODER_PG_CONNECTION_URL are available without duplication. + # Inherit the coder.service environment so CODER_PG_CONNECTION_URL (and the + # other server vars) are available without duplication. The CODER_ADMIN_* + # credentials are merged in on top via the coder-init-admin.environment + # definition in hosts//local.nix (NixOS merges attrset options). inherit (config.systemd.services.coder) environment; serviceConfig = { @@ -687,7 +694,10 @@ in ]; requires = [ "postgresql.service" ]; - inherit (config.systemd.services.coder) environment; + # Step 8 mints a session token using CODER_ADMIN_EMAIL/PASSWORD, so pull in + # the coder-init-admin environment (which itself includes the coder.service + # vars plus the CODER_ADMIN_* credentials from local.nix). + inherit (config.systemd.services.coder-init-admin) environment; serviceConfig = { Type = "oneshot"; diff --git a/hosts/incus-vm/README.md b/hosts/incus-vm/README.md index 69a8c6d..4bd7580 100644 --- a/hosts/incus-vm/README.md +++ b/hosts/incus-vm/README.md @@ -148,7 +148,7 @@ Edit `hosts/$HOSTNAME/local.nix` and at minimum set: ```nix services.coder-nixos.lanIp = "192.168.x.x"; # VM's primary IP -systemd.services.coder.environment = { +systemd.services.coder-init-admin.environment = { CODER_ADMIN_EMAIL = "you@example.com"; CODER_ADMIN_USERNAME = "admin"; CODER_ADMIN_PASSWORD = "changeme"; diff --git a/local.nix.example b/local.nix.example index 8070069..e85fbbb 100644 --- a/local.nix.example +++ b/local.nix.example @@ -31,21 +31,27 @@ in # Use the email address linked to your GitHub account so that OAuth login # merges into this admin account automatically. # Skipped if CODER_ADMIN_EMAIL is empty (complete the wizard in the browser instead). - systemd.services.coder.environment = { + # + # These credentials live on coder-init-admin.service (the bootstrap service), + # NOT coder.service, so they stay out of the long-running server's environment. + systemd.services.coder-init-admin.environment = { CODER_ADMIN_EMAIL = "you@example.com"; # change this CODER_ADMIN_USERNAME = "admin"; CODER_ADMIN_PASSWORD = "changeme"; # change this - - # ── GitHub OAuth (optional) ────────────────────────────────────────────── - # Leave this block commented out to use the built-in Coder GitHub App. - # CODER_OAUTH2_GITHUB_CLIENT_ID = ""; - # CODER_OAUTH2_GITHUB_CLIENT_SECRET = ""; - # CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS = "true"; - # CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE = "false"; - # CODER_OAUTH2_GITHUB_ALLOW_EVERYONE = "true"; - # CODER_OAUTH2_GITHUB_ALLOWED_ORGS = "my-org"; }; + # ── GitHub OAuth (optional) ──────────────────────────────────────────────── + # Read by the long-running coder.service. Leave this block commented out to + # use the built-in Coder GitHub App. + # systemd.services.coder.environment = { + # CODER_OAUTH2_GITHUB_CLIENT_ID = ""; + # CODER_OAUTH2_GITHUB_CLIENT_SECRET = ""; + # CODER_OAUTH2_GITHUB_ALLOW_SIGNUPS = "true"; + # CODER_OAUTH2_GITHUB_DEFAULT_PROVIDER_ENABLE = "false"; + # CODER_OAUTH2_GITHUB_ALLOW_EVERYONE = "true"; + # CODER_OAUTH2_GITHUB_ALLOWED_ORGS = "my-org"; + # }; + # ── Desktop / OS login account ───────────────────────────────────────────── # SDDM / SSH login. Change with `passwd ${nixosUsername}` after first boot; # initialPassword only fires on user creation. diff --git a/nixos/_images/box-turnkey.nix b/nixos/_images/box-turnkey.nix index af27caf..9284bae 100644 --- a/nixos/_images/box-turnkey.nix +++ b/nixos/_images/box-turnkey.nix @@ -224,11 +224,13 @@ in initialPassword = "PleaseChangeMe1234"; }; - # coder-init-admin.service reads CODER_ADMIN_* from coder.service's + # coder-init-admin.service reads CODER_ADMIN_* from its own service # environment and creates a local admin on first boot, then mints a session # token and deploys the templates from /etc/nixos-repo/coderd. With these set - # the Coder instance is ready to use immediately. - systemd.services.coder.environment = { + # the Coder instance is ready to use immediately. These admin credentials are + # only needed by the bootstrap service, so they are kept off the long-running + # coder.service environment. + systemd.services.coder-init-admin.environment = { CODER_ADMIN_EMAIL = "admin@coder.com"; CODER_ADMIN_USERNAME = "admin"; CODER_ADMIN_PASSWORD = "PleaseChangeMe1234";