feat(auth): rfc 0029 green (config) — auth.oidc section, coexistence rules, oidc-only enforced - #422
Conversation
…rules, oidc-only enforced
RFC0029.1: auth.oidc {issuer, audience, tenant_claim, name_claim}
parses with ${env} substitution; missing audience / neither-half /
explicit tokens: [] (unconditionally) each fail startup; an
oidc-only config serves with the gates enforced via an empty store
bridge (retired by the verifier slice), never open.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR adds RFC 0029 OIDC configuration alongside existing RFC 0026 bearer token auth. Core introduces OidcSpec/OidcConfig/AuthConfig types with validation and an enforcement_store method. Server config schema makes tokens optional and adds an oidc section. Server auth mapping and main.rs wiring are updated to resolve and use AuthConfig, and new integration tests cover OIDC-only startup and enforcement behavior. ChangesOIDC-aware auth resolution
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant MainRs as main.rs
participant ServerAuth as server::auth
participant CoreAuth as core::auth
participant Listener as OTLP/Querier
MainRs->>ServerAuth: build_auth_config(file.auth)
ServerAuth->>CoreAuth: build_auth_config(tokens, oidc)
CoreAuth-->>ServerAuth: AuthConfig (tokens + oidc)
ServerAuth-->>MainRs: Option<AuthConfig>
MainRs->>MainRs: enforcement_store(&config)
MainRs->>CoreAuth: auth.enforcement_store()
CoreAuth-->>MainRs: Option<Arc<TokenStore>>
MainRs->>Listener: construct with auth = enforcement_store
Listener->>CoreAuth: authenticate(bearer)
CoreAuth-->>Listener: match or none (401)
Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Pull request overview
Implements the first “green” slice of RFC 0029 (scenario RFC0029.1) by adding config/schema support for an auth.oidc section, enforcing the RFC coexistence rules between static tokens and OIDC, and ensuring oidc-only configs start in enforced (not open) mode via an empty enforcement store bridge.
Changes:
- Add
auth.oidcschema +${env:…}substitution support, and makeauth.tokensoptional to distinguish omitted vs explicitly empty. - Introduce core
OidcSpec/OidcConfigandAuthConfigwithbuild_auth_config+ validation rules (missing audience, neither-half configured, explicittokens: []always invalid). - Wire server startup to pass the enforcement store derived from
AuthConfig, plus add end-to-end integration tests asserting startup failures and oidc-only enforced behavior.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/ourios-server/tests/it/rfc0029_oidc.rs | Converts RFC0029.1 stub into integration tests covering startup validation errors and oidc-only enforced serving. |
| crates/ourios-server/src/main.rs | Switches from TokenStore to AuthConfig in resolved config, adds enforcement_store() adapter, and updates mapping tests. |
| crates/ourios-server/src/config/file.rs | Extends file schema with auth.oidc and changes auth.tokens to Option<Vec<_>> to support oidc-only shape. |
| crates/ourios-server/src/auth.rs | Adds build_auth_config mapping from file schema into core AuthConfig (static tokens + optional OIDC spec). |
| crates/ourios-core/src/auth.rs | Introduces OIDC spec/config + auth config validation, plus the enforcement-store bridge behavior for oidc-only configs. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… explicit Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
First RFC 0029 green slice: scenario RFC0029.1 (config resolution) end to end.
auth.oidc {issuer, audience, tenant_claim, name_claim}parses with${env:…}substitution (schema arms inconfig::file, validation matrix inourios_core::auth, mapping insrc/main.rs, startup-observable arms against the spawned binary intests/it/rfc0029_oidc.rs).audiencefails; anauthsection with neithertokensnoroidcfails; an explicittokens: []fails unconditionally (the coexistence rule settled in docs(rfc): rfc 0029 — oidc bearer layer (issuer-agnostic, dex-validated), drafted #419 review); omittingtokensis the oidc-only shape (AuthSection.tokensbecameOptionso absent ≠ empty).AuthConfig::enforcement_store()hands the listeners an empty store (every bearer 401s) until the verifier slice teaches the gates the full config and retires the bridge. The it-test asserts the 401 on a real socket and that no open-mode warning is emitted. Open mode (noauthsection) is byte-for-byte unchanged.ourios_core::authgrowsOidcSpec/OidcConfig/AuthConfig+build_auth_config/build_oidc_config; RFC 0026'sbuild_token_storerules are unchanged (its empty-list error message now points at the oidc-only alternative).Verified locally:
cargo fmt --check, clippy-D warnings(all targets/features), full workspace suite 965/965 (30 skipped = the#[ignore]d red stubs + known-manual tests).Next slices: verifier (fixture issuer, .2/.6), binding (.3–.5), Dex acceptance (.7).
🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes