feat(dashboard): add administrator authentication
Verify and publish ARM64 image / verify-arm64 (pull_request) Canceled after 0s
Verify and publish ARM64 image / publish (pull_request) Canceled after 0s

This commit is contained in:
2026-09-25 14:40:19 +00:00
parent 069d4c16fd
commit 7c2a6bdcd3
12 changed files with 1309 additions and 1 deletions
+154
View File
@@ -0,0 +1,154 @@
# Dashboard 관리자 인증 인터페이스 계약
## 목적과 범위
Streamlit Dashboard의 관리자 credential 입력, 환경 설정 판정, browser session 인증과 로그아웃 호출 규칙을 정의한다.
- 포함 범위: Dashboard 환경변수 credential, 로그인·로그아웃 UI, 인증 결과와 오류, 기존 page dispatch 경계
- 제외 범위: MCP 인증, 다중 사용자, 영속 session, OIDC·SSO, TLS와 Ingress
- 사용 주체: Dashboard 사용자, 배포 운영자, `dashboard/app.py`, Dashboard page view
## 계약
### dashboard-auth-config — 관리자 인증 설정
- 책임: 배포 secret에서 단일 관리자 credential을 fail-closed로 읽는다.
- 종류·프로토콜: process environment
- 호출 대상·operation: `dashboard.authentication.load_admin_credentials`
- 버전: 1.0
- 호출 주체: Dashboard 인증 경계
- 인증 방식: 해당 없음; 인증을 구성하는 입력
- 필요 권한: Dashboard process environment를 설정할 배포 권한
#### 입력
| 필드 | 위치 | 타입 | 필수 여부 | 기본값 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|---|
| `JARCA_DASHBOARD_ADMIN_ID` | 환경변수 | `string` | 필수 | 없음 | 비어 있지 않은 문자열 | 단일 관리자 ID | 예 |
| `JARCA_DASHBOARD_ADMIN_PASSWORD` | 환경변수 | `string` | 필수 | 없음 | 비어 있지 않은 평문 password secret | 관리자 password | 예 |
#### 출력
| 필드 | 위치 | 타입 | 필수 여부 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|
| `AdminCredentials` | process memory | `dataclass` | 성공 시 필수 | 두 비어 있지 않은 문자열 | 현재 rerun에서만 사용할 검증 값 | 예 |
#### 오류
| 코드 | 분류 | 발생 조건 | 재시도 가능 여부 | 호출자 대응 | 실패 시 상태 변경 |
|---|---|---|---|---|---|
| `AUTH_CONFIGURATION_ERROR` | 설정 | 누락, 빈 값, 비문자열 또는 environment read 실패 | 설정 수정 후 가능 | 일반 설정 오류만 표시하고 Dashboard 중단 | 기존 인증 boolean 폐기, 금융 상태 무변경 |
### dashboard-login — 관리자 로그인
- 책임: 제출 credential을 검증하고 현재 browser session의 인증 상태를 설정한다.
- 종류·프로토콜: Streamlit form rerun
- 호출 대상·operation: `dashboard.authentication.require_dashboard_authentication`
- 버전: 1.0
- 호출 주체: 미인증 Dashboard 사용자
- 인증 방식: 관리자 ID·password의 constant-time 비교
- 필요 권한: 없음
#### 입력
| 필드 | 위치 | 타입 | 필수 여부 | 기본값 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|---|
| `admin_id` | Streamlit text input | `string` | 필수 | 빈 문자열 | 사용자 제출 문자열 | 관리자 ID 후보 | 예 |
| `password` | Streamlit password input | `string` | 필수 | 빈 문자열 | 사용자 제출 문자열 | 관리자 password 후보 | 예 |
| `page` | URL query parameter | `string` | 선택 | `요약` | 기존 Dashboard page 이름 | 인증 성공 후 이동할 page | 아니요 |
#### 출력
| 필드 | 위치 | 타입 | 필수 여부 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|
| `_jarca_dashboard_authenticated` | `st.session_state` | `boolean` | 성공 후 필수 | `true` | 현재 session의 인증 여부 | 아니요 |
| 화면 | Streamlit UI | `view` | 필수 | 로그인 또는 인증된 Dashboard | 현재 인증 상태의 사용자 화면 | 금융 화면은 인증 후 민감 |
| 인증 event | application log | `string` | 제출 후 필수 | event와 correlation ID | 운영 진단 신호 | 아니요 |
#### 오류
| 코드 | 분류 | 발생 조건 | 재시도 가능 여부 | 호출자 대응 | 실패 시 상태 변경 |
|---|---|---|---|---|---|
| `INVALID_CREDENTIALS` | 인증 | ID 또는 password 불일치 | 가능 | 최소 1초 후 동일 일반 오류 표시 | 금융 상태 무변경, credential 입력 제거 |
| `AUTH_CONFIGURATION_ERROR` | 설정 | credential source 무효 | 설정 수정 후 가능 | 일반 설정 오류만 표시 | 인증 상태 폐기, 금융 상태 무변경 |
### dashboard-logout — 관리자 로그아웃
- 책임: 현재 browser session의 인증 상태를 즉시 폐기한다.
- 종류·프로토콜: Streamlit button rerun
- 호출 대상·operation: sidebar `로그아웃`
- 버전: 1.0
- 호출 주체: 인증된 Dashboard 사용자
- 인증 방식: 현재 session의 인증 boolean
- 필요 권한: 인증된 session
#### 입력
| 필드 | 위치 | 타입 | 필수 여부 | 기본값 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|---|
| `로그아웃` | Streamlit button | `click event` | 필수 | 없음 | 단일 click | 인증 종료 요청 | 아니요 |
#### 출력
| 필드 | 위치 | 타입 | 필수 여부 | 허용 값·형식 | 의미 | 민감정보 |
|---|---|---|---|---|---|---|
| 인증 상태 | `st.session_state` | `absent` | 필수 | key 제거 | 현재 session 재인증 요구 | 아니요 |
| 화면 | Streamlit UI | `view` | 필수 | 로그인 화면 | 로그아웃 완료 | 아니요 |
#### 오류
| 코드 | 분류 | 발생 조건 | 재시도 가능 여부 | 호출자 대응 | 실패 시 상태 변경 |
|---|---|---|---|---|---|
| `없음` | 없음 | 없음 | 해당 없음 | 해당 없음 | 인증 boolean 제거 외 금융 상태 무변경 |
## 호환성
- 유지할 기존 호출 방식: 인증 성공 후 기존 `page` query parameter와 Dashboard page dispatch를 유지한다.
- 버전 변경 정책: 환경변수 이름 또는 session 계약 변경은 requirement revision과 본 문서를 함께 변경한다.
- 폐기 정책: 두 환경변수는 대체 계약 승인 전까지 폐기하지 않는다.
- 재시도 계약: 설정 오류는 설정 수정 후 rerun, credential 오류는 각 제출마다 독립 재시도한다.
- 중복 처리 계약: 반복 실패는 잠금을 만들지 않으며 각 실패에 최소 1초 지연을 적용한다. 로그아웃 재시도는 금융 상태를 변경하지 않는다.
- 순서 보장: 설정 판정 → session 판정 → 로그인 또는 로그아웃 → 인증 성공 후에만 DB 경로 취득과 page dispatch 순서를 유지한다.
## 예시
### config-example — 배포 환경변수 이름
- 대상 인터페이스: `dashboard-auth-config`
#### 호출
```text
JARCA_DASHBOARD_ADMIN_ID=<secret-injected-admin-id>
JARCA_DASHBOARD_ADMIN_PASSWORD=<secret-injected-password>
```
#### 결과
```text
유효한 두 값: 로그인 form 제공
누락 또는 빈 값: 일반 설정 오류와 Dashboard 차단
```
### login-failure-example — 잘못된 credential
- 대상 인터페이스: `dashboard-login`
#### 호출
```text
관리자 ID와 password 제출
```
#### 결과
```text
최소 1초 후 "관리자 ID 또는 비밀번호가 올바르지 않습니다."
```
## 검증
- 정상 계약: test-only credential과 synthetic DB를 사용한 AppTest 로그인 후 기존 페이지 렌더링
- 실패 계약: 누락·빈 값·read error와 잘못된 ID·password의 일반 오류·무변경 검증
- 경계 계약: query parameter 우회 금지, 새 session 재인증, 로그아웃 직후 차단, credential session 제거
- 구현·스키마·예시 정합성: `dashboard/authentication.py`, `dashboard/app.py`, `.env.example`, `docker-compose.yml`과 인증 test를 함께 검토하며 DB migration이 없음을 확인