Skip to main content

pas_external/oidc/
mod.rs

1//! γ port-and-adapter SDK boundary for OpenID Connect Relying Party
2//! (RP) integration.
3//!
4//! Phase 10.11 — sibling of [`crate::token`]. Where `token::*` exposes
5//! the [`BearerVerifier`](crate::token::BearerVerifier) port for RFC 9068
6//! access-token verification (the resource-server side of OAuth), this
7//! module exposes [`IdTokenVerifier`] for OIDC id_token verification
8//! (the user-authentication side). The two are intentionally disjoint:
9//! id_tokens authenticate the user *to the RP*, access_tokens authorize
10//! the RP *to the resource server* (OIDC Core §1.2 / RFC 9068 §1).
11//!
12//! Phase 11.A — adds [`RelyingParty<S>`] composition root + the
13//! [`StateStore`] port + `discovery` primitive. The verify-half
14//! ([`IdTokenVerifier`] + [`PasIdTokenVerifier`]) stays as the
15//! resource-side surface; [`RelyingParty<S>`] composes both halves
16//! (start_authorization → callback completion) for the user-flow side.
17//!
18//! ── Module layout — mirrors [`crate::token`] for parallel structure ─────
19//!
20//! - [`port`] — [`IdTokenVerifier`], [`IdAssertion`], [`IdVerifyError`]
21//!   (always compiled when `token` feature is on; depends on engine
22//!   `ScopeSet` / `Nonce` types).
23//! - [`verifier`] — [`PasIdTokenVerifier<S>`] production adapter (gated
24//!   `well-known-fetch`; depends on the engine's id_token verify entry
25//!   and a TTL-cached JWKS).
26//! - [`memory`] — [`MemoryIdTokenVerifier<S>`] +
27//!   [`InMemoryStateStore`] test-support adapters (gated
28//!   `cfg(any(test, feature = "test-support"))`).
29//! - [`state_store`] — [`StateStore`] port + value types ([`Config`],
30//!   [`State`], [`RelativePath`], [`PendingAuthRequest`],
31//!   [`AuthorizationRedirect`], [`CallbackParams`], [`Completion<S>`])
32//!   (gated `feature = "oauth"` + `feature = "token"`; Phase 11.A).
33//! - [`discovery`] — `fetch_discovery` primitive for OIDC
34//!   well-known-openid-configuration documents (gated
35//!   `feature = "well-known-fetch"`; Phase 11.A).
36//! - [`relying_party`] — [`RelyingParty<S>`] composition root (gated
37//!   `feature = "well-known-fetch"`; Phase 11.A skeleton, Phase 11.B
38//!   impl).
39//!
40//! ── Phase 9 inheritance — [`AuditSink`] reuse ───────────────────────────
41//!
42//! Verify-failure emission travels through the same
43//! [`AuditSink`](crate::AuditSink) port that [`PasJwtVerifier`](crate::PasJwtVerifier)
44//! uses. One audit pipeline serves both verifiers; consumers pass the
45//! same `Arc<dyn AuditSink>` to both `with_audit` builders. The
46//! [`VerifyErrorKind`](crate::VerifyErrorKind) enum gains an
47//! `IdToken(_)` nested variant in 10.11.B so dashboard pivots can
48//! filter "all id_token failures" with a single match arm.
49//!
50//! ── Scope re-exports ────────────────────────────────────────────────────
51//!
52//! The engine's [`scopes`](ppoppo_token::id_token::scopes) markers are
53//! re-exported here so consumers reach them via the SDK boundary:
54//!
55//! ```ignore
56//! use pas_external::oidc::{IdTokenVerifier, Openid, Email, EmailProfile};
57//! ```
58//!
59//! rather than depending on `ppoppo-token` directly. This preserves the
60//! γ invariant: the engine type never crosses the SDK boundary except
61//! through SDK-shaped re-exports.
62
63#[cfg(feature = "token")]
64pub mod port;
65
66#[cfg(feature = "well-known-fetch")]
67pub(crate) mod verifier;
68
69#[cfg(all(feature = "token", feature = "oauth"))]
70pub mod state_store;
71
72#[cfg(feature = "well-known-fetch")]
73pub mod discovery;
74
75#[cfg(feature = "well-known-fetch")]
76pub mod relying_party;
77
78#[cfg(feature = "well-known-fetch")]
79pub mod refresh_outcome;
80
81#[cfg(all(feature = "token", any(test, feature = "test-support")))]
82pub mod memory;
83
84// Phase 11.X.C — perimeter `BearerAuthLayer` lifted from chat-auth +
85// RCW + CTW (N=3 evidence). Lives in its own submodule so the namespace
86// signals "axum-framework adapter for the OIDC perimeter" vs the
87// generic `oidc::*` (id_token verify-half, RP composition root). No
88// crate-level or `oidc::*`-level re-export — consumers import via the
89// explicit `pas_external::oidc::axum::*` path so the framework
90// dependency is visible at the import site. See
91// `RFC_2026-05-07_oidc-rp-phase-11x-rcw-ctw-migration.md` §11.
92#[cfg(feature = "axum")]
93pub mod axum;
94
95#[cfg(feature = "token")]
96pub use port::{Address, IdAssertion, IdTokenVerifier, IdVerifyError, ScopePiiReader};
97
98#[cfg(all(feature = "token", feature = "oauth"))]
99pub use state_store::{
100    AuthorizationRedirect, CallbackParams, Completion, Config, PendingAuthRequest, RelativePath,
101    RelativePathError, State, StateStore, StateStoreError,
102};
103
104#[cfg(feature = "well-known-fetch")]
105pub use discovery::{fetch_discovery, Discovery, DiscoveryError};
106
107#[cfg(feature = "well-known-fetch")]
108pub use relying_party::{
109    CallbackError, RefreshError, RelyingParty, RelyingPartyInitError, RequestedScope, StartError,
110};
111
112#[cfg(feature = "well-known-fetch")]
113pub use refresh_outcome::RefreshOutcome;
114
115#[cfg(all(feature = "token", any(test, feature = "test-support")))]
116pub use memory::MemoryIdTokenVerifier;
117
118#[cfg(all(
119    feature = "token",
120    feature = "oauth",
121    any(test, feature = "test-support")
122))]
123pub use memory::InMemoryStateStore;
124
125// Engine re-exports — consumers reach scope markers + Nonce via the SDK
126// boundary rather than depending on `ppoppo-token` directly.
127#[cfg(feature = "token")]
128pub use ppoppo_token::id_token::{
129    Nonce,
130    scopes::{
131        Email, EmailProfile, EmailProfilePhone, EmailProfilePhoneAddress, HasAddress, HasEmail,
132        HasPhone, HasProfile, Openid, Profile, ScopeSet,
133    },
134};