API 키 관리 UI — /api/admin/keys + Streamlit 페이지 #46

Closed
opened 2026-04-23 02:00:32 +09:00 by xhh · 0 comments
Owner

CLI (scripts/apikey.py) 를 건드리지 않고 브라우저에서 API 키를 발급/폐기/회전할 수 있게 한다. scripts/apikey.py 의 기존 로직을 REST 엔드포인트로 노출하고, Streamlit 운영 대시보드에 전용 페이지 추가.

  • NAS 에 ssh 들어가서 docker compose exec api python scripts/apikey.py ... 를 치는 게 번거로움
  • admin-xhh write 키 1장만 부트스트랩으로 CLI 발급하면 이후 모든 키 관리는 UI 로
  • #44 에서 확보되는 Tailscale 게이트를 이 페이지도 재사용 (공개 노출 금지)

범위

1) 신규 엔드포인트: /api/admin/keys/*

전부 require_scope("write") 로 보호.

메서드 경로 동작
GET /api/admin/keys 활성 키 목록 (name/prefix/scopes/created/last_used)
GET /api/admin/keys?include_revoked=true 폐기 포함
POST /api/admin/keys 발급 → 원문 키를 1회만 응답
DELETE /api/admin/keys/{name} soft revoke (revoked_at 세움)
POST /api/admin/keys/{name}/rotate 기존 폐기 + 동명 재발급, 새 원문 응답

2) Streamlit 페이지 7_API_Keys.py

  • 상단에 Tailscale 게이트 (없으면 차단 문구)
  • 키 목록 테이블 (활성/폐기 필터)
  • 발급 폼: name 입력 + read/write 체크박스 → 제출 시 원문 키를 큰 코드블록으로 1회 표시
  • 각 행에 폐기 / 회전 버튼
  • 직전 발급/회전한 원문 키는 st.session_state 에 보관 (재실행 시 재표시)

3) Tailscale 게이트 유틸 (#44 와 공유)

  • frontend/streamlit/utils/tailscale_probe.py
  • 클라이언트 JS 로 100.100.100.100 프로브 후 st.session_state["tailscale_on"] 설정
  • ADMIN_FORCE_ON=1 환경변수로 로컬 개발 시 강제 admin 모드 (CI/로컬 테스트용)
  • 이 유틸은 이 이슈에서 먼저 구현#44 배포 작업이 이 파일을 재사용한다

부트스트랩 문제

첫 write 키는 여전히 CLI (scripts/apikey.py create --scopes write) 로 발급. 이후 관리는 UI.

보안

  • 원문 키가 HTTP 응답 바디를 타고 감 → Cloudflare Tunnel TLS + Tailscale 암호화로 보호. 하지만 이 페이지는 반드시 Tailscale 에서만 활성 — 실수로 외부 공개돼도 write 스코프 요구로 2중 방어.
  • 폐기는 soft delete (revoked_at). 물리 삭제 안 함.

구현 순서

  1. api/routers/admin.py + api/schemas/admin.py + main.py 등록 + 단위 테스트
  2. frontend/streamlit/utils/tailscale_probe.py 유틸 (#44 선행 구현)
  3. pages/7_API_Keys.py
  4. pages/6_Manual_Trigger.py 도 새 게이트 재사용하도록 리팩터

완료 기준

  • 4개 엔드포인트 모두 테스트 커버
  • 로컬 Streamlit 에서 ADMIN_FORCE_ON=1 으로 페이지 전부 동작
  • 발급 → 목록에 새 키 보임, 회전 → 원문 변경, 폐기 → active=false
  • write 스코프 없는 키로 접근 시 403

선행

  • #22 (Streamlit 3페이지) — 완료
  • #45 (write → read 암시) — 완료

후행

  • #44 (NAS 배포) — 이 이슈에서 만든 tailscale_probe.py 를 그대로 쓴다
CLI (`scripts/apikey.py`) 를 건드리지 않고 브라우저에서 API 키를 발급/폐기/회전할 수 있게 한다. `scripts/apikey.py` 의 기존 로직을 REST 엔드포인트로 노출하고, Streamlit 운영 대시보드에 전용 페이지 추가. ## 왜 - NAS 에 ssh 들어가서 `docker compose exec api python scripts/apikey.py ...` 를 치는 게 번거로움 - `admin-xhh` write 키 1장만 부트스트랩으로 CLI 발급하면 이후 모든 키 관리는 UI 로 - #44 에서 확보되는 Tailscale 게이트를 이 페이지도 재사용 (공개 노출 금지) ## 범위 ### 1) 신규 엔드포인트: `/api/admin/keys/*` 전부 `require_scope("write")` 로 보호. | 메서드 | 경로 | 동작 | |---|---|---| | GET | `/api/admin/keys` | 활성 키 목록 (name/prefix/scopes/created/last_used) | | GET | `/api/admin/keys?include_revoked=true` | 폐기 포함 | | POST | `/api/admin/keys` | 발급 → 원문 키를 **1회만** 응답 | | DELETE | `/api/admin/keys/{name}` | soft revoke (`revoked_at` 세움) | | POST | `/api/admin/keys/{name}/rotate` | 기존 폐기 + 동명 재발급, 새 원문 응답 | ### 2) Streamlit 페이지 `7_API_Keys.py` - 상단에 Tailscale 게이트 (없으면 차단 문구) - 키 목록 테이블 (활성/폐기 필터) - 발급 폼: `name` 입력 + `read`/`write` 체크박스 → 제출 시 원문 키를 큰 코드블록으로 1회 표시 - 각 행에 `폐기` / `회전` 버튼 - 직전 발급/회전한 원문 키는 `st.session_state` 에 보관 (재실행 시 재표시) ### 3) Tailscale 게이트 유틸 (#44 와 공유) - `frontend/streamlit/utils/tailscale_probe.py` - 클라이언트 JS 로 `100.100.100.100` 프로브 후 `st.session_state["tailscale_on"]` 설정 - `ADMIN_FORCE_ON=1` 환경변수로 로컬 개발 시 강제 admin 모드 (CI/로컬 테스트용) - **이 유틸은 이 이슈에서 먼저 구현** — #44 배포 작업이 이 파일을 재사용한다 ## 부트스트랩 문제 첫 write 키는 여전히 CLI (`scripts/apikey.py create --scopes write`) 로 발급. 이후 관리는 UI. ## 보안 - 원문 키가 HTTP 응답 바디를 타고 감 → Cloudflare Tunnel TLS + Tailscale 암호화로 보호. 하지만 이 페이지는 **반드시 Tailscale 에서만 활성** — 실수로 외부 공개돼도 write 스코프 요구로 2중 방어. - 폐기는 soft delete (`revoked_at`). 물리 삭제 안 함. ## 구현 순서 1. `api/routers/admin.py` + `api/schemas/admin.py` + `main.py` 등록 + 단위 테스트 2. `frontend/streamlit/utils/tailscale_probe.py` 유틸 (#44 선행 구현) 3. `pages/7_API_Keys.py` 4. `pages/6_Manual_Trigger.py` 도 새 게이트 재사용하도록 리팩터 ## 완료 기준 - [ ] 4개 엔드포인트 모두 테스트 커버 - [ ] 로컬 Streamlit 에서 `ADMIN_FORCE_ON=1` 으로 페이지 전부 동작 - [ ] 발급 → 목록에 새 키 보임, 회전 → 원문 변경, 폐기 → active=false - [ ] write 스코프 없는 키로 접근 시 403 ## 선행 - #22 (Streamlit 3페이지) — 완료 - #45 (write → read 암시) — 완료 ## 후행 - #44 (NAS 배포) — 이 이슈에서 만든 `tailscale_probe.py` 를 그대로 쓴다
xhh closed this issue 2026-04-23 02:06:18 +09:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
xhh/financial-data-platform#46
No description provided.