[](https://crates.io/crates/loopauth)
[](https://docs.rs/loopauth)
[](#license)
# loopauth
OAuth 2.0 Authorization Code + PKCE flow for CLI applications.
`loopauth` opens the user's browser to the authorization URL, spins up a short-lived loopback HTTP server to receive the redirect callback, exchanges the authorization code for tokens, and returns a `TokenSet` containing access and refresh tokens. Your application can then use those tokens (e.g., the ID token) to authenticate users against your own backend.
It is not a full OAuth 2.0 or OIDC library. Other grant types (client credentials, device flow, etc.), token introspection, and app-level authentication are out of scope.
Token storage and downstream identity consumption are intentionally out of scope; implement the `TokenStore` trait to provide your own persistence.
## Quick start
### OIDC auto-discovery
Provider URLs are fetched automatically via `.well-known/openid-configuration`:
```rust
use loopauth::{CliTokenClientBuilder, RequestScope, oidc::OpenIdConfiguration};
use url::Url;
let open_id_configuration = OpenIdConfiguration::fetch(
Url::parse("https://provider.example.com")?,
).await?;
// from_open_id_configuration automatically includes the openid scope
let client = CliTokenClientBuilder::from_open_id_configuration(&open_id_configuration)
.client_id("my-client-id")
.with_open_id_configuration_jwks_validator(&open_id_configuration)
.add_scopes([RequestScope::Email])
.build();
let tokens = client.run_authorization_flow().await?;
```
### Explicit URLs
```rust
use loopauth::{CliTokenClient, RequestScope};
use url::Url;
let client = CliTokenClient::builder()
.client_id("my-client-id")
.auth_url(Url::parse("https://provider.example.com/authorize")?)
.token_url(Url::parse("https://provider.example.com/token")?)
.with_openid_scope()
.jwks_validator(Box::new(my_validator)) // or .without_jwks_validation()
.add_scopes([RequestScope::Email])
.build();
let tokens = client.run_authorization_flow().await?;
```
## Features
- PKCE ([RFC 7636])
- OIDC discovery
- JWKS validation
- Token refresh
- Configurable token storage
- Configurable browser open behavior
- Configurable HTML success/error pages
[RFC 7636]: https://datatracker.ietf.org/doc/html/rfc7636
## Examples
The `examples/` directory contains runnable demos. Each example's source file documents its required and optional environment variables.
| [`auth.rs`](examples/auth.rs) | Manual configuration (explicit auth + token URLs) |
| [`auth_discovery.rs`](examples/auth_discovery.rs) | OIDC discovery-based setup |
| [`jwks_demo.rs`](examples/jwks_demo.rs) | JWKS JWT validation demo |
| [`refresh_demo.rs`](examples/refresh_demo.rs) | Token refresh flow |
Some examples require environment variables (provider credentials, URLs). Review the source file for each example before running it.
```sh
cargo run --example auth
cargo run --example auth_discovery
cargo run --example jwks_demo
cargo run --example refresh_demo
```
## Local development
You'll need to install [just](https://just.systems/).
```sh
just setup # install required tools (cargo-nextest, cargo-watch, cargo-llvm-cov)
just test # full test suite
just docs # open API docs in browser
```
## License
This crate is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
- MIT license ([LICENSE-MIT](LICENSE-MIT))
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE))