Skip to main content

oauth_resource_server/
lib.rs

1// The crate documentation IS the README, so its Rust snippets run as doctests
2// and the two cannot drift. Those snippets use the `serde`, `env` and `axum`
3// features, so the README is included only when all three are on (as with
4// `--all-features`, which CI and docs.rs use); any narrower build gets the
5// short pointer below instead, rather than doctests that cannot compile.
6#![cfg_attr(
7    all(feature = "serde", feature = "env", feature = "axum"),
8    doc = include_str!("../README.md")
9)]
10// Linked for rustdoc readers; the README itself has no intra-doc links, since
11// GitHub and crates.io would render them as literal brackets.
12#![cfg_attr(
13    all(feature = "serde", feature = "env", feature = "axum"),
14    doc = "
15## API map
16
17| Item | Role |
18|---|---|
19| [`OAuthConfig`], [`OAuthConfig::resolve`] | The unvalidated settings, and their all-or-nothing validation into a [`ResolvedOAuthConfig`] or a [`ConfigError`]. [`KeyNaming`] decides how problems name settings. |
20| [`OAuthValidator`] | Validates one token ([`OAuthValidator::validate`]), renders the challenges and the metadata document, and keeps the signing keys fresh ([`OAuthValidator::spawn_background_refresh`]). |
21| [`AuthorizedToken`], [`TokenRejection`] | The two outcomes of a validation. |
22| [`authenticate`], [`Credential`] | Framework-free checking of several candidate credentials against a static token and OAuth. |
23| [`Algorithm`], [`parse_algorithm`], [`AlgorithmError`] | The JWS algorithms a config may allow (never HMAC or `none`). |
24| [`static_token_policy`], [`StaticTokenDecision`] | The startup decision about a static API key alongside OAuth. |
25| [`axum::AuthLayer`], [`axum::require_auth`], [`axum::metadata_router`] | The axum integration (feature `axum`). |
26| [`env::oauth_config_from_env`], [`env::secret_from_env`] | Configuration from environment variables (feature `env`). |"
27)]
28// The last row links the `testing` module, which exists only with that feature;
29// without it the row is rendered with no link, so a `serde,env,axum` doc build
30// has no unresolved intra-doc link.
31#![cfg_attr(
32    all(
33        feature = "serde",
34        feature = "env",
35        feature = "axum",
36        feature = "testing"
37    ),
38    doc = "| [`testing`] | Fixtures for your tests (feature `testing`). |"
39)]
40#![cfg_attr(
41    all(
42        feature = "serde",
43        feature = "env",
44        feature = "axum",
45        not(feature = "testing")
46    ),
47    doc = "| `testing` | Fixtures for your tests (feature `testing`, not enabled in this build). |"
48)]
49#![cfg_attr(
50    not(all(feature = "serde", feature = "env", feature = "axum")),
51    doc = "OAuth 2.0 bearer-token resource server for Rust HTTP services: JWT \
52           access-token validation against a JWKS (RFC 9068), RFC 9728 \
53           protected-resource metadata, RFC 6750 `WWW-Authenticate` challenges, an \
54           optional static API key alongside OAuth, and axum integration.\n\n\
55           The full guide is this crate's README, which becomes the crate \
56           documentation when it is built with the `serde`, `env` and `axum` \
57           features (as on docs.rs): <https://docs.rs/oauth-resource-server>."
58)]
59#![cfg_attr(docsrs, feature(doc_cfg))]
60#![warn(missing_docs)]
61#![forbid(unsafe_code)]
62
63// Without a TLS backend reqwest cannot fetch an https JWKS, and every real
64// authorization server serves its keys over https — the validator would build,
65// then fail closed on every token. Refuse at compile time instead. No cfg(test)
66// or docs exemption: `cargo test` and `cargo doc` build with the default
67// feature set, which includes `rustls-tls`.
68#[cfg(not(any(
69    feature = "rustls-tls",
70    feature = "rustls-tls-native-roots",
71    feature = "native-tls"
72)))]
73compile_error!(
74    "oauth-resource-server needs a TLS backend for JWKS fetches: enable the `rustls-tls` \
75     (default), `rustls-tls-native-roots` or `native-tls` feature"
76);
77
78mod algorithms;
79mod challenge;
80pub mod config;
81mod jwks;
82mod token;
83mod validator;
84
85mod authenticate;
86mod policy;
87
88#[cfg(feature = "env")]
89#[cfg_attr(docsrs, doc(cfg(feature = "env")))]
90pub mod env;
91
92#[cfg(feature = "axum")]
93#[cfg_attr(docsrs, doc(cfg(feature = "axum")))]
94pub mod axum;
95
96#[cfg(any(test, feature = "testing"))]
97#[cfg_attr(docsrs, doc(cfg(feature = "testing")))]
98pub mod testing;
99
100pub use algorithms::{Algorithm, AlgorithmError, DEFAULT_ALGORITHMS, parse_algorithm};
101pub use authenticate::{Credential, authenticate};
102pub use challenge::PROTECTED_RESOURCE_METADATA_PREFIX;
103pub use config::{
104    ConfigError, DEFAULT_LEEWAY_SECS, DEFAULT_PRINCIPAL_CLAIMS, DEFAULT_SCOPE_CLAIMS, KeyNaming,
105    KeyNamingBuf, MAX_LEEWAY_SECS, OAuthConfig, ResolvedOAuthConfig,
106};
107pub use jwks::RefreshError;
108pub use policy::{NoAuthConfigured, StaticTokenDecision, static_token_policy};
109pub use token::{AuthorizedToken, TokenRejection};
110pub use validator::{OAuthValidator, ValidatorError};