Skip to content

feat: credential registry for admin secrets (env as bootstrap only) - #55

Merged
seonghobae merged 5 commits into
mainfrom
feat/credential-registry-admin-secrets
Aug 2, 2026
Merged

feat: credential registry for admin secrets (env as bootstrap only)#55
seonghobae merged 5 commits into
mainfrom
feat/credential-registry-admin-secrets

Conversation

@seonghobae

@seonghobae seonghobae commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

Why

Buyers (and org governance) expect secrets not to be the long-term runtime source of truth via raw std::env::var. Admin tokens were still read directly from env in run_from_env.

What changed

  • Added CredentialRegistry with get_credential for secret-bearing keys (admin_token, admin_tokens).
  • Bootstrap precedence: WAF_IDS_CREDENTIALS_PATH JSON per-key, then env fill for missing keys.
  • run_from_env seeds auth from the registry; operational config remains env for now.
  • /healthz reports credentials_source (file|env|none) and admin_auth_configured without secret values.
  • Ops runbook + threat model + AGENTS guidance updated.

Buyer impact

Operators can ship lab/prod packaging with a credentials file instead of baking tokens only into the process environment, and health evidence proves auth was configured without leaking tokens.

Test plan

  • cargo fmt --check
  • cargo test --locked --workspace
  • cargo clippy --locked --workspace --all-targets -- -D warnings

Summary by CodeRabbit

  • 새 기능

    • 관리자 인증 정보를 환경 변수 또는 credentials 파일에서 안전하게 불러옵니다.
    • credentials 파일 설정이 환경 변수보다 우선하며, 누락된 값은 환경 변수로 보완됩니다.
    • Health Check에 인증 정보 출처와 관리자 인증 설정 여부가 표시됩니다.
  • 문서

    • 운영 런북과 보안 위협 모델에 인증 정보 관리 및 보안 지침을 추가했습니다.

Load ADMIN_TOKEN / ADMIN_TOKENS through a process-local
CredentialRegistry (get_credential) seeded from optional
WAF_IDS_CREDENTIALS_PATH JSON (preferred) or env bootstrap.
Expose credentials_source and admin_auth_configured on /healthz
without leaking secret values. Document ops/threat-model path.
@coderabbitai

coderabbitai Bot commented Jul 31, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

관리자 자격 증명을 시작 시 CredentialRegistry에 등록합니다. 파일 값을 환경 변수보다 우선합니다. 런타임 인증은 레지스트리에서 값을 읽습니다. Health 응답은 자격 증명 출처와 관리자 인증 설정 여부를 표시합니다.

Changes

관리자 자격 증명 레지스트리 흐름

Layer / File(s) Summary
레지스트리와 부트스트랩 구현
src/credentials.rs
CredentialRegistryCredentialSource를 추가했습니다. JSON 파일의 값을 우선 적용하고, 누락된 값은 환경 변수로 보완합니다. 파일 읽기 및 JSON 파싱 오류를 반환합니다. 관련 테스트를 추가했습니다.
런타임 인증과 Health 상태 연결
src/lib.rs
run_from_env가 레지스트리에서 관리자 토큰과 RBAC 토큰을 읽도록 변경했습니다. AppStateHealthStatus에 자격 증명 출처와 관리자 인증 설정 여부를 추가했습니다. 관련 실행 및 Health 테스트를 갱신했습니다.
운영 및 보안 문서 갱신
AGENTS.md, docs/runbooks/operations.md, docs/security/threat-model.md
CredentialRegistry 설정, credentials 파일 형식, Health 필드, 비밀값 보호 통제를 문서화했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant run_from_env
  participant CredentialRegistry
  participant AppConfig
  participant AppState
  participant HealthStatus
  run_from_env->>CredentialRegistry: 관리자 토큰과 RBAC 토큰 부트스트랩
  CredentialRegistry-->>run_from_env: 토큰 조회와 출처 반환
  run_from_env->>AppConfig: 관리자 인증 설정
  run_from_env->>AppState: credentials_source 설정
  AppState->>HealthStatus: 출처와 admin_auth_configured 계산
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 관리자 비밀을 위한 CredentialRegistry 도입과 환경 변수의 부트스트랩 역할을 정확하고 간결하게 설명합니다.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/credential-registry-admin-secrets

Comment @coderabbitai help to get the list of available commands.

@seonghobae
seonghobae enabled auto-merge (squash) July 31, 2026 13:28

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

🧹 Nitpick comments (1)
src/lib.rs (1)

1775-1832: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

run_from_env의 자격 증명 배선은 정확합니다. 파일 기반 경로에 대한 통합 테스트를 추가하는 것을 권장합니다.

run_from_envCredentialRegistry::bootstrap_secrets를 호출하고, 그 결과로 AppConfig.admin_token, admin_tokens, with_credentials_source를 올바르게 채웁니다. 다만 기존 run_from_env 테스트 중 WAF_IDS_CREDENTIALS_PATH를 실제로 설정해 파일 기반 자격 증명이 끝까지 반영되는지 확인하는 테스트가 없습니다. credentials.rs의 단위 테스트는 bootstrap_secrets만 검증합니다. health_reports_runtime_configuration 테스트는 with_credentials_source를 직접 호출합니다. 두 부분을 run_from_env를 통해 연결하는 종단 테스트를 추가하면 배선 회귀를 조기에 잡을 수 있습니다.

원한다면 이 테스트를 작성해 드릴까요?

Also applies to: 1864-1864

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/lib.rs` around lines 1775 - 1832, Add an end-to-end test covering
run_from_env with WAF_IDS_CREDENTIALS_PATH pointing to a temporary credentials
file. Verify the file-backed admin token and admin tokens are applied through
AppConfig and the built application, and that the runtime configuration reports
the credentials source from the registry. Keep the test focused on the full
run_from_env wiring rather than only testing
CredentialRegistry::bootstrap_secrets.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@AGENTS.md`:
- Line 33: Remove the unauthorized “Remaining deviation” exception in the
AGENTS.md configuration guidance by either migrating the operational settings
currently read via std::env::var() in the configuration-loading flow to
CredentialRegistry/KV access, or explicitly documenting a tracking issue for
adopting a durable store and completing that migration.

In `@docs/runbooks/operations.md`:
- Around line 41-42: Update the health reporting description in the operations
runbook to clarify that credentials_source=file means at least one credential
was loaded from a file, even when other missing values were supplemented from
the environment; it does not mean all credentials came from the file. Preserve
the existing file/env/none values and admin_auth_configured description.
- Around line 26-38: Update the credentials-file guidance around
WAF_IDS_CREDENTIALS_PATH to require service-account ownership, chmod 600
permissions, exclusion from repository commits and backups, and external
secret-manager usage in production. Reference the existing
docs/security/threat-model.md hardening requirement and retain the current
example commands.
- Around line 15-19: Update the “Admin secrets (credential registry)” section to
accurately describe the startup data path: CredentialRegistry values are copied
into AppConfig and AppState during bootstrap, and runtime authentication uses
those stored values rather than querying the registry per request. Explicitly
state that changes to the credentials file or bootstrap environment take effect
only after restarting the process.

In `@docs/security/threat-model.md`:
- Line 31: Update the threat-model table entry’s health disclosure wording to
state that health exposes only the two non-sensitive fields, credentials_source
and admin_auth_configured, while preserving that no secret values are disclosed.

In `@src/credentials.rs`:
- Around line 59-65: Update has_admin_auth so the CRED_ADMIN_TOKEN check trims
its value before testing for emptiness, matching the existing CRED_ADMIN_TOKENS
validation and treating whitespace-only tokens as unset.
- Around line 38-44: Replace the derived Debug implementation on
CredentialRegistry with a manual implementation that never formats the values
map or its secret contents. Preserve Debug output for non-sensitive metadata
such as source, and keep the existing Clone and Default derives unchanged.
- Around line 136-149: Update json_value_as_nonempty_string so only non-empty
JSON string values return Some(text); return None for numbers, booleans, arrays,
objects, null, and empty strings, removing the fallback conversion through
to_string().

---

Nitpick comments:
In `@src/lib.rs`:
- Around line 1775-1832: Add an end-to-end test covering run_from_env with
WAF_IDS_CREDENTIALS_PATH pointing to a temporary credentials file. Verify the
file-backed admin token and admin tokens are applied through AppConfig and the
built application, and that the runtime configuration reports the credentials
source from the registry. Keep the test focused on the full run_from_env wiring
rather than only testing CredentialRegistry::bootstrap_secrets.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dd7af366-3f01-4103-8414-2b7aa9e16f3e

📥 Commits

Reviewing files that changed from the base of the PR and between 7b72432 and 9002194.

📒 Files selected for processing (5)
  • AGENTS.md
  • docs/runbooks/operations.md
  • docs/security/threat-model.md
  • src/credentials.rs
  • src/lib.rs

Comment thread AGENTS.md
Comment thread docs/runbooks/operations.md
Comment thread docs/runbooks/operations.md
Comment thread docs/runbooks/operations.md
Comment thread docs/security/threat-model.md
Comment thread src/credentials.rs
Comment thread src/credentials.rs
Comment thread src/credentials.rs
@opencode-agent
opencode-agent Bot disabled auto-merge July 31, 2026 13:48
@seonghobae
seonghobae enabled auto-merge (squash) August 2, 2026 10:32
@opencode-agent
opencode-agent Bot disabled auto-merge August 2, 2026 10:32
@seonghobae
seonghobae enabled auto-merge (squash) August 2, 2026 10:32
@seonghobae
seonghobae merged commit fa57eda into main Aug 2, 2026
34 checks passed
@seonghobae
seonghobae deleted the feat/credential-registry-admin-secrets branch August 2, 2026 10:44
seonghobae added a commit that referenced this pull request Aug 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant