1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
// #![cfg_attr(docsrs, feature(doc_cfg))]
//! [](https://opensource.org/licenses/Apache-2.0)
//! [](https://github.com/vakamo-labs/limes-rs/actions/workflows/unittests.yaml)
//!
//! # Limes
//!
//! Limes is a multi-tenant capable Authentication middleware for OAuth2.0 and Open ID Connect with optional support for `axum`.
//! It supports the following [`Authenticator`]s natively:
//!
//! * [`JWKSWebAuthenticator`](`jwks::JWKSWebAuthenticator`) that fetches JWKs keys from a `.well-known/openid-configuration`, refreshes keys regularly, and validates tokens locally.
//! * [`KubernetesAuthenticator`](`kubernetes::KubernetesAuthenticator`) which validates tokens using Kubernetes `TokenReview`.
//! * [`AuthenticatorChain`] holds a collection of [`Authenticator`]s and authenticates the token with the first suitable Authenticator. This is especially useful for multi-tenant setups where tokens from multiple IdPs should be accepted. Each IdP is assigned a unique `idp_id` to provide a globally unique [`Subject`] that identifies a user.
//!
//! Custom Authenticators can easily be added by implementing the [`Authenticator`] trait.
//!
//! # Why the Name?
//! "Limes" is the ancient Roman wall that fortified the ROman Empire. Just like those mighty walls, our Limes library
//! stands guard, protecting your applications from unauthorized access. So, while you won't find any tangy flavors here,
//! you will find robust authentication to keep your digital empire safe. When life gives you Limes, add auth to your
//! crate! Wait a minute ...
//!
//! # Single-Tenant Example
//!
//! ```no_run
//! use axum::{middleware::from_fn_with_state, response::IntoResponse, routing::get, Extension};
//! use limes::{
//! axum::authentication_middleware, format_subject, jwks::JWKSWebAuthenticator, Authentication,
//! };
//!
//! // Use none for single tenant setups
//! const IDP_SEPARATOR: Option<char> = None;
//!
//! #[tokio::main]
//! async fn main() {
//! let authenticator = JWKSWebAuthenticator::new(
//! "https://accounts.google.com", // Must provide ./well-known/openid-configuration
//! Some(std::time::Duration::from_secs(10 * 60)), // Refresh JWKS keys every 10 minutes
//! )
//! .await
//! .unwrap()
//! .set_accepted_audiences(vec!["my-app".to_string()]); // Acceptable audiences (optional)
//!
//! let app = axum::Router::new()
//! .route("/whoami", get(whoami))
//! .layer(from_fn_with_state(
//! authenticator,
//! authentication_middleware::<JWKSWebAuthenticator>,
//! ));
//!
//! let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
//! .await
//! .unwrap();
//! println!("listening on {}", listener.local_addr().unwrap());
//! axum::serve(listener, app).await.unwrap();
//! }
//!
//! async fn whoami(Extension(auth): Extension<Authentication>) -> impl IntoResponse {
//! format!("Hello, {}!", format_subject(auth.subject(), IDP_SEPARATOR))
//! }
//! ```
//!
//! # Multi-Tenant Setup
//! Limes supports the chained Authenticators. As each Authenticator can point to a different IdP, and subject IDs are not guaranteed to be unique across IdPs, it is important to specify the `idp_id` for each [`Authenticator`] that is used in a [`AuthenticatorChain`].
//!
//! ```no_run
//! use axum::{middleware::from_fn_with_state, response::IntoResponse, routing::get, Extension};
//! use limes::{
//! axum::authentication_middleware, format_subject, jwks::JWKSWebAuthenticator,
//! kubernetes::KubernetesAuthenticator, Authentication, AuthenticatorChain, AuthenticatorEnum,
//! };
//!
//! // We recommend using a character that is never used in subject ids
//! const IDP_SEPARATOR: Option<char> = Some('~');
//!
//! #[tokio::main]
//! async fn main() {
//! let oidc_authenticator = JWKSWebAuthenticator::new(
//! "https://accounts.google.com", // Must provide ./well-known/openid-configuration
//! Some(std::time::Duration::from_secs(10 * 60)), // Refresh JWKS keys every 10 minutes
//! )
//! .await
//! .unwrap()
//! .set_idp_id("oidc") // Unique identifier for this IdP. Must never contain the `IDP_SEPARATOR`
//! .set_accepted_audiences(vec!["my-app".to_string()]); // Acceptable audiences (optional)
//!
//! // Uses the default Kubernetes client. Other constructors are available that accept a custom client.
//! let kubernetes_authenticator = KubernetesAuthenticator::try_new_with_default_client(
//! Some("kubernetes"), // Unique identifier for this IdP. Must never contain the `IDP_SEPARATOR`
//! vec![], // Don't validate the audience
//! )
//! .await
//! .unwrap();
//!
//! // Chain the authenticators together. Order matters.
//! // The first authenticator that returns true for `can_handle_token` will be used.
//! let chain = AuthenticatorChain::<AuthenticatorEnum>::builder()
//! .add_authenticator(oidc_authenticator)
//! .add_authenticator(kubernetes_authenticator)
//! .build();
//!
//! let app = axum::Router::new()
//! .route("/whoami", get(whoami))
//! .layer(from_fn_with_state(
//! chain,
//! authentication_middleware::<AuthenticatorChain<AuthenticatorEnum>>,
//! ));
//!
//! let listener = tokio::net::TcpListener::bind("127.0.0.1:3000")
//! .await
//! .unwrap();
//! println!("listening on {}", listener.local_addr().unwrap());
//! axum::serve(listener, app).await.unwrap();
//! }
//!
//! async fn whoami(Extension(auth): Extension<Authentication>) -> impl IntoResponse {
//! format!("Hello, {}!", format_subject(auth.subject(), IDP_SEPARATOR))
//! // Would print "oidc~<subject_id>" for google tokens, where oidc is the `idp_id` we set above.
//! }
//! ```
//!
//! # Feature flags
//! Limes uses a set of feature flags to reduce the amount of compiled code.
//! The following feature flags are available:
//!
//! * `all`: Activate all features
//! * `default`: Includes `rustls-tls` and `jwks`.
//! * `kubernetes`: Provides the `KubernetesAuthenticator` implementation which validates tokens using Kubernetes `TokenReview`.
//! When enabling this feature you must also select a Kubernetes API version by adding a direct
//! dependency on `k8s-openapi` with a version feature, e.g. `k8s-openapi = { version = "0.28", features = ["v1_32"] }`.
//! Limes intentionally does not pin a version so the choice is left to your binary crate.
//! * `rustls-tls`: Enable `rustls` for all dependant crates.
//! * `jwks`: Provides the `JWKSWebAuthenticator`
//! * `axum`: Provides axum middleware that performs the Authentication and provides the tokens Payload as extension.
pub use ;
pub use ;
pub use Subject;
pub use ;