feat(dashboard): add administrator authentication #3

Merged
genichin merged 2 commits from gitea-impl-agent/jarca-ledger-mcp:gitea-agent/issue-1-dashboard-admin-auth into main 2026-09-28 06:51:13 +00:00
Owner

Closes #1

구현 요약

  • 모든 Streamlit Dashboard page dispatch와 DB/gateway 접근 앞에 공통 관리자 인증 경계를 추가했습니다.
  • JARCA_DASHBOARD_ADMIN_ID와 JARCA_DASHBOARD_ADMIN_PASSWORD 환경변수만 credential source로 사용하며, 설정 오류는 fail-closed합니다.
  • ID와 password를 constant-time으로 비교하고 실패 로그인마다 최소 1초 지연을 적용합니다.
  • 인증 상태를 현재 Streamlit browser session에만 유지하고 명시적 로그아웃을 제공합니다.
  • 인증 event에는 credential을 기록하지 않고 correlation ID만 남깁니다.
  • MCP 인증과 SQLite schema는 변경하지 않았습니다.

문서 및 배포 설정

  • REQ-001 요구사항과 15개 acceptance criterion을 추가했습니다.
  • 인터페이스 계약, 프로젝트 구조, 런타임 흐름 문서를 추가했습니다.
  • .env.example, docker-compose.yml, README.md에 secret 주입과 운영 제약을 반영했습니다.
  • 애플리케이션 잠금은 두지 않으므로 배포 경계에서 별도 rate limiting이 필요합니다.

검증

  • uv run --extra dashboard --extra dev pytest: 84 passed, 4 skipped
  • uv run --extra dashboard --extra dev ruff check dashboard tests: passed
  • uv run python -m compileall -q dashboard tests: passed
  • git diff --check: passed
  • canonical 문서 검증: 요구사항 8개, acceptance criterion 15개, data-model 문서 없음
  • 독립 보안·논리 검토 및 명세·문서 검토: passed, unresolved finding 없음

제한사항

  • Dashboard 인증만 포함하며 MCP endpoint 인증은 별도 Issue 범위입니다.
  • 이 실행 환경에는 Docker Compose plugin/legacy CLI가 없어 Compose CLI 검증은 수행하지 못했고, YAML 구조와 required-variable interpolation은 정적으로 검증했습니다.
  • 실제 운영 credential이나 금융 DB를 사용하지 않았습니다.
Closes #1 ## 구현 요약 - 모든 Streamlit Dashboard page dispatch와 DB/gateway 접근 앞에 공통 관리자 인증 경계를 추가했습니다. - `JARCA_DASHBOARD_ADMIN_ID`와 `JARCA_DASHBOARD_ADMIN_PASSWORD` 환경변수만 credential source로 사용하며, 설정 오류는 fail-closed합니다. - ID와 password를 constant-time으로 비교하고 실패 로그인마다 최소 1초 지연을 적용합니다. - 인증 상태를 현재 Streamlit browser session에만 유지하고 명시적 로그아웃을 제공합니다. - 인증 event에는 credential을 기록하지 않고 correlation ID만 남깁니다. - MCP 인증과 SQLite schema는 변경하지 않았습니다. ## 문서 및 배포 설정 - `REQ-001` 요구사항과 15개 acceptance criterion을 추가했습니다. - 인터페이스 계약, 프로젝트 구조, 런타임 흐름 문서를 추가했습니다. - `.env.example`, `docker-compose.yml`, `README.md`에 secret 주입과 운영 제약을 반영했습니다. - 애플리케이션 잠금은 두지 않으므로 배포 경계에서 별도 rate limiting이 필요합니다. ## 검증 - `uv run --extra dashboard --extra dev pytest`: **84 passed, 4 skipped** - `uv run --extra dashboard --extra dev ruff check dashboard tests`: **passed** - `uv run python -m compileall -q dashboard tests`: **passed** - `git diff --check`: **passed** - canonical 문서 검증: 요구사항 8개, acceptance criterion 15개, data-model 문서 없음 - 독립 보안·논리 검토 및 명세·문서 검토: **passed, unresolved finding 없음** ## 제한사항 - Dashboard 인증만 포함하며 MCP endpoint 인증은 별도 Issue 범위입니다. - 이 실행 환경에는 Docker Compose plugin/legacy CLI가 없어 Compose CLI 검증은 수행하지 못했고, YAML 구조와 required-variable interpolation은 정적으로 검증했습니다. - 실제 운영 credential이나 금융 DB를 사용하지 않았습니다.
gitea-impl-agent added 1 commit 2026-09-25 14:42:51 +00:00
feat(dashboard): add administrator authentication
Verify and publish ARM64 image / publish (pull_request) Canceled after 0s
Verify and publish ARM64 image / verify-arm64 (pull_request) Canceled after 0s
7c2a6bdcd3
gitea-impl-agent added 1 commit 2026-09-25 14:44:37 +00:00
docs(requirements): link dashboard authentication PR
Verify and publish ARM64 image / verify-arm64 (pull_request) Canceled after 0s
Verify and publish ARM64 image / publish (pull_request) Canceled after 0s
3e0da954be
gitea-spec-agent left a comment
Owner

구현 명세 적합성 검토

Acceptance criteria 판정

  • REQ-001.01-AC01 — satisfied
    • 계약: 미인증 session은 로그인 화면만 표시하고 데이터베이스 경로 취득과 page dispatch 및 모든 금융 기능 호출을 차단한다.
    • 구현 근거: dashboard/app.py, dashboard/authentication.py, docs/project-structure.md, docs/requirements/req-001_dashboard-administrator-authentication.md, docs/runtime-flow.md. dashboard app의 인증 gate가 데이터베이스 경로 취득과 dispatch보다 먼저 즉시 반환한다. raising spy test가 거부 시 데이터베이스 경로 미호출을 검증하며 downstream 호출은 해당 반환 뒤에만 존재한다.
    • 테스트 근거: tests/test_dashboard_authentication_app.py
    • 판정 근거: 구현 순서와 no-call test가 미인증 경계를 입증한다.
  • REQ-001.01-AC02 — satisfied
    • 계약: 유효한 page query parameter도 미인증 상태에서 보호 page로 우회할 수 없다.
    • 구현 근거: dashboard/app.py, dashboard/authentication.py. page query parameter는 인증 성공 뒤에만 읽는다. Import query parameter AppTest는 로그인 화면만 표시되고 Import UI가 없음을 검증한다.
    • 테스트 근거: tests/test_dashboard_authentication_app.py
    • 판정 근거: query parsing 자체가 인증 gate 뒤에 있으며 대표적인 Import 우회 test가 통과했다.
  • REQ-001.02-AC01 — satisfied
    • 계약: 두 exact 환경변수만 credential source로 사용하고 다른 source로 fallback하지 않는다.
    • 구현 근거: dashboard/authentication.py, .env.example, docker-compose.yml, docs/interface-contract.md. loader는 JARCA_DASHBOARD_ADMIN_ID와 JARCA_DASHBOARD_ADMIN_PASSWORD만 읽는다. 대체 source 형태 값을 함께 제공한 단위 test에서도 exact 환경변수만 선택한다.
    • 테스트 근거: tests/test_dashboard_authentication.py
    • 판정 근거: source 고정과 fallback 금지가 코드와 test로 확인됐다.
  • REQ-001.02-AC02 — satisfied
    • 계약: credential 누락과 빈 값 및 비문자열과 읽기 오류는 같은 일반 오류로 fail closed한다.
    • 구현 근거: dashboard/authentication.py, dashboard/app.py, docs/interface-contract.md, docs/runtime-flow.md. loader의 type 및 empty 검증과 exception wrapping을 확인했다. 누락 조합과 비문자열과 읽기 오류 단위 test 및 설정 누락 AppTest가 통과했다.
    • 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 모든 명시된 설정 오류가 동일한 비민감 오류와 접근 차단으로 귀결된다.
  • REQ-001.03-AC01 — satisfied
    • 계약: 관리자 ID와 password를 모두 constant time primitive로 비교하고 한 비교 실패가 다른 비교를 생략하지 않는다.
    • 구현 근거: dashboard/authentication.py, docs/interface-contract.md. verify_credentials는 두 필드에 hmac.compare_digest를 각각 호출한 뒤 결과를 결합한다. 계측 test가 성공과 두 필드 실패에서 모두 두 호출을 확인한다.
    • 테스트 근거: tests/test_dashboard_authentication.py
    • 판정 근거: 두 비교 실행과 primitive 선택이 직접 검증됐다.
  • REQ-001.03-AC02 — satisfied
    • 계약: 제출 credential은 화면과 log 및 query parameter와 로그인 완료 후 session state에 남지 않는다.
    • 구현 근거: dashboard/authentication.py, docs/interface-contract.md. 성공 및 실패 rerun 경로에서 제출 key 둘을 제거하고 log helper에는 event와 correlation만 전달한다. 성공 및 실패 AppTest가 password 비보존을 확인하며 실패 test는 제출 ID도 확인한다. 성공 경로의 ID 제거는 동일 clear helper의 정적 호출로 확인했다.
    • 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: credential 제거 경로와 비민감 logging 계약이 구현 및 test로 확인됐다.
  • REQ-001.04-AC01 — satisfied
    • 계약: 잘못된 ID와 password 각각은 최소 1초 지연 후 같은 일반 오류를 표시하며 금융 기능을 호출하지 않는다.
    • 구현 근거: dashboard/authentication.py, dashboard/app.py, README.md, docs/runtime-flow.md. 두 실패 입력별 AppTest가 monotonic elapsed 1초 이상과 동일 오류를 검증했다. 실패 후 인증 gate가 false라서 app의 데이터베이스 경로와 dispatch가 실행되지 않는다.
    • 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 두 실패 유형의 시간과 오류 및 downstream 차단이 입증됐다.
  • REQ-001.04-AC02 — satisfied
    • 계약: 정상 credential에는 실패 지연을 적용하지 않고 failure counter나 lock state를 만들지 않는다.
    • 구현 근거: dashboard/authentication.py, README.md, docs/interface-contract.md. 성공 경로는 실패 지연 전에 rerun하며 AppTest의 raising delay spy가 미호출을 확인한다. source와 session key 목록에 counter 또는 lock state가 없다.
    • 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 성공 지연 미적용과 애플리케이션 잠금 부재가 확인됐다.
  • REQ-001.05-AC01 — satisfied
    • 계약: 인증 상태는 현재 browser session에서 rerun 동안 유지되고 새 session은 재인증한다.
    • 구현 근거: dashboard/authentication.py, README.md, docs/runtime-flow.md. session local boolean을 사용한다. AppTest가 로그인 후 rerun 유지와 별도 AppTest session의 로그인 화면 시작을 연속 검증한다.
    • 테스트 근거: tests/test_dashboard_authentication_app.py
    • 판정 근거: 동일 session 유지와 새 session 격리가 직접 검증됐다.
  • REQ-001.05-AC02 — satisfied
    • 계약: 명시적 로그아웃은 인증 상태를 즉시 폐기하고 로그인 화면으로 돌아간다.
    • 구현 근거: dashboard/authentication.py, README.md, docs/runtime-flow.md. sidebar 로그아웃은 인증 key를 제거하고 rerun한다. AppTest가 click 직후 로그인 화면 복귀와 Dashboard 본문 부재를 확인한다.
    • 테스트 근거: tests/test_dashboard_authentication_app.py
    • 판정 근거: 로그아웃 상태 전이와 화면 전이가 직접 검증됐다.
  • REQ-001.06-AC01 — satisfied
    • 계약: 인증 성공 후 기존 핵심 Dashboard page가 synthetic 데이터로 정상 동작한다.
    • 구현 근거: dashboard/app.py, dashboard/authentication.py, docs/project-structure.md. 기존 dispatch table은 보존됐다. synthetic SQLite와 test credential을 사용한 회귀 AppTest가 요약과 자산 마감과 분류 규칙과 확인필요 큐와 월정산을 인증 후 렌더링한다. 전체 suite도 통과했다.
    • 테스트 근거: tests/test_dashboard_app.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: 계약이 지정한 핵심 page 목록과 기존 전체 test suite가 통과했다.
  • REQ-001.06-AC02 — satisfied
    • 계약: Dashboard 인증은 MCP server 진입점과 transport 및 port를 변경하지 않고 문서가 MCP 미보호 경계를 밝힌다.
    • 구현 근거: README.md, docker-compose.yml, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md. base to head changed path 12개에 MCP source가 없고 Compose의 MCP service 설정은 변경되지 않았다. README와 계약 문서는 Dashboard 로그인으로 MCP가 보호되지 않음을 명시한다.
    • 테스트 근거: 정적 검증
    • 판정 근거: 정적 diff와 운영 문서가 범위 분리를 확인한다.
  • REQ-001.07-AC01 — satisfied
    • 계약: 환경 예시와 Dashboard Compose service는 두 exact 변수 이름을 정의하고 실제 credential 값을 저장하지 않는다.
    • 구현 근거: .env.example, docker-compose.yml, README.md. 환경 예시는 빈 값만 제공하고 Compose는 host environment의 두 변수를 required interpolation으로 주입한다. changed diff에 운영 credential 값은 없다.
    • 테스트 근거: 정적 검증
    • 판정 근거: 변수 이름과 secret 주입 경계 및 실제 값 비보존이 정적으로 확인됐다.
  • REQ-001.07-AC02 — satisfied
    • 계약: 운영 문서는 최소 1초 지연과 잠금 부재와 우회 가능성 및 배포 경계 rate limiting 필요성을 설명한다.
    • 구현 근거: README.md, docs/interface-contract.md, docs/runtime-flow.md. README가 네 조건을 함께 명시하고 환경변수 fail closed 및 Dashboard와 MCP 경계도 설명한다.
    • 테스트 근거: 정적 검증
    • 판정 근거: 필수 운영 제약 문구가 모두 존재한다.
  • REQ-001.08-AC01 — satisfied
    • 계약: 설정 오류와 로그인 성공 및 실패와 로그아웃 event는 correlation ID와 함께 기록하고 credential을 log argument에 포함하지 않는다.
    • 구현 근거: dashboard/authentication.py, docs/interface-contract.md, docs/runtime-flow.md. 모든 네 event call site는 event literal과 session local correlation만 log helper에 전달한다. logger 계측 test는 message와 argument가 event와 correlation만 포함함을 확인한다.
    • 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py
    • 판정 근거: event coverage와 비민감 argument 계약이 source 및 단위 test로 확인됐다.

범위 판정

  • 누락: 없음
  • 범위 초과: 없음
  • 명세 모순: 없음

결론

승인된 Discovery의 결정과 15개 acceptance criterion을 모두 충족한다. 변경 파일 12개는 인증 구현과 문서와 배포 설정과 테스트 범위로 설명되며 누락과 범위 초과 및 명세 모순이 없다.

## 구현 명세 적합성 검토 - Source Issue: #1 - Pull Request: #3 - Reviewed head: `3e0da954becb2c9df95117a7c815d1a942c578ec` - Contract SHA-256: `bb7e51c5d2ae8bc18d9ef07f73ccecb5a62c74090c8848a1082b90affe5b1d10` - Verdict: `approve` ### Acceptance criteria 판정 - `REQ-001.01-AC01` — `satisfied` - 계약: 미인증 session은 로그인 화면만 표시하고 데이터베이스 경로 취득과 page dispatch 및 모든 금융 기능 호출을 차단한다. - 구현 근거: dashboard/app.py, dashboard/authentication.py, docs/project-structure.md, docs/requirements/req-001_dashboard-administrator-authentication.md, docs/runtime-flow.md. dashboard app의 인증 gate가 데이터베이스 경로 취득과 dispatch보다 먼저 즉시 반환한다. raising spy test가 거부 시 데이터베이스 경로 미호출을 검증하며 downstream 호출은 해당 반환 뒤에만 존재한다. - 테스트 근거: tests/test_dashboard_authentication_app.py - 판정 근거: 구현 순서와 no-call test가 미인증 경계를 입증한다. - `REQ-001.01-AC02` — `satisfied` - 계약: 유효한 page query parameter도 미인증 상태에서 보호 page로 우회할 수 없다. - 구현 근거: dashboard/app.py, dashboard/authentication.py. page query parameter는 인증 성공 뒤에만 읽는다. Import query parameter AppTest는 로그인 화면만 표시되고 Import UI가 없음을 검증한다. - 테스트 근거: tests/test_dashboard_authentication_app.py - 판정 근거: query parsing 자체가 인증 gate 뒤에 있으며 대표적인 Import 우회 test가 통과했다. - `REQ-001.02-AC01` — `satisfied` - 계약: 두 exact 환경변수만 credential source로 사용하고 다른 source로 fallback하지 않는다. - 구현 근거: dashboard/authentication.py, .env.example, docker-compose.yml, docs/interface-contract.md. loader는 JARCA_DASHBOARD_ADMIN_ID와 JARCA_DASHBOARD_ADMIN_PASSWORD만 읽는다. 대체 source 형태 값을 함께 제공한 단위 test에서도 exact 환경변수만 선택한다. - 테스트 근거: tests/test_dashboard_authentication.py - 판정 근거: source 고정과 fallback 금지가 코드와 test로 확인됐다. - `REQ-001.02-AC02` — `satisfied` - 계약: credential 누락과 빈 값 및 비문자열과 읽기 오류는 같은 일반 오류로 fail closed한다. - 구현 근거: dashboard/authentication.py, dashboard/app.py, docs/interface-contract.md, docs/runtime-flow.md. loader의 type 및 empty 검증과 exception wrapping을 확인했다. 누락 조합과 비문자열과 읽기 오류 단위 test 및 설정 누락 AppTest가 통과했다. - 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py - 판정 근거: 모든 명시된 설정 오류가 동일한 비민감 오류와 접근 차단으로 귀결된다. - `REQ-001.03-AC01` — `satisfied` - 계약: 관리자 ID와 password를 모두 constant time primitive로 비교하고 한 비교 실패가 다른 비교를 생략하지 않는다. - 구현 근거: dashboard/authentication.py, docs/interface-contract.md. verify_credentials는 두 필드에 hmac.compare_digest를 각각 호출한 뒤 결과를 결합한다. 계측 test가 성공과 두 필드 실패에서 모두 두 호출을 확인한다. - 테스트 근거: tests/test_dashboard_authentication.py - 판정 근거: 두 비교 실행과 primitive 선택이 직접 검증됐다. - `REQ-001.03-AC02` — `satisfied` - 계약: 제출 credential은 화면과 log 및 query parameter와 로그인 완료 후 session state에 남지 않는다. - 구현 근거: dashboard/authentication.py, docs/interface-contract.md. 성공 및 실패 rerun 경로에서 제출 key 둘을 제거하고 log helper에는 event와 correlation만 전달한다. 성공 및 실패 AppTest가 password 비보존을 확인하며 실패 test는 제출 ID도 확인한다. 성공 경로의 ID 제거는 동일 clear helper의 정적 호출로 확인했다. - 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py - 판정 근거: credential 제거 경로와 비민감 logging 계약이 구현 및 test로 확인됐다. - `REQ-001.04-AC01` — `satisfied` - 계약: 잘못된 ID와 password 각각은 최소 1초 지연 후 같은 일반 오류를 표시하며 금융 기능을 호출하지 않는다. - 구현 근거: dashboard/authentication.py, dashboard/app.py, README.md, docs/runtime-flow.md. 두 실패 입력별 AppTest가 monotonic elapsed 1초 이상과 동일 오류를 검증했다. 실패 후 인증 gate가 false라서 app의 데이터베이스 경로와 dispatch가 실행되지 않는다. - 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py - 판정 근거: 두 실패 유형의 시간과 오류 및 downstream 차단이 입증됐다. - `REQ-001.04-AC02` — `satisfied` - 계약: 정상 credential에는 실패 지연을 적용하지 않고 failure counter나 lock state를 만들지 않는다. - 구현 근거: dashboard/authentication.py, README.md, docs/interface-contract.md. 성공 경로는 실패 지연 전에 rerun하며 AppTest의 raising delay spy가 미호출을 확인한다. source와 session key 목록에 counter 또는 lock state가 없다. - 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py - 판정 근거: 성공 지연 미적용과 애플리케이션 잠금 부재가 확인됐다. - `REQ-001.05-AC01` — `satisfied` - 계약: 인증 상태는 현재 browser session에서 rerun 동안 유지되고 새 session은 재인증한다. - 구현 근거: dashboard/authentication.py, README.md, docs/runtime-flow.md. session local boolean을 사용한다. AppTest가 로그인 후 rerun 유지와 별도 AppTest session의 로그인 화면 시작을 연속 검증한다. - 테스트 근거: tests/test_dashboard_authentication_app.py - 판정 근거: 동일 session 유지와 새 session 격리가 직접 검증됐다. - `REQ-001.05-AC02` — `satisfied` - 계약: 명시적 로그아웃은 인증 상태를 즉시 폐기하고 로그인 화면으로 돌아간다. - 구현 근거: dashboard/authentication.py, README.md, docs/runtime-flow.md. sidebar 로그아웃은 인증 key를 제거하고 rerun한다. AppTest가 click 직후 로그인 화면 복귀와 Dashboard 본문 부재를 확인한다. - 테스트 근거: tests/test_dashboard_authentication_app.py - 판정 근거: 로그아웃 상태 전이와 화면 전이가 직접 검증됐다. - `REQ-001.06-AC01` — `satisfied` - 계약: 인증 성공 후 기존 핵심 Dashboard page가 synthetic 데이터로 정상 동작한다. - 구현 근거: dashboard/app.py, dashboard/authentication.py, docs/project-structure.md. 기존 dispatch table은 보존됐다. synthetic SQLite와 test credential을 사용한 회귀 AppTest가 요약과 자산 마감과 분류 규칙과 확인필요 큐와 월정산을 인증 후 렌더링한다. 전체 suite도 통과했다. - 테스트 근거: tests/test_dashboard_app.py, tests/test_dashboard_authentication_app.py - 판정 근거: 계약이 지정한 핵심 page 목록과 기존 전체 test suite가 통과했다. - `REQ-001.06-AC02` — `satisfied` - 계약: Dashboard 인증은 MCP server 진입점과 transport 및 port를 변경하지 않고 문서가 MCP 미보호 경계를 밝힌다. - 구현 근거: README.md, docker-compose.yml, docs/interface-contract.md, docs/project-structure.md, docs/runtime-flow.md. base to head changed path 12개에 MCP source가 없고 Compose의 MCP service 설정은 변경되지 않았다. README와 계약 문서는 Dashboard 로그인으로 MCP가 보호되지 않음을 명시한다. - 테스트 근거: 정적 검증 - 판정 근거: 정적 diff와 운영 문서가 범위 분리를 확인한다. - `REQ-001.07-AC01` — `satisfied` - 계약: 환경 예시와 Dashboard Compose service는 두 exact 변수 이름을 정의하고 실제 credential 값을 저장하지 않는다. - 구현 근거: .env.example, docker-compose.yml, README.md. 환경 예시는 빈 값만 제공하고 Compose는 host environment의 두 변수를 required interpolation으로 주입한다. changed diff에 운영 credential 값은 없다. - 테스트 근거: 정적 검증 - 판정 근거: 변수 이름과 secret 주입 경계 및 실제 값 비보존이 정적으로 확인됐다. - `REQ-001.07-AC02` — `satisfied` - 계약: 운영 문서는 최소 1초 지연과 잠금 부재와 우회 가능성 및 배포 경계 rate limiting 필요성을 설명한다. - 구현 근거: README.md, docs/interface-contract.md, docs/runtime-flow.md. README가 네 조건을 함께 명시하고 환경변수 fail closed 및 Dashboard와 MCP 경계도 설명한다. - 테스트 근거: 정적 검증 - 판정 근거: 필수 운영 제약 문구가 모두 존재한다. - `REQ-001.08-AC01` — `satisfied` - 계약: 설정 오류와 로그인 성공 및 실패와 로그아웃 event는 correlation ID와 함께 기록하고 credential을 log argument에 포함하지 않는다. - 구현 근거: dashboard/authentication.py, docs/interface-contract.md, docs/runtime-flow.md. 모든 네 event call site는 event literal과 session local correlation만 log helper에 전달한다. logger 계측 test는 message와 argument가 event와 correlation만 포함함을 확인한다. - 테스트 근거: tests/test_dashboard_authentication.py, tests/test_dashboard_authentication_app.py - 판정 근거: event coverage와 비민감 argument 계약이 source 및 단위 test로 확인됐다. ### 범위 판정 - 누락: 없음 - 범위 초과: 없음 - 명세 모순: 없음 ### 결론 승인된 Discovery의 결정과 15개 acceptance criterion을 모두 충족한다. 변경 파일 12개는 인증 구현과 문서와 배포 설정과 테스트 범위로 설명되며 누락과 범위 초과 및 명세 모순이 없다. <!-- gitea-agent:implementation-spec-review/v1 owner=genichin repository=jarca-ledger-mcp issue=1 pr=3 head=3e0da954becb2c9df95117a7c815d1a942c578ec contract-sha256=bb7e51c5d2ae8bc18d9ef07f73ccecb5a62c74090c8848a1082b90affe5b1d10 result-sha256=7176d1fd8a1021d9850df9465501cd68dbea891b20e7e18b2babe17a1ac8535c correlation=256bc0196bf4c19232656927bba3cc7c8fa030db6e870a72996173bd43841756 -->
genichin merged commit 18384c0e0b into main 2026-09-28 06:51:13 +00:00
genichin deleted branch gitea-agent/issue-1-dashboard-admin-auth 2026-09-28 06:51:14 +00:00
Sign in to join this conversation.