Files
portfolio-hub/docs/srs/Interface/req-023_null-daemon-token-migration-cli.md
T
genichinandClaude Sonnet 4.6 c815ce39b6 feat: dcy-003/004 토큰 surface 개편 및 daemon lifecycle 정책 구현 (BAT-006/007)
BAT-006 (REQ-016/017/018):
- client token 발급 경로 제거 (issue_client_token, POST /auth/tokens, 관련 스키마/테스트)
- service-token rotate unique index revoked_at IS NULL 조건 추가 (Alembic CONCURRENTLY 마이그레이션)
- POST /auth/service-tokens body daemon_id forward 누락 보정 (1-line fix)

BAT-007 (REQ-022/023):
- daemon deactivate 시 바인딩 service token 자동 revoke (CLI --force 옵션 + revoke_tokens_by_daemon_id)
- NULL daemon_id legacy token 진단 CLI (migrate-null-daemon --dry-run)

거버넌스 문서: dcy-003/004 Discovery, REQ-016~023/025~032 신규, BAT-006/007 전체 산출물

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-21 01:03:39 +00:00

104 lines
6.2 KiB
Markdown

# REQ-023: NULL daemon_id legacy token 마이그레이션 CLI
- Status: Implemented
- Type: Interface
- Priority: Medium
- Owner: Justin Ko
## Intent
- `daemon_id IS NULL`인 active service token이 운영 환경에 존재하면 v1 API daemon-scoped endpoints가 fail-closed로 작동해 운영 정리가 필요하다. 자동 매핑은 권한 escalation 리스크로 채택하지 않고(dcy-004 OQ-7), 운영자 수동 매핑을 보조하는 진단 CLI를 제공한다.
- dry-run으로 inventory + 매핑 후보를 진단 출력하고, 운영자가 token별 `rebind` 또는 `revoke`를 명시적으로 실행하는 패턴을 표준화한다.
## Requirement
- 신규 CLI 서브커맨드 `pfhub service-token migrate-null-daemon` 추가:
- `--dry-run` 옵션: NULL daemon active service token inventory를 출력. 각 token에 대해 `id`, `user_id`, `name`, `runtime_id`, `created_at`, 매핑 후보 daemon(같은 `owner_user_id == user_id`인 active daemon 목록)을 표 또는 JSON 형식으로 보고.
- 매핑 후보 검증: `token.user_id == daemon.owner_user_id` 일치 여부를 명시 표시. 불일치 가능성이 있는 token은 별도 경고 표시.
- `--dry-run` 없이 실행하면 안전상 명시적 거부(예: "use --dry-run for inspection, then `pfhub service-token rebind` or `revoke` per token") 또는 no-op.
- 본 CLI는 자동 rebind/revoke를 수행하지 않는다. 실제 적용은 운영자가 token별로 `pfhub service-token rebind NAME --daemon-id ID` 또는 `pfhub service-token revoke NAME`을 명시 실행해야 한다.
- 본 CLI는 idempotent하다(재실행 안전, NULL token이 0건이어도 정상 종료).
- DATA-2 inventory(2026-05-20)에서 발견된 admin 테스트 fixture 1건은 본 batch release 시점에 운영자가 직접 `pfhub service-token revoke admin` 수동 실행으로 정리(release plan에 명시).
## Acceptance Criteria
1. Given `pfhub service-token migrate-null-daemon --dry-run` 실행, When NULL daemon active service token 1건 이상 존재, Then 각 token의 `id`, `user_id`, `name`, `runtime_id`, `created_at`, 매핑 후보 daemon 목록, user_id 일치 여부가 출력된다.
2. Given `pfhub service-token migrate-null-daemon --dry-run` 실행, When NULL daemon 활성 service token이 0건, Then "no NULL daemon tokens" 메시지 출력 후 exit code 0으로 정상 종료.
3. Given `pfhub service-token migrate-null-daemon` (--dry-run 없이) 실행, When 호출, Then 자동 변경을 거부하고(예: error message + non-zero exit) 운영자에게 `rebind`/`revoke` 수동 실행을 안내한다.
4. Given AC-1 출력 후 운영자가 `pfhub service-token rebind NAME --daemon-id ID` 실행, When 매핑이 성공적으로 적용, Then 해당 token의 `daemon_id`가 갱신되고 다시 `--dry-run` 실행 시 해당 token이 inventory에서 제외된다.
5. Given AC-1 실행 후 운영자가 `pfhub service-token revoke admin` 실행, When DATA-2 admin 테스트 fixture가 revoke, Then 다시 `--dry-run` 실행 시 해당 token이 inventory에서 제외된다.
## Impacted Area
- Docs:
- `docs/interface-contract.md` — `pfhub service-token migrate-null-daemon` CLI 명세 추가 (REQ-019 baseline 작업)
- Modules:
- `app/cli/commands/service_tokens.py` — `migrate_null_daemon` 함수 신규 추가 (Typer 서브커맨드 등록)
- `app/services/auth_service.py` — `list_null_daemon_service_tokens()` 및 `find_candidate_daemons_for_user(user_id)` 헬퍼 추가(또는 직접 repository 조회)
- `app/repositories/portfolio_repository.py`, `app/repositories/postgres.py` — `list_service_tokens_with_null_daemon()` 메서드 신규 추가
- Tests:
- 신규 `tests/test_null_daemon_migration.py` — AC-1~5 시나리오. dry-run 출력 검증 + idempotency 회귀 + non-dry-run 거부 동작 검증
## Notes
- dcy-004 OQ-7 결정으로 자동 매핑/auto-create daemon은 채택하지 않음(권한 escalation 리스크). 본 CLI는 진단 도구로만 작동.
- DATA-2 inventory 1건(admin 테스트 fixture)은 본 batch release 시점에 운영자가 직접 처리. CLI 진단 + 운영자 수동 적용이라는 본 REQ 패턴의 첫 번째 적용 사례.
- 매핑 후보가 0건(같은 user_id의 active daemon 없음)인 token은 dry-run 출력에 별도 표시해 운영자가 daemon 신규 생성 후 rebind를 진행하거나 token revoke를 결정하도록 안내.
- 본 CLI는 batch 시점 1회 정리 + 향후 NULL daemon token이 발생할 때마다 사용 가능한 영구 운영 도구로 작동한다.
- Source: dcy-004 FR-8, dcy-004 NFR-5, dcy-004 OQ-7 결정.
## Change Log
### CHG-20260520-02
- Date: 2026-05-20
- Author: Justin Ko
#### Change Summary
- Status: Proposed → Approved
#### Intent
- 승인 게이트 통과: 필수 필드(Status/Type/Priority/Owner/Intent/Requirement/AC/Impacted Area/Change Log) 모두 충족, AC 구체성 확인 완료, blocker 없음
#### Acceptance Criteria Delta
- No change
#### Impacted Area Delta
- No change
#### Delivery Trace Delta
- Batches: none (미정)
- Releases: none (미정)
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: promote-to-approved
- Follow-up Action: batch 계획 편입
### CHG-20260520-01
- Date: 2026-05-20
- Author: Justin Ko
#### Change Summary
- 최초 생성 — dcy-004 confirm-discovery 후 draft-req 실행. dcy-004 FR-8 산출물.
#### Intent
- NULL daemon legacy token 마이그레이션을 운영자 수동 매핑 패턴으로 표준화 + 진단 CLI 제공.
#### Acceptance Criteria Delta
- Added:
- AC-1~5 최초 작성
#### Impacted Area Delta
- Docs: docs/interface-contract.md (REQ-019에서 처리)
- Modules: app/cli/commands/service_tokens.py, app/services/auth_service.py, app/repositories/portfolio_repository.py, app/repositories/postgres.py — 최초 지정
- Tests: tests/test_null_daemon_migration.py — 최초 지정
#### Delivery Trace Delta
- Batches: none (미정)
- Releases: none (미정). DATA-2 정리(admin 테스트 fixture revoke)는 release plan에 명시.
#### Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 후 batch 계획 편입
#### Validation Plan
- pytest로 AC-1~5 검증; CLI smoke + idempotency 회귀 + non-dry-run 거부 동작