Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VHtM5Ws1HKCKQ4JGi6GRb5
3.4 KiB
3.4 KiB
BAT-022 Implementation
- Status: completed
- Commit: 6a0e14d
변경 파일 목록
신규 파일
| 파일 | 역할 |
|---|---|
app/api/v1_admin_daemons.py |
REQ-053 admin daemon CRUD 라우터 (/v1/admin/daemons) |
app/api/v1_daemon_credential.py |
REQ-052 소유 스코프 credential 관리 라우터 (/v1/daemons/{id}/credential) |
tests/test_bat022_req052_credential_api.py |
REQ-052 AC-1~10 테스트 (17 케이스) |
tests/test_bat022_req053_admin_daemon_crud.py |
REQ-053 AC-1~12 테스트 (15 케이스) |
tests/test_bat022_req054_security.py |
REQ-054 AC-1~7 + REQ-051 회귀 (12 케이스) |
변경 파일
| 파일 | 변경 내용 |
|---|---|
app/schemas/v1.py |
CredentialSetRequest, CredentialMetaResponse, DaemonCreateRequest, DaemonUpdateRequest, DaemonAdminResponse 추가 |
app/repositories/postgres.py |
get_broker_credential_by_daemon, delete_credentials_by_daemon_id, update_daemon_owner 추가 |
app/repositories/portfolio_repository.py |
Protocol에 신규 3개 메서드 추가 |
app/main.py |
v1_admin_daemons_router, v1_daemon_credential_router include |
REQ별 구현 요약
REQ-052 (소유 스코프 인증정보 관리 API)
GET /v1/daemons/{daemon_id}/credential— 소유 스코프 검증 후 BrokerCredential 메타데이터 반환 (has_credential, version, last_rotated_at). secret 없음.PUT /v1/daemons/{daemon_id}/credential—app_key/app_secretFernet 암호화 후upsert_broker_credential(daemon_id=...)호출. 응답 메타데이터만.DELETE /v1/daemons/{daemon_id}/credential—delete_broker_credential(daemon_id=...)호출, 204 반환(멱등).- 소유 스코프 게이트:
daemon.owner_user_id != auth.user_id→ 403. admin role도 동일 검사(AC-9). - service-token 거부:
token_source == "db" and token_type == "service"→ 403(AC-10). - 기존
upsert_broker_credential,delete_broker_credential(dcy-010 자산) 재사용. CLI와 동일 repo 메서드.
REQ-053 (admin 데몬 CRUD API)
POST /v1/admin/daemons→ 기존create_daemon()재사용, 201.PATCH /v1/admin/daemons/{id}→ owner 변경 시update_daemon_owner()(새 메서드), display_name만 변경 시 기존update_daemon().POST .../deactivate→update_daemon(is_active=False)+revoke_tokens_by_daemon_id()(REQ-022 재사용).POST .../activate→update_daemon(is_active=True).DELETE .../→ 명시적 405 핸들러 등록.require_admindependency 사용 (기존app/core/auth.py).
REQ-054 (보안 격리)
- 응답 스키마:
CredentialMetaResponse/DaemonAdminResponse모두 secret 필드 부재. - 로그:
PUT credential처리 시 broker/daemon_id만 기록 (app_key/app_secret 값 미포함). - Fernet at-rest:
encrypt_payload()호출 후upsert_broker_credential()— 평문 미저장(AC-5). - REQ-051 decrypt 경로 불변:
/v1/user_info코드 무변경, 회귀 4개 테스트 PASS(AC-7).
설계 결정 트레이스 (design.md 참조)
- OQ-1 해소:
/v1/daemons/{daemon_id}/credential— daemon-scoped, REST 정합. - OQ-2 해소:
/v1/admin/daemons— admin 전용 prefix, 기존 GET /v1/daemons(caller-scoped)와 분리. - service-token 403:
token_source == "db" and token_type == "service"조건. env-token은 token_type=None이므로 해당 없음. - admin + 소유 스코프: admin role도 ownership 검사 통과 → 403(REQ-052 AC-9).