turul-a2a-auth
Authentication middleware for the turul-a2a server framework.
Two ready-made middlewares implementing the A2aMiddleware trait:
BearerMiddleware— JWT verification with JWKS caching, backed byturul-jwt-validator.ApiKeyMiddleware— Static API key enforcement on a configurable header (defaultX-API-Key).
Both populate RequestContext.identity with AuthIdentity::Authenticated,
which the framework surfaces to executors via ExecutionContext. Both
also publish a SecurityContribution so the framework merges scheme
declarations into the agent card automatically.
API key
use HashMap;
use Arc;
use A2aServer;
use ;
let mut keys = new;
keys.insert;
keys.insert;
let lookup = new;
let auth = new;
builder
.executor
.middleware
.build?;
RedactedApiKeyLookup is a reference implementation whose Debug
output never contains key material — important if you ever log the
middleware. Plug in your own ApiKeyLookup for database-backed
resolution.
use async_trait;
use ApiKeyLookup;
Bearer JWT
use Arc;
use A2aServer;
use BearerMiddleware;
use JwtValidator;
let validator = new;
let auth = new
.with_principal_claim // default
.with_required_scopes;
builder
.executor
.middleware
.build?;
JWKS is fetched and cached by JwtValidator. The middleware extracts
the principal from the configured claim (default sub) and rejects
empty/whitespace values.
Validator failures collapse to InvalidToken deliberately — the
underlying error never reaches the response, to avoid leaking JWKS
URLs or token fragments via error_description.
Reading identity in your executor
use *;
use AuthIdentity;
For Bearer, the full claims set is also available as
AuthIdentity::Authenticated { claims, .. } (a serde_json::Value).
Security declarations on the agent card
Each middleware publishes a SecurityContribution so the framework's
agent card auto-includes the matching SecurityScheme and any
required scopes. Adopters do not need to hand-write
security_schemes on the card; the framework merges contributions at
build time.
Failure modes
| Cause | HTTP status | Auth header behaviour |
|---|---|---|
No Authorization / API key header |
401 | WWW-Authenticate challenge |
| Invalid token / unknown key | 401 | error="invalid_token" (Bearer) or no detail (API key) |
| Empty principal claim | 401 | error="invalid_token" |
| Required scope missing (Bearer) | 403 | error="insufficient_scope" |
Errors are emitted at the transport layer (outside A2aError) so they
never leak through the JSON-RPC envelope.
Examples
examples/auth-agent— runnable agent with API key middleware.examples/skill-security-agent— declares per-skill security requirements on the card.
See the workspace README for the project overview and crate map.
License
Licensed under either MIT or Apache 2.0 at your option.