Files
portfolio-hub/docs/discovery/dcy-004_20260520_token-issuance-and-lifecycle-overhaul.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

45 KiB
Raw Blame History

0. 문서 상태

이 문서의 현재 상태와 식별 정보를 기록한다. 문서 추적과 승인 흐름에 필요한 최소 메타데이터를 적는다.

  • 상태: confirmed
  • 문서 ID: dcy-004_20260520_token-issuance-and-lifecycle-overhaul
  • 이슈명: 토큰 발급 및 관리 전면 정비 — client token 폐지, service-token rotate 정상화, 발급 권한 매트릭스, 만료·회전·자동 revoke 정책
  • 작성 시각(KST): 2026-05-20T07:00+09:00
  • 마지막 갱신 시각(KST): 2026-05-20T14:30+09:00 (draft-req 완료 — REQ-016024 9건 생성. FR-1/2/3/4+10/5/6/7/8/9 분해, NFR-16 흡수, docs/srs/index.md 갱신)
  • 대체됨: 없음
  • 후속 Discovery 참조: 없음
  • 생성된 REQ 참조: REQ-016, REQ-017, REQ-018, REQ-019, REQ-020, REQ-021, REQ-022, REQ-023, REQ-024

1. 계획 상태 요약

현재 Discovery가 어떤 배경에서 작성되고 있는지, 연계 문서가 있는지, 지금 시점의 해석이 무엇인지 짧게 요약한다.

  • 연계 문서 현황:
    • 관련 점수 파일: 미생성
    • 관련 TODO/메모: temp/2026-05-18_todo.md (운영 결함 inventory — service-token rotate 실패, HTTP daemon_id forward 누락, rebind/AuthContext 문서 누락), temp/20260519_old_sdlc/releases/rel-006_20260513_daemon-model-implementation.md (rotate verification 실패 기록 + Feedback Handoff에 NULL daemon_id 마이그레이션·daemon deactivation 자동 revoke 항목 잔존)
  • 해석:
    • 현행 토큰 surface는 4종(session/client/service/env)이 발급 경로·만료·회전·문서화에서 부분 정합성 결함을 누적해 왔고, 작은 결함들(client v1 mutation 진입, service-token rotate 실 DB 실패, HTTP body daemon_id silently drop, rebind/AuthContext 문서 누락)이 운영 단계에서 노출되었다. dcy-003에서 client token 폐지를 후속 Discovery에 명시 위임하면서 토큰 surface 정비를 단일 batch로 묶을 시점이 됐다.
    • 본 Discovery는 토큰 surface 전면 정비 — client token 발급 경로 폐지, rotate 정상화, HTTP/CLI 일관성, 발급 권한 매트릭스, 만료·회전 정책, daemon deactivation 자동 revoke, NULL daemon_id legacy token 마이그레이션, env admin token 운영 SOP — 를 단일 주기로 처리한다.

2. 요구사항 판정 결과

이번 요청이 기존 요구사항과 비교해 신규인지, 유사한지, 중복인지 판단하고 그 근거를 남긴다.

  • 판정: 신규
  • 근거
    • 활성 SDLC(dcy-001 asset catalog, dcy-002 tag 정책, dcy-003 portfolio v1)는 모두 도메인 모델·portfolio API에 집중하며 토큰 surface 정비를 다루는 active Discovery는 없다. dcy-003 §10 DATA_CLIENT_TOKEN_DEPRECATION_DISCOVERY가 본 Discovery의 명시 예고에 해당한다.
    • 폐기된 옛 SDLC의 dcy-005(production-admin-bootstrap)는 운영 admin 토큰 절차의 일부만 다루며 본 Discovery의 토큰 surface 전반 정비 범위와는 부분 겹침에 그친다. 새 SDLC 리셋(2026-05-19) 이후 토큰 surface 정비는 미수용 backlog로 남아 있었다.

3. 문제점의 요약

문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다. Discovery의 핵심 맥락을 가장 먼저 이해할 수 있어야 한다.

  • 현재 상태
    • 토큰 surface 4종: app/core/auth.py의 AuthContext가 token_type ∈ {session, client, service, None(env)} × token_source ∈ {db, env} 두 축으로 분류. 발급 경로는 app/services/auth_service.py의 login(session), issue_client_token(client), issue_service_token(service)에 분리. env token은 settings.admin_tokens/trade_write_tokens/read_tokens로 환경 변수에 박힌 형태.
    • 결함 1 — client token 발급 경로 잔존: POST /auth/tokens HTTP API(app/api/auth_routes.py:100-109)로 user가 본인 명의 발급 가능. dcy-003에서 v1 portfolio mutation 진입을 차단하기로 결정(token_type 게이트)했으나 발급 경로·issue_client_token·CreateClientTokenRequest 코드는 잔존.
    • 결함 2 — service-token rotate 실 DB 실패: app/repositories/postgres.py:161-167의 idx_auth_tokens_service_name_unique partial index가 WHERE token_type='service' 조건만 적용해 revoked row와 새 row가 같은 name으로 unique 충돌. REL-006 verification에 "rotate insert 막힘" 검증 실패 기록.
    • 결함 3 — POST /auth/service-tokens body daemon_id silently drop: app/schemas/auth.py:74-80의 IssueServiceTokenRequest.daemon_id 필드는 노출되나 app/api/auth_routes.py:131-137에서 service.issue_service_token 호출 시 forward 하지 않음. CLI --daemon-id는 정상 forward하나 HTTP 경로만 daemon binding 불가.
    • 결함 4 — pfhub service-token rebind CLI 문서화 누락: app/cli/commands/service_tokens.py:119-141에 구현 완료, repository protocol/postgres 모두 존재하나 docs/interface-contract.md CLI surface 열거에 명시 없음.
    • 결함 5 — runtime-flows.md AuthContext 필드 목록 daemon_id 누락: docs/runtime-flows.md:76이 user_id, token_type, permission, runtime_id로 daemon_id 누락. 실제 코드는 보유.
    • 정책 공백 1 — 발급 권한 매트릭스 부재: 누가 어떤 token type을 발급/회전/폐기할 수 있는가가 코드에 흩어진 dependency(require_admin/require_read)로만 표현되고 baseline에 명시 없음.
    • 정책 공백 2 — 만료·회전 정책 부재: session은 settings.session_token_ttl_hours 강제, client는 발급 시 ttl 인자, service는 --no-expiry 허용. 일관 기준·강제 회전 주기 미정의.
    • 정책 공백 3 — daemon deactivation 자동 revoke 부재: pfhub daemon update --deactivate가 daemon is_active=false만 설정하고 바인딩 service token에 영향 없음 (REL-006 Feedback Handoff에 후속 항목으로 기록).
    • 정책 공백 4 — NULL daemon_id legacy token 마이그레이션 자동화 부재: REL-006 Feedback Handoff에 "rotate + rebind 자동화" 후보로 기록만 됨.
    • 정책 공백 5 — env admin token 운영 SOP 부재: 환경 변수 갱신·회전·폐기 절차가 baseline에 없음.
  • 기대 상태
    • 토큰 surface 3종(session/service/env)으로 정리, client token 발급 경로 코드 폐지
    • service-token rotate가 실 DB에서 정상 작동
    • HTTP/CLI 토큰 발급 surface가 일관 (daemon_id forward 누락 해소, rebind/AuthContext 문서 반영)
    • 발급 권한 매트릭스·만료·회전 정책이 baseline에 명시
    • daemon deactivation 시 바인딩 service token 자동 revoke (또는 grace period)
    • NULL daemon_id legacy token 마이그레이션 자동화(CLI 서브커맨드 또는 스크립트, dry-run 포함)
    • env admin token 회전·폐기 운영 SOP 정의
  • 이해관계자
    • admin/운영자: 토큰 발급·회전·폐기 SOP의 일관성 확보, env admin token 회전 책임
    • 로그인 user: client 폐지 후 자동화 use case의 대체 경로 명확화
    • daemon 운영 주체 (trex-basic 등): rotate/rebind 정상 작동, daemon deactivation 동기화
    • repository-maintainers: 토큰 surface 정합성 유지, baseline 문서 일관성
  • 제약사항
    • dcy-003(draft, 본 Discovery 결정 완료 후 진행 재개 예정)이 client token v1 portfolio mutation 진입 차단을 이미 결정(OQ-5 Answered 2026-05-20) → 본 Discovery는 그 결정 위에서 발급 경로 자체 폐지로 진행. 진행 순서: 본 Discovery 결정·confirm 완료 → dcy-003 잔여 항목(CONFIRM 2건, DATA 1건, dcy-001 REQ Approved 선행 조건) 처리 재개
    • 기존 발급된 client token이 운영 중일 수 있어 폐지 마이그레이션 절차 필요 (DB inventory 사전 조사)
    • service-token rotate 정상화는 unique index 변경을 포함 → Alembic migration 추가
    • env admin token 회전은 코드 변경과 환경 변수 갱신을 동시 수행해야 운영 차단 회피
    • 본 Discovery 범위는 토큰 surface 정비에 한정. 신규 토큰 타입 도입(OAuth, PAT 등), 외부 SSO 통합, 감사 로그 정책은 별도 Discovery로 분리

주요 사용자 시나리오

사용자 또는 운영자가 실제로 어떤 상황에서 이 변경을 필요로 하는지 대표 시나리오를 적는다.

  • admin이 alice의 trex-basic daemon용 service-token을 발급한다. pfhub service-token issue NAME --user alice --daemon-id DID (CLI) 또는 POST /auth/service-tokens body {"name": "...", "username": "alice", "daemon_id": "DID", ...} (HTTP) 두 경로 모두 동일하게 daemon_id binding이 작동한다.
  • admin이 alice의 service-token을 회전한다. pfhub service-token rotate NAME --force 실행 시 새 raw token이 발급되고 unique index 충돌 없이 성공한다. 새 토큰의 runtime_id는 새로 발급, daemon_id는 유지(invariant).
  • admin이 alice의 daemon을 비활성화한다(pfhub daemon update DID --deactivate). 해당 daemon에 바인딩된 service token이 자동 revoke되어 후속 v1 호출은 HTTP 401/403.
  • user가 본인 명의 client token 발급을 시도하면 HTTP 404 또는 405 (path 자체 제거)를 받는다. 자동화 use case는 admin이 발급한 service token으로 흡수 또는 OQ-8 결정에 따른 새 경로.
  • 운영자가 NULL daemon_id legacy service token을 일괄 마이그레이션한다. pfhub service-token migrate-null-daemon --dry-run으로 inventory 확인 후 매핑 결정, 실제 실행으로 rebind 또는 revoke 처리.
  • env admin token 회전 시점에 운영자가 SOP에 따라 신규 admin token을 환경 변수에 추가 → service rolling restart → 구 admin token 환경 변수 제거 절차를 단계적으로 수행한다.

4. 이번에 정의할 변경

이번 Discovery에서 다루는 핵심 변경 항목을 목록으로 적는다. 기능, 구조, 규칙 변경을 함께 포함해도 된다.

  • client token 발급 경로 코드 폐지: POST /auth/tokens HTTP route, issue_client_token service 메서드, CreateClientTokenRequest/IssuedClientTokenResponse schemas, 관련 테스트
  • service-token rotate unique index 보강: idx_auth_tokens_service_name_unique에 AND revoked_at IS NULL 조건 추가 또는 동등 효과 정책 채택
  • POST /auth/service-tokens HTTP body의 daemon_id forward 정상화: auth_routes.py:131-137 호출 시 payload.daemon_id 전달
  • 토큰 발급 권한 매트릭스·만료·회전 정책을 baseline 문서(docs/interface-contract.md, docs/runtime-flows.md)에 명시
  • daemon deactivation 시 바인딩 service token 자동 revoke 동작 추가 (pfhub daemon update --deactivate 흐름)
  • NULL daemon_id legacy token 마이그레이션 자동화: 신규 CLI 서브커맨드(pfhub service-token migrate-null-daemon) 또는 일괄 스크립트, dry-run + report 포함
  • env admin token 운영 SOP 정의: docs/runtime-flows.md 또는 README.md에 회전·폐기 절차 추가
  • baseline 문서 정합성 회복: pfhub service-token rebind CLI 명세 추가, AuthContext 필드 목록에 daemon_id 추가, 토큰 surface 전체 명세 갱신

영향 범위

변경이 미칠 코드/문서/운영 범위를 명시해 REQ 정제와 batch planning에서 추정 누락을 줄인다.

  • 코드 영향:
    • app/api/auth_routes.py: POST /auth/tokens 라우트 + 관련 dependency 제거; POST /auth/service-tokens에서 payload.daemon_id forward 보정
    • app/services/auth_service.py: issue_client_token 메서드 제거; revoke_tokens_for_daemon(daemon_id) 등 신규 헬퍼 도입 검토
    • app/schemas/auth.py: CreateClientTokenRequest, IssuedClientTokenResponse 제거
    • app/repositories/postgres.py: idx_auth_tokens_service_name_unique 조건 보강(ensure_schema + Alembic migration), daemon deactivation 시 바인딩 token 일괄 revoke를 위한 repository 메서드 추가
    • app/repositories/portfolio_repository.py: Protocol에 신규 메서드 선언
    • app/cli/commands/daemon.py: update --deactivate 동작에 자동 revoke 호출 추가
    • app/cli/commands/service_tokens.py: migrate-null-daemon 신규 서브커맨드(또는 별도 모듈) 추가
    • migrations/versions/: 신규 Alembic revision — partial index 조건 보강(CONCURRENTLY 적용 권장)
    • tests/: client 폐지 후 호출 경로 회귀 테스트, rotate 정상화 통합 테스트, daemon deactivation 자동 revoke 회귀 테스트, NULL daemon_id 마이그레이션 dry-run 테스트
  • 문서 영향:
    • docs/interface-contract.md: client 발급 경로 제거, pfhub service-token rebind 명세 추가, 토큰 발급 권한 매트릭스 표 추가, 만료·회전 정책 명시
    • docs/runtime-flows.md: 토큰 발급/회전/리바인드/자동 revoke flow, AuthContext 필드 목록에 daemon_id 추가, env admin token 운영 SOP flow
    • docs/data-model.md: auth_tokens 인덱스 변경 반영, 토큰 surface 3종 정리
    • docs/project-structure.md: 신규 마이그레이션 스크립트/CLI 서브커맨드 추가에 따른 패키지 책임 갱신(필요 시)
    • README.md: daemon provisioning runbook 갱신 (auto-revoke 정책 반영), env admin token 회전 SOP 섹션 추가
  • 운영 영향:
    • 기존 발급된 client token 보유자 영향: 폐지 release 전 inventory 조사 + 보유자 통보 필요 (R-1)
    • service-token rotate migration이 partial index recreate를 포함하므로 운영 시간대·CONCURRENTLY 적용 검토 필요 (R-2)
    • daemon deactivation 자동 revoke가 in-flight 거래에 영향 가능 — graceful drain 절차 검토 (R-3)
    • env admin token 회전 SOP가 잘못 적용되면 운영 차단 발생 — 다단계 절차 + rollback 명시 (R-4)

5. 요구사항 목록

실제로 구현과 검증으로 이어질 요구사항을 기능/비기능으로 나누어 정리하고, 범위 경계를 명확히 적는다.

기능 요구사항

  • FR-1: client token 발급 경로 코드 폐지 — POST /auth/tokens HTTP route, app/services/auth_service.py:issue_client_token, CreateClientTokenRequest, IssuedClientTokenResponse, 관련 테스트 모두 제거. 기존 발급된 client token 처리 정책(OQ-1 Answered 2026-05-20): 즉시 코드 폐지로 진행. DATA-1 inventory(2026-05-20)에서 active client token 0건 확인됐으므로 별도 revoke 스크립트 실행이나 grace period 운영 불필요. 폐지 release 직전 동일 쿼리로 재확인하는 절차만 release plan에 포함한다.
  • FR-2: idx_auth_tokens_service_name_unique partial index 조건 보강 (OQ-2 Answered 2026-05-20) — 현행 WHERE token_type='service'에 AND revoked_at IS NULL 추가. ensure_schema()(app/repositories/postgres.py)와 신규 Alembic migration 양쪽 갱신. 기존 active service token 행에는 영향 없음. migration은 CREATE INDEX CONCURRENTLY 적용으로 R-2 lock 영향 최소화(autocommit 외부 트랜잭션 필요).
  • FR-3: POST /auth/service-tokens HTTP body daemon_id forward 정상화 — app/api/auth_routes.py:131-137이 payload.daemon_id를 service.issue_service_token 호출에 전달. CLI --daemon-id와 동등 동작 보장. 비존재/비활성 daemon 지정 시 동일한 ValueError → HTTP 4xx 변환.
  • FR-4: baseline 문서 정합성 회복 — docs/interface-contract.md CLI surface에 service-token rebind 추가, docs/runtime-flows.md AuthContext 필드 목록에 daemon_id 추가, 토큰 surface 전체(env vs DB, session/service 만료 정책, rotate runtime_id/daemon_id invariant) 명세 갱신.
  • FR-5: 토큰 발급 권한 매트릭스 정의 — type(session/service/env) × 발급자 권한(admin/trade-write/read) × 발급 가능 여부의 표를 docs/interface-contract.md에 명시. (client는 폐지 후 표에서 제거.) 매트릭스 위반 호출은 HTTP 403 fail-closed. admin이 자기 자신에게 service token을 발급하는 경로는 허용(OQ-4 Answered 2026-05-20)하며 admin은 본인 user_id를 대상으로 daemon-bound 또는 unbound service token을 발급할 수 있다. 발급된 self-service token의 권한 한도는 admin이 명시한 permission이지만, 관행상 자기 자동화에 필요한 최소 권한(예: trade-write)으로 발급할 것을 매트릭스 주석에 권장.
  • FR-6: 토큰 만료·회전 정책 정의 (OQ-5 Answered 2026-05-20 — 현행 유지) — type별 기본 TTL을 docs/runtime-flows.md에 명시: session = settings.session_token_ttl_hours(현행 값 유지), service = 365일 default, env = 만료 없음. no_expiry 허용 범위는 service 한정(session/client 발급 경로 모두 거부). 강제 회전 주기는 본 정책에 두지 않으며 env admin token 회전 주기만 OQ-6에서 별도 결정한다. 정책 위반 발급(예: no_expiry를 session에 요청)은 HTTP 422 또는 ValueError로 거부.
  • FR-7: daemon deactivation 자동 revoke (OQ-3 Answered 2026-05-20 — 즉시 revoke) — pfhub daemon update <id> --deactivate 실행 시 해당 daemon에 바인딩된 service token(auth_tokens.daemon_id == <id> AND revoked_at IS NULL)을 동일 트랜잭션 내에서 즉시 revoke. graceful drain은 daemon 측 책임이며 trex-basic 등 daemon 구현이 종료 전 in-flight 처리를 수행할 것을 release plan에 명시. CLI에 --keep-tokens 같은 회피 옵션은 노출하지 않는다(정책 일관성). 동작 evidence는 revoked_at 갱신 timestamp로 추적.
  • FR-8: NULL daemon_id legacy token 마이그레이션 (OQ-7 Answered 2026-05-20 — 운영자 수동 매핑) — 신규 CLI 서브커맨드 pfhub service-token migrate-null-daemon 또는 동등 진단 스크립트. dry-run(--dry-run) 옵션으로 inventory + 매핑 후보(같은 user_id의 active daemon 목록) 출력. 실제 적용은 운영자가 token별로 pfhub service-token rebind NAME --daemon-id ID(매핑) 또는 pfhub service-token revoke NAME(폐기)을 수동 실행한다. 자동 매핑/auto-create daemon 경로는 노출하지 않는다(권한 escalation 위험). idempotent 작동(재실행 안전) 필수. 본 batch release 시점에는 DATA-2 inventory에서 발견된 admin 테스트 fixture 1건을 운영자가 직접 revoke 처리(별도 운영 작업).
  • FR-9: env admin token 운영 SOP 정의 (OQ-6 Answered 2026-05-20 — 분기 권장 주기, 강제 없음) — docs/runtime-flows.md 또는 README.md에 명시할 항목: (1) 권장 회전 주기: 분기(3개월). 강제 회전·만료 알람 없음. (2) 운영자 권한 매트릭스: env admin token 추가/제거는 인프라 운영자 권한. (3) 다단계 회전 절차: 신규 token 생성(python -c "import secrets; print(secrets.token_urlsafe(48))" 권장) → PORTFOLIOHUB_ADMIN_TOKENS에 신규 token 추가(콤마 분리) → service rolling restart → 운영 검증 → 구 token 제거 → service rolling restart. (4) 회전 트리거 조건: 정기(분기) / token leak 의심 / 운영자 교체·퇴사 / 보안 사고 대응. (5) rollback 절차: 회전 실패 시 환경 변수에 구 token 재추가 후 rolling restart. (6) token 강도 가이드: 최소 48-byte URL-safe 무작위. 평문 단어·예측 가능한 패턴 금지.
  • FR-10: docs/data-model.md, docs/project-structure.md baseline 갱신 — auth_tokens 인덱스 변경 반영, 토큰 surface 3종 정리, 신규 CLI/migration 파일 책임 반영(필요 시).

비기능 요구사항

성능, 운영성, 일관성, 자동화 안정성 등 기능 외 요구사항을 적는다.

  • NFR-1: client token 폐지 후 dcy-003 v1 portfolio mutation 동작에 회귀 없음. token_type='client' 자체가 생성 불가하므로 dcy-003 FR-1/3/4/5의 게이트 로직은 유지하되 실 트래픽에서는 자연 사라짐.
  • NFR-2: service-token rotate는 docker-compose.local-test.yml 실 DB 환경에서 unique 위반 없이 성공해야 한다. staging 환경 통합 검증 필수.
  • NFR-3: 기존 service-token의 daemon_id invariant(rotate 시 daemon_id 유지)는 본 Discovery 변경 후에도 보존. runtime_id는 매 rotate마다 갱신.
  • NFR-4: 토큰 발급 권한 매트릭스의 위반 호출은 HTTP 403 fail-closed로 통일.
  • NFR-5: NULL daemon_id 마이그레이션은 idempotent. 재실행 시 안전, 부분 실패 시 보고된 예외 목록과 일치.
  • NFR-6: idx_auth_tokens_service_name_unique 변경 migration은 운영 환경에서 long-running lock 회피를 위해 CONCURRENTLY 옵션 적용 또는 운영 시간대 적용 권장.

범위 경계

이번 반복에서 반드시 포함할 범위와 명시적으로 제외할 범위를 구분한다.

  • In Scope
    • client token 발급 경로 코드 폐지 + 기존 토큰 처리 절차
    • service-token rotate unique index 보강 + migration
    • HTTP POST /auth/service-tokens body daemon_id forward 정상화
    • 토큰 발급 권한 매트릭스 정의 (baseline 명시)
    • 토큰 만료·회전 정책 정의 (baseline 명시)
    • daemon deactivation 자동 revoke
    • NULL daemon_id legacy token 마이그레이션 자동화 (CLI + dry-run)
    • env admin token 운영 SOP 정의
    • baseline 문서 정합성 회복 (rebind, AuthContext daemon_id, 토큰 surface 전체)
  • Out of Scope
    • 신규 토큰 타입 도입 (Personal Access Token, OAuth, API key 서비스) — 별도 Discovery
    • user 신원/SSO 통합 — 별도 Discovery
    • 토큰 사용 감사 로그·audit trail 정책 — 별도 Discovery (단, daemon deactivation 자동 revoke의 logging은 본 Discovery 범위)
    • token 시각 동기화·시간대 정책 — 별도 운영 Discovery
    • service-token 발급량/rate-limit 정책 — 별도 Discovery

6. 리스크/가정 목록

불확실성과 전제 조건을 분리해서 적는다. 리스크는 영향과 완화 방안을, 가정은 현재 판단의 전제를 기록한다.

리스크

  • R-1 (해소됨, 잔여 모니터링 Low): DATA-1 inventory(2026-05-20)에서 active client token 0건 확인됐으므로 폐지 release 시 보유자 영향 없음. 잔여 리스크는 release 직전 새로 발급된 client token이 0건이 아닐 가능성뿐이다.
    • 완화 방안: 폐지 release 직전 SELECT COUNT(*) FROM auth_tokens WHERE token_type='client' AND revoked_at IS NULL 재확인을 release plan에 포함. >0이면 발급 사유 조사 후 즉시 revoke 또는 release 보류.
  • R-2 (High): idx_auth_tokens_service_name_unique partial index 재생성이 long-running lock을 유발하면 운영 중 auth_tokens 쓰기가 블로킹된다.
    • 완화 방안: Alembic migration에 CREATE INDEX CONCURRENTLY 적용(단, autocommit 외부 트랜잭션 필요), 운영 시간대 적용, staging 환경 dry-run으로 lock 시간 사전 측정. partial index 변경이 어려우면 OQ-2의 대안(name suffix 부여)으로 전환.
  • R-3 (Medium): daemon deactivation 즉시 revoke(OQ-3 Answered)는 정책상 단순하나 in-flight ledger trade가 진행 중인 시점에 deactivation이 실행되면 거래 기록이 누락될 수 있다.
    • 완화 방안: graceful drain은 daemon 구현 측 책임으로 분리(trex-basic이 종료 신호 수신 시 in-flight 마무리 후 종료). release plan에 deactivation SOP를 "(1) daemon 프로세스 종료/drain 완료 확인 → (2) pfhub daemon update --deactivate 실행 → (3) 자동 revoke" 순서로 명시. deactivation 호출 전 daemon process health check 권장.
  • R-4 (Medium): env admin token 회전 절차가 잘못 적용되면 운영자가 admin HTTP/CLI 접근을 잃어 회복 자체가 불가.
    • 완화 방안: env admin token 회전 SOP에 다단계 절차(신규 token 추가 → 동시 운영 기간 → 구 token 제거) + rollback 절차 명시. 회전 중 fallback admin 접근 경로(예: DB 직접 접근으로 토큰 재생성) 보장.
  • R-5 (해소됨, 잔여 모니터링 Low): OQ-7에서 자동 매핑/auto-create daemon 경로를 채택하지 않기로 결정(2026-05-20)했으므로 권한 escalation 리스크는 본 Discovery 범위에서 발생하지 않는다. DATA-2 inventory(2026-05-20)에서 NULL daemon service token 1건만 발견됐고 운영자 확인 결과 테스트 fixture로 분류돼 본 batch 시점 release에 운영자가 직접 revoke 처리한다.
    • 완화 방안: release 직전 동일 쿼리로 NULL daemon token 0건 재확인. >0이면 운영자가 token별 rebind 또는 revoke 수동 실행. pfhub service-token migrate-null-daemon --dry-run 보고에 token.user_id와 매핑 후보 daemon의 owner_user_id 일치 여부를 명시 표시(자동 매핑은 하지 않더라도 진단 데이터 제공).
  • R-6 (Low): 토큰 발급 권한 매트릭스 정의가 현행 dependency 체계(require_admin/require_read)와 불일치하면 구현 단계에서 광범위 회귀 가능.
    • 완화 방안: 매트릭스 정의 단계에서 코드 grep으로 현행 dependency 사용처와 1:1 매핑 확인, 불일치 시 매트릭스나 dependency 중 한쪽 우선 조정.
  • R-7 (High, 본 Discovery 범위 밖 — 별도 hotfix 권장): DATA-3 수집(2026-05-20) 결과 prod 환경에 env admin token이 약한 placeholder 값(admin-token-789 — 예측 가능한 영문+숫자 패턴)으로 운영 중. 환경 변수 leak 또는 단순 brute-force 시 즉시 admin 권한 escalation 가능. 본 Discovery는 토큰 surface 정비 batch이므로 단일 token 값 교체는 본 Discovery 외부 hotfix로 분리하며, 본 Discovery FR-9의 SOP가 이 hotfix의 표준 절차를 제공한다.
    • 완화 방안: 본 Discovery confirm-discovery 이전이라도 보안상 즉시 hotfix 권장. 절차(FR-9 SOP 미리 적용): (1) 강한 무작위 token 생성, (2) PORTFOLIOHUB_ADMIN_TOKENS에 신규 token 추가, (3) service rolling restart, (4) 운영 검증, (5) 구 token(admin-token-789) 제거, (6) service rolling restart, (7) 회전 evidence 기록. hotfix 추적은 §10 DATA_PROD_ADMIN_TOKEN_HOTFIX 항목으로 관리.

가정

아직 확정되지 않았지만 현재 문서 작성의 기반이 되는 전제를 적는다.

  • A-1: 본 Discovery 후 토큰 surface는 4종(session/client/service/env)에서 3종(session/service/env)으로 정리된다. user의 자동화 use case는 admin이 발급한 service token으로 흡수한다(OQ-8 Answered 2026-05-20 — admin 발급 service token으로 충분). PAT 등 새 토큰 타입 도입은 본 batch 후 운영 피드백을 보고 별도 Discovery에서 판단한다.
  • A-2: dcy-003 FR-1/3/4/5의 token_type 게이트(token_type ∈ {service, client} 거부)는 client 폐지 후 "client는 더 이상 발급 불가"로 자연 강화. 게이트 자체는 env token 외부 침투 방어로 유지.
  • A-3: idx_auth_tokens_service_name_unique 보강은 단일 Alembic migration으로 처리 가능. 기존 active service token 행 데이터에는 변경 없음.
  • A-4: daemon deactivation 자동 revoke는 기존 daemon registry CRUD(dcy-006 모델 — daemons 테이블, is_active 플래그) 위에 얹는 동작이며 daemon 모델 자체에는 변경 없음.
  • A-5: env admin token 회전 SOP는 환경 변수 다중 등록(예: PORTFOLIOHUB_ADMIN_TOKENS 콤마 분리)이 가능한 현행 구조(app/core/auth.py:43-50의 _resolve_permission이 set 기반)를 활용해 다단계 운영이 가능하다.
  • A-6: 본 Discovery는 기존 service-token의 정상 운영 중 daemon binding을 변경하지 않는다. NULL daemon_id token만 마이그레이션 대상이며, 이미 daemon-bound token은 그대로 유지.

오픈 질문

답을 아직 모르는 항목을 적는다. 추정으로 덮지 말고 REQ 초안 작성 이전에 확인할 질문으로 남긴다.

  • OQ-1: 기존 발급된 client token 처리 정책 — 폐지 release에서 즉시 일괄 revoke vs grace period(기간 명시) vs 자연 만료 대기?
    • 상태: Answered
    • 처리 방안: 즉시 코드 폐지로 결정(2026-05-20). DATA-1 inventory에서 active client token 0건 확인됐으므로 grace period/revoke 스크립트 불필요. 폐지 release 직전 동일 쿼리로 재확인하는 절차만 release plan에 포함.
    • 반영 위치: FR-1 본문 갱신 완료, R-1 완화 방안 갱신 완료, §10 DECIDE에서 DECIDE_CLIENT_TOKEN_DEPRECATION_POLICY 처리 완료, §10 DATA에서 DATA_CLIENT_TOKEN_INVENTORY 수집 완료(0건).
  • OQ-2: idx_auth_tokens_service_name_unique 보강 방식 — AND revoked_at IS NULL partial 조건 추가 vs rotate 시 revoked row의 name suffix 부여(예: <name>__revoked_<ts>) vs unique 제약을 active row로만 한정하는 별도 모델 재설계?
    • 상태: Answered
    • 처리 방안: partial 조건 추가로 결정(2026-05-20). WHERE token_type='service' AND revoked_at IS NULL. 단일 Alembic migration + CONCURRENTLY 적용으로 R-2 lock 영향 완화. ensure_schema와 migration 양쪽 갱신.
    • 반영 위치: FR-2 본문 갱신 완료, §10 DECIDE에서 DECIDE_ROTATE_UNIQUE_INDEX_STRATEGY 처리 완료.
  • OQ-3: daemon deactivation 자동 revoke 동작 — 즉시 revoke vs grace period(예: 30분 drain) vs 운영자 별도 확정 명령?
    • 상태: Answered
    • 처리 방안: 즉시 revoke로 결정(2026-05-20). pfhub daemon update --deactivate 실행 시 동일 트랜잭션 내에서 바인딩 service token 모두 revoke. graceful drain은 daemon 측 책임으로 분리. release plan에 deactivation SOP(drain 완료 확인 → deactivate 실행 → 자동 revoke) 명시.
    • 반영 위치: FR-7 본문 갱신 완료, R-3 완화 방안 갱신 완료, §10 DECIDE에서 DECIDE_DAEMON_DEACTIVATION_REVOKE_TIMING 처리 완료.
  • OQ-4: 토큰 발급 권한 매트릭스에서 admin이 자기 자신에게 service token을 발급할 수 있는가? (admin이 본인 user_id로 service token 발급해 운영 자동화에 사용하는 시나리오)
    • 상태: Answered
    • 처리 방안: 허용으로 결정(2026-05-20). admin이 본인 user_id 대상으로 daemon-bound 또는 unbound service token 발급 가능. 권한 한도는 admin이 명시한 permission이며, 관행상 최소 권한(예: trade-write) 발급을 매트릭스 주석에 권장.
    • 반영 위치: FR-5 본문 갱신 완료, §10 DECIDE에서 DECIDE_ADMIN_SELF_SERVICE_TOKEN 처리 완료.
  • OQ-5: 토큰 type별 기본 TTL — session(현행 session_token_ttl_hours), service(현행 365일 default), env(만료 없음) 유지 vs 신규 정책?
    • 상태: Answered
    • 처리 방안: 현행 유지로 결정(2026-05-20). session/service/env 각 정책이 운영상 안정. no_expiry 옵션은 service 한정. 강제 회전 주기는 OQ-6 env admin 결정으로 흡수.
    • 반영 위치: FR-6 본문 갱신 완료, §10 DECIDE에서 DECIDE_TOKEN_TTL_POLICY 처리 완료.
  • OQ-6: env admin token 회전 주기 — 권장 주기(예: 분기/반기/연간), 강제 회전 여부?
    • 상태: Answered
    • 처리 방안: 분기(3개월) 권장 주기, 강제 회전 없음으로 결정(2026-05-20). 만료 알람 없음. SOP에 회전 트리거 조건(정기·leak 의심·운영자 교체·보안 사고)과 다단계 절차·rollback·token 강도 가이드를 명시.
    • 반영 위치: FR-9 본문 갱신 완료, §10 DECIDE에서 DECIDE_ENV_ADMIN_ROTATION_INTERVAL 처리 완료, §10 DATA에서 DATA_ENV_ADMIN_TOKEN_ROTATION_HISTORY 수집 완료. 추가로 R-7(prod 약한 token hotfix) 신규 추가 및 §10 DATA_PROD_ADMIN_TOKEN_HOTFIX 추적 항목 추가.
  • OQ-7: NULL daemon_id legacy token 마이그레이션 매핑 전략 — 운영자 수동 매핑(token name 기반 추정) vs daemon auto-create 후 매핑 vs 폐기 후 재발급?
    • 상태: Answered
    • 처리 방안: 운영자 수동 매핑으로 결정(2026-05-20). CLI는 dry-run으로 inventory + 매핑 후보(같은 user_id의 active daemon) 진단만 제공하고 실제 적용은 운영자가 rebind 또는 revoke를 명시적으로 실행. 자동 매핑/auto-create daemon은 권한 escalation 리스크로 채택하지 않음. DATA-2 inventory(2026-05-20)에서 발견된 admin 테스트 fixture 1건은 운영자가 직접 revoke 처리.
    • 반영 위치: FR-8 본문 갱신 완료, R-5 완화 방안 갱신 완료, §10 DECIDE에서 DECIDE_NULL_DAEMON_MIGRATION_STRATEGY 처리 완료, §10 DATA에서 DATA_NULL_DAEMON_TOKEN_INVENTORY 수집 완료(1건, 테스트 fixture).
  • OQ-8: client token 폐지 후 user 자동화 경로 — admin 발급 service token으로 충분한가, user가 본인 명의로 발급 가능한 새 토큰 타입(예: Personal Access Token)을 후속 Discovery에서 도입할지?
    • 상태: Answered
    • 처리 방안: admin 발급 service token으로 충분으로 결정(2026-05-20). 본 batch 후 토큰 surface 3종(session/service/env)으로 종료. PAT 등 새 토큰 타입은 본 batch 후 운영 피드백을 확인한 뒤 필요 시 별도 Discovery에서 검토.
    • 반영 위치: A-1 갱신 완료, §10 DECIDE에서 DECIDE_USER_AUTOMATION_PATH_AFTER_CLIENT 처리 완료.

오픈 질문 처리 기준

  • Open: 아직 답이 없고 다음 단계 진행에 영향이 있는 상태다. 문서에 유지한다.
  • Answered: 답이 확정된 상태다. 관련 본문/요구사항에 반영한 뒤 오픈 질문 목록에서는 제거하거나 resolved 기록으로 이동한다.
  • Deferred: 지금 단계에서 결정하지 않고 다음 단계 또는 후속 이슈로 넘기는 상태다. 넘길 대상과 이유를 반드시 적는다.
  • Dropped: 더 이상 유효하지 않은 질문이다. 삭제 사유를 짧게 남기고 목록에서 제거한다.
  • 처리 원칙 1: 질문만 남기지 말고 반드시 상태, 처리 방안, 종료 조건을 함께 적는다.
  • 처리 원칙 2: 답이 나온 질문은 본문 반영 없이 단순 삭제하지 않는다. 반영 위치를 먼저 갱신한다.
  • 처리 원칙 3: High 영향 질문은 Deferred 처리 후 처리 방안에 REQ 인계 추적 방식을 명시한다.

7. 초기 성공 기준

이 변경이 성공했다고 판단할 기준을 측정 가능하게 정의한다. 가능하면 데이터 출처까지 연결한다.

  • S-1: codebase에서 client token 관련 코드 모두 제거 — POST /auth/tokens 라우트, issue_client_token 메서드, CreateClientTokenRequest/IssuedClientTokenResponse schemas grep 결과 0건.
  • S-2: 실 DB 환경에서 pfhub service-token issue NAME --user U --no-expiry → pfhub service-token rotate NAME --force 시퀀스가 unique 위반 없이 성공. 새 token의 runtime_id는 갱신, daemon_id는 유지.
  • S-3: POST /auth/service-tokens body {"daemon_id": "<id>", "name": "...", "username": "..."}로 호출 시 issued token의 auth_token.daemon_id == <id> 반환.
  • S-4: pfhub daemon update <id> --deactivate 실행 후 해당 daemon에 바인딩된 service token이 모두 revoked_at IS NOT NULL 상태로 전환 (또는 OQ-3 결정 방식대로 grace period 후 전환).
  • S-5: pfhub service-token migrate-null-daemon --dry-run 실행 시 NULL daemon_id token inventory + 매핑 후보가 보고로 출력. 실 실행 후 NULL daemon_id token이 0건 또는 예외 보고 목록과 일치.
  • S-6: baseline 문서(docs/interface-contract.md, docs/runtime-flows.md, docs/data-model.md)에 토큰 surface 변경(client 제거, rebind 추가, AuthContext daemon_id, 발급 권한 매트릭스, 만료·회전 정책, 자동 revoke flow, env admin SOP) 모두 반영. baseline grep으로 누락 없음 확인.
  • S-7: env admin token 회전 SOP가 docs/runtime-flows.md 또는 README.md에 명시되어 있고, staging 환경에서 dry-run으로 회전 절차 실행 가능.

측정 방식 및 데이터 출처

각 성공 기준을 어떻게 측정할지와 어떤 데이터나 문서를 근거로 쓸지 적는다.

  • S-1 측정 방식: codebase grep(grep -rn "issue_client_token\|CreateClientTokenRequest\|POST /auth/tokens") + pytest로 폐지된 endpoint 호출 시 HTTP 404/405 확인 / 데이터 출처: codebase grep 결과 + 신규 tests/test_auth_surface_after_client_deprecation.py
  • S-2 측정 방식: 실 DB(docker-compose.local-test.yml) 환경 통합 테스트 / 데이터 출처: 신규 tests/test_service_token_rotate_integration.py (DB 의존 마킹)
  • S-3 측정 방식: pytest로 HTTP request 시뮬레이션 / 데이터 출처: 갱신 tests/test_auth.py
  • S-4 측정 방식: pytest로 daemon deactivation 후 바인딩 token 상태 검증 / 데이터 출처: 갱신 tests/test_daemon_registry.py
  • S-5 측정 방식: CLI smoke + 마이그레이션 스크립트 단위 테스트 (dry-run 출력 검증 + idempotency 회귀) / 데이터 출처: 신규 tests/test_null_daemon_migration.py
  • S-6 측정 방식: baseline 문서 grep + 사람 리뷰 (grep -n "service-token rebind\|AuthContext.daemon_id\|발급 권한 매트릭스\|만료·회전 정책" docs/) / 데이터 출처: 갱신된 baseline 문서
  • S-7 측정 방식: SOP 문서 + 운영 환경 dry-run 실행 결과 / 데이터 출처: 갱신 README.md 또는 docs/runtime-flows.md의 env admin SOP 섹션

8. REQ로 넘기기 전 확인 체크

REQ 초안 작성 단계로 넘기기 전에 무엇이 확정되어야 하는지 확인한다. 미완료 항목은 후속 결정이 필요함을 뜻한다.

  • 범위(In Scope/Out of Scope) 확정
    • 기준: OQ-1~8 전체 Answered 완료(2026-05-20). In/Out of Scope 경계 최종화 완료. CONFIRM 2건 모두 Confirmed. DATA-1/2/3 Collected. R-7(prod 약한 token hotfix)는 본 Discovery 범위 밖 별도 운영 작업으로 분리.
  • 성공 지표의 측정 방식/데이터 출처 확정
    • 기준: S-1~7 측정 방식이 §7 측정 방식 섹션에 각각 신규/갱신 pytest 시나리오(tests/test_auth_surface_after_client_deprecation.py, tests/test_service_token_rotate_integration.py, tests/test_auth.py, tests/test_daemon_registry.py, tests/test_null_daemon_migration.py) 또는 SOP 문서(README.md/docs/runtime-flows.md)로 명시 연결됨.
  • High 영향 리스크 우선순위 및 해소 책임자 지정
    • 기준: R-1(client token 보유자 식별)은 DATA-1 0건 확인으로 해소(잔여 Low), R-2(migration lock)는 CONCURRENTLY 적용으로 완화. R-7(prod 약한 admin token)은 본 Discovery 외부 hotfix로 분리. 책임자 = repository-maintainers(본 Discovery 단계). REQ 작성 시 개별 작업 책임자가 REQ Impacted Area에 반영될 예정.
  • 모든 오픈 질문(OQ) Open 상태 없음 확인
    • 기준: OQ-1~8 전체 Answered 완료(2026-05-20). Open 상태 OQ 0건.
  • Freeze 확정 담당자(CONFIRMED_BY) 지정
    • 기준: §11 Confirmed By에 Justin 지정 완료(2026-05-20).
  • dcy-003 의존성 확인
    • 기준: dcy-003(draft)의 client token 폐지 결정이 본 Discovery로 이관됐음을 §3 제약사항·§9 참조에 반영 완료. 진행 순서: 본 Discovery 결정·confirm 완료 → dcy-003 잔여 항목 처리 재개(사용자 결정 2026-05-20).
  • 운영 inventory 수집
    • 기준: DATA-1(client token, 0건) / DATA-2(NULL daemon service token, 1건 테스트 fixture) / DATA-3(env admin token 1개, 약한 placeholder, 회전 이력 없음) 모두 Collected(2026-05-20). DATA_PROD_ADMIN_TOKEN_HOTFIX는 본 Discovery 외부 hotfix 추적 항목으로 잔존.

9. 파일 처리 결과

이 Discovery 문서 생성/갱신 결과와 참조 문서를 기록한다. 이후 추적과 리뷰 시 근거로 사용한다.

  • 처리 결과: 생성
  • 생성 경로: docs/discovery/dcy-004_20260520_token-issuance-and-lifecycle-overhaul.md
  • 참조 문서:
    • docs/discovery/dcy-003_20260520_user-portfolio-mutation-v1-api-migration.md (선행 Discovery — client token 폐지 결정 위임, DATA_CLIENT_TOKEN_DEPRECATION_DISCOVERY 명시 예고)
    • temp/2026-05-18_todo.md (운영 결함 inventory — service-token rotate 실패, HTTP body daemon_id 무시, rebind/AuthContext 문서 누락)
    • temp/20260519_old_sdlc/releases/rel-006_20260513_daemon-model-implementation.md (rotate verification 실패 기록 + Feedback Handoff에 NULL daemon_id 마이그레이션·daemon deactivation 자동 revoke 잔존)
    • app/core/auth.py, app/services/auth_service.py, app/api/auth_routes.py, app/schemas/auth.py, app/repositories/postgres.py, app/cli/commands/service_tokens.py, app/cli/commands/daemon.py (저장소 근거)
    • docs/interface-contract.md, docs/runtime-flows.md, docs/data-model.md, docs/project-structure.md (본 Discovery로 갱신 예정)

10. 사용자 결정 필요 항목 요약

사용자나 승인자가 결정해야 하는 항목만 모아 정리한다. 결정, 확인, 데이터 요청을 구분해서 적는다.

DECIDE

  • {{DECIDE_CLIENT_TOKEN_DEPRECATION_POLICY}}: Decided — 즉시 코드 폐지. DATA-1 inventory(2026-05-20) active client token 0건 확인, grace period/revoke 스크립트 불필요. release 직전 재확인만 release plan에 포함. FR-1·R-1·OQ-1 본문 반영 완료. (OQ-1 Answered 2026-05-20)
  • {{DECIDE_ROTATE_UNIQUE_INDEX_STRATEGY}}: Decided — idx_auth_tokens_service_name_unique에 AND revoked_at IS NULL partial 조건 추가. CONCURRENTLY migration으로 R-2 lock 완화. FR-2·OQ-2 본문 반영 완료. (OQ-2 Answered 2026-05-20)
  • {{DECIDE_DAEMON_DEACTIVATION_REVOKE_TIMING}}: Decided — daemon deactivation 즉시 revoke. graceful drain은 daemon 측 책임 분리. release plan에 SOP 명시. FR-7·R-3·OQ-3 본문 반영 완료. (OQ-3 Answered 2026-05-20)
  • {{DECIDE_ADMIN_SELF_SERVICE_TOKEN}}: Decided — admin이 본인 user_id 대상으로 service token 발급 허용. 권한 한도는 명시 permission, 최소 권한 발급 권장. FR-5·OQ-4 본문 반영 완료. (OQ-4 Answered 2026-05-20)
  • {{DECIDE_TOKEN_TTL_POLICY}}: Decided — 현행 TTL 정책 유지(session/service/env 각 정책). no_expiry는 service 한정. 강제 회전 주기는 env admin(OQ-6)에서 별도 결정. FR-6·OQ-5 본문 반영 완료. (OQ-5 Answered 2026-05-20)
  • {{DECIDE_ENV_ADMIN_ROTATION_INTERVAL}}: Decided — 분기(3개월) 권장 주기, 강제 회전 없음. SOP에 다단계 절차·rollback·token 강도 가이드 명시. FR-9·OQ-6 본문 반영 완료. (OQ-6 Answered 2026-05-20)
  • {{DECIDE_NULL_DAEMON_MIGRATION_STRATEGY}}: Decided — 운영자 수동 매핑. CLI는 dry-run 진단(inventory + 매핑 후보 user_id 일치 표시)만 제공, 실제 rebind/revoke는 운영자가 명시적으로 실행. 자동 매핑/auto-create 미채택(권한 escalation 리스크). DATA-2 inventory(2026-05-20) 1건(admin 테스트 fixture)은 운영자가 직접 revoke 처리. FR-8·R-5·OQ-7 본문 반영 완료. (OQ-7 Answered 2026-05-20)
  • {{DECIDE_USER_AUTOMATION_PATH_AFTER_CLIENT}}: Decided — admin 발급 service token으로 충분. PAT 등 새 토큰 타입은 본 batch 후 운영 피드백 확인 후 별도 Discovery에서 검토. A-1·OQ-8 본문 반영 완료. (OQ-8 Answered 2026-05-20)

CONFIRM

  • {{CONFIRM_DISCOVERY_SCOPE_OPTION_C}}: Confirmed — 옵션 C(Wide — 토큰 발급/관리 전면 정비) 범위로 9개 변경 항목을 단일 batch로 다루는 결정 사용자 동의 완료. (2026-05-20)
  • {{CONFIRM_DCY003_DEPENDENCY}}: Confirmed — dcy-003(draft)에서 결정된 client token v1 mutation 진입 차단 정책이 본 Discovery로 이관됐다는 의존성 관계 사용자 동의. 진행 순서: 본 Discovery 결정·confirm 완료 → dcy-003 잔여 항목 처리 재개. §3 제약사항·§8 체크리스트·§11 Handoff Rationale 반영 완료. (2026-05-20)

DATA

  • {{DATA_CLIENT_TOKEN_INVENTORY}}: Collected (2026-05-20) — active client token 0건. SELECT ... WHERE token_type='client' AND revoked_at IS NULL 결과 0행. OQ-1 즉시 폐지 결정의 evidence.
  • {{DATA_NULL_DAEMON_TOKEN_INVENTORY}}: Collected (2026-05-20) — NULL daemon_id active service token 1건. token name admin(user 500e336a-..., created 2026-05-11, no_expiry). 운영자 확인 결과 테스트 fixture, 운영 용도 없음. release 시점에 운영자가 pfhub service-token revoke admin 수동 실행으로 정리. OQ-7 수동 매핑 결정의 evidence.
  • {{DATA_ENV_ADMIN_TOKEN_ROTATION_HISTORY}}: Collected (2026-05-20) — prod 환경 PORTFOLIOHUB_ADMIN_TOKENS=admin-token-789 1개 운영 중. token 강도: 약함(예측 가능 영문+숫자 placeholder, dev default 추정). 회전 이력 없음(최초 발급 후 미회전). SOP 부재. OQ-6 회전 주기 결정 및 R-7 hotfix 트리거의 evidence.
  • {{DATA_PROD_ADMIN_TOKEN_HOTFIX}}: External tracking (본 Discovery 외부 hotfix) — prod 환경 admin-token-789 교체는 §6 R-7로 추적. 본 Discovery는 SOP(FR-9)를 정의하고 hotfix는 그 SOP를 적용하는 운영 작업이라 본 Discovery confirm-discovery 게이트 차단 사유는 아님. 실행 evidence는 운영 노트에 별도 기록.

11. Discovery Freeze

REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다. 내용 재작성 없이 원본 섹션을 링크로 대신한다.

섹션 참조

Freeze 플래그

  • Handoff Decision: 승인
  • Handoff Rationale: OQ-1~8 전체 Answered + CONFIRM 2건 모두 Confirmed + DATA-1/2/3 모두 Collected + §8 체크리스트 7건 모두 [x] 완료(2026-05-20). confirm-discovery 게이트 통과로 본 Discovery는 confirmed 상태로 승급되어 REQ 초안 작성 가능. 외부 의존 항목: R-7(prod 약한 admin token) hotfix는 본 Discovery 외부 운영 작업이라 별도 처리, dcy-003 잔여 처리 + dcy-001 REQ Approved는 batch 통합 시점 의존성으로 §3 제약사항에 명시됨.
  • Ready for REQ Drafting: true
  • Confirmed By: Justin
  • Confirmed At (KST): 2026-05-20T11:00+09:00