Files
portfolio-hub/docs/batches/bat-002_20260502_service-token-rotate-cli/planning.md
T
genichin b4d964253b feat(REQ-012): implement service token rotation CLI
- 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
2026-05-02 12:43:43 +00:00

2.2 KiB

BAT-002 Planning

  • Status: confirmed
  • Batch: BAT-002
  • Profile: batch-lite

Included REQ

  • REQ-012: service-token rotate CLI 명령 구현

Delivery Plan

Out of Scope

  • expires_at 변경 옵션 (이번 rotate는 secret 교체만)
  • HTTP API rotate 엔드포인트 (CLI 전용)

구현 순서

1단계: Repository 레이어

  • app/repositories/portfolio_repository.py — rotate_service_token(token_id, token_hash, token_prefix, runtime_id) -> AuthToken Protocol stub 추가
  • app/repositories/postgres.py — rotate_service_token UPDATE 구현
    UPDATE auth_tokens
    SET token_hash = %s, token_prefix = %s, runtime_id = %s
    WHERE id = %s AND revoked_at IS NULL
    RETURNING id, user_id, name, token_prefix, ...
    
    • 대상 행이 없거나 revoked이면 ValueError 반환

2단계: Service 레이어

  • app/services/auth_service.py — rotate_service_token(name) -> IssuedServiceToken 추가
    • get_service_token_by_name(name) 조회 → 없으면 ValueError
    • revoked 상태이면 ValueError
    • expires_at is not None이면 ValueError ("만료일이 설정된 토큰은 rotate할 수 없습니다")
    • generate_token() + hash_token() + token_prefix() + uuid.uuid4() 로 새 값 생성
    • repository.rotate_service_token(...) 호출
    • IssuedServiceToken(token=raw_token, auth_token=updated_token) 반환

3단계: CLI 명령

  • app/cli/commands/service_tokens.py — rotate 명령 추가
    • --force 없으면 확인 프롬프트
    • issue 명령과 동일한 1회 원문 출력 패턴 적용

4단계: 테스트

  • tests/test_cli.py — 인메모리 repo에 rotate_service_token stub 추가 및 케이스 추가
    • rotate 성공 (no-expiry 토큰, 새 token 출력 확인)
    • 없는 이름 → 오류
    • revoked 토큰 → 오류
    • expires_at가 설정된 토큰 → 오류

Dependencies

  • Internal: 없음 (기존 get_service_token_by_name, generate_token, hash_token 활용)
  • External: 없음 (DB 스키마 변경 없음)

Design Gate

  • Design Required Before Implementation: no
  • Reason: DB 스키마 변경 없음. 기존 패턴(issue/revoke) 동일하게 적용. 결정 사항 없음.