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:
- Base token: SVID assertion at the IdP's token endpoint. The grant type and parameter names vary by IdP.
- 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) withclientAuthenticatorType=federated-jwt,serviceAccountsEnabled=true, andstandard.token.exchange.enabled=true. jwt.credential.subset to the agent's SPIFFE ID.jwt.credential.issuerset 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
audincludes 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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aae569ae4319904dcadf43081d693dd759c0b1506525e3a323e3c55c56f947b9
|
|
| MD5 |
f4c6d5c40985465e563ecbf9d6adfafd
|
|
| BLAKE2b-256 |
ce1d1e548070153f4342b9ec861b2d51a21a47705f2389985d409e3e168b2fb0
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
631c57ab2938d7d47efc4108877d97da663427fd83eec924a3b86ed431c26cc5
|
|
| MD5 |
364d456257a96cc6a88e150f15b6138f
|
|
| BLAKE2b-256 |
202a7b27940d3f9c85d8da9e17c9e97b22068c5d5edbdbee2b723d4139fc9b6d
|