- Add service token rotation CLI command with force flag support - Implement token rotation in auth service with expiration handling - Add portfolio repository helper for transaction/batch operations - Add cascade delete support in postgres repository - Add comprehensive CLI tests for service token operations - Add REQ-012 specification for service token rotation - Create BAT-002 delivery batch for token rotation implementation - Update SRS and batch indexes
4.8 KiB
4.8 KiB
req-012: service-token rotate CLI 명령 구현
- Status: Approved
- 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 원문만 배포할 수 있게 한다.
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
- Given
expires_at IS NULL인 유효한 service-token 이름, Whenpfhub service-token rotate <name> --force를 실행, Then DB 행의token_hash,token_prefix,runtime_id가 새 값으로 변경되고id,permission,expires_at(NULL)은 기존과 동일하다. - Given rotate 성공, When CLI 출력, Then 새 token 원문이 화면에 1회 출력되고 "이 토큰은 지금 1회만 표시" 안내 메시지가 함께 표시된다.
- Given 존재하지 않는 token 이름, When
rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다. - Given revoked 상태의 token, When
rotate, Then 오류 메시지를 출력하고 종료 코드 1을 반환한다. - Given
expires_at이 NULL이 아닌(만료일이 설정된) token, Whenrotate, Then "만료일이 설정된 토큰은 rotate할 수 없습니다" 오류를 출력하고 종료 코드 1을 반환한다. - Given
--force없이 실행, When CLI, Then 확인 프롬프트를 표시하고 거절 시 변경 없이 종료한다.
Impacted Area
- Docs: docs/project-structure.md (변경 없음), docs/runtime-flows.md (변경 없음)
- Modules:
app/repositories/portfolio_repository.py—rotate_service_tokenProtocol stub 추가app/repositories/postgres.py—rotate_service_tokenUPDATE 구현 추가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하는 것이 권장 패턴이다. - DB 스키마 변경(migration)은 없다. 기존
auth_tokens테이블의 기존 컬럼만 UPDATE한다. - 구조/인터페이스/런타임 흐름 변경 없음 → minor-change fast path 적용.
Change Log
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 테스트 회귀 없음으로 완료 판단