# π Schlussel
> **Secure OAuth 2.0 for CLI applications** - Written in Rust, works everywhere π¦
OAuth authentication made simple for command-line tools. No more copying tokens or managing credentials manually!
---
## β¨ Features
π **Multiple OAuth Flows**
- Device Code Flow (perfect for CLI!)
- Authorization Code Flow with PKCE
- Automatic browser handling
π **Secure by Default**
- OS credential manager integration (Keychain/Credential Manager)
- Cross-process token refresh locking
- Automatic token refresh
β‘ **Developer Friendly**
- Provider presets (GitHub, Google, Microsoft, GitLab, Tuist)
- One-line configuration
- Automatic expiration handling
π **Cross-Platform**
- Linux, macOS, Windows
- x86_64 and ARM64
---
## π Quick Start
### Installation
**Rust:**
```toml
[dependencies]
schlussel = "0.1"
```
**Swift Package Manager:**
```swift
.binaryTarget(
name: "Schlussel",
url: "https://github.com/tuist/schlussel/releases/download/0.5.0/Schlussel.xcframework.zip",
checksum: "36c002746caa5c1af8c6edea751ad971c5b67940775dba398308207dc981e253"
)
```
### Authenticate with GitHub (3 lines!)
```rust
use schlussel::prelude::*;
use std::sync::Arc;
let storage = Arc::new(SecureStorage::new("my-app").unwrap());
let config = OAuthConfig::github("your-client-id", Some("repo user"));
let client = OAuthClient::new(config, storage);
// That's it! Opens browser, handles OAuth, returns token
let token = client.authorize_device().unwrap();
```
---
## π Documentation
π **[Full Documentation](docs/README.md)**
Quick links:
- π [Quick Start Guide](docs/quick-start.md)
- π [Provider Presets](docs/provider-presets.md) - GitHub, Google, Microsoft, etc.
- πΎ [Storage Options](docs/storage-backends.md) - Secure, File, or Memory
- π [Token Refresh](docs/token-refresh.md) - Automatic refresh strategies
- π± [Swift/iOS Integration](docs/swift-integration.md) - XCFramework usage
---
## π‘ Why Schlussel?
### Before Schlussel π«
```rust
// 50+ lines of boilerplate
// Manual token expiration checking
// Race conditions with multiple processes
// Plaintext tokens in files
// Complex OAuth flow management
```
### With Schlussel π
```rust
// 3 lines total
let storage = Arc::new(SecureStorage::new("app").unwrap());
let config = OAuthConfig::github("client-id", Some("repo"));
let token = OAuthClient::new(config, storage).authorize_device().unwrap();
```
---
## π― Use Cases
β
CLI tools that need GitHub/GitLab API access
β
Build tools that integrate with cloud services
β
Developer tools with OAuth authentication
β
Cross-platform desktop applications
β
CI/CD tools with secure credential management
---
## ποΈ Architecture
```
βββββββββββββββββββ
β Your CLI App β
ββββββββββ¬βββββββββ
β
ββββββΌββββββ
β Schlusselβ
ββββββ¬ββββββ
β
ββββββΌβββββββββββββββββββββββββ
β Storage Backend β
βββββββββββββββββββββββββββββββ€
β SecureStorage (OS Keyring) β β Recommended
β FileStorage (JSON files) β
β MemoryStorage (In-memory) β
βββββββββββββββββββββββββββββββ
```
---
## π Highlights
### π Secure by Default
Tokens stored in **OS credential manager** (Keychain on macOS, Credential Manager on Windows, libsecret on Linux)
### π¨ Provider Presets
```rust
OAuthConfig::github("id", Some("repo")) // GitHub
OAuthConfig::google("id", Some("email")) // Google
OAuthConfig::microsoft("id", "common", None) // Microsoft
OAuthConfig::gitlab("id", None, None) // GitLab
OAuthConfig::tuist("id", None, None) // Tuist
```
### β‘ Automatic Token Refresh
```rust
let refresher = TokenRefresher::new(client);
let token = refresher.get_valid_token("key").unwrap();
// Auto-refreshes if expired!
```
### π Cross-Process Safe
Multiple processes can safely refresh the same token without race conditions
---
## π¦ Examples
Check out [examples/](examples/) for working code:
- π [GitHub Device Flow](examples/github_device_flow.rs)
- π [GitHub with Callback](examples/github_callback.rs)
- π [Token Refresh](examples/token_refresh.rs)
- β‘ [Automatic Refresh](examples/automatic_refresh.rs)
- π [Secure Storage](examples/secure_storage.rs)
- π [Cross-Process Refresh](examples/cross_process_refresh.rs)
---
## π€ Contributing
Contributions welcome! Please ensure:
- β
Tests pass: `cargo test`
- β
Code formatted: `cargo fmt`
- β
Clippy clean: `cargo clippy`
---
## π License
See [LICENSE](LICENSE) for details.
---
## π Links
- π [Documentation](docs/README.md)
- π [Issues](https://github.com/tuist/schlussel/issues)
- π [Changelog](CHANGELOG.md)
- π [API Docs](https://docs.rs/schlussel)
---
**Made with π by the Tuist team**