Skip to main content

Official Python SDK for Vorim AI — AI Agent Identity, Permissions & Audit

Project description

vorim

Official Python SDK for Vorim AI — the identity, permissions, and audit layer for AI agents.

Vorim AI provides cryptographic agent identities (Ed25519), fine-grained permissions (7 scopes), immutable audit trails, and trust scoring (0-100) for production AI agent deployments. EU AI Act compliant out of the box.

PyPI Python License

vorim.ai — Create a free account and get your API key in 30 seconds. Documentation — Full API reference, framework integrations, and examples. Quick Start — Set up in under 5 minutes.

Install

pip install vorim

With framework integrations:

pip install vorim[langchain]    # LangChain / LangGraph
pip install vorim[crewai]       # CrewAI
pip install vorim[openai]       # OpenAI Agents SDK
pip install vorim[all]          # All integrations

Requires Python 3.10+.

Quick Start

from vorim import Vorim

vorim = Vorim(api_key="agid_sk_live_...")

# Register an agent (returns Ed25519 keypair, private key shown once)
result = vorim.register(
    name="invoice-processor",
    capabilities=["read_documents", "extract_data"],
    scopes=["agent:read", "agent:execute"],
)
print(result.agent.agent_id)    # agid_acme_a1b2c3d4
print(result.agent.trust_score) # 50

# Check permissions (<5ms via Redis)
check = vorim.check(result.agent.agent_id, "agent:execute")

if check.allowed:
    # Emit audit event
    vorim.emit(
        agent_id=result.agent.agent_id,
        event_type="tool_call",
        action="process_invoice",
        resource="INV-2026-0042",
        result="success",
        latency_ms=142,
    )

# Verify any agent's trust (public, no auth required)
trust = vorim.verify(result.agent.agent_id)
print(f"Trust score: {trust.trust_score}/100")

Async Client

from vorim import AsyncVorim

async with AsyncVorim(api_key="agid_sk_live_...") as vorim:
    result = await vorim.register(
        name="my-agent",
        capabilities=["search"],
        scopes=["agent:read"],
    )

    trust = await vorim.verify(result.agent.agent_id)
    print(f"Trust score: {trust.trust_score}/100")

API Reference

Vorim(api_key, base_url?, timeout?, auto_sign=True)

Method Description
register(name, capabilities, scopes) Register an agent; caches the returned Ed25519 private key for auto-signing
check(agent_id, scope) Check if agent has permission (sub-5ms)
emit(agent_id, event_type, action, ..., sign=None) Emit an audit event. Auto-signed if the agent's key is in the keyring
emit_batch(events, sign=None) Emit up to 1,000 audit events. Auto-signs each one
verify(agent_id) Verify agent identity and trust score (public)
get_agent(agent_id) Get agent details
list_agents(status?, page?, per_page?) List agents with filtering
revoke(agent_id) Permanently revoke an agent
grant(agent_id, scope, valid_until?, rate_limit?) Grant a permission scope
use_agent_key(agent_id, private_key_pem) Restore a private key into the in-memory keyring after process restart
forget_agent_key(agent_id) Remove a private key from the keyring

Module-level helpers: canonical_payload_v1(event) and canonical_payload_v0(event) (return the bytes that get signed) and sign_payload(payload, private_key_pem) (returns ed25519:<base64>).

AsyncVorim has the same interface with await on all methods.

Per-event signing (auto-signing)

From v3.7.0, every audit event is signed at source with the agent's Ed25519 private key — no code change required. register() caches the returned key in memory and emit() attaches the signature transparently.

Canonical form. Since 3.7.0 the SDK defaults to v1 canonical form: RFC 8785 JSON Canonicalization Scheme (JCS) over the whole event minus signature and canonical_form. v1 brings metadata, replayable-evidence fields (model_version, tool_catalogue_hash, system_prompt_hash, prev_event_hash), and delegation context (on_behalf_of, delegator_agent_id, delegation_chain_id, delegation_depth) under the signature. The previous v0 form was a pipe-joined six-field string event_type|action|resource|input_hash|output_hash|result and is now deprecated — passing canonical_form="v0" explicitly still works for verifier-compat scenarios but logs a deprecation warning. Use @vorim/verify@0.2.0+ (or the v1 helpers in this package) to verify v1 events offline.

result = vorim.register(name="agent", capabilities=[], scopes=[])

# Auto-signed. The signature is attached before the request leaves the process.
vorim.emit(
    agent_id=result.agent.agent_id,
    event_type="tool_call",
    action="transfer_funds",
    result="success",
)

To verify signatures server-side, the API operator sets VORIM_VERIFY_AUDIT_SIGNATURES=true.

Restoring keys across process restarts. The in-memory keyring is lost on restart. Load the private key from your secret store:

vorim.use_agent_key(agent_id, private_key_pem)
vorim.forget_agent_key(agent_id)  # revoke from memory

Opting out. Per event with sign=False, or globally with auto_sign=False:

vorim.emit(agent_id=..., event_type=..., action=..., result=..., sign=False)
vorim = Vorim(api_key=..., auto_sign=False)

Runtime Control (gate actions before they happen)

Ask Vorim whether an action should proceed before your agent performs it. before_action() returns a typed decision and, by default, raises on deny (a denial is in the response body, not the HTTP status).

from vorim import Vorim, VorimDeniedError

vorim = Vorim(api_key="agid_sk_live_...")

try:
    decision = vorim.before_action(
        agent_id="agid_acme_a1b2c3d4",      # always the public agid_* id
        action_type="tool_call",
        action_target="sendEmail",
        required_scope="agent:communicate",
        payload={"to": "customer@example.com", "body": "..."},
    )

    payload = decision.modified_payload or {"to": "customer@example.com"}

    if decision.decision in ("allow", "modify"):
        send_email(payload)
    elif decision.decision == "escalate":
        resolved = vorim.wait_for_decision_resolution(decision.decision_id)
        if resolved.decision == "allow":
            send_email(payload)

    # Link the post-action audit event back to the decision.
    vorim.emit(
        agent_id="agid_acme_a1b2c3d4",
        event_type="tool_call",
        action="sendEmail",
        result="success",
        decision_id=decision.decision_id,   # correlates audit ↔ decision
    )
except VorimDeniedError as err:
    print("Action denied:", err.decision.reason)

Verdicts: allow · deny (raises VorimDeniedError by default) · modify (use decision.modified_payload) · escalate (poll wait_for_decision_resolution) · fallback.

modify is client-cooperative. Vorim returns the sanitised modified_payload; your agent must send it in place of the original. The platform does not sit inline and does not currently enforce that you do — carry decision_id into the matching emit() so the action stays auditable.

Fail-open: if the decision API is unreachable, before_action() returns a synthetic fallback decision. Pass runtime_fail_open=False to the constructor to fail closed. A reachable server returning deny always denies. AsyncVorim exposes the same async methods.

Requires an API key with the runtime:decide scope and a Growth+ plan. modify verdicts come from policy rules provisioned by Vorim (rule-authoring API ships in a later release).

Permission Scopes

Scope Description
agent:read Read data on behalf of owner
agent:write Write or modify data
agent:execute Trigger actions or tool calls
agent:transact Financial or contractual actions
agent:communicate Send messages or emails
agent:delegate Sub-delegate to other agents
agent:elevate Request permission elevation

Framework Integrations

LangChain / LangGraph

from vorim import Vorim
from vorim.integrations.langchain import vorim_tool, VorimCallbackHandler

vorim = Vorim(api_key="agid_sk_live_...")

@vorim_tool(vorim, agent_id="agid_acme_...", permission="agent:execute")
def search(query: str) -> str:
    """Search documents."""
    return f"Results for {query}"

# search() is now a standard LangChain tool with built-in permission checks + audit

CrewAI

from vorim import Vorim
from vorim.integrations.crewai import register_crew

vorim = Vorim(api_key="agid_sk_live_...")

crew = register_crew(vorim, {
    "crew_name": "content-pipeline",
    "members": [
        {
            "role": "researcher",
            "name": "crew-researcher",
            "capabilities": ["web_search"],
            "scopes": ["agent:read", "agent:execute"],
        },
    ],
})

OpenAI Function Calling

from openai import OpenAI
from vorim import Vorim
from vorim.integrations.openai_agents import VorimToolRegistry

vorim = Vorim(api_key="agid_sk_live_...")
client = OpenAI()

registry = VorimToolRegistry(vorim=vorim, agent_id="agid_acme_...")
registry.add(
    name="search",
    description="Search documents",
    parameters={"type": "object", "properties": {"query": {"type": "string"}}},
    execute=lambda args: f"Results for {args['query']}",
)

response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Search for AI papers"}],
    tools=registry.to_openai_tools(),
)

# Permission checked + audited automatically
tool_messages = registry.execute_tool_calls(
    response.choices[0].message.tool_calls or []
)

Resources

License

MIT

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

vorim-3.8.1.tar.gz (58.8 kB view details)

Uploaded Source

Built Distribution

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

vorim-3.8.1-py3-none-any.whl (51.4 kB view details)

Uploaded Python 3

File details

Details for the file vorim-3.8.1.tar.gz.

File metadata

  • Download URL: vorim-3.8.1.tar.gz
  • Upload date:
  • Size: 58.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for vorim-3.8.1.tar.gz
Algorithm Hash digest
SHA256 1458a40c2b9d86c803cecddfbd15cbadacb7eaa76f6d2490bd4dc59b0bade9e2
MD5 6af1fe9fc3e784c7937c39fe917bb217
BLAKE2b-256 89a039a23f4d0ba74e97006bcb9ece48954993c288acc9d71f64b0b19377d612

See more details on using hashes here.

File details

Details for the file vorim-3.8.1-py3-none-any.whl.

File metadata

  • Download URL: vorim-3.8.1-py3-none-any.whl
  • Upload date:
  • Size: 51.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.8

File hashes

Hashes for vorim-3.8.1-py3-none-any.whl
Algorithm Hash digest
SHA256 c608a56189d97d495b9585b376b7dc895221a111a3791ae87e37c1e736ece0a3
MD5 3a3f2547903b96c397b862277a95680d
BLAKE2b-256 c21a3800e9b984cc844e86e7e9c897cf2de667668b133d22d10a56dc71cf1a15

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