ppoppo-sdk-core 0.2.0

Internal shared primitives for the Ppoppo SDK family (pas-external, pas-plims, pcs-external) — verifier port, audit trait, session liveness port, OIDC discovery, perimeter Bearer-auth Layer kit, identity types. Not a stable public API; do not depend on this crate directly. Consume the SDK crates that re-export from it (e.g. `pas-external`).
Documentation
//! γ port — `BearerVerifier` trait.
//!
//! The SDK's verification surface, format-blind by design. Consumers
//! receive a [`VerifiedClaims`](super::VerifiedClaims) that exposes
//! typed accessors for the values they need (`ppnum_id`, `ppnum`,
//! `session_id`, `expires_at`) without ever seeing the underlying JWT
//! or the `jsonwebtoken` / `ppoppo_token` types. Swapping the
//! production [`JwtVerifier`](super::JwtVerifier) adapter for the
//! in-memory test adapter
//! ([`MemoryBearerVerifier`](super::MemoryBearerVerifier), gated
//! behind `test-support`) requires zero consumer changes — the port is
//! the contract.
//!
//! D-04 (locked γ, 2026-05-05): port-and-adapter SDK boundary; the
//! engine becomes the only place that knows JWT.

use async_trait::async_trait;

use super::{VerifiedClaims, VerifyError};

/// Verification port for incoming bearer tokens.
///
/// Implementations swap the cryptographic backend without altering the
/// caller's surface. The production [`super::JwtVerifier`] verifies
/// PAS-issued JWTs against a TTL-cached JWKS; the test-support
/// [`super::MemoryBearerVerifier`] returns canned
/// [`VerifiedClaims`] values keyed by the bare token string.
///
/// `verify` is async because the production adapter performs
/// stale-on-failure JWKS refresh inside the verify path, and any
/// future 3rd-party adapter is free to make HTTP calls. Caller
/// middleware that needs synchronous semantics wraps the call in
/// `tokio::block_on`; the port itself stays uniformly async.
///
/// The single `bearer_token` parameter mirrors the M38 transport-blind
/// invariant: the engine never reaches into request framing, and
/// neither does the SDK port. Consumer middleware extracts the bare
/// token before calling.
#[async_trait]
pub trait BearerVerifier: Send + Sync {
    async fn verify(&self, bearer_token: &str) -> Result<VerifiedClaims, VerifyError>;
}