Files
portfolio-hub/docs/srs/Interface/req-012_service-token-rotate-cli.md
T
genichin d20d784452 docs: add rel-002 release and transition REQ-011, REQ-012, REQ-015 to Implemented
Release: rel-002_20260511_operator-cli-tooling-and-baseline-docs-sync

Requirements Completed:
- REQ-011: baseline docs update for trex-basic contract (BAT-008 verification passed)
- REQ-012: service-token rotate CLI command (BAT-002 verification passed)
- REQ-015: broker credential CLI command group (BAT-005 verification passed)

Release Contents:
- Operator CLI tooling with service-token rotate and broker credential management
- Baseline documentation synchronized with trex-basic interface contract
- Complete v1 API and portfolio ownership model documentation

Documentation Updates:
- Create rel-002 release document with included batches and deployment notes
- Update docs/releases/index.md with release entry
- Add implementation evidence to REQ-011, REQ-012, REQ-015
- Update SRS index with Implemented status transitions and change log
2026-05-11 12:13:29 +00:00

7.8 KiB

req-012: service-token rotate CLI 명령 구현

  • Status: Implemented
  • Type: Interface
  • Priority: Medium
  • Owner: repository-maintainers

Intent

  • 발급된 service-token의 원문이 노출되었거나 주기적 교체가 필요한 경우, token을 revoke 없이 in-place로 갱신할 수 있는 CLI 명령이 필요하다.
  • 기존 revoke → re-issue 방식은 token_id, user_id, permission, expires_at, created_at 등 메타데이터가 변경되므로, 운영 시스템에서 동일한 이름으로 참조하는 통합 구성을 다시 설정해야 하는 불편이 있다.
  • rotate는 token_hash, token_prefix, runtime_id만 교체하고 나머지 메타데이터를 유지하여, 동일한 token 이름과 메타데이터를 유지한 채 새 token 원문만 배포할 수 있게 한다. 단, runtime_id를 소비하는 시스템은 rotate 후 새 토큰 기준으로 runtime_id를 재조회해야 한다.

Requirement

  • pfhub service-token rotate <name> [--force] CLI 명령을 구현한다.
  • rotate는 기존 auth_token 행의 token_hash, token_prefix, runtime_id를 새 값으로 UPDATE한다.
  • id, user_id, name, permission, token_type, expires_at, created_at은 변경하지 않는다.
  • rotate 대상 token이 존재하지 않으면 오류를 반환한다.
  • rotate 대상 token이 이미 revoked 상태이면 오류를 반환한다.
  • rotate 대상 token의 expires_at이 NULL이 아닌 경우(만료일이 설정된 토큰) 오류를 반환한다. rotate는 --no-expiry로 발급된 영구 토큰에만 허용된다.
  • --force 없이 실행하면 확인 프롬프트를 표시한다.
  • rotate 성공 시 새 token 원문을 1회 출력하고, 이후 list/조회에서는 token_prefix만 표시된다.

Acceptance Criteria

  1. Given expires_at IS NULL인 유효한 service-token 이름, When pfhub service-token rotate <name> --force를 실행, Then DB 행의 token_hash, token_prefix, runtime_id가 새 값으로 변경되고 id, permission, expires_at(NULL)은 기존과 동일하다.
  2. Given rotate 성공, When CLI 출력, Then 새 token 원문이 화면에 1회 출력되고 "이 토큰은 지금 1회만 표시" 안내 메시지가 함께 표시된다.
  3. Given 존재하지 않는 token 이름, When rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다.
  4. Given revoked 상태의 token, When rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다.
  5. Given expires_at이 NULL이 아닌(만료일이 설정된) token, When rotate, Then "만료일이 설정된 토큰은 rotate할 수 없습니다" 오류를 출력하고 종료 코드 1을 반환한다.
  6. Given --force 없이 실행, When CLI, Then 확인 프롬프트를 표시하고 거절 시 변경 없이 종료한다.

Impacted Area

  • Docs: docs/project-structure.md (변경 없음), docs/runtime-flows.md (변경 없음)
  • Modules:
    • app/repositories/portfolio_repository.py — rotate_service_token Protocol stub 추가
    • app/repositories/postgres.py — rotate_service_token UPDATE 구현 추가
    • app/services/auth_service.py — rotate_service_token(name) 서비스 메서드 추가
    • app/cli/commands/service_tokens.py — rotate 명령 추가
    • tests/test_cli.py — stub repo에 rotate_service_token 추가 및 테스트 케이스 추가
  • Tests:
    • tests/test_cli.py: rotate 성공, 없는 이름, revoked 상태 3개 케이스

Notes

  • expires_at은 rotate 시 변경하지 않는다. 만료일 변경이 필요하면 revoke + re-issue를 사용한다.
  • rotate는 --no-expiry로 발급된 영구 토큰(expires_at IS NULL)에만 허용된다. 만료일이 설정된 토큰은 rotate 대상이 아니다. 해당 토큰은 만료 후 re-issue하는 것이 권장 패턴이다.
  • rotate는 runtime_id도 새 값으로 갱신한다. trex-basic 등 runtime_id를 소비하는 시스템은 rotate 후 새 토큰으로 다시 인증하고 GET /v1/user_info를 재호출해 새 runtime_id를 재인식해야 한다.
  • 기존 runtime_id를 캐싱한 상태로 계속 사용하면 consumer 식별 불일치가 발생할 수 있다. rotate는 "토큰 원문 교체 시 token name과 메타데이터를 유지한다"는 의미이지, runtime_id까지 불변이라는 뜻은 아니다.
  • DB 스키마 변경(migration)은 없다. 기존 auth_tokens 테이블의 기존 컬럼만 UPDATE한다.
  • 구조/인터페이스/런타임 흐름 변경 없음 → minor-change fast path 적용.

Change Log

CHG-20260511-02

  • Date: 2026-05-11
  • Author: repository-maintainers

Change Summary

  • Implemented 전환 — BAT-002 verification passed, confirm-req-implemented 게이트 통과

Intent

  • BAT-002 verification.md에서 REQ-012 AC-1~6이 모두 PASS이고 blocking issue가 없음을 근거로 Implemented로 승격한다.

Acceptance Criteria Delta

  • Added: none
  • Updated: none
  • Removed: none

Impacted Area Delta

  • Docs: none
  • Modules: none
  • Tests: none

Delivery Trace Delta

  • Batches:
    • BAT-002 (release-candidate)
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: implemented
  • Follow-up Action: tooling release에 포함 시 rotate 후 runtime_id 재조회 운영 메모 반영

Validation Plan

  • BAT-002 verification.md의 REQ-012 AC-1~6 evidence와 Ready for Release: true 확인

CHG-20260511-01

  • Date: 2026-05-11
  • Author: repository-maintainers

Change Summary

  • rotate 후 runtime_id lifecycle 명시 추가 — downstream consumer는 새 토큰 배포 후 runtime_id를 재조회해야 함

Intent

  • CONFLICT-3 분석 결과를 반영해 runtime_id가 rotate 시 변경된다는 사실과, trex-basic 같은 consumer가 이를 어떻게 재인식해야 하는지 REQ-012 문서에 명시한다.

Acceptance Criteria Delta

  • Added:
    • none
  • Updated:
    • none
  • Removed:
    • none

Impacted Area Delta

  • Docs:
    • docs/srs/Interface/req-012_service-token-rotate-cli.md: Intent/Notes에 rotate 후 runtime_id 재조회 lifecycle 추가
  • Modules:
    • none
  • Tests:
    • none

Delivery Trace Delta

  • Batches:
    • BAT-002 (release-candidate) — verification evidence는 유지 가능하나, rotate 후 consumer 재인식 절차를 운영 메모로 함께 검토해야 한다.
  • Releases:
    • none

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: trex-basic 연동 runbook 또는 후속 REQ에서 rotate 후 runtime_id 재조회 절차를 운영 문서에 반영 검토

Validation Plan

  • REQ-005, REQ-007, REQ-012 문구를 대조해 rotate 시 runtime_id 변경과 GET /v1/user_info 재조회 필요성이 일관되게 설명되는지 코드 리뷰로 확인

CHG-20260502-01

  • Date: 2026-05-02
  • Author: repository-maintainers

Change Summary

  • REQ-012 신규 작성 (minor-change fast path, Approved 직행)
  • rotate 허용 대상을 expires_at IS NULL(no-expiry) 토큰으로 제한

Intent

  • service-token rotate CLI 명령 필요성 확인 후 즉시 구현 진행

Acceptance Criteria Delta

  • Added:
    • 6개 기준 신규 정의 (AC-5: expires_at 설정 토큰 rotate 거부 추가)

Impacted Area Delta

  • Modules:
    • postgres.py, auth_service.py, service_tokens.py, test_cli.py 추가
  • Tests:
    • test_cli.py 3개 케이스 신규

Delivery Trace Delta

  • Batches:
    • BAT-002 (batch-lite)
  • Releases:
    • none (미정)

Revalidation Impact

  • Reverification Needed: no
  • Existing Implementation Invalidated: no
  • Status Recommendation: keep-current
  • Follow-up Action: BAT-002 planning → implementation → verification 진행

Validation Plan

  • test_cli.py 3개 케이스 통과 + 기존 service-token 테스트 회귀 없음으로 완료 판단