Files
portfolio-hub/docs/discovery/dcy-011_20260628_daemon-crud-and-self-service-credential-api.md
T
genichinandClaude Opus 4.8 80d0511d7f docs(dcy-011): draft-req + confirm-req — REQ-052/053/054 Approved
Add three approved requirements documents for dcy-011:
- REQ-052: User-owned credential management API (Interface)
- REQ-053: Admin daemon CRUD API (Interface)
- REQ-054: Credential management security with write-only constraint (Non-Functional)

Update discovery document to reference generated requirements and update index with new REQ IDs and Change Log.

Scope: Self-service credential management + admin daemon CRUD + security-isolated API for portfolio-hub.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
2026-06-28 13:55:45 +09:00

16 KiB

0. 문서 상태

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

1. 계획 상태 요약

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

  • 연계 문서 현황:
    • 관련 점수 파일: 미생성
    • 관련 TODO/메모: GitHub org 보드 fourblocks2020/trex #7 — "portfolio-hub 데몬 레지스트리/관리 API", "서비스 토큰/데몬 발급·관리". 교차 발원 = trex-web dcy-009(사용자 self-service 인증정보 관리 + admin 데몬 provisioning UI). 선행 = dcy-010(daemon-scoped 브로커 인증정보 모델/보안), dcy-004(토큰·권한 모델)
  • 해석:
    • trex-web dcy-009가 정의한 기능(사용자가 자기 데몬 KIS 인증정보를 self-service 관리, admin이 데몬 provisioning)을 받쳐줄 portfolio-hub 백엔드 API가 없다. 현재 데몬은 read-only(/v1/daemons), 인증정보는 CLI(pfhub credential) 전용이며 복호화 read는 service-token /v1/user_info뿐이다.
    • 핵심 판단: ① 사용자 소유 스코프 인증정보 관리 API(write/rotate/delete + 메타데이터, 복호화 secret 절대 미반환), ② admin 데몬 CRUD API(생성·할당·(비)활성화)를 dcy-004 권한 모델 위에 어떻게 설계하고, service-token decrypt 경로(REQ-051)와 어떻게 분리·불변 유지할지.

2. 요구사항 판정 결과

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

  • 판정: 신규
  • 근거
    • 기존 /v1/daemons는 read 전용이고, 인증정보 관리는 CLI 전용이다. HTTP 기반 소유 스코프 인증정보 관리 API와 admin 데몬 CRUD API는 정의된 바 없다.
    • dcy-010은 인증정보 모델/저장(CLI·service-token read)을 다뤘고, 본 건은 사용자/admin HTTP 관리 표면을 신설하므로 신규 주기로 추적한다.

3. 문제점의 요약

문제의 현재 상태, 기대 상태, 관련 이해관계자, 제약사항을 정리한다.

  • 현재 상태
    • BrokerCredential(dcy-010): PK (daemon_id, broker), user_id 보유, Fernet 암호화 {app_key, app_secret}. 관리=CLI(pfhub credential set/list/remove --daemon-id). 복호화 read=service-token 전용 GET /v1/user_info(REQ-051, web/user-token 403).
    • Daemon(id, owner_user_id, daemon_slug, display_name, is_active): read API GET /v1/daemons만. 생성·변경·(비)활성화 HTTP API 없음.
    • 권한 모델(dcy-004): user-token(권한 read/write), admin role, service-token(daemon_id 바인딩). 소유 스코프 인가 선례 = dcy-009 trex-web 포트폴리오/REQ-049 managed_by_daemon_id 일치.
    • 암호화 유틸(app/core/encryption.py Fernet, CREDENTIAL_ENCRYPTION_KEY) 존재.
  • 기대 상태
    • 사용자(소유 스코프): HTTP로 자기 소유 데몬의 인증정보를 등록·회전·삭제하고 메타데이터(broker, account_ref, version, last_rotated, 보유 여부)를 조회. 자기 것만.
    • admin: HTTP로 데몬을 생성·사용자 할당·변경·(비)활성화.
    • 복호화된 app_secret은 user-token/admin 어떤 응답에도 포함되지 않는다. service-token decrypt 경로(REQ-051)는 불변.
  • 이해관계자
    • 사장님(보안·권한·결재), 팀장(거버넌스), portfolio-hub-dev(구현), 일반 사용자(self-service 소비, trex-web 경유), admin/운영자(데몬 provisioning), trex-web 개발(dcy-009 소비측)
  • 제약사항
    • 최민감 시크릿(KIS app_secret = 실계좌·실자금) 복호화 평문이 user-token/admin 응답·로그에 노출 금지. service-token /v1/user_info(REQ-051)가 유일 decrypt-return 경로 — 불변.
    • 소유 스코프 인가 엄격: 사용자는 자기 소유 데몬(owner_user_id==요청자)의 인증정보만. 타인 접근 403.
    • 데몬은 운영 런타임 식별자 → 생성·(비)활성화 영향 큼. 삭제는 dcy-009 결정대로 제외(비활성화).
    • CLI(pfhub credential)와 신규 API의 동작 정합(동일 repository·암호화 자산 재사용).

주요 사용자 시나리오

  • admin이 POST /v1/daemons(또는 동등)로 데몬 D를 생성하고 owner=사용자 U로 할당한다.
  • 사용자 U가 (trex-web 경유, user-token) 자기 데몬 D의 인증정보를 등록(app_key/app_secret) → 서버 Fernet 암호화 저장. 응답엔 secret 미포함, account_ref·version만.
  • 사용자 V가 사용자 U의 데몬 D 인증정보 조회/수정 요청 → 403(소유 스코프).
  • 데몬 D 인스턴스는 service-token으로 /v1/user_info에서 복호화 인증정보 fetch(기존 경로 불변).

4. 이번에 정의할 변경

이번 Discovery에서 다루는 핵심 변경 항목.

  • (C1) 사용자 소유 스코프 인증정보 관리 API — 자기 소유 데몬 인증정보 set/rotate/delete + 메타데이터 GET. user-token + ownership 게이트. 복호화 secret 미반환. 암호화·저장은 dcy-010 자산 재사용.
  • (C2) admin 데몬 CRUD API — 데몬 생성·owner 할당·변경·(비)활성화. admin role. (삭제 제외 — 비활성화.)
  • (C3) repository 계층 확장 — credential ownership/메타데이터 조회·daemon CRUD 메서드. CLI와 동일 자산 공유.

영향 범위

  • 코드 영향:
    • app/api/ — 신규 인증정보 관리 라우트(소유 스코프) + v1_daemons.py write(admin) 확장
    • app/repositories/* — credential 메타데이터/ownership 조회, daemon create/update/deactivate
    • app/core/auth.py — ownership 게이트(요청자==owner) + admin 게이트 재사용
    • app/schemas/* — 관리 요청/응답 스키마(secret 미포함 메타데이터 응답)
    • 암호화: app/core/encryption.py(dcy-010) 재사용
  • 문서 영향:
    • docs/srs/(신규 REQ), docs/discovery/index.md(본 문서), docs/interface-contract.md(신규 엔드포인트)
    • 교차: trex-web dcy-009(소비자 UI)
  • 운영 영향:
    • 사용자 self-service 등록으로 CLI 부담 감소(CLI는 fallback 유지). admin 데몬 provisioning HTTP 경로.

5. 요구사항 목록

기능 요구사항

  • FR-1: 사용자가 자기 소유 데몬의 인증정보를 등록·회전·삭제한다(user-token). app_key/app_secret 입력 → Fernet 암호화 저장(dcy-010). 회전 시 credential_version++/last_rotated_at 갱신.
  • FR-2: 사용자가 자기 인증정보 메타데이터(broker, account_ref, credential_version, last_rotated_at, 데몬별 보유 여부)를 조회한다. 복호화된 app_key/app_secret은 응답에 포함되지 않는다.
  • FR-3: 인증정보 관리 경로는 소유 스코프 인가를 강제한다 — 요청자 user_id != 대상 데몬 owner_user_id → HTTP 403(타인 데몬·계좌 접근 차단).
  • FR-4: admin이 데몬을 생성·owner 할당·변경(display_name 등)·(비)활성화한다(admin role). 하드 삭제는 제공하지 않는다(비활성화로 대체).

비기능 요구사항

  • NFR-1 (보안 — 최우선): 복호화된 app_secret은 user-token/admin 어떤 응답·로그에도 포함되지 않는다(쓰기 전용 관리 + 메타데이터). service-token GET /v1/user_info(REQ-051)가 유일 decrypt-return 경로 — 본 건으로 변경하지 않는다. at-rest Fernet 불변.
  • NFR-2 (권한): 인증정보 관리 = 소유 스코프(user-token, 요청자==데몬 owner). 데몬 CRUD = admin role. dcy-004 토큰/권한 모델 재사용.
  • NFR-3 (일관성): 신규 API·CLI(pfhub credential)·service-token read가 동일 BrokerCredential/Daemon 모델·암호화 자산에서 정합 동작. daemon_id·owner_user_id 바인딩 정합(dcy-010).

범위 경계

  • In Scope
    • 소유 스코프 인증정보 관리 API(set/rotate/delete + 메타데이터, secret 미반환).
    • admin 데몬 CRUD API(생성·할당·변경·(비)활성화, 삭제 제외).
    • repository·스키마·권한 게이트.
  • Out of Scope
    • service-token 복호화 read 경로(/v1/user_info, dcy-010/REQ-051) 변경 — 불변.
    • trex-web UI(= dcy-009).
    • 서비스 토큰 발급·폐기(별 Discovery, dcy-009 OQ-3).
    • 외부 시크릿 매니저 외부화.
    • 데몬 하드 삭제.

6. 리스크/가정 목록

리스크

  • R-1 (High): 복호화 app_secret이 user-token/admin 관리 응답·로그로 유출(실계좌 탈취).
    • 완화 방안: 관리 API는 set/rotate/delete + 메타데이터만, 복호화 payload 절대 미반환. 응답 스키마에 secret 필드 부재. 로그 secret 미포함(REQ-051 패턴). service-token 경로와 라우트·권한 분리. 음성 테스트.
  • R-2 (High): ownership 인가 결함 → 사용자가 타인 데몬 인증정보 조회·수정(횡적 권한 상승).
    • 완화 방안: 모든 관리 경로 엄격 ownership 검사(요청자==owner_user_id, 불일치 403). dcy-009 trex-web 포트폴리오/REQ-049 daemon-scope 인가 재사용. 음성 테스트(타인 자원→403) 필수.
  • R-3 (Medium): 데몬 (비)활성화·변경 blast radius — 운영 인스턴스가 daemon_id로 fetch 중.
    • 완화 방안: 삭제 미제공(비활성화), 참조 무결성·활성 데몬 보호, 인증정보 보유 데몬 비활성화 경고.
  • R-4 (Medium): CLI·신규 API 이중 관리 경로 불일치.
    • 완화 방안: 동일 repository 메서드·암호화 자산 재사용, PK (daemon_id, broker) 정합.

가정

  • A-1: dcy-010 BrokerCredential(PK (daemon_id, broker), user_id, Fernet, CREDENTIAL_ENCRYPTION_KEY) 완료. (확인됨, Implemented)
  • A-2: Daemon.owner_user_id 존재 → 소유 스코프 인가가 데이터상 가능. (확인됨)
  • A-3: dcy-004 토큰/권한(user-token, admin role, service-token) 재사용.
  • A-4: 교차 발원 trex-web dcy-009(confirmed)가 소비자. UI는 dcy-009 범위.
  • A-5: service-token /v1/user_info(REQ-051) decrypt-return 경로 불변(유일 decrypt 경로).

오픈 질문

  • OQ-1: 인증정보 관리 엔드포인트 경로·형태 — daemon-scoped(/v1/daemons/{id}/credential) vs user-credential.
    • 상태: Deferred (2026-06-28) → draft-batch-design 단계 위임.
    • 처리 방안: design에서 REST 형태 확정. 팀장 권고 = daemon-scoped 경로(소유 스코프 자연). dcy-009 UI 흐름·v1 컨벤션 정합.
    • 종료 조건: draft-batch-design 전 경로·메서드 확정.
  • OQ-2: admin 데몬 CRUD 경로 — /v1/daemons 확장 vs /v1/admin/daemons.
    • 상태: Deferred (2026-06-28) → draft-batch-design 단계 위임.
    • 처리 방안: design에서 확정. dcy-006 admin 경로 컨벤션 참고.
    • 종료 조건: draft-batch-design 전 확정.
  • OQ-3: 데몬 owner 재할당 허용 여부 + 재할당 시 인증정보 처리.
    • 상태: Answered (2026-06-28)
    • 결정: 재할당 허용(admin), 단 owner 변경 시 해당 데몬의 기존 인증정보 자동 무효화(이전 owner의 KIS 계좌 이관 금지 — 새 owner가 재등록). §5 FR-4/범위·R-2 반영.

7. 초기 성공 기준

  • S-1: 사용자가 자기 데몬 인증정보를 API로 등록하면, 그 데몬이 service-token /v1/user_info에서 동일 계좌를 fetch함을 검증할 수 있다.
  • S-2: 인증정보 관리/메타데이터·데몬 CRUD 어떤 user-token/admin 응답에도 복호화 app_secret/app_key가 포함되지 않음이 테스트로 확인된다.
  • S-3: 사용자 A가 사용자 B 소유 데몬의 인증정보 조회·수정 시 403(소유 스코프)이 테스트로 확인된다.
  • S-4: admin이 데몬 생성·owner 할당·(비)활성화를 수행하고, 비-admin은 거부(403)됨이 확인된다.

측정 방식 및 데이터 출처

  • S-1 측정 방식: API 등록 → service-token /v1/user_info fetch 일치 / 데이터 출처: 통합테스트, broker_credentials 행
  • S-2 측정 방식: 관리·CRUD 응답 스키마/실응답에서 secret 필드 부재 + 로그 미노출 / 데이터 출처: API·로그 테스트
  • S-3 측정 방식: 타 사용자 자원 접근 → 403 음성 테스트 / 데이터 출처: API 테스트
  • S-4 측정 방식: admin/비-admin 권한 경로 테스트 / 데이터 출처: API 테스트

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

  • 범위(In Scope/Out of Scope) 확정
    • 기준: 데몬 owner 재할당 정책(OQ-3 재할당+인증정보 무효화) 결정 완료
  • 성공 지표의 측정 방식/데이터 출처 확정
    • 기준: S-1~S-4 측정 가능성 검토 완료
  • High 영향 리스크 우선순위 및 해소 책임자 지정
    • 기준: R-1(secret 노출 — 쓰기전용)·R-2(소유 스코프 인가 — 엄격 ownership) 완화 모델 확정. 구현 책임=portfolio-hub-dev
  • 모든 오픈 질문(OQ) Open 상태 없음 확인
    • 기준: OQ-3 Answered, OQ-1/OQ-2 Deferred(design 위임)
  • Freeze 확정 담당자(CONFIRMED_BY) 지정
    • 기준: 사장님+팀장 confirm-discovery 완료

9. 파일 처리 결과

  • 처리 결과: 생성
  • 생성 경로: docs/discovery/dcy-011_20260628_daemon-crud-and-self-service-credential-api.md
  • 참조 문서:
    • trex-web docs/discovery/dcy-009_20260628_daemon-and-broker-credential-admin-management.md (교차 발원 — 소비자 UI/요건)
    • docs/discovery/dcy-010_20260627_daemon-scoped-broker-credential-provisioning.md (선행 — 인증정보 모델/보안/REQ-051)
    • docs/discovery/dcy-004_20260520_token-issuance-and-lifecycle-overhaul.md (권한/토큰 모델)

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

DECIDE

  • 데몬 owner 재할당 (OQ-3) → RESOLVED 2026-06-28: 재할당 허용(admin), owner 변경 시 기존 인증정보 자동 무효화

CONFIRM

  • 쓰기 전용·secret 미반환·service-token 유일 decrypt 불변 → RESOLVED 2026-06-28: 확정(NFR-1)
  • 엄격 소유 스코프 인가 + 데몬 CRUD admin → RESOLVED 2026-06-28: 확정(NFR-2)

DATA

  • {{DATA_V1_CONVENTIONS:기존 v1 API 경로·권한 컨벤션(/v1/daemons, /v1/portfolios, dcy-006 admin) — 엔드포인트 형태(OQ-1/OQ-2 design) 설계 입력}}

11. Discovery Freeze

REQ 초안 작성 인계 시점의 확정 플래그와 섹션 참조만 기록한다.

섹션 참조

Freeze 플래그

  • Handoff Decision: REQ Drafting 진행 가능
  • Handoff Rationale: confirm-discovery 완료(2026-06-28). CONFIRM 2건(쓰기전용·secret 미반환·service-token 유일 decrypt / 엄격 소유 스코프+데몬 CRUD admin) + DECIDE 1건(OQ-3 owner 재할당 허용+인증정보 자동 무효화) 확정. OQ-1/OQ-2(엔드포인트 경로)는 draft-batch-design 위임 Deferred. 잔여 Open 0건 → REQ 인계 가능. trex-web dcy-009가 이 계약 소비.
  • Ready for REQ Drafting: true
  • Confirmed By: 팀장(Claude)
  • Confirmed At (KST): 2026-06-28