#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq)]
pub enum AuthError {
#[error("M66: nonce claim absent from payload")]
NonceMissing,
#[error("M66: nonce does not match expected value")]
NonceMismatch,
#[error("nonce config: empty value")]
NonceConfigEmpty,
#[error("M67: at_hash claim absent from payload")]
AtHashMissing,
#[error("M67: at_hash does not match expected access_token binding")]
AtHashMismatch,
#[error("M68: c_hash claim absent from payload")]
CHashMissing,
#[error("M68: c_hash does not match expected authorization_code binding")]
CHashMismatch,
#[error("M69: azp claim absent on multi-audience id_token")]
AzpMissing,
#[error("M69: azp does not match expected client_id")]
AzpMismatch,
#[error("M70: auth_time claim absent while max_age is configured")]
AuthTimeMissing,
#[error("M70: auth_time exceeds max_age window — re-authentication required")]
AuthTimeStale,
#[error("M71: acr claim absent while acr_values is configured")]
AcrMissing,
#[error("M71: acr value not in configured acr_values allowlist")]
AcrNotAllowed,
#[error("M72: unknown id_token claim '{0}' outside per-scope allowlist")]
UnknownClaim(String),
#[error("M29-mirror: id_token cat must be 'id', got '{0}'")]
CatMismatch(String),
#[error(transparent)]
Jose(#[from] crate::SharedAuthError),
}