adk-auth
Access control and authentication for Rust Agent Development Kit (ADK-Rust).
Overview
adk-auth provides enterprise-grade access control for AI agents:
- Declarative Scope-Based Security - Tools declare required scopes, framework enforces automatically
- Role-Based Access - Define roles with tool/agent permissions (allow/deny, deny precedence)
- Audit Logging - Log all access attempts to JSONL files
- SSO/OAuth - JWT validation with Google, Azure AD, Okta, Auth0, and generic OIDC providers
- Auth Bridge - Flow authenticated identity from HTTP requests into agent execution via
adk-server
Features
Core Role Based Access Control (RBAC), scope-based security, and audit logging are always available with no feature flags required.
| Feature | Description |
|---|---|
sso |
JWT/OIDC providers (Google, Azure AD, Okta, Auth0, generic OIDC) |
auth-bridge |
JwtRequestContextExtractor for adk-server identity flow (implies sso) |
Declarative Scope-Based Security
Tools declare what scopes they need. The framework enforces before execution — no imperative checks in your handlers:
use FunctionTool;
use ;
// Tool declares its required scopes
let transfer = new
.with_scopes;
// ScopeGuard enforces automatically
let guard = new;
let protected = guard.protect;
// Or wrap all tools at once
let protected_tools = guard.protect_all;
With audit logging:
let guard = with_audit;
let protected = guard.protect;
// All scope checks (allowed + denied) are logged
Pluggable resolvers:
| Resolver | Source |
|---|---|
ContextScopeResolver |
Delegates to ToolContext::user_scopes() (JWT claims, session state) |
StaticScopeResolver |
Fixed scopes — useful for testing |
Custom impl ScopeResolver |
Any async source (database, external IdP, etc.) |
For resolvers that call external services, cache the resolved scopes at the request or session layer to avoid repeated lookups during multi-tool runs.
Role-Based Access Control
use ;
// Define roles
let admin = new.allow;
let user = new
.allow
.deny;
// Build access control
let ac = builder
.role
.role
.assign
.assign
.build?;
// Protect tools
let middleware = new;
let protected_tools = middleware.protect_all;
Combining RBAC + Scopes
Use RBAC for coarse tool/agent entitlement and scopes for request-level constraints:
use Arc;
use ;
let rbac = new;
let scoped = new;
let protected = scoped.protect;
SSO Integration
Enable with features = ["sso"]:
use ;
// Create provider
let provider = new;
// Map IdP groups to roles
let mapper = builder
.map_group
.default_role
.user_id_from_email
.build;
// Combined SSO + RBAC
let sso = builder
.validator
.mapper
.access_control
.build?;
// Validate token and check permission
let claims = sso.check_token.await?;
println!;
user_id_from_email() only uses the email claim when email_verified == true; otherwise it falls back to sub.
Providers
| Provider | Usage |
|---|---|
GoogleProvider::new(client_id) |
|
| Azure AD | AzureADProvider::new(tenant_id, client_id) or ::multi_tenant(client_id).with_allowed_tenants(["tenant-id"]) |
| Okta | OktaProvider::new(domain, client_id) or ::with_auth_server(domain, server_id, client_id) |
| Auth0 | Auth0Provider::new(domain, audience) |
| Generic OIDC | OidcProvider::from_discovery(issuer, client_id).await or ::new(issuer, client_id, jwks_uri) |
AzureADProvider::multi_tenant() accepts tokens from any tenant targeting the configured audience unless you restrict it with with_allowed_tenants(...).
Auth Bridge
Enable with features = ["auth-bridge"] to validate Bearer tokens directly into adk-server request contexts:
use JwtRequestContextExtractor;
use ;
let extractor = builder
.validator
.mapper
.build?;
The extractor maps:
user_idfrom the configuredClaimsMapperscopesfrom JWTscopeandscpclaimsmetadataincluding issuer, subject, email, and tenant ID when present
Audit Logging
use FileAuditSink;
let audit = new?;
let middleware = with_audit;
Output:
Examples
License
Apache-2.0
Part of ADK-Rust
This crate is part of the ADK-Rust framework for building AI agents in Rust.
Security Notes
- Prefer short-lived access tokens and rotate signing keys regularly.
- The JWKS cache refreshes hourly by default; lower the refresh interval if your IdP rotates keys aggressively.
OidcProvider::from_discovery()now rejects discovery documents whoseissuerdoes not match the requested issuer URL.- Token revocation and blacklist checks are not built in. If you need immediate revocation, enforce it in a custom
TokenValidatoror request extractor.