Skip to main content

slim_auth/
errors.rs

1// Copyright AGNTCY Contributors (https://github.com/agntcy)
2// SPDX-License-Identifier: Apache-2.0
3
4use http::StatusCode;
5#[cfg(not(target_arch = "wasm32"))]
6use jsonwebtoken::jwk::KeyAlgorithm;
7
8#[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
9use spiffe::{
10    JwtSourceError, JwtSvidError, SpiffeIdError, TrustDomain, WorkloadApiError, X509SourceError,
11};
12
13use thiserror::Error;
14
15#[derive(Error, Debug)]
16pub enum AuthError {
17    // JWT errors
18    #[cfg(not(target_arch = "wasm32"))]
19    #[error("unsupported key algorithm: {0}")]
20    JwtUnsupportedKeyAlgorithm(KeyAlgorithm),
21    #[error("JWK does not contain the key algorithm (alg) field")]
22    JwtMissingKeyAlgorithm,
23    #[error("no private key available for signing")]
24    JwtMissingPrivateKey,
25    #[error("missing decoding key or autoresolve is disabled")]
26    JwtMissingDecodingKeyOrKeyResolver,
27    #[error("missing 'iss' in JWT claims")]
28    JwtMissingIssuer,
29    #[error("no key resolver available")]
30    JwtNoKeyResolver,
31    #[error("no static JWT token configured")]
32    JwtNoStaticTokenConfigured,
33    #[error("JWK format not supported for encoding (signing) keys")]
34    JwtJwkFormatNotSupportedForEncoding,
35    #[error("failed to fetch JWKS for issuer - status_code: {0}")]
36    JwtFetchJwksFailed(StatusCode),
37    #[error("StaticTokenProvider does not support custom claims")]
38    JwtStaticUnsupportedCustomClaims,
39
40    // OIDC/Oauth2 errors
41    #[error("token_endpoint not found in discovery document")]
42    OidcDiscoveryMissingTokenEndpoint,
43    #[error("OIDC discovery document missing 'issuer' field")]
44    OidcDiscoveryMissingIssuer,
45    #[error("OIDC discovery 'issuer' mismatch: expected '{expected}', got '{got}'")]
46    OidcDiscoveryIssuerMismatch { expected: String, got: String },
47    #[error("OIDC discovery field '{field}' URL '{url}' does not share origin with issuer")]
48    OidcDiscoveryUrlOriginMismatch { field: &'static str, url: String },
49    #[error("OIDC issuer URL must use https (got: {0})")]
50    OidcInsecureIssuerUrl(String),
51    #[error("key not found: {0}")]
52    OidcKeyNotFound(String),
53    #[error("kid is missing and multiple keys are available")]
54    OidcMissingKidWithMultipleKeys,
55    #[error("OIDC Token Provider does not support custom claims")]
56    OidcUnsupportedCustomClaims,
57    #[error("Token endpoint error: status {status}, body: {body}")]
58    TokenEndpointError { status: u16, body: String },
59    #[error("Invalid client credentials")]
60    InvalidClientCredentials,
61    #[error("refresh token revoked or expired")]
62    RefreshTokenRevoked,
63
64    // hmac
65    #[error("hmac key is too short")]
66    HmacKeyTooShort,
67    #[error("hmac key is missing")]
68    HmacKeyMissing,
69
70    // Time
71    #[error("time error")]
72    TimeError(#[from] std::time::SystemTimeError),
73
74    // URL parsing
75    #[cfg(not(target_arch = "wasm32"))]
76    #[error("URL parse error")]
77    UrlParseError(#[from] url::ParseError),
78
79    // Header parsing
80    #[error("invalid header name")]
81    HeaderNameError(#[from] http::header::InvalidHeaderName),
82    #[error("invalid header value")]
83    HeaderValueError(#[from] http::header::InvalidHeaderValue),
84
85    // File watcher
86    #[cfg(not(target_arch = "wasm32"))]
87    #[error("file watcher error")]
88    FileWatcherError(#[from] crate::file_watcher::FileWatcherError),
89
90    // Token lifecycle
91    #[error("no token available")]
92    GetTokenError,
93    #[error("token invalid")]
94    TokenInvalid,
95    #[error("token malformed")]
96    TokenMalformed,
97    #[error("token invalid: missing subject claim")]
98    TokenInvalidMissingSub,
99    #[error("token invalid: replay")]
100    TokenInvalidReplay,
101    #[cfg(not(target_arch = "wasm32"))]
102    #[error("token invalid")]
103    JwtTokenInvalid(#[from] jsonwebtoken::errors::Error),
104    #[error("token invalid - missing or invalid exp claim")]
105    TokenInvalidMissingExp,
106
107    // HTTP / networking
108    #[cfg(not(target_arch = "wasm32"))]
109    #[error("HTTP request error")]
110    HttpError(#[from] reqwest::Error),
111
112    // JWKS / key resolution
113    #[error("failed to parse JWKS: {source}")]
114    JwksParse { source: serde_json::Error },
115    #[error("no suitable key found in JWKS for token header")]
116    JwksNoSuitableKey,
117    #[error("no cached JWKS for issuer: {issuer}")]
118    JwksCacheMiss { issuer: String },
119    #[error("openid discovery document missing jwks_uri field")]
120    OidcDiscoveryMissingJwksUri,
121    #[error("cached JWKS expired for issuer: {issuer}")]
122    JwksCacheExpired { issuer: String },
123
124    // SPIFFE / SPIRE integration
125    #[error("spire integration is not supported on Windows")]
126    SpireUnsupportedOnWindows,
127    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
128    #[error("serde error while encoding audience: {source}")]
129    SpiffeCustomClaimsSerialize { source: serde_json::Error },
130    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
131    #[error("spiffe error")]
132    SpiffeError(#[from] SpiffeIdError),
133    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
134    #[error("spiffe grpc error")]
135    SpiffeGrpcError(#[from] WorkloadApiError),
136    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
137    #[error("spiffe workload api unavailable")]
138    SpiffeWorkloadApiUnavailable,
139    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
140    #[error("spiffe x509 source error")]
141    SpiffeX509SourceError(#[from] X509SourceError),
142    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
143    #[error("spiffe jwt source error")]
144    SpiffeJwtSourceError(#[from] JwtSourceError),
145    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
146    #[error("jwt source not initialized")]
147    SpiffeJwtSourceNotInitialized,
148    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
149    #[error("missing jwt svid")]
150    SpiffeJwtSvidMissing,
151    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
152    #[error("missing jwt bundle")]
153    SpiffeJwtBundleMissing,
154    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
155    #[error("invalid JWT svid")]
156    SpiffeInvalidJwtSvid(#[from] JwtSvidError),
157    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
158    #[error("failed to fetch x509 SVID")]
159    SpiffeX509SvidMissing,
160    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
161    #[error("x509 source not initialized")]
162    SpiffeX509SourceNotInitialized,
163    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
164    #[error("x509 trust bundle not available: {0}")]
165    SpiffeX509BundleMissing(TrustDomain),
166    #[cfg(all(not(target_arch = "wasm32"), not(target_family = "windows")))]
167    #[error("spire x509 empty certificate chain")]
168    SpiffeX509EmptyCertChain,
169    // Serialization
170    #[error("JSON serialization error")]
171    JsonError(#[from] serde_json::Error),
172    #[error("base64 decode error")]
173    Base64DecodeError(#[from] base64::DecodeError),
174
175    // Rego policy
176    #[error("rego policy compilation failed: {0}")]
177    PolicyCompile(String),
178
179    // Operational
180    #[error("operation would block on async I/O; call async variant")]
181    WouldBlockOn,
182
183    // MLS
184    #[error("MLS is not supported by this provider")]
185    MlsNotSupported,
186    #[error("MLS signature key generation failed")]
187    MlsKeyGenerationFailed,
188    #[error("public key not found in identity claims")]
189    PublicKeyNotFound,
190    #[error("subject not found in identity claims")]
191    SubjectNotFound,
192}