Zugriffskontrolle
Unternehmensgerechte Zugriffskontrolle fรผr KI-Agenten mithilfe von adk-auth.
รbersicht
adk-auth bietet rollenbasierte Zugriffskontrolle (RBAC) mit Audit-Protokollierung und SSO-Unterstรผtzung fรผr ADK-Agenten. Es ermรถglicht sichere, feingranulare Kontrolle darรผber, welche Benutzer auf welche Tools zugreifen kรถnnen.
Architektur
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Agent Request โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ SSO Token Validation โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ Google โ โ Azure AD โ โ OIDC Discovery โ โ
โ โ Provider โ โ Provider โ โ (Okta, Auth0, etc) โ โ
โ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ โ โ
โ โโโโโโโโดโโโโโโโ โ
โ โ JWKS Cache โ โ Auto-refresh keys โ
โ โโโโโโโโโโโโโโโ โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ TokenClaims
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Claims Mapper โ
โ โ
โ IdP Groups โ adk-auth Roles โ
โ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ โ
โ "AdminGroup" โ "admin" โ
โ "DataAnalysts" โ "analyst" โ
โ (default) โ "viewer" โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ Roles
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Access Control โ
โ โ
โ Role: admin โ
โ โโโ allow: AllTools โ
โ โโโ allow: AllAgents โ
โ โ
โ Role: analyst โ
โ โโโ allow: Tool("search") โ
โ โโโ allow: Tool("summarize") โ
โ โโโ deny: Tool("code_exec") โ Deny takes precedence โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ Check Result
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Audit Logging โ
โ โ
โ {"user":"alice","resource":"search","outcome":"allowed"} โ
โ {"user":"bob","resource":"exec","outcome":"denied"} โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ
โผ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ Tool Execution โ
โ (only if access granted) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Entwurfsprinzipien
1. Verweigerung hat Vorrang
Wenn eine Rolle sowohl Erlaubnis- als auch Verweigerungsregeln hat, gewinnt die Verweigerung immer:
let role = Role::new("limited")
.allow(Permission::AllTools) // Alles erlauben...
.deny(Permission::Tool("admin")); // ...auรer admin
// Ergebnis: Kann auf jedes Tool ZUGREIFEN, AUSSER "admin"
2. Multi-Rollen-Vereinigung
Benutzer mit mehreren Rollen erhalten die Vereinigung der Berechtigungen, aber Verweigerungsregeln aus jeder Rolle gelten weiterhin:
let ac = AccessControl::builder()
.role(reader) // erlauben: search
.role(writer) // erlauben: write
.assign("alice", "reader")
.assign("alice", "writer")
.build()?;
// Alice kann sowohl auf "search" ALS AUCH auf "write" zugreifen
3. Explizit vor Implizit
Berechtigungen sind explizit โ standardmรครig wird kein Zugriff gewรคhrt:
let role = Role::new("empty");
// Diese Rolle gewรคhrt KEINE Berechtigungen
ac.check("user", &Permission::Tool("anything")); // โ Verweigert
4. Trennung von Authentifizierung und Autorisierung
- Authentifizierung (SSO): รberprรผft, WER der Benutzer ist (via JWT)
- Autorisierung (RBAC): Bestimmt, WORAUF sie zugreifen kรถnnen
// Authentifizierung: JWT validieren, Claims extrahieren
let claims = provider.validate(token).await?;
// Autorisierung: spezifische Berechtigung prรผfen
ac.check(&claims.sub, &Permission::Tool("search"))?;
// Kombiniert: SsoAccessControl erledigt beides
sso.check_token(token, &permission).await?;
Installation
[dependencies]
adk-auth = "0.2.0"
# Fรผr SSO/OAuth-Unterstรผtzung
adk-auth = { version = "0.2.0", features = ["sso"] }
Kernkomponenten
Berechtigung
pub enum Permission {
Tool(String), // Spezifisches Tool nach Name
AllTools, // Wildcard: alle Tools
Agent(String), // Spezifischer Agent nach Name
AllAgents, // Wildcard: alle Agents
}
Rolle
let analyst = Role::new("analyst")
.allow(Permission::Tool("search".into()))
.allow(Permission::Tool("summarize".into()))
.deny(Permission::Tool("code_exec".into()));
Zugriffskontrolle
let ac = AccessControl::builder()
.role(admin)
.role(analyst)
.assign("alice@company.com", "admin")
.assign("bob@company.com", "analyst")
.build()?;
// Berechtigung prรผfen
ac.check("bob@company.com", &Permission::Tool("search".into()))?;
Geschรผtztes Tool
Umschlieรt ein Tool mit automatischer Berechtigungsprรผfung:
use adk_auth::ToolExt;
let protected = my_tool.with_access_control(Arc::new(ac));
// Bei Ausfรผhrung wird die Berechtigung vor dem Start geprรผft
protected.execute(ctx, args).await?;
Auth-Middleware
Schรผtzt mehrere Tools im Batch-Modus:
let middleware = AuthMiddleware::new(ac);
let protected_tools = middleware.protect_all(tools);
SSO-Integration
Unterstรผtzte Anbieter
| Anbieter | Konstruktor | Aussteller |
|---|---|---|
GoogleProvider::new(client_id) | accounts.google.com | |
| Azure AD | AzureADProvider::new(tenant, client) | login.microsoftonline.com |
| Okta | OktaProvider::new(domain, client) | {domain}/oauth2/default |
| Auth0 | Auth0Provider::new(domain, audience) | {domain}/ |
| Generic | OidcProvider::from_discovery(issuer, client) | Jeder OIDC-Anbieter |
TokenClaims
Aus validierten JWTs extrahierte Claims:
pub struct TokenClaims {
pub sub: String, // Subjekt (Benutzer-ID)
pub email: Option<String>, // E-Mail
pub name: Option<String>, // Anzeigename
pub groups: Vec<String>, // IdP-Gruppen
pub roles: Vec<String>, // IdP-Rollen
pub hd: Option<String>, // Von Google gehostete Domain
pub tid: Option<String>, // Azure Mandanten-ID
// ... weitere standardmรครige OIDC-Ansprรผche
}
ClaimsMapper
Ordnet IdP-Gruppen adk-auth-Rollen zu:
let mapper = ClaimsMapper::builder()
.map_group("AdminGroup", "admin")
.map_group("Users", "viewer")
.default_role("guest")
.user_id_from_email()
.build();
SsoAccessControl
Kombiniert SSO-Validierung mit RBAC in einem Aufruf:
let sso = SsoAccessControl::builder()
.validator(GoogleProvider::new("client-id"))
.mapper(mapper)
.access_control(ac)
.audit_sink(audit)
.build()?;
// Token validieren + Berechtigung prรผfen + Audit-Protokoll
let claims = sso.check_token(token, &Permission::Tool("search".into())).await?;
Audit-Protokollierung
FileAuditSink
let audit = FileAuditSink::new("/var/log/adk/audit.jsonl")?;
let middleware = AuthMiddleware::with_audit(ac, audit);
Ausgabeformat (JSONL)
{"timestamp":"2025-01-01T10:30:00Z","user":"bob","session_id":"sess-123","event_type":"tool_access","resource":"search","outcome":"allowed"}
{"timestamp":"2025-01-01T10:30:01Z","user":"bob","session_id":"sess-123","event_type":"tool_access","resource":"code_exec","outcome":"denied"}
Benutzerdefinierte Audit-Sink
use adk_auth::{AuditSink, AuditEvent, AuthError};
use async_trait::async_trait;
pub struct DatabaseAuditSink { /* ... */ }
#[async_trait]
impl AuditSink for DatabaseAuditSink {
async fn log(&self, event: AuditEvent) -> Result<(), AuthError> {
// In Datenbank einfรผgen
sqlx::query("INSERT INTO audit_log ...")
.bind(event.user)
.bind(event.resource)
.execute(&self.pool)
.await?;
Ok(())
}
}
Beispiele
# Core RBAC
cargo run --example auth_basic # Rollenbasierte Zugriffskontrolle
cargo run --example auth_audit # Audit-Protokollierung
# SSO (erfordert --features sso)
cargo run --example auth_sso --features sso # Vollstรคndiger SSO-Ablauf
cargo run --example auth_jwt --features sso # JWT-Validierung
cargo run --example auth_oidc --features sso # OIDC-Erkennung
cargo run --example auth_google --features sso # Google Identity
Best Practices fรผr die Sicherheit
| Praktik | Beschreibung |
|---|---|
| Standardmรครig verweigern | Nur explizit benรถtigte Berechtigungen erteilen |
| Explizite Verweigerungen | Verweigerungsregeln fรผr gefรคhrliche Operationen hinzufรผgen |
| Alles auditieren | Protokollierung fรผr Compliance aktivieren |
| Serverseitig validieren | JWTs immer serverseitig validieren |
| HTTPS verwenden | JWKS-Endpunkte erfordern sichere Verbindungen |
| Schlรผssel rotieren | JWKS-Cache wird stรผndlich automatisch aktualisiert |
| Token-Lebensdauer begrenzen | Kurzlebige Zugriffstoken verwenden |
Fehlerbehandlung
use adk_auth::{AccessDenied, AuthError};
use adk_auth::sso::TokenError;
// RBAC-Fehler
match ac.check("user", &Permission::Tool("admin".into())) {
Ok(()) => { /* Zugriff gewรคhrt */ }
Err(AccessDenied { user, permission }) => {
eprintln!("Verweigert: {} kann nicht auf {} zugreifen", user, permission);
}
}
// SSO-Fehler
match provider.validate(token).await {
Ok(claims) => { /* Token gรผltig */ }
Err(TokenError::Expired) => { /* Token abgelaufen */ }
Err(TokenError::InvalidSignature) => { /* Signatur ungรผltig */ }
Err(TokenError::InvalidIssuer { expected, actual }) => { /* falscher Aussteller */ }
Err(e) => { /* anderer Fehler */ }
}
Zurรผck: โ Evaluierung | Weiter: Entwicklungsrichtlinien โ