Eniyan SDK (Python)
Govern your AI agents wherever they run. This SDK wraps the Eniyan API —
agent identity verification, live scope decisions, JIT credential windows,
short-lived OAuth tokens, and self-reported run telemetry — so any agent
loop becomes Eniyan-governed in a few lines. Eniyan never hosts or observes
your loop; your agent reports metadata-only telemetry (names, scopes, token
counts, outcomes — never prompts, arguments, results, or model output).
The package also ships three governed MCP servers — eniyan-mcp
(governance operations), eniyan-fs (local files), and eniyan-web
(websites, and, where the org opts in, transaction execution at web
checkouts).
pip install eniyan
Quickstart
import os
from eniyan import EniyanClient, governed_run, EniyanScopeRefused
client = EniyanClient(
base_url="https://api.eniyantrust.com",
api_key=os.environ["ENIYAN_API_KEY"],
credential_token=os.environ["ENIYAN_CREDENTIAL_TOKEN"],
agent_id=os.environ["ENIYAN_AGENT_ID"],
)
with governed_run(client, harness="my-loop", jit=True, scopes=["crm:read"]) as run:
fetch = run.tool("fetch_accounts", scope="crm:read")(fetch_accounts)
accounts = fetch() # refused under block mode BEFORE it runs
run.model_call("claude-sonnet-5", input_tokens=1200, output_tokens=300)
On exit — success or crash — the run is finished, buffered steps are flushed, and the JIT window is completed and attested.
What each piece maps to
| SDK call | API |
|---|---|
client.verify() / client.check_scope() |
POST /v1/credentials/verify |
client.mint_token() / client.introspect() |
POST /v1/oauth/token / /introspect |
client.mint_consumer_token() / mint_trading_token() |
POST /v1/oauth/token (delegation_id / mandate_id) |
client.report_delegation_usage() / report_trading_usage() |
POST /v1/consumer/delegations/{ref}/usage / POST /v1/trading/mandates/{ref}/usage |
client.validate_grant() |
POST /v1/agents/credentials/validate |
client.get_web_config() / report_web_injection() |
POST /v1/agents/credentials/web-access-config / /web-injection-events |
client.create_purchase_request() / get_purchase_status() / consume_purchase_request() / report_purchase_outcome() |
POST /v1/agents/credentials/purchase-requests[...] |
client.create_task() / complete_task() / attest_task() |
JIT task lifecycle |
client.start_run() / append_steps() / finish_run() |
POST /v1/runs |
Advisory-mode scope violations do not raise — the call proceeds and the
violation is flagged server-side (GovernanceDecision.advisory_flagged).
Block mode raises EniyanScopeRefused before the tool executes.
MCP server
pip install "eniyan[mcp]" and run eniyan-mcp to expose the same
governance operations as MCP tools for Claude Code or any MCP-capable
harness. See the gated docs for configuration.
Development
pip install -e ".[dev]"
pytest
tests/integration_local.py runs the full flow against a local Eniyan
stack (docker compose up from the repo root).
eniyan-fs — govern your agents' access to local files
A second MCP server in the same package: agents reach files ONLY inside the roots you configure, every access is policy-checked and audited by Eniyan (metadata only — root aliases + path hashes, never contents, never full paths), and revoking the agent's credential is the kill switch.
{
"mcpServers": {
"eniyan-fs": {
"command": "eniyan-fs",
"env": {
"ENIYAN_API_KEY": "...",
"ENIYAN_CREDENTIAL_TOKEN": "...",
"ENIYAN_AGENT_ID": "...",
"ENIYAN_FS_ROOTS": "projects=/abs/path:notes=/abs/other"
}
}
}
}
Writes and deletes fail closed when Eniyan is unreachable; deletion is
double-gated (org scope fs:delete AND ENIYAN_FS_ALLOW_DELETE=1).
eniyan-web — govern your agents' web access
A third MCP server in the same package: agents reach ONLY the websites
allowlisted on the agent's Eniyan dashboard page, with per-site read /
write / edit / download abilities (mapped to request effect: GET, POST,
PUT/PATCH/DELETE) plus a Pay / Transact ability that lets the browser
engine execute purchases and transactions the org has authorized — see
"Web transaction execution (0.5.0)" below (shopping/transaction tools
register on the browser engine; the local card vault is set up with
eniyan-web --setup-card). Every access is policy-checked and audited (metadata
only — domains and URL hashes, never page content, never full URLs),
page content is screened locally for prompt injections and always
delivered wrapped as untrusted data, and revoking the credential is the
kill switch.
{
"mcpServers": {
"eniyan-web": {
"command": "eniyan-web",
"env": {
"ENIYAN_API_KEY": "...",
"ENIYAN_CREDENTIAL_TOKEN": "...",
"ENIYAN_AGENT_ID": "..."
}
}
}
}
No sites live in the config — the allowlist is managed in the dashboard
and syncs to the gate within a minute. Writes/edits/downloads fail
closed when Eniyan is unreachable; downloads are double-gated (the
dashboard switch AND ENIYAN_WEB_ALLOW_DOWNLOADS=1 +
ENIYAN_WEB_DOWNLOAD_DIR). The real-browser engine (Playwright) is the
enterprise default and needs pip install "eniyan[browser]" plus the
dashboard engine set to browser.
Web transaction execution (0.5.0) — delegations & mandates at web checkouts
When the organization opts in (dashboard toggles), the browser gate executes the SAME transaction authority agents already exercise via API:
- Consumer delegations —
authorize_transactionwith the delegation ref mints a 5-minute transaction-constrained token bound to the page the gate is actually on (the observed host is the counterparty). A step-up pauses locally: relay the consumer's challenge link through your platform, then pollcheck_transaction. Caps, budgets, counterparty allow-lists, and approvals are identical on either surface. - Trading mandates — full parity: web orders ride mandate math only; a refusal is final.
- Personal purchases — an approved purchase now authorizes the SUBMIT itself.
Fill-less first-class (0.5.0 behavior change): the authorization
opens the submit window with no card fill — merchant-saved cards, wallet
buttons (Apple/Google Pay on the site), and payment methods on file all
ride it, and Eniyan touches no payment instrument of any kind. The
locally-vaulted card remains only for stores where the card must be
typed (fill_payment); the vault is cross-platform (macOS Keychain
built in, Windows/Linux via pip install "eniyan[card]"). The minted
access token never appears in tool results or model context. In 0.4.0
the submit window opened only after a card fill — 0.5.0 opens it at
authorization.
Release files for eniyan 0.7.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| eniyan-0.7.0.tar.gz | 100.3 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| eniyan-0.7.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 185.1 kB
Release files / eniyan-0.7.0.tar.gz
| Download URL | eniyan-0.7.0.tar.gz |
|---|---|
| Size | 100.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1642cc63bd0f5cb338ece8b0b7512097db3ee0d6e58e85c5bfee8caf719acf73
|
|
BLAKE2b-256 checksum How to use checksums |
12527debfba504fd62d8321cb0d363e81d036e55b5b749d15c069674100a0b48
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|
Release files / eniyan-0.7.0-py3-none-any.whl
| Download URL | eniyan-0.7.0-py3-none-any.whl |
|---|---|
| Size | 84.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
4779b7a141750efd32cd6521b62270528e5509098d6490d27e97bd468df5bd09
|
|
BLAKE2b-256 checksum How to use checksums |
52e309df4eb6108416c74fe6a6526683b1b5004845cad7952213e2f391836c95
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.3
|