Skip to main content

ppoppo_token/
algorithm.rs

1//! Sealed JWS signature algorithm whitelist (Phase 7 §6.8 — structural M51/M52/M54).
2//!
3//! Shared by both token profiles (RFC 9068 access tokens, OIDC Core 1.0 id
4//! tokens) — the algorithm vocabulary is JOSE-level, not profile-level.
5//! Living at the crate root so neither `access_token::*` nor `id_token::*`
6//! can claim ownership.
7//!
8//! Only `EdDSA` exists. Consumer attempts to construct `Algorithm::HS256`
9//! or any other variant fail at compile time (`variant not found`),
10//! making M51/M52/M54 enforcement structural rather than lint-based.
11//! `jsonwebtoken::Algorithm` is no longer re-exported — `crates/shared/ppoppo-token`
12//! owns the algorithm vocabulary.
13//!
14//! Adding a new variant is a deliberate spec change — the matrix M02/M06
15//! rows must be revisited and the negative regression in
16//! `tests/jwt_negative.rs` reinstated to cover the cfg-vs-header SSOT
17//! invariant.
18
19#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
20pub enum Algorithm {
21    /// EdDSA over Ed25519 — RFC 9068 access-token profile and (post-Phase
22    /// 10.1) OIDC Core 1.0 id-token profile.
23    EdDSA,
24}
25
26impl std::str::FromStr for Algorithm {
27    type Err = ();
28
29    /// Parse the `alg` header field. Anything other than `"EdDSA"` is
30    /// rejected — family-level rejections (HS/RS/ES) fire earlier in
31    /// `check_algorithm::run` to give audit logs the family signal.
32    fn from_str(s: &str) -> Result<Self, Self::Err> {
33        match s {
34            "EdDSA" => Ok(Algorithm::EdDSA),
35            _ => Err(()),
36        }
37    }
38}