Skip to content

docs(adr): first-admin bootstrap strategy across environments (ADR 0001)#28

Closed
jlc488 wants to merge 1 commit into
mainfrom
docs/adr-bootstrap-admin
Closed

docs(adr): first-admin bootstrap strategy across environments (ADR 0001)#28
jlc488 wants to merge 1 commit into
mainfrom
docs/adr-bootstrap-admin

Conversation

@jlc488
Copy link
Copy Markdown
Contributor

@jlc488 jlc488 commented May 30, 2026

Design-only PR — no code yet. Opening this for sign-off before I implement.

This answers the question: how does a fresh devslab-kit deployment get its first administrator (so the dashboard is usable at all), without leaving a permanent backdoor, as the same jar moves local-dev → staging → production?

The decision in one paragraph

Bootstrap is property-driven and OFF by default (devslab.kit.bootstrap.enabled=false), so a no-config production deploy provisions nothing. When enabled, a blank password generates a random one logged exactly once (GitLab/Jenkins pattern) — a literal admin/admin only exists if the operator writes it, which is what a local profile does and a production config must not. The first admin is flagged must-change-password, so the dashboard forces rotation on first login before any other route is reachable. Profiles stay the consumer's mechanism for toggling these properties, never the kit's trigger.

Why not just @Profile("dev")

  • Profiles belong to the consumer (local/dev/development — inconsistent).
  • Profiles are on/off only — can't express "password injected?" / "forced-change on?".
  • A profile slip in prod = silent admin/admin backdoor.

Covered in the ADR

  • Per-environment config snippets (local / staging / prod, incl. the "don't auto-bootstrap, provision out-of-band" prod option).
  • Idempotency + an optional fail-on-default-password-in-prod safety pin.
  • Frontend dashboard implications: the mustChangePassword guard now, and a forward-looking note on a future first-run setup wizard (GET /bootstrap/status) for interactive installs.
  • A 5-PR implementation plan and the alternatives considered.

Bilingual — English · 한국어, mirroring the README convention.

What I need from you

Sign-off (or edits) on:

  1. Random-password-logged as the default when no password is injected — agreed, or do you prefer hard fail-fast?
  2. The 5-PR split (identity flag → self-service change-pw → autoconfig runner → UI guard/screen → docs).
  3. Whether production should lean Option A (bootstrap with injected secret) or Option B (no auto-bootstrap, provision out-of-band) as the documented default.

Once you're happy I'll flip Status: Proposed → Accepted and start PR 1.

Design-only PR — no code yet. Captures the decision for how a fresh
devslab-kit deployment gets its first administrator, so the dashboard
is usable, without leaving a permanent backdoor as the same artifact
moves local-dev → staging → production.

Key decisions:
- Bootstrap is property-driven (devslab.kit.bootstrap.*), OFF by
  default → a no-config prod deploy provisions nothing.
- No fixed default password: blank admin-password generates a random
  one logged exactly once (GitLab/Jenkins pattern). A literal
  admin/admin only appears if the operator writes it (i.e. local dev).
- Forced password change on first login via a must_change_password
  flag + a self-service change-password endpoint; the dashboard guards
  every route until rotation.
- Profiles stay the consumer's mechanism for toggling the properties,
  never the kit's trigger — with per-environment config snippets for
  local / staging / prod.
- Idempotent runner + optional prod safety pin
  (fail-on-default-password-in-prod).
- Forward-looking: leaves room for a future first-run setup wizard
  (GET /bootstrap/status) for interactive installs.

Bilingual (en + ko), mirroring the README convention. Includes a
5-PR implementation plan and the alternatives considered. Status:
Proposed — awaiting sign-off before implementation.
@jlc488
Copy link
Copy Markdown
Contributor Author

jlc488 commented May 31, 2026

Superseded by #29, which carries this ADR (now Accepted) plus the full implementation in one reviewable PR. Closing this design-only PR in favour of #29.

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