Okta Agent
CLI or API | MCP
Version: 2.2.0
Documentation — Installation, deployment, usage across the API, CLI, and MCP server live on the docs site: https://knuckles-team.github.io/okta-agent/
Table of Contents
- Overview
- Architecture
- Installation
- Configure
- Environment Variables
- Quick Start
- Run
- MCP Tools
- Deployment
- Keycloak Parity
- Development
Overview
Enterprise CIAM/SSO connector for the agent fleet: a production-grade MCP
applications, policies, and the system log. Complements keycloak-agent
(open-source IdP) with the commercial-IdP side of the house, mirroring its
verb taxonomy so agents can switch IdPs with familiar verbs.
- Raw
httpxclient — no Okta SDK; every method documents the endpoint it calls. - Two auth modes: SSWS API token and OAuth2 private-key-JWT (org authorization server, Okta API scopes).
- Rate-limit aware: every response envelope carries the latest
X-Rate-Limit-*snapshot; HTTP 429 triggers capped automatic backoff. - Cursor pagination via
Link: rel="next"headers (Okta'saftercursor), with hard item caps and resumablenext_cursors. - Safety: destructive operations (disable / remove / clear sessions / password ops) are blocked unless explicitly allowed; credential material is redacted from logs and error envelopes.
Architecture
Installation
Install the connector-focused
[mcp]extra. Examples useokta-agent[mcp]to add FastMCP / FastAPI throughagent-connector-sdk; the required Agent Connector SDK core enables model orchestration.
Pick the extra that matches what the operator want to run:
| Extra | Installs | Use when |
|---|---|---|
okta-agent[mcp] |
Connector-focused MCP server (agent-connector-sdk — FastMCP/FastAPI + epistemic-graph[full]) |
The operator only run the MCP server (smallest install / image) |
okta-agent[all] |
Everything (mcp + agent + logfire) |
Development / both surfaces |
Container images (:mcp)
One multi-stage docker/Dockerfile builds the MCP-only image (--target mcp):
| Image tag | Build target | Contents | Entrypoint |
|---|
</code></pre>
<p>agent (<code>immutable agent digest</code>) with a co-located <code>:mcp</code> sidecar.</p>
<h3 id="user-content-knowledge-graph-database-epistemic-graph">Knowledge-graph database (<code>epistemic-graph</code>)<a href="#user-content-knowledge-graph-database-epistemic-graph" aria-label="Link to heading 'Knowledge-graph database (epistemic-graph)'" data-heading-content="Knowledge-graph database (epistemic-graph)" class="anchor"></a></h3>
<p>Agent Connector SDK core dependency (<code>epistemic-graph[full]</code>). The <code>[mcp]</code> extra keeps
deployments can use the bundled engine. For production or shared state, run
<strong>epistemic-graph as a dedicated database service</strong> and configure the runtime to use it.
Deployment recipes (single-node + Raft HA), connection configuration, and architecture
diagrams are documented in the
<a href="https://knuckles-team.github.io/epistemic-graph/deployment/">epistemic-graph deployment guide</a>.</p>
<h2 id="user-content-configure">Configure<a href="#user-content-configure" aria-label="Link to heading 'Configure'" data-heading-content="Configure" class="anchor"></a></h2>
<pre><code class="language-bash">export OKTA_ORG_URL="https://acme.okta.com"
# Mode 1 — SSWS API token (takes precedence)
export OKTA_API_TOKEN="<api token>"
# Mode 2 — OAuth2 private-key-JWT (service app, Okta API scopes)
export OKTA_CLIENT_ID="0oa..."
export OKTA_PRIVATE_KEY_FILE="/path/to/key.pem" # or OKTA_PRIVATE_KEY inline
export OKTA_SCOPES="okta.users.read okta.groups.manage"
See .env.example for every knob (OKTA_TLS_PROFILE, OKTA_MAX_RETRIES,
OKTA_BACKOFF_CAP_SECONDS, OKTA_ALLOW_DESTRUCTIVE, per-tool switches).
Environment Variables
Package environment variables
| Variable | Example | Description |
|---|---|---|
HOST |
0.0.0.0 |
|
PORT |
8000 |
|
TRANSPORT |
stdio |
options: stdio, streamable-http, sse |
ENABLE_OTEL |
True |
|
OTEL_EXPORTER_OTLP_ENDPOINT |
http://localhost:8080/api/public/otel |
|
OTEL_EXPORTER_OTLP_PUBLIC_KEY_REF |
secret://telemetry/otlp-public-key |
|
OTEL_EXPORTER_OTLP_SECRET_KEY_REF |
secret://telemetry/otlp-secret-key |
|
OTEL_EXPORTER_OTLP_PROTOCOL |
http/protobuf |
|
EUNOMIA_TYPE |
none |
options: none, embedded, remote |
EUNOMIA_POLICY_FILE |
mcp_policies.json |
|
EUNOMIA_REMOTE_URL |
http://eunomia-server:8000 |
|
OKTA_ORG_URL |
https://acme.okta.com |
Okta org URL (no trailing slash), e.g. https://acme.okta.com |
OKTA_AGENT_BASE_URL |
— | Accepted as a fallback for OKTA_ORG_URL when that is unset |
OKTA_API_TOKEN |
secret-injected | |
OKTA_CLIENT_ID |
— | Service-app client id (org authorization server, client_credentials grant) |
OKTA_PRIVATE_KEY |
secret-injected | PEM private key inline, or a path to a PEM file |
OKTA_PRIVATE_KEY_FILE |
secret-injected | |
OKTA_KEY_ID |
secret-injected | Optional JWKS key id for the client assertion header |
OKTA_SCOPES |
okta.users.read okta.groups.read okta.apps.read |
Space-separated Okta API scopes |
OKTA_TLS_PROFILE |
system |
Named outbound TLS policy. Configure profiles in AgentConfig; a reference may resolve runtime trust material without persisting certificate paths here. |
OKTA_TLS_PROFILE_REF |
— | |
OKTA_MAX_RETRIES |
2 |
429 handling: retry attempts and backoff cap (seconds) |
OKTA_BACKOFF_CAP_SECONDS |
60 |
|
OKTA_ALLOW_DESTRUCTIVE |
False |
Safety: org-wide default for destructive tool actions (deactivate/delete/clear-sessions/password ops). Per-call allow_destructive=true also works; default is blocked. |
USERSTOOL |
True |
Tool registration switches |
GROUPSTOOL |
True |
|
APPSTOOL |
True |
|
POLICIESTOOL |
True |
|
SYSTEMTOOL |
True |
|
INGESTTOOL |
True |
Inherited agent-connector-sdk variables (apply to every connector)
| Variable | Example | Description |
|---|---|---|
MCP_TOOL_MODE |
intent |
Tool surface: intent | condensed | verbose | both |
MCP_ENABLED_TOOLS |
— | Comma-separated tool allow-list |
MCP_DISABLED_TOOLS |
— | Comma-separated tool deny-list |
MCP_ENABLED_TAGS |
— | Comma-separated tag allow-list |
MCP_DISABLED_TAGS |
— | Comma-separated tag deny-list |
MCP_CLIENT_AUTH |
— | Outbound MCP child auth: oidc-client-credentials | basic | none |
OIDC_CLIENT_ID |
— | OIDC client id (service-account auth) |
OIDC_CLIENT_SECRET_REF |
secret://identity/oidc-client-secret |
Runtime secret reference for the OIDC service account |
MCP_BASIC_AUTH_USERNAME |
— | HTTP Basic username (MCP_CLIENT_AUTH=basic) |
MCP_BASIC_AUTH_PASSWORD_REF |
secret://identity/mcp-basic-password |
Runtime secret reference for HTTP Basic auth (MCP_CLIENT_AUTH=basic) |
DEBUG |
False |
Verbose logging |
PYTHONUNBUFFERED |
1 |
Unbuffered stdout (recommended in containers) |
MCP_URL |
http://localhost:8000/mcp |
URL of the MCP server the agent connects to |
PROVIDER |
openai |
LLM provider for the agent |
MODEL_ID |
gpt-4o |
Model id for the agent |
30 package + 16 inherited variable(s). Auto-generated from .env.example + the shared agent-connector-sdk set — do not edit.
| Variable | Default | Purpose |
|---|---|---|
OKTA_ORG_URL |
— | Okta org URL, no trailing slash (OKTA_AGENT_BASE_URL accepted as fallback) |
OKTA_API_TOKEN |
— | SSWS API token (auth mode 1, takes precedence) |
OKTA_CLIENT_ID |
— | Service-app client id (private-key-JWT) |
OKTA_PRIVATE_KEY / OKTA_PRIVATE_KEY_FILE |
— | PEM private key inline or path |
OKTA_KEY_ID |
— | Optional JWKS key id for the client assertion |
OKTA_SCOPES |
read scopes | Space-separated Okta API scopes |
OKTA_TLS_PROFILE |
system |
Named outbound TLS policy from AgentConfig |
OKTA_MAX_RETRIES |
2 |
429 retry attempts |
OKTA_BACKOFF_CAP_SECONDS |
60 |
429 backoff cap |
OKTA_ALLOW_DESTRUCTIVE |
False |
Org-wide default for destructive tool actions |
HOST / PORT / TRANSPORT |
0.0.0.0 / 8000 / stdio |
MCP server bind + transport |
USERSTOOL / GROUPSTOOL / APPSTOOL / POLICIESTOOL / SYSTEMTOOL |
True |
Per-domain tool toggles |
ENABLE_OTEL / OTEL_EXPORTER_OTLP_* |
— | Telemetry (OTEL / Langfuse) |
EUNOMIA_TYPE / EUNOMIA_POLICY_FILE / EUNOMIA_REMOTE_URL |
none |
MCP authorization middleware |
AUTH_TYPE |
none |
MCP server auth mode (Docker) |
Quick Start
from okta_agent import Api
from okta_agent.api.credentials import SswsToken
from okta_agent.okta_input_models import SearchInput, FilterCondition
api = Api(org_url="https://acme.okta.com", credential=SswsToken("<token>"))
active = api.search_users(
conditions=[{"field": "status", "op": "eq", "value": "ACTIVE"}],
)
print(active["data"], active["rate_limit"])
# Or build typed tool params for the MCP surface:
params = SearchInput(
conditions=[FilterCondition(field="status", op="eq", value="ACTIVE")]
).model_dump_json(exclude_none=True)
Run
okta-mcp # stdio MCP server
okta-mcp --transport streamable-http --host 0.0.0.0 --port 8000
MCP Tools
Five consolidated, action-routed tools. Each takes action, params_json,
and (where applicable) allow_destructive.
Condensed action-routed tools (MCP_TOOL_MODE=condensed)
| MCP Tool | Toggle Env Var | Description |
|---|---|---|
okta_apps |
APPSTOOL |
Manage Okta applications — CRUD, lifecycle, and user/group assignments. |
okta_groups |
GROUPSTOOL |
Manage Okta groups — CRUD, membership, and dynamic group rules. |
okta_ingest |
INGESTTOOL |
Natively ingest Okta users/groups/apps into epistemic-graph as typed nodes. |
okta_policies |
POLICIESTOOL |
Inspect Okta policies and toggle policy/rule lifecycle. |
okta_system |
SYSTEMTOOL |
Inspect the Okta org — settings, auth servers, system log, authenticators, zones. |
okta_users |
USERSTOOL |
Manage Okta users — lifecycle, credentials, groups/apps/factors, sessions. |
Verbose 1:1 API-mapped tools (MCP_TOOL_MODE=verbose or both)
54 per-operation tools — one per public API method (click to expand)
| MCP Tool | Toggle Env Var | Description |
|---|---|---|
okta_activate_app |
APITOOL |
Activate an application. |
okta_activate_group_rule |
APITOOL |
Activate a group rule. |
okta_activate_policy |
APITOOL |
Activate a policy. |
okta_activate_policy_rule |
APITOOL |
Activate a policy rule. |
okta_activate_user |
APITOOL |
Activate a STAGED/DEPROVISIONED user. |
okta_add_group_member |
APITOOL |
Add a user to a group. |
okta_assign_group_to_app |
APITOOL |
Assign a group to an app. |
okta_assign_user_to_app |
APITOOL |
Assign a user to an app with an optional app-specific profile. |
okta_clear_user_sessions |
APITOOL |
Revoke all of a user's sessions — destructive. |
okta_create_app |
APITOOL |
Create an app from a basic template (oidc/saml/bookmark). |
okta_create_group |
APITOOL |
Create an OKTA_GROUP. |
okta_create_group_rule |
APITOOL |
Create an INACTIVE group rule from an Okta Expression Language condition. |
okta_create_user |
APITOOL |
Create a user, optionally activated immediately. |
okta_deactivate_app |
APITOOL |
Deactivate an application — destructive. |
okta_deactivate_group_rule |
APITOOL |
Deactivate a group rule — destructive. |
okta_deactivate_policy |
APITOOL |
Deactivate a policy — destructive. |
okta_deactivate_policy_rule |
APITOOL |
Deactivate a policy rule — destructive. |
okta_deactivate_user |
APITOOL |
Deactivate (deprovision) a user — destructive. |
okta_delete_group |
APITOOL |
Delete a group — destructive. |
okta_expire_password |
APITOOL |
Expire a user's password — destructive. |
okta_get_app |
APITOOL |
Get one application by id. |
okta_get_group |
APITOOL |
Get one group by id. |
okta_get_org |
APITOOL |
Get the org settings (company info, subdomain, status). |
okta_get_policy |
APITOOL |
Get one policy, optionally expanded with its rules. |
okta_get_system_log |
APITOOL |
Query the system log (audit events), capped and cursor-paginated. |
okta_get_user |
APITOOL |
Get one user by id, login, or login shortname. |
okta_list_app_groups |
APITOOL |
List the groups assigned to an app. |
okta_list_app_users |
APITOOL |
List the users assigned to an app. |
okta_list_apps |
APITOOL |
List applications with optional q label match or SCIM filter. |
okta_list_authenticators |
APITOOL |
List the org's authenticators (Okta Verify, WebAuthn, password, ...). |
okta_list_authorization_servers |
APITOOL |
List custom authorization servers. |
okta_list_group_members |
APITOOL |
List the users in a group. |
okta_list_group_rules |
APITOOL |
List group rules. |
okta_list_groups |
APITOOL |
List groups with optional q name prefix, SCIM filter or search. |
okta_list_network_zones |
APITOOL |
List network zones. |
okta_list_org_factors |
APITOOL |
List org-level MFA factor enablement (legacy Factors API view). |
okta_list_policies |
APITOOL |
List policies of one type (okta_sign_on/password/mfa_enroll/access_policy). |
okta_list_policy_rules |
APITOOL |
List the rules of a policy. |
okta_list_user_apps |
APITOOL |
List the app links assigned to a user. |
okta_list_user_factors |
APITOOL |
List the enrolled MFA factors for a user. |
okta_list_user_groups |
APITOOL |
List the groups a user belongs to. |
okta_list_users |
APITOOL |
List users with optional q prefix match, SCIM filter or search. |
okta_remove_group_member |
APITOOL |
Remove a user from a group — destructive. |
okta_reset_password |
APITOOL |
Start the password-reset flow — destructive. |
okta_search_groups |
APITOOL |
Search groups from structured SCIM conditions (built safely). |
okta_search_users |
APITOOL |
Search users from structured SCIM conditions (built safely). |
okta_suspend_user |
APITOOL |
Suspend an ACTIVE user — destructive. |
okta_unassign_group_from_app |
APITOOL |
Remove a group's app assignment — destructive. |
okta_unassign_user_from_app |
APITOOL |
Remove a user's app assignment — destructive. |
okta_unlock_user |
APITOOL |
Unlock a LOCKED_OUT user. |
okta_unsuspend_user |
APITOOL |
Return a SUSPENDED user to ACTIVE. |
okta_update_app |
APITOOL |
Replace an application (PUT semantics — pass the full app object). |
okta_update_group |
APITOOL |
Replace a group's profile (PUT semantics — name is required). |
okta_update_user |
APITOOL |
Partially update a user's profile and/or credentials. |
6 action-routed tool(s) · 54 verbose 1:1 tool(s). Each is enabled unless its <DOMAIN>TOOL toggle is set false; MCP_TOOL_MODE selects the surface (intent default — the six verb-tools, granular set loaded on demand · condensed action-routed · verbose 1:1 · both). Auto-generated — do not edit.
Examples
{"action": "search", "params_json": "{\"conditions\": [{\"field\": \"status\", \"op\": \"eq\", \"value\": \"ACTIVE\"}, {\"field\": \"profile.department\", \"op\": \"eq\", \"value\": \"Engineering\"}]}"}
{"action": "create", "params_json": "{\"template\": \"oidc\", \"label\": \"My App\", \"settings\": {\"redirect_uris\": [\"https://app.example.com/cb\"]}}"}
{"action": "deactivate", "params_json": "{\"user_id\": \"00u1\"}", "allow_destructive": true}
Every successful response is an envelope:
{"data": [...], "rate_limit": {"limit": 600, "remaining": 599, "reset": 1700000000}, "count": 5, "truncated": false, "next_cursor": null}
Errors map Okta's envelope: {"error": {"status", "error_code", "error_summary", "error_id", "error_causes", "rate_limit"}}.
Deployment
MCP_URL, PROVIDER, and MODEL_ID from the environment. Prebuilt images:
(full agent) — see Container images. See
docs/deployment.md for transports, reverse proxy, and DNS
guidance.
Additional Deployment Options
okta-agent can run as a local stdio process or container, or behind a remote
network boundary. The
Deployment guide carries
the detailed transport contract.
- Local container — launch a reviewed immutable image as a least-privilege stdio child with no listener or published port.
- Remote URL — connect through an operator-supplied authenticated HTTPS
ingress. Keep its URL, outbound identity references, trust profile, and exact
MCP_ALLOWED_HOSTSinAgentConfig.
Keycloak parity
Verbs intentionally mirror keycloak-agent where the concepts overlap, so an
agent fluent in one IdP connector can drive the other:
| Concept | keycloak-agent | okta-agent |
|---|---|---|
| Users CRUD | keycloak_agent_users list/get/create/update |
okta_users list/get/create/update |
| Password reset | reset_password |
reset_password (plus expire_password) |
| User's groups | list_users_by_user_id_groups |
list_groups |
| Groups CRUD + members | keycloak_agent_groups |
okta_groups (+ Okta group rules) |
| OAuth/SAML clients | keycloak_agent_clients |
okta_apps (Keycloak "clients" = Okta "apps") |
| Auth policies/flows | keycloak_agent_authentication |
okta_policies (read + lifecycle) |
| Server/org info & events | keycloak_agent_info / attack detection |
okta_system (org + system log) |
Okta-only surface: lifecycle states (suspend/unlock), group rules, app assignment profiles, network zones, Okta API scopes via private-key-JWT.
Development
pip install -e .[mcp,test]
pytest -v
pre-commit run --all-files
API references are cited in every client docstring (https://developer.okta.com/docs/api/).
Deploy with agent-connector-sdk-deployment
Provision this package with the consolidated agent-connector-sdk-deployment
workflow. It selects an installed-package, editable-source, or immutable-container
path; records only runtime secret and TLS-profile references in AgentConfig; and
runs doctor, registration, policy, observability, and rollback gates. Ask your agent
to "deploy okta-agent with agent-connector-sdk-deployment".
| Install mode | Command |
|---|---|
| Installed package | uv tool install "okta-agent[mcp]", then run okta-mcp |
| Immutable container | deploy registry.example.invalid/okta-agent@sha256:<digest> through the operator-selected orchestrator |
The repository embeds no deployment profile, credential value, certificate path, or
environment-specific endpoint. Supply those at runtime through AgentConfig and the
configured secret provider.
Governed capability contract
This package ships a compact canonical skill surface with specialist procedures
kept as referenced workflows. The current MCP tools, skill metadata,
connector_manifest.yml, ontology, mappings, shapes, fixtures, migrations,
tool-schema fingerprints, and certification metadata form one versioned
capability contract. Validate them together; do not rely on stale tool names or
historical per-task skill wrappers.
Runtime endpoints, credentials, certificate trust, tenant identity, retention, and observability policy are deployment inputs and are never packaged values. See Configuration, trust, and privacy before enabling a network transport, connector ingestion, Arbora delegation, or trace export.
Metadata
Release files for okta-agent 2.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| okta_agent-2.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Release files / okta_agent-2.2.0-py3-none-any.whl
| Download URL | okta_agent-2.2.0-py3-none-any.whl |
|---|---|
| Size | 99.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c0d963634f3f86f6d20e9b662d2bf2d128b00879cdb01c830c519cf28b1af488
|
|
BLAKE2b-256 checksum How to use checksums |
8867dbc89add392ed2f91bdedf5b7aeeacd900b024762d10baf9fa230b7e830e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.4
|
Security for okta-agent 2.2.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.