docs(auth): complete persistent token contracts
This commit is contained in:
@@ -66,6 +66,8 @@ Dashboard 인증 설정, login/cleanup/logout HTTP route, signed cookie와 Strea
|
|||||||
| `Set-Cookie` | response header | `cookie` | success | hardened auth cookie, redacted value | persistent auth | 값은 민감 |
|
| `Set-Cookie` | response header | `cookie` | success | hardened auth cookie, redacted value | persistent auth | 값은 민감 |
|
||||||
| `Location` | response header | `string` | success/failure | `/` or generic error path | browser navigation | 비민감 |
|
| `Location` | response header | `string` | success/failure | `/` or generic error path | browser navigation | 비민감 |
|
||||||
|
|
||||||
|
발급 token은 `v`, `sub=dashboard-admin`, `iat`, `exp`, `jti` claim만 가진다. `sub=dashboard-admin`은 관리자 ID가 아닌 고정 비민감 role이고, token 값과 서명은 민감하므로 browser의 hardened cookie에만 저장한다. 성공한 login 시각에 `iat`와 `exp`를 한 번 고정하며 기본 TTL은 24시간, `remember_me=on`이면 30일이다. 활동, 일반 요청, rerun 또는 인증 복원은 token을 재발급하거나 두 시각을 연장하지 않는다.
|
||||||
|
|
||||||
#### 오류
|
#### 오류
|
||||||
|
|
||||||
| 코드 | 분류 | 발생 조건 | 재시도 가능 여부 | 호출자 대응 | 실패 시 상태 변경 |
|
| 코드 | 분류 | 발생 조건 | 재시도 가능 여부 | 호출자 대응 | 실패 시 상태 변경 |
|
||||||
@@ -148,7 +150,7 @@ Dashboard 인증 설정, login/cleanup/logout HTTP route, signed cookie와 Strea
|
|||||||
|
|
||||||
| 필드 | 위치 | 타입 | 필수 여부 | 기본값 | 허용 값·형식 | 의미 | 민감정보 |
|
| 필드 | 위치 | 타입 | 필수 여부 | 기본값 | 허용 값·형식 | 의미 | 민감정보 |
|
||||||
|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|
|
||||||
| `auth_cookie` | request cookie | `string` | success path | absent | signed token | browser proof | 민감 |
|
| `auth_cookie` | request cookie | `string` | success path | absent | current configuration으로 서명을 검증할 수 있고 claim이 정확히 `v`, `sub=dashboard-admin`, `iat`, `exp`, `jti`인 token | browser proof | 값과 서명은 민감; `sub`는 비민감 |
|
||||||
|
|
||||||
#### 출력
|
#### 출력
|
||||||
|
|
||||||
@@ -162,6 +164,8 @@ Dashboard 인증 설정, login/cleanup/logout HTTP route, signed cookie와 Strea
|
|||||||
|---|---|---|---|---|---|
|
|---|---|---|---|---|---|
|
||||||
| `unauthenticated` | authentication | absent/invalid/expired/config failure | login 가능 | cleanup then show login | no protected work |
|
| `unauthenticated` | authentication | absent/invalid/expired/config failure | login 가능 | cleanup then show login | no protected work |
|
||||||
|
|
||||||
|
관리자 ID, password 또는 signing secret 변경은 server-only signing key binding을 바꾸므로 기존 token을 모두 무효화하고 cleanup으로 전이한다. DB session, token registry와 per-token revocation은 만들지 않는다.
|
||||||
|
|
||||||
## 호환성
|
## 호환성
|
||||||
|
|
||||||
- 유지할 기존 호출 방식: authenticated `page` query parameter, page dispatch, gateway와 MCP behavior
|
- 유지할 기존 호출 방식: authenticated `page` query parameter, page dispatch, gateway와 MCP behavior
|
||||||
@@ -170,6 +174,7 @@ Dashboard 인증 설정, login/cleanup/logout HTTP route, signed cookie와 Strea
|
|||||||
- 재시도 계약: credential 실패는 최소 1초 지연; origin/request 오류는 수정 후 재시도
|
- 재시도 계약: credential 실패는 최소 1초 지연; origin/request 오류는 수정 후 재시도
|
||||||
- 중복 처리 계약: login은 새 token 발급 가능; cleanup/logout deletion은 idempotent
|
- 중복 처리 계약: login은 새 token 발급 가능; cleanup/logout deletion은 idempotent
|
||||||
- 순서 보장: config → cookie verify → cleanup if invalid → DB/page dispatch only if valid
|
- 순서 보장: config → cookie verify → cleanup if invalid → DB/page dispatch only if valid
|
||||||
|
- 만료 보장: login 성공 시 고정한 `iat`와 `exp`는 활동·일반 요청·rerun·복원에서 변경하거나 연장하지 않음
|
||||||
|
|
||||||
## 예시
|
## 예시
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ ASGI startup부터 login, token restoration, invalid-cookie cleanup, explicit lo
|
|||||||
| `login-01` | auth server | POST `/api/auth/login` | validate scheme/origin/body | request only | none | `login-02` | `login-reject` |
|
| `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-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-03` | authentication | configured settings | constant-time compare ID/password | no persistent write | none | `login-04` | `login-fail` |
|
||||||
| `login-04` | authentication | valid credential | issue signed claims with `sub=dashboard-admin` | server memory | none | `login-05` | `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 and redirect | browser cookie write | response | `gate-01` | `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
|
### restore — Existing cookie restoration
|
||||||
|
|
||||||
@@ -49,7 +49,7 @@ ASGI startup부터 login, token restoration, invalid-cookie cleanup, explicit lo
|
|||||||
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|
| 단계 ID | 실행 주체 | 시작 조건·입력 | 처리 | 읽기·쓰기 상태 | 외부 호출 | 성공 시 다음 단계 | 실패 시 전이 |
|
||||||
|---|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|---|
|
||||||
| `gate-01` | dashboard app | page startup | call authentication before DB path/page dispatch | no DB access | none | `gate-02` | `unauthenticated` |
|
| `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 claims, fixed role subject, TTL and rotation | no session write | none | `dashboard-01` | `cleanup-01` |
|
| `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` |
|
| `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
|
### cleanup — Invalid cookie cleanup
|
||||||
@@ -82,7 +82,7 @@ ASGI startup부터 login, token restoration, invalid-cookie cleanup, explicit lo
|
|||||||
|---|---|---|---|---|---|---|
|
|---|---|---|---|---|---|---|
|
||||||
| `login-02` | missing/empty/read-error/short secret | yes | fix deployment config | no cookie | operator injects secret | `config-fail` |
|
| `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` |
|
| `login-03` | wrong ID/password | yes | retry after generic error and 1s delay | no lock | external rate limit | `login-fail` |
|
||||||
| `gate-02` | invalid/expired/tampered/claim/rotation failure | yes | cleanup then login | matching deletion | user logs in again | `unauthenticated` |
|
| `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` |
|
| `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` |
|
| `logout-02` | non-HTTPS/cross-origin | yes | retry same origin | deletion is idempotent | browser clears manually if needed | `logout-reject` |
|
||||||
|
|
||||||
@@ -92,6 +92,8 @@ ASGI startup부터 login, token restoration, invalid-cookie cleanup, explicit lo
|
|||||||
- 잠금·직렬화 단위: none for authentication; existing SQLite rules remain for financial writes
|
- 잠금·직렬화 단위: none for authentication; existing SQLite rules remain for financial writes
|
||||||
- 순서 보장: config/cookie gate precedes DB path, gateway and page dispatch
|
- 순서 보장: config/cookie gate precedes DB path, gateway and page dispatch
|
||||||
- 충돌 검출·처리: token is stateless; password/signing-secret/admin-ID rotation invalidates old claims
|
- 충돌 검출·처리: 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`로 전이
|
||||||
|
|
||||||
## 관찰 가능성
|
## 관찰 가능성
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user