webgates-tonic
User-focused tonic server-side integration for the webgates stack.
webgates-tonic is the tonic-facing transport adapter for webgates. It lets you apply bearer-token authentication and authorization to gRPC services running on tonic while keeping the core auth and policy logic in the framework-agnostic webgates crate.
This crate is server-side only. It does not provide cookie transport, browser-based OAuth2 flows, or tonic client utilities.
Who this crate is for
Use webgates-tonic when you want to:
- protect tonic gRPC services with bearer-token authentication
- enforce
webgatesauthorization policies in server middleware - read typed authentication context inside tonic handlers
- use optional JWT auth context for mixed public/authenticated gRPC methods
- support static-token service-to-service authentication
- keep transport concerns separate from the core
webgatesdomain and auth logic
You still depend on webgates for domain types, codecs, policies, claims, and repository contracts.
What this crate helps you build
Use this crate when you want one or more of these tonic-facing workflows:
- bearer-token authentication for tonic services
- authorization enforcement in tonic middleware
- typed auth context extraction inside handlers
- optional authenticated-or-public gRPC methods
- static-token service-to-service protection
Install
Most applications should depend on both crates explicitly.
[]
= "0.14"
= "1.0.0"
= "1.0.0"
Minimum supported Rust version: 1.91.
The mental model
The easiest way to understand webgates-tonic is:
- define auth and authorization rules in
webgates - adapt them into tonic middleware with
webgates_tonic::gate::Gate - let middleware validate bearer metadata and enforce policy
- read typed auth context from request extensions inside your gRPC handlers
This keeps responsibilities separate:
webgatesowns policies, account claims, and token validation building blockswebgates-tonicowns tonic-layer request interception and status mapping
Quick start
Strict JWT bearer gate
Applies the configured AccessPolicy to every request. Returns UNAUTHENTICATED or PERMISSION_DENIED on failure and inserts JwtAuthContext on success.
use Arc;
use Account;
use AccessPolicy;
use ;
use Group;
use Role;
use Gate;
type Claims = ;
let codec = new;
let layer = bearer
.with_policy;
Require any authenticated user
let layer = bearer.require_login;
Optional authentication
Optional mode forwards all requests and inserts OptionalJwtAuthContext.
Handlers decide what to do with authenticated vs anonymous requests.
use OptionalJwtAuthContext;
use Role;
use Group;
let layer = bearer.allow_anonymous_with_optional_user;
// In the handler:
// let ctx = req.extensions().get::<OptionalJwtAuthContext<Role, Group>>();
// if ctx.map(|c| c.is_authenticated()).unwrap_or(false) { ... }
Static-token gate
Static-token mode performs constant-time bearer token matching and inserts StaticTokenAuthorized.
use StaticTokenAuthorized;
let layer = bearer.with_static_token;
let optional_layer = bearer
.with_static_token
.allow_anonymous_with_optional_user;
Reading auth context in a handler
use ;
use JwtAuthContext;
use Group;
use Role;
async
Core concepts
1. Gate is the main integration entry point
Use webgates_tonic::gate::Gate to build tonic bearer-token middleware.
The main entry point is:
Gate::bearer(issuer, codec)
From there you can configure:
.with_policy(policy).require_login().allow_anonymous_with_optional_user().with_static_token(token)
2. Context types are how handlers read auth state
The middleware inserts typed values into request extensions so handlers can read authentication state without manually decoding metadata.
Main types are:
JwtAuthContextOptionalJwtAuthContextStaticTokenAuthorized
3. AuthError defines status mapping
AuthError is the typed error model used by the middleware for auth failures.
It maps failures to appropriate tonic::Status values such as:
UNAUTHENTICATEDPERMISSION_DENIEDINTERNAL
Transport mechanism
webgates-tonic uses tower Layer and Service wrappers that operate directly on http::Request<tonic::body::Body>.
That gives the middleware access to the full HTTP header set, including Authorization: Bearer <token>, before the tonic request type is constructed. The layer can then insert typed extensions that handlers later read through request.extensions().
Non-goals
- client-side tonic authentication
- cookie-based authentication
- browser-redirect or OAuth2 authorization code flows
- any feature not required for server-side bearer token validation
Features
default = []audit-logging: enables audit logging integration fromwebgatesprometheus: installs Prometheus metrics integration for auth events; depends onaudit-logging
Security checklist
- keep the issuer identical between token minting and gate validation
- use persistent signing keys in production and rotate them deliberately
- prefer short-lived JWTs and explicit observability
- avoid logging secrets, raw tokens, or sensitive payloads
- for static-token mode, the comparison is constant-time but the token is still held in memory as a plain string; protect the process environment accordingly
Recommended onboarding path
If you are new to this crate, I recommend this order:
gate::Gatecontexterrorsgate::bearergate::remote_jwks_bearerif you need remote JWKS-backed verification
Which crate should you use?
- use
webgates-tonicwhen you want tonic server-side bearer-token integration - use
webgateswhen you want the higher-level application-facing auth stack - use
webgates-axumwhen you want HTTP/Axum integration instead of gRPC - use
webgates-codecswhen you need codec or JWT support directly
License
MIT