# req-010: credential_payload Fernet 암호화 및 startup validation - Status: Approved - Type: Non-Functional - Priority: High - Owner: repository-maintainers ## Intent - broker_credentials의 credential_payload(KIS app_key/app_secret)는 민감 데이터이므로 DB 평문 저장이 금지된다(R-1 High). - Python cryptography 패키지의 Fernet(AES-128-CBC + HMAC-SHA256)으로 저장 전 암호화, 조회 시 복호화한다. - CREDENTIAL_ENCRYPTION_KEY 환경변수가 없으면 서비스 기동을 거부해 운영 실수를 사전에 방지한다. ## Requirement - 서비스 기동 시 CREDENTIAL_ENCRYPTION_KEY 환경변수(base64 인코딩 32바이트)가 존재하지 않으면 기동을 중단하고 에러 메시지를 출력해야 한다. - broker_credentials에 credential_payload를 저장할 때 Fernet으로 암호화한 ciphertext를 저장해야 한다. - broker_credentials에서 credential_payload를 조회할 때 Fernet으로 복호화한 JSON을 반환해야 한다. ## Acceptance Criteria 1. Given CREDENTIAL_ENCRYPTION_KEY가 설정된 환경에서 서비스 기동 시, Then 정상 기동되어야 한다. 2. Given CREDENTIAL_ENCRYPTION_KEY가 설정되지 않은 환경에서 서비스 기동 시, Then 기동이 실패하고 키 누락을 알리는 에러 메시지가 출력되어야 한다. 3. Given credential_payload를 broker_credentials에 저장한 뒤 DB를 직접 조회하면, Then 암호화된 ciphertext가 저장되어 있어야 한다(평문 app_key/app_secret 불가). 4. Given 암호화 저장된 credential_payload를 조회 API(GET /v1/user_info)로 읽으면, Then 복호화된 JSON({app_key: ..., app_secret: ...})이 반환되어야 한다. 5. Given 잘못된 키로 복호화를 시도하면, Then cryptography.fernet.InvalidToken 예외가 발생하고 500 또는 적절한 오류 응답이 반환되어야 한다. ## Impacted Area - Docs: docs/project-structure.md (app/core/encryption.py 신규 모듈 반영 필요) - Modules: app/core/config.py (CREDENTIAL_ENCRYPTION_KEY 설정 필드 및 startup validation 추가), app/core/security.py 또는 app/core/encryption.py (Fernet 암복호화 유틸리티 신규), app/repositories/postgres.py (broker_credentials 저장·조회 시 암복호화 적용) - Tests: tests/test_auth.py 또는 신규 테스트에서 startup validation 및 암복호화 검증 ## Notes - CREDENTIAL_ENCRYPTION_KEY는 `from cryptography.fernet import Fernet; Fernet.generate_key()`로 생성한 base64 인코딩 키를 사용한다. - startup validation은 FastAPI lifespan 이벤트 또는 Settings 초기화 시 수행한다. 설계 단계에서 위치를 확정한다. - 키 로테이션 절차는 이번 반복 Out of Scope이다. - Source Discovery: dcy-002 (NFR-3, R-1, OQ-3 Answered) ## Change Log ### CHG-20260502-02 - Date: 2026-05-02 - Author: repository-maintainers #### Change Summary - REQ-010 confirm-req 승인 전환 (Status: Proposed → Approved) #### Intent - 필수 필드(Status, Type, Priority, Owner, Intent, Requirement, Acceptance Criteria 5개, Impacted Area, Change Log) 모두 충족 확인 후 승인 #### Acceptance Criteria Delta - No change #### Impacted Area Delta - No change #### Delivery Trace Delta - Batches: - none - Releases: - none #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: suggest-batch-reqs → draft-batch ### CHG-20260502-01 - Date: 2026-05-02 - Author: repository-maintainers #### Change Summary - REQ-010 최초 생성 (source Discovery: dcy-002 NFR-3) #### Intent - credential_payload 암호화 및 startup validation 요구사항을 독립 Non-Functional REQ로 승격 정규화 #### Acceptance Criteria Delta - Added: - 전체 Acceptance Criteria 신규 작성 #### Impacted Area Delta - Docs: - docs/project-structure.md (encryption 모듈 반영 필요) - Modules: - app/core/config.py startup validation 추가 - app/core/encryption.py 신규 - Tests: - startup validation 및 암복호화 테스트 #### Delivery Trace Delta - Batches: - none - Releases: - none #### Revalidation Impact - Reverification Needed: no - Existing Implementation Invalidated: no - Status Recommendation: keep-current - Follow-up Action: confirm-req 후 batch 배정. REQ-007(GET /v1/user_info), REQ-009(broker_credentials 테이블)과 함께 delivery 단위 구성 권장.