8.3 KiB
8.3 KiB
Runtime Flow — Dashboard 관리자 인증
목적과 범위
ASGI startup부터 login, token restoration, invalid-cookie cleanup, explicit logout까지의 실행 순서와 상태 계약을 정의한다.
- 포함 범위: config, HTTPS routes, cookie verification, Streamlit gate, cleanup/deletion
- 제외 범위: MCP request authentication, DB session/token registry, per-token revocation
- 시작 조건: trusted ASGI process receives request
- 성공 종료 상태: authenticated Dashboard page executes
- 실패 종료 상태: matching cookie deletion and unauthenticated login page
흐름
startup — ASGI startup
- 시작 이벤트: process startup
- 선행조건: deployment injects configuration without recording values
- 실행 방식: synchronous startup/request handling
- 트랜잭션·영속성 경계: no auth persistence; existing financial SQLite is untouched
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|---|---|---|---|---|---|---|---|
startup-01 |
Uvicorn | process command | load dashboard.server:app |
process memory only | none | startup-02 |
startup-fail |
startup-02 |
ASGI app | app loaded | mount auth routes and Streamlit runtime | route table only | none | gate-01 |
startup-fail |
login — Credential login
- 시작 이벤트: same-origin HTTPS form POST
- 선행조건: valid trusted scheme, origin and bounded body
- 실행 방식: synchronous request
- 트랜잭션·영속성 경계: no DB transaction; cookie is browser state
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|---|---|---|---|---|---|---|---|
login-01 |
auth server | POST /api/auth/login |
validate scheme/origin/body | request only | none | login-02 |
login-reject |
login-02 |
authentication | validated form | load three settings, fail closed | server memory | secret provider/environment | login-03 |
config-fail |
login-03 |
authentication | configured settings | constant-time compare ID/password | no persistent write | none | login-04 |
login-fail |
login-04 |
authentication | valid credential | issue exactly v, sub=dashboard-admin, iat, exp, jti; fix iat/exp at login success for default 24 hours or remember_me=on 30 days |
server memory | none | login-05 |
login-fail |
login-05 |
auth server | signed token | set hardened cookie with selected absolute expiry and redirect; later activity never reissues or extends it | browser cookie write | response | gate-01 |
login-fail |
restore — Existing cookie restoration
- 시작 이벤트: new request/session with browser cookie
- 선행조건: cookie present or absent; current configuration available
- 실행 방식: synchronous gate
- 트랜잭션·영속성 경계: no server-side session; financial DB begins only after gate success
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|---|---|---|---|---|---|---|---|
gate-01 |
dashboard app | page startup | call authentication before DB path/page dispatch | no DB access | none | gate-02 |
unauthenticated |
gate-02 |
authentication | current config and cookie | verify signature, exact v/sub=dashboard-admin/iat/exp/jti claims, current admin-ID/password/signing-secret binding and absolute exp; never refresh or extend on restoration, rerun or activity |
no session or token write | none | dashboard-01 |
cleanup-01 |
dashboard-01 |
dashboard app | accepted token | resolve DB path and dispatch requested page | existing SQLite reads/writes | gateway/page code | authenticated |
dashboard-fail |
cleanup — Invalid cookie cleanup
- 시작 이벤트: gate rejects malformed, expired, tampered, claim-invalid, or config-failure cookie
- 선행조건: same-origin HTTPS cleanup request
- 실행 방식: synchronous request
- 트랜잭션·영속성 경계: no DB or token registry write
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|---|---|---|---|---|---|---|---|
cleanup-01 |
browser/auth gate | invalid cookie | navigate to GET /api/auth/cleanup |
request only | auth route | cleanup-02 |
cleanup-reject |
cleanup-02 |
auth server | same-origin HTTPS Referer |
emit matching deletion (Max-Age=0) and root redirect |
browser cookie deletion | response | unauthenticated |
cleanup-reject |
logout — Explicit logout
- 시작 이벤트: user submits logout form
- 선행조건: same-origin HTTPS POST
- 실행 방식: synchronous request
- 트랜잭션·영속성 경계: no financial DB change and no per-token revocation
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|---|---|---|---|---|---|---|---|
logout-01 |
browser | POST /api/auth/logout |
validate same-origin HTTPS | request only | none | logout-02 |
logout-reject |
logout-02 |
auth server | validated request | matching deletion and root redirect | browser cookie deletion | response | unauthenticated |
logout-reject |
실패와 복구
| 대상 단계 | 실패 조건 | 추가 쓰기 중단 | 재시도 계약 | 중복 방지 | 보상·수동 복구 | 최종 상태 |
|---|---|---|---|---|---|---|
login-02 |
missing/empty/read-error/short secret | yes | fix deployment config | no cookie | operator injects secret | config-fail |
login-03 |
wrong ID/password | yes | retry after generic error and 1s delay | no lock | external rate limit | login-fail |
gate-02 |
expired, malformed/tampered claims, or admin-ID/password/signing-secret rotation failure | yes | cleanup then login | matching deletion | user logs in again | unauthenticated |
cleanup-02 |
non-HTTPS/cross-origin | yes | retry same origin | deletion is idempotent | browser clears manually if needed | cleanup-reject |
logout-02 |
non-HTTPS/cross-origin | yes | retry same origin | deletion is idempotent | browser clears manually if needed | logout-reject |
동시성과 순서
- 동시 실행 허용 여부: independent requests allowed; no application-wide auth lock
- 잠금·직렬화 단위: none for authentication; existing SQLite rules remain for financial writes
- 순서 보장: config/cookie gate precedes DB path, gateway and page dispatch
- 충돌 검출·처리: token is stateless; password/signing-secret/admin-ID rotation invalidates old claims
- 만료 불변조건: login 성공 시 고정한
iat와exp는 복원·rerun·활동 동안 바뀌지 않으며 token을 재발급하거나 만료를 연장하지 않음 - rotation 불변조건: admin ID, password 또는 signing secret 변경은 이전 설정으로 발급한 모든 token을 무효화하고
cleanup-01로 전이
관찰 가능성
| 신호 종류 | 이름 | 발생 단계·조건 | 상관 식별자 | 진단 속성 | 민감정보 처리 |
|---|---|---|---|---|---|
| event log | authentication_required |
gate-01 rejects |
non-sensitive correlation ID | event class only | no cookie/token/reason |
| event log | login_succeeded |
login-05 |
non-sensitive correlation ID | TTL class only | no credential/token |
| event log | login_failed |
login-03 |
non-sensitive correlation ID | generic failure class | no ID/password |
| event log | cleanup |
cleanup-02 |
non-sensitive correlation ID | generic cleanup class | no cookie header |
| event log | logout |
logout-02 |
non-sensitive correlation ID | operation result | no token/cookie value |
검증
- 정상 흐름: auth server tests plus loopback HTTPS login and fresh session restoration
- 실패 흐름: configuration, wrong credential, malformed/tampered/expired cookie and origin rejection tests
- 경계 흐름: TTL boundary, rotation, oversized token, same-host different-port origin
- 동시성 흐름: independent failed submissions and no application lock; ingress rate-limit configuration review
- 운영 진입점과 기대 결과:
uvicorn dashboard.server:app --host 0.0.0.0 --port 8501; valid HTTPS reaches login or authenticated page, invalid cookie receives matching deletion before unauthenticated page