| Crates.io | grpc-jwt-tonic |
| lib.rs | grpc-jwt-tonic |
| version | 0.2.0 |
| created_at | 2025-08-26 10:43:33.348866+00 |
| updated_at | 2025-10-31 11:20:39.885545+00 |
| description | JWT authentication and authorization middleware for servers in Rust + Tonic ecosystem |
| homepage | https://github.com/LdDl/grpc-jwt-tonic |
| repository | https://github.com/LdDl/grpc-jwt-tonic |
| max_upload_size | |
| id | 1810988 |
| size | 110,733 |
This crate provides JWT (JSON Web Token) authentication and authorization middleware for Tonic-based gRPC servers in Rust. It's the port of my original Go library grpc-jwt, maintaining the same API patterns and functionality while leveraging Rust's type safety and performance benefits.
✅ JWT Authentication - Login with username/password, receive JWT tokens
✅ Token Refresh - Refresh expired tokens
✅ Method Interception - Selectively protect gRPC methods
✅ Multiple Algorithms - Support for HMAC (HS256, HS384, HS512) and RSA (RS256, RS384, RS512)
✅ Custom Claims - Add custom payload data to JWT tokens
✅ Authorization Logic - Flexible user authorization callbacks
✅ Streaming Support - Works with both unary and streaming gRPC calls
Add this to your Cargo.toml:
[dependencies]
grpc-jwt-tonic = "0.1.0"
tonic = "0.14.2"
tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] }
serde_json = "1.0"
[build-dependencies]
tonic-prost-build = "0.14.2"
To regenerate protobuf files, use:
# Use the build.rs approach (recommended)
cargo build
Here's a complete server implementation with JWT authentication - server-side directory
# Start Rust gRPC server with JWT authentication
cd examples/server
cargo run --bin server
Here's how to use the JWT authentication from a Rust client - client-side directory
# Test with Rust client
cd examples/client
cargo run --bin client
For production use with RSA keys, generate private/public key pairs:
# Generate RSA private key
ssh-keygen -t rsa -b 4096 -m PEM -f jwtRS512.key
# Extract public key
openssl rsa -in jwtRS512.key -pubout -outform PEM -out jwtRS512.key.pub
Then use in your code:
let private_key = std::fs::read("jwtRS512.key")?;
let public_key = std::fs::read("jwtRS512.key.pub")?;
let opts = JwtEngineOptions {
alg: AlgorithmKind::RS512 { private_key, public_key },
// ... other options
};
Configure the JWT engine behavior:
pub struct JwtEngineOptions {
pub realm: String, // JWT realm identifier (default: "grpc jwt")
pub alg: AlgorithmKind, // Signing algorithm (default: HS256 with "secret")
pub timeout: Duration, // Token expiration time (default: 1 hour)
pub max_refresh: Duration, // Maximum refresh duration (default: 7 days)
pub identity_key: String, // Key for identity in claims (default: "identity")
pub token_lookup: String, // Where to find token (default: "header:Authorization")
pub token_head_name: String, // Token prefix (default: "Bearer")
pub send_authorization: bool, // Send auth in response (default: false)
pub disabled_abort: bool, // Disable abort on auth failure (default: false)
pub priv_key_file: String, // Private key file path for RSA (default: empty)
pub pub_key_file: String, // Public key file path for RSA (default: empty)
}
Supported JWT signing algorithms:
pub enum AlgorithmKind {
HS256(Vec<u8>), // HMAC with SHA-256
HS384(Vec<u8>), // HMAC with SHA-384
HS512(Vec<u8>), // HMAC with SHA-512
RS256 { private_pem: Vec<u8>, public_pem: Vec<u8> }, // RSA with SHA-256
RS384 { private_pem: Vec<u8>, public_pem: Vec<u8> }, // RSA with SHA-384
RS512 { private_pem: Vec<u8>, public_pem: Vec<u8> }, // RSA with SHA-512
}
This Rust implementation maintains full compatibility with the original Go version:
| Feature | Go Version | Rust Version | Compatible |
|---|---|---|---|
| JWT Authentication | ✅ | ✅ | ✅ |
| Token Refresh | ✅ | ✅ | ✅ |
| HMAC Algorithms | ✅ | ✅ | ✅ |
| RSA Algorithms | ✅ | ✅ | ✅ |
| Custom Claims | ✅ | ✅ | ✅ |
| Method Interception | ✅ | ✅ | ✅ |
| Streaming Support | ✅ | ✅ | ✅ |
| Cross-Language Clients | ✅ | ✅ | ✅ |
If you have troubles or questions please open an issue.
Use this crate carefully: there are no tests. I have no that much time to test every case (for my job purposes it works as intended).
PRs are welcome!
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
This is the official Rust port by LdDl, the original author of grpc-jwt. 🦀
Why Rust?
After building and maintaining the Go version, I wanted to explore how this JWT gRPC pattern would work in Rust, taking advantage of:
- Zero-cost abstractions and compile-time optimizations
- Memory safety without garbage collection overhead
- Async performance with Tokio
— Dmitrii (LdDl)