5.3 KiB
Runtime Flow — Dashboard Persistent Authentication
목적과 범위
Dashboard startup, login token 발급, 새 browser session의 인증 복원, 실패 차단과 logout cookie 삭제 순서를 정의한다.
- 포함: ASGI startup, config, login/logout POST, signed cookie, Streamlit gate, DB 이전 차단
- 제외: MCP 요청, token registry, OAuth/OIDC, external auth middleware
정상 흐름
START — ASGI server 시작
| 단계 | 주체 | 처리 | 다음 |
|---|---|---|---|
START-01 |
Uvicorn | dashboard.server:app 로드 |
START-02 |
START-02 |
Streamlit App |
custom auth routes와 dashboard/app.py runtime 조립 |
UNAUTHENTICATED |
운영 command는 uvicorn dashboard.server:app --host 0.0.0.0 --port 8501이다.
LOGIN — Credential 제출과 token 발급
| 단계 | 주체 | 입력/처리 | 상태·외부 효과 | 다음 |
|---|---|---|---|---|
LOGIN-01 |
Browser | Streamlit이 렌더링한 HTML form을 same-origin HTTPS POST | credential은 request body에만 존재 | LOGIN-02 |
LOGIN-02 |
auth_server |
Origin, content type, body size와 field cardinality 검증 | 금융 상태 없음 | LOGIN-03 또는 LOGIN-REJECT |
LOGIN-03 |
authentication |
세 environment setting을 fail-closed로 읽음 | process memory | LOGIN-04 또는 CONFIG-FAIL |
LOGIN-04 |
authentication |
ID와 password 모두 constant-time 비교 | 실패 시 남은 최소 1초 sleep | LOGIN-05 또는 LOGIN-FAIL |
LOGIN-05 |
authentication |
v/sub/iat/exp/jti payload와 derived key로 token 서명 |
DB 상태 없음 | LOGIN-06 |
LOGIN-06 |
auth_server |
303 response에 hardened cookie 설정 | browser cookie 생성 | RESTORE-01 |
기본 exp-iat는 86400초, remember-me는 2592000초다. 이 값은 발급 시 고정된다.
RESTORE — 새 session·재접속 인증 복원
| 단계 | 주체 | 입력/처리 | 상태 | 다음 |
|---|---|---|---|---|
RESTORE-01 |
Browser | Streamlit initial request/WebSocket handshake에 host cookie 전송 | HttpOnly token | GATE-01 |
GATE-01 |
dashboard.app |
page config 직후 authentication gate 호출 | DB 미접근 | GATE-02 |
GATE-02 |
authentication |
현재 ID/password/signing secret 로드 | secret은 session에 저장하지 않음 | GATE-03 또는 CONFIG-FAIL |
GATE-03 |
authentication |
signature 검증 후 exact claim schema, subject, TTL, time 검증 | token 재발급 없음 | DASHBOARD-01 또는 TOKEN-FAIL |
DASHBOARD-01 |
dashboard.app |
DB path 해석과 기존 page dispatch | 기존 금융 계약 | AUTHENTICATED |
각 rerun은 cookie를 현재 설정으로 다시 검증한다. 일반 요청은 iat, exp, cookie Max-Age를 연장하지 않는다.
LOGOUT — Browser cookie 삭제
| 단계 | 주체 | 처리 | 다음 |
|---|---|---|---|
LOGOUT-01 |
Browser | same-origin HTTPS POST /api/auth/logout |
LOGOUT-02 |
LOGOUT-02 |
auth_server |
matching name/path/security 속성과 Max-Age=0 response |
LOGOUT-03 |
LOGOUT-03 |
Browser | cookie 삭제 후 / 재접속 |
UNAUTHENTICATED |
Logout은 DB를 변경하지 않는다. 복사된 stateless token의 개별 server-side revocation은 없으며 password/signing-secret rotation이 전체 기존 token을 무효화한다.
실패와 복구
| 실패 상태 | 원인 | 차단 범위 | 복구 |
|---|---|---|---|
CONFIG-FAIL |
ID/password/signing secret 누락·invalid·read error | DB/gateway/page 전체 | 올바른 secret 주입 후 rerun |
LOGIN-REJECT |
cross-site, malformed, oversized POST | cookie 발급 | same-origin 정상 form 재시도 |
LOGIN-FAIL |
ID 또는 password 불일치 | cookie 발급·DB 접근 | 최소 1초 후 일반 오류, 재시도 |
TOKEN-FAIL |
absent/malformed/tampered/expired/wrong claims/rotation | DB/gateway/page 전체 | 재로그인 |
DASHBOARD-FAIL |
인증 이후 기존 page/DB 오류 | 기존 page 계약 | 기존 운영 복구 |
Invalid token의 세부 원인을 UI에서 구분하지 않는다. Credential, secret, token, cookie header 또는 exception 원문을 log에 넣지 않는다.
동시성·순서
- 서로 다른 browser session은 같은 signed token을 보낼 수 있다.
- Token verification은 stateless이고 shared mutable authentication state를 만들지 않는다.
- 설정 및 cookie 검증은 항상 DB path/gateway/page보다 먼저다.
- Password/signing-secret rotation 직후 다음 rerun부터 기존 token이 실패한다.
- 실패당 1초 delay는 병렬 요청을 직렬화하지 않으므로 TLS ingress/reverse-proxy 경계에서 rate limiting이 필요하다.
관찰 가능성
허용 event: configuration_error, authentication_required, token_accepted, login_succeeded, login_failed, login_origin_rejected, login_request_rejected, logout, logout_origin_rejected.
각 log는 event와 비민감 correlation ID만 포함한다. Token, credential, origin 세부값, request body와 cookie header는 기록하지 않는다.
검증
- Normal/remember TTL 및 non-sliding: token unit tests
- Tamper/expiry/rotation/schema rejection: token unit tests
- HTTP response cookie와 logout deletion: auth-server tests
- Fail-closed DB-before-gate ordering: AppTest
- 실제 loopback HTTPS login/reconnect/logout와 cookie 속성: HTTP evidence script
- MCP behavior와 DB schema가 변경되지 않았음을 full regression과 diff로 확인