एक्सेस कंट्रोल

एआई एजेंटों के लिए एंटरप्राइज़-ग्रेड एक्सेस कंट्रोल, adk-auth का उपयोग करके।

अवलोकन

adk-auth एडीके एजेंटों के लिए ऑडिट लॉगिंग और एसएसओ समर्थन के साथ भूमिका-आधारित एक्सेस कंट्रोल (आरबीएसी) प्रदान करता है। यह सुरक्षित, बारीक नियंत्रण को सक्षम बनाता है कि कौन से उपयोगकर्ता किन टूल तक पहुंच सकते हैं।

वास्तुकला

┌─────────────────────────────────────────────────────────────────┐
│                        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)                          │
└─────────────────────────────────────────────────────────────────┘

डिज़ाइन सिद्धांत

1. अस्वीकृति की प्राथमिकता

जब किसी भूमिका में अनुमति और अस्वीकृति दोनों नियम होते हैं, तो अस्वीकृति हमेशा जीतती है:

let role = Role::new("limited")
    .allow(Permission::AllTools)      // Allow everything...
    .deny(Permission::Tool("admin")); // ...except admin

// Result: Can access any tool EXCEPT "admin"

2. बहु-भूमिका संघ

कई भूमिकाओं वाले उपयोगकर्ताओं को अनुमतियों का संघ प्राप्त होता है, लेकिन किसी भी भूमिका के अस्वीकृति नियम अभी भी लागू होते हैं:

let ac = AccessControl::builder()
    .role(reader)    // allow: search
    .role(writer)    // allow: write
    .assign("alice", "reader")
    .assign("alice", "writer")
    .build()?;

// Alice can access both "search" AND "write"

3. निहित पर स्पष्ट

अनुमतियाँ स्पष्ट होती हैं - डिफ़ॉल्ट रूप से कोई पहुँच प्रदान नहीं की जाती है:

let role = Role::new("empty");
// यह भूमिका कोई अनुमति प्रदान नहीं करती है

ac.check("user", &Permission::Tool("anything")); // → अस्वीकृत

4. प्रमाणीकरण और प्राधिकरण का पृथक्करण

  • प्रमाणीकरण (SSO): सत्यापित करता है कि उपयोगकर्ता कौन है (JWT के माध्यम से)
  • प्राधिकरण (RBAC): निर्धारित करता है कि वे क्या पहुँच सकते हैं
// प्रमाणीकरण: JWT को मान्य करें, दावों को निकालें
let claims = provider.validate(token).await?;

// प्राधिकरण: विशिष्ट अनुमति की जाँच करें
ac.check(&claims.sub, &Permission::Tool("search"))?;

// संयुक्त: SsoAccessControl दोनों करता है
sso.check_token(token, &permission).await?;

स्थापना

[dependencies]
adk-auth = "0.2.0"

# SSO/OAuth समर्थन के लिए
adk-auth = { version = "0.2.0", features = ["sso"] }

मुख्य घटक

Permission

pub enum Permission {
    Tool(String),     // नाम से विशिष्ट टूल
    AllTools,         // वाइल्डकार्ड: सभी टूल
    Agent(String),    // नाम से विशिष्ट एजेंट
    AllAgents,        // वाइल्डकार्ड: सभी एजेंट
}

Role

let analyst = Role::new("analyst")
    .allow(Permission::Tool("search".into()))
    .allow(Permission::Tool("summarize".into()))
    .deny(Permission::Tool("code_exec".into()));

AccessControl

let ac = AccessControl::builder()
    .role(admin)
    .role(analyst)
    .assign("alice@company.com", "admin")
    .assign("bob@company.com", "analyst")
    .build()?;

// अनुमति जाँचें
ac.check("bob@company.com", &Permission::Tool("search".into()))?;

ProtectedTool

एक टूल को स्वचालित अनुमति जाँच के साथ लपेटता है:

use adk_auth::ToolExt;

let protected = my_tool.with_access_control(Arc::new(ac));

// निष्पादित होने पर, चलाने से पहले अनुमति की जाँच करता है
protected.execute(ctx, args).await?;

AuthMiddleware

कई टूल को बैच में सुरक्षित करें:

let middleware = AuthMiddleware::new(ac);
let protected_tools = middleware.protect_all(tools);

SSO एकीकरण

समर्थित प्रदाता

प्रदाताकंस्ट्रक्टरजारीकर्ता
GoogleGoogleProvider::new(client_id)accounts.google.com
Azure ADAzureADProvider::new(tenant, client)login.microsoftonline.com
OktaOktaProvider::new(domain, client){domain}/oauth2/default
Auth0Auth0Provider::new(domain, audience){domain}/
GenericOidcProvider::from_discovery(issuer, client)कोई भी OIDC प्रदाता

TokenClaims

मान्य JWTs से निकाले गए क्लेम:

pub struct TokenClaims {
    pub sub: String,              // विषय (उपयोगकर्ता ID)
    pub email: Option<String>,    // ईमेल
    pub name: Option<String>,     // प्रदर्शित नाम
    pub groups: Vec<String>,      // IdP समूह
    pub roles: Vec<String>,       // IdP भूमिकाएँ
    pub hd: Option<String>,       // Google होस्टेड डोमेन
    pub tid: Option<String>,      // Azure टेनेंट ID
    // ... अधिक मानक OIDC क्लेम
}

ClaimsMapper

IdP समूहों को adk-auth भूमिकाओं में मैप करता है:

let mapper = ClaimsMapper::builder()
    .map_group("AdminGroup", "admin")
    .map_group("Users", "viewer")
    .default_role("guest")
    .user_id_from_email()
    .build();

SsoAccessControl

एक ही कॉल में SSO सत्यापन को RBAC के साथ जोड़ता है:

let sso = SsoAccessControl::builder()
    .validator(GoogleProvider::new("client-id"))
    .mapper(mapper)
    .access_control(ac)
    .audit_sink(audit)
    .build()?;

// टोकन को मान्य करें + अनुमति की जांच करें + ऑडिट लॉग
let claims = sso.check_token(token, &Permission::Tool("search".into())).await?;

ऑडिट लॉगिंग

FileAuditSink

let audit = FileAuditSink::new("/var/log/adk/audit.jsonl")?;
let middleware = AuthMiddleware::with_audit(ac, audit);

आउटपुट प्रारूप (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"}

कस्टम ऑडिट सिंक

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> {
        // डेटाबेस में डालें
        sqlx::query("INSERT INTO audit_log ...")
            .bind(event.user)
            .bind(event.resource)
            .execute(&self.pool)
            .await?;
        Ok(())
    }
}

उदाहरण

# कोर RBAC
cargo run --example auth_basic          # भूमिका-आधारित एक्सेस नियंत्रण
cargo run --example auth_audit          # ऑडिट लॉगिंग

# SSO (आवश्यकता है --features sso)
cargo run --example auth_sso --features sso     # पूर्ण SSO प्रवाह
cargo run --example auth_jwt --features sso     # JWT सत्यापन
cargo run --example auth_oidc --features sso    # OIDC खोज
cargo run --example auth_google --features sso  # Google पहचान

सुरक्षा के सर्वोत्तम अभ्यास

अभ्यासविवरण
डिफ़ॉल्ट रूप से अस्वीकार करेंकेवल स्पष्ट रूप से आवश्यक अनुमतियाँ प्रदान करें
स्पष्ट अस्वीकृतियाँखतरनाक ऑपरेशनों के लिए अस्वीकृति नियम जोड़ें
सब कुछ ऑडिट करेंअनुपालन के लिए लॉगिंग सक्षम करें
सर्वर-साइड मान्य करेंसर्वर पर हमेशा JWTs को मान्य करें
HTTPS का उपयोग करेंJWKS एंडपॉइंट को सुरक्षित कनेक्शन की आवश्यकता होती है
कुंजियाँ घुमाएँJWKS कैश हर घंटे स्वतः रीफ़्रेश होता है
टोकन के जीवनकाल को सीमित करेंकम समय तक चलने वाले एक्सेस टोकन का उपयोग करें

त्रुटि प्रबंधन

use adk_auth::{AccessDenied, AuthError};
use adk_auth::sso::TokenError;

// RBAC errors
match ac.check("user", &Permission::Tool("admin".into())) {
    Ok(()) => { /* access granted */ }
    Err(AccessDenied { user, permission }) => {
        eprintln!("Denied: {} cannot access {}", user, permission);
    }
}

// SSO errors
match provider.validate(token).await {
    Ok(claims) => { /* token valid */ }
    Err(TokenError::Expired) => { /* token expired */ }
    Err(TokenError::InvalidSignature) => { /* signature invalid */ }
    Err(TokenError::InvalidIssuer { expected, actual }) => { /* wrong issuer */ }
    Err(e) => { /* other error */ }
}

पिछला: ← मूल्यांकन | अगला: विकास दिशानिर्देश →