Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
7.2 KiB
7.2 KiB
REQ-054: 인증정보 관리 보안 격리 — write-only·secret 미반환·로그 미노출
- Status: Implemented
- Type: Non-Functional
- Priority: High
- Owner: Justin Ko
Intent
- dcy-011 NFR-1(보안 최우선): 복호화된
app_secret/app_key(KIS API 비밀키 — 실계좌·실자금 직결)는 user-token/admin 어떤 관리 API 응답·로그에도 포함되어서는 안 된다. - REQ-052(사용자 소유 스코프 인증정보 관리 API)와 REQ-053(admin 데몬 CRUD API)이 신설됨으로써 응답/로그 노출 표면이 확대된다. 이 표면에서 복호화 secret이 유출되지 않음을 독립적으로 측정·검증한다.
GET /v1/user_info(service-token 전용, REQ-051/REQ-049)가 유일 decrypt-return 경로라는 불변 정책을 신규 관리 API 추가 이후에도 유지한다.
Requirement
- 인증정보 관리 API(REQ-052: 소유 스코프 write/read/delete + 메타데이터, REQ-053: admin 데몬 CRUD) 응답 스키마에
app_key및app_secret필드가 존재해서는 안 된다. - 인증정보 관리 API 처리 중 생성되는 모든 로그(INFO, WARNING, ERROR 수준 포함)에
app_secret또는app_key평문이 포함되어서는 안 된다. 로그에는broker이름,daemon_id, 오류 유형만 기록한다. - 복호화된
credential_payload(app_key,app_secret)를 반환하는 유일 경로는 service-token 전용GET /v1/user_info(REQ-051/REQ-049)이다. 이 REQ-052·REQ-053 신설로 인해 이 경로가 변경되어서는 안 된다. - 인증정보 쓰기(등록/회전) 후 DB에 저장되는 값은 반드시 Fernet 암호화된 형태여야 한다. 평문
app_secret/app_key가broker_credentials테이블에 저장되어서는 안 된다.
Acceptance Criteria
- Given REQ-052 인증정보 write(등록/회전) 엔드포인트 응답 JSON, When 응답 필드를 열거, Then
app_key,app_secret키가 최상위 및 중첩 객체에 포함되지 않는다. - Given REQ-052 인증정보 메타데이터 GET 엔드포인트 응답 JSON, When 응답 필드를 열거, Then
app_key,app_secret키가 포함되지 않는다. - Given REQ-053 admin 데몬 생성·변경·(비)활성화 엔드포인트 응답 JSON, When 응답 필드를 열거, Then
app_key,app_secret,credential_payload키가 포함되지 않는다. - Given 인증정보 write/rotate 처리 중 caplog 수집, When 로그 출력을 확인, Then 실제
app_key/app_secret값이 로그 메시지에 포함되지 않는다. - Given 인증정보 write 요청의
app_key/app_secret값으로 DB row를 직접 조회, Whenbroker_credentials.credential_payload컬럼을 확인, Then 평문이 아닌 Fernet 암호화 토큰(gAAAA...) 형태로 저장되어 있다. - Given REQ-052 인증정보 write 후 service-token
GET /v1/user_info(REQ-049)로 조회, When 호출, Thenbroker.credential_payload.app_secret이 올바르게 복호화되어 반환된다 — 관리 API 추가가 유일 decrypt 경로(REQ-051)를 파괴하지 않음 확인. - Given REQ-052·REQ-053 신규 엔드포인트가 추가된 후 기존
GET /v1/user_info보안 격리 테스트(REQ-051 AC-1~8), When 회귀 실행, Then 전체 PASS — 신규 API 추가가 기존 service-token 전용 경로에 영향 없음 확인.
Impacted Area
- Docs:
docs/interface-contract.md— 인증정보 관리 API 보안 정책 섹션: 복호화 secret 미반환·로그 미노출·Fernet at-rest 불변·service-token 유일 decrypt 경로 명시.
- Modules:
app/schemas/— REQ-052 응답 스키마(CredentialMetaResponse)에app_key/app_secret필드 부재 강제(Pydantic 모델 설계 단계 확인).app/services/— 인증정보 write 서비스에서 로그 호출 시 secret 평문 비포함 확인.app/core/encryption.py— Fernet 암호화 후 저장 경로(REQ-052 write) 재사용.
- Tests:
- caplog 기반 로그 secret 비노출 테스트(AC-4).
- 응답 스키마 secret 필드 부재 테스트(AC-1/2/3).
- DB 저장 암호화 확인 테스트(AC-5).
- REQ-051 회귀 테스트(AC-7): 신규 API 추가 후 기존 service-token gate 테스트 전부 PASS.
Notes
- dcy-011 NFR-1(보안 — 최우선): REQ-052/REQ-053의 각 AC에 secret 부재 조건이 포함되어 있으나, 이 REQ-054는 신규 관리 API 전체를 아우르는 독립 측정·검증 목적 Non-Functional REQ로 분리한다. REQ-051(서비스 토큰 전용 격리)과 나란히 추적한다.
- AC-7(REQ-051 회귀): REQ-052·REQ-053 구현 후 기존 service-token 보안 격리(REQ-051 AC-1~8)가 회귀 없이 통과함을 이 REQ의 검증 항목으로 포함한다.
- at-rest Fernet 암호화(AC-5):
CREDENTIAL_ENCRYPTION_KEY관리 정책은 REQ-051 Notes에 따라 이 REQ 범위 밖(환경변수 기반 유지). - NFR-2(권한)·NFR-3(일관성)의 나머지는 REQ-052/REQ-053 AC에 흡수된다. NFR-1 보안만 별도 Non-Functional REQ로 승격한다.
- Source: dcy-011 NFR-1, R-1(복호화 secret 유출 리스크), S-2(복호화 secret 미포함 성공 기준).
Change Log
CHG-20260628-01
- Date: 2026-06-28
- Author: Justin Ko
Change Summary
- 신규 생성 (Proposed) — dcy-011 NFR-1 산출물.
Intent
- dcy-011 NFR-1(복호화 secret이 user-token/admin 응답·로그에 미포함, REQ-051 패턴)을 신규 관리 API(REQ-052·REQ-053) 표면 전체에 대한 독립 측정 가능 Non-Functional REQ로 정규화한다.
Acceptance Criteria Delta
- Added:
- AC-1 ~ AC-7 전체 (신규 초안)
- Updated: 없음
- Removed: 없음
Impacted Area Delta
- Docs:
docs/srs/Non-Functional/req-054_credential-management-security-write-only.md신규 생성docs/interface-contract.md갱신 예고
- Modules:
- 응답 스키마(secret 필드 부재), 서비스 로그 확인
- Tests:
- caplog 로그 비노출(AC-4), 응답 schema secret 부재(AC-1~3), DB 암호화 확인(AC-5), REQ-051 회귀(AC-7) 신규
Delivery Trace Delta
- Batches: 미정 (suggest-batch-reqs 대기)
- Releases: 미정
Revalidation Impact
- Reverification Needed: no
- Existing Implementation Invalidated: no
- Status Recommendation: keep-current
- Follow-up Action: confirm-req 후 suggest-batch-reqs. REQ-052/REQ-053와 동일 batch 묶기 권고.
Validation Plan
- pytest caplog fixture로 AC-4(로그 비노출), 응답 JSON 필드 열거로 AC-1~3, DB row 직접 확인으로 AC-5, REQ-051 회귀 suite로 AC-7 검증.
CHG-20260628-02
- Date: 2026-06-28
- Author: 팀장(Claude)
- confirm-req:
Proposed→Approved. dcy-011 NFR-1 추적. 신규 관리 API(REQ-052/053) 응답·로그 secret 미포함(AC-1~4)·Fernet at-rest(AC-5)·service-token 유일 decrypt 불변(AC-6)·REQ-051 회귀(AC-7) testable. REQ-051과 나란히 독립 보안 REQ 승격 타당. blocker 없음.
CHG-20260628-03
- Date: 2026-06-28
- Author: 팀장(Claude)
- confirm-req-implemented:
Approved→Implemented. 근거: BAT-022 PR #19 mergeCommit1b78c18, QC PASS-WITH-NOTES(opus, blocker 0). AC-1~7 전건 통과(565 passed). 응답 schema secret 부재(AC-1/2/3)·caplog 로그 비노출(AC-4)·Fernet at-rest(AC-5)·service-token 유일 decrypt 불변(AC-6)·REQ-051 회귀 PASS(AC-7) 확인. owner 재할당 원자화 수정(83e6dde) 반영으로 음성 보안 테스트 3종 추가 포함. 잔여 리스크 없음.