Skip to main content

Authentication and authorization for AI agents: SPIFFE identity, per-tool OAuth tokens, per-call authorization, and behavioral telemetry

Project description

draco (Python)

Python library for the Draco AI agent authentication and authorization system.

Install

uv pip install -e ".[dev]"

Optional extras:

uv pip install -e ".[metrics]"   # OpenTelemetry instrumentation

Test

pytest

Lint

ruff check .
ruff format --check .
mypy src/

Configuration

The SDK reads a JSON config file via bootstrap(Mode.DIRECT, path). All IdP-specific behavior is controlled by config fields; the code has no IdP-specific branches.

Token flow

The SDK uses a two-phase token model:

  1. Base token: SVID assertion at the IdP's token endpoint. The grant type and parameter names vary by IdP.
  2. Per-target tokens: RFC 8693 token exchange of the base token, scoped by audience.

DCR (RFC 7591) is optional. When configured, the agent self-registers with the IdP at startup and deregisters on shutdown. When not configured, the agent uses a pre-registered client identified by the SVID's subject claim.

Keycloak

Keycloak uses client_credentials grant with the SVID as a client_assertion (federated-jwt client authentication). DCR is not supported directly with SVIDs; agents use pre-registered clients.

{
  "agent_spiffe_id": "spiffe://example.draco.local/agents/hello-agent/default",
  "spiffe_endpoint_socket": "unix:///spiffe-workload-api/spire-agent.sock",
  "idp_token_endpoint": "https://keycloak.example.draco.local/realms/draco/protocol/openid-connect/token",
  "idp_grant_type": "client_credentials",
  "ca_bundle_path": "/etc/ssl/step-ca/root_ca.crt",

  "authz_backend": "openfga",
  "openfga_url": "https://openfga.example.draco.local",
  "openfga_store_id": "01ARZ3NDEKTSV4RRFFQ69G5FAV",
  "openfga_audience": "openfga",

  "posture_source": "/etc/draco/bundles",
  "trust_store_backend": "file",
  "trust_store_path": "/var/draco/trust-state.json",

  "tools": [...]
}

Keycloak prerequisites:

  • A Keycloak client (e.g. draco-hello-agent) with clientAuthenticatorType=federated-jwt, serviceAccountsEnabled=true, and standard.token.exchange.enabled=true.
  • jwt.credential.sub set to the agent's SPIFFE ID.
  • jwt.credential.issuer set to the SPIFFE IdP alias (e.g. spire).
  • A SPIFFE identity provider at the realm level with the SPIRE trust domain and bundle endpoint.
  • For each target service (e.g. OpenFGA), a Keycloak client registered with that service name as the clientId, and the requesting client's service account assigned a role on that target client (Keycloak resolves available exchange audiences via role mappings).
  • A self-audience mapper on the agent's client so the base token's aud includes the client itself (required by Keycloak's standard token exchange).

Other RFC 8693-capable IdPs are supported through the same configuration surface (idp_grant_type, idp_client_audience, and the optional dcr block); Keycloak is the documented reference.

Config field reference

Field Required Default Description
agent_spiffe_id yes The agent's SPIFFE ID.
spiffe_endpoint_socket yes Path to the SPIRE Workload API socket.
idp_token_endpoint yes OAuth token endpoint URL.
idp_grant_type no client_credentials Grant type for the base token. client_credentials (Keycloak federated-jwt), or urn:ietf:params:oauth:grant-type:jwt-bearer for IdPs that take the SVID as the authorization grant.
idp_assertion_type no urn:ietf:params:oauth:client-assertion-type:jwt-spiffe Client assertion type.
idp_client_audience no derived from token endpoint Audience for the client_assertion SVID. Omit for Keycloak (derived from realm URL); set explicitly when the IdP expects a fixed audience string.
ca_bundle_path no CA bundle for TLS verification to the IdP.
authz_backend yes openfga for live authz, bundle for local-only.
openfga_url when openfga OpenFGA API URL.
openfga_store_id when openfga OpenFGA store ID.
openfga_audience no openfga_url Audience for RFC 8693 exchange when targeting OpenFGA. Set to the Keycloak client_id for OpenFGA (e.g. openfga).
posture_source yes Path to the directory containing per-trust-level bundle JSON files.
trust_store_backend no file file or openbao.
trust_store_path when file Path to the trust state JSON file.
dcr no DCR configuration. Omit to skip DCR (pre-registered client).
dcr.auth_method no private_key_jwt token_endpoint_auth_method declared to the IdP during DCR.
dcr.grant_types no [client_credentials, token-exchange] Grant types requested during DCR.
dcr.jwks_uri no SPIRE OIDC JWKS URL, included in the DCR body so the IdP can verify the client's assertions.
dcr.scopes_source no policy Where to derive scopes for DCR.
tools no Array of tool definitions (name, description, parameters, endpoint, transport).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

draco_toolkit-0.1.1.tar.gz (195.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

draco_toolkit-0.1.1-py3-none-any.whl (65.7 kB view details)

Uploaded Python 3

File details

Details for the file draco_toolkit-0.1.1.tar.gz.

File metadata

  • Download URL: draco_toolkit-0.1.1.tar.gz
  • Upload date:
  • Size: 195.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for draco_toolkit-0.1.1.tar.gz
Algorithm Hash digest
SHA256 aae569ae4319904dcadf43081d693dd759c0b1506525e3a323e3c55c56f947b9
MD5 f4c6d5c40985465e563ecbf9d6adfafd
BLAKE2b-256 ce1d1e548070153f4342b9ec861b2d51a21a47705f2389985d409e3e168b2fb0

See more details on using hashes here.

File details

Details for the file draco_toolkit-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: draco_toolkit-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 65.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for draco_toolkit-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 631c57ab2938d7d47efc4108877d97da663427fd83eec924a3b86ed431c26cc5
MD5 364d456257a96cc6a88e150f15b6138f
BLAKE2b-256 202a7b27940d3f9c85d8da9e17c9e97b22068c5d5edbdbee2b723d4139fc9b6d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page