콘텐츠로 이동

최초 관리자 부트스트랩

빈 데이터베이스에는 사용자가 없습니다 — 그럼 영구 백도어 없이 처음에 어떻게 로그인할까요? kit의 최초 관리자 부트스트랩이 첫 부팅 때 쓸 수 있는 관리자를 만들어 줍니다: opt-in, 속성 기반, 멱등(idempotent)입니다(배경: ADR 0001).

처음이면 튜토리얼이 바로 이걸로 로그인까지 데려갑니다 — 이 가이드는 그 단계의 레퍼런스입니다.

무엇을 하나

bootstrap.enabled = true면, 시작 시 kit이 멱등하게 (없을 때만) 생성합니다:

  1. 테넌트 bootstrap.tenant-id,
  2. 전체 admin.* 권한을 가진 PLATFORM_ADMIN 역할,
  3. 그 역할을 가진 관리자 사용자(bootstrap.admin-login-id)를 해당 테넌트에.

멱등이므로 켜 둬도 안전합니다 — 이후 부팅은 레코드를 찾고 아무것도 하지 않습니다.

설정

# src/main/resources/application.yml
devslab:
  kit:
    bootstrap:
      enabled: true
      tenant-id: default
      admin-login-id: admin
      admin-password: ${DEVSLAB_BOOTSTRAP_ADMIN_PASSWORD:}   # 비우면 → 랜덤, 한 번만 로그
      must-change-password: true

모든 키는 설정 레퍼런스 참고.

스타터 역할·권한 시드

빈 데이터베이스에는 관리자만 있고 애플리케이션 역할은 없습니다. consumer가 콘솔에서 일일이 만들게 하는 대신 설정으로 시드하세요 — kit이 부팅 시 권한·역할을 멱등하게 생성하고 각 역할에 권한을 부여합니다:

# src/main/resources/application.yml
devslab:
  kit:
    bootstrap:
      enabled: true
      seed:
        permissions: [tasks.read, tasks.write, tasks.update, tasks.delete]
        roles:
          viewer: [tasks.read]
          editor: [tasks.read, tasks.write, tasks.update]
          owner:  [tasks.read, tasks.write, tasks.update, tasks.delete]

tasks.*는 placeholder입니다 — 당신 도메인의 권한 코드를 나열하세요. 참고:

  • 멱등 + 추가형. 매 부팅 시 없는 것을 만들고 나열된 grant를 추가하되, 회수·삭제는 안 합니다. 여기에 권한/역할을 추가하고 재배포하면 반영됩니다. (파괴적 동기화는 dev 전용 설정 동기화 mirror 담당.)
  • 역할이 나열했지만 permissions 블록엔 없는 권한은 자동 생성됩니다 — 그래서 permissions는 아직 아무 데도 부여하지 않을 코드를 위한 것입니다.
  • 권한은 전역, 역할은 tenant-id에 생성됩니다.

관리자 콘솔에서 계속 만들고 관리할 수 있습니다 — 시드는 빈 상태 대신 합리적인 출발점을 줄 뿐입니다.

비밀번호

  • 알려진 값이 필요하면 명시 설정(예: 로컬 개발 admin/admin).
  • 비워 두면 kit이 강한 랜덤 비밀번호를 생성해 시작 시 한 번만 로그에 찍습니다 — 로그에서 복사하면 그 뒤엔 사라집니다.
  • prod / production 프로파일에서는 약한 부트스트랩 비밀번호로 시작을 거부하므로, 플레이스홀더가 운영에 새어 들어가지 않습니다.

알려진 비밀번호는 must-change-password: true와 함께 써서 운영자가 첫 로그인 때 교체하게 하세요.

처음 로그인하기

위 설정(admin/admin)으로 앱을 시작한 뒤:

  1. 관리자 콘솔을 띄우고 브라우저에서 엽니다.
  2. admin / admin(테넌트 default)으로 로그인.
  3. 이제 PLATFORM_ADMIN을 가졌으니 모든 화면을 쓸 수 있습니다.
# 자격 증명을 JWT로 교환:
curl -X POST localhost:8080/admin/api/v1/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"tenantId":"default","loginId":"admin","rawPassword":"admin"}'
# → { "token": "eyJ…" }  — `Authorization: Bearer eyJ…`로 전송

첫 실행 감지

인증 없이 호출하는 GET /admin/api/v1/bootstrap/status{ "initialized": boolean }을 반환합니다. 셋업 마법사나 랜딩 페이지가 이걸로 분기할 수 있습니다 — 예: 갓 배포된 인스턴스를 로그인 폼 대신 "관리자 만들기" 흐름으로 보냅니다:

curl localhost:8080/admin/api/v1/bootstrap/status
# → { "initialized": false }   (아직 관리자 없음)  /  true (프로비저닝됨)

일부러 공개입니다 — 마법사는 누가 인증하기 전에 이걸 호출합니다.

운영 가이드

실제 환경에서는 둘 중 하나를 권장합니다:

  • 강한 admin-password(시크릿으로 주입) + must-change-password: true, 또는
  • enabled: false로 두고 최초 관리자를 외부에서 프로비저닝(SQL/마이그레이션/운영 도구).

더 보기