Skip to main content

Governance wrapper for AI agents — check_action → execute → record_outcome against a Stryda control plane.

Project description

stryda-sdk (Python)

One-file wrapper that puts a Stryda governance check in front of any tool call your agent makes, records the outcome afterwards, and hands you back a verifiable attestation.

This is Stryda's Layer 3 enforcement path — for agents that cannot route through MCP (custom scripts, third-party frameworks you do not control, internal services). For MCP-native agents, use /api/mcp directly — the pipeline at backend/mcp/pipeline.py already governs every call.

See docs/system-architecture.md for the full picture.

Install

Not published to PyPI. Install from the repo:

pip install -e ./packages/stryda-sdk-python
# Optional — offline attestation verification
pip install -e "./packages/stryda-sdk-python[verify]"

Quick start

import os
import stripe
from stryda_sdk import StrydaClient, governed, PolicyDenied, PendingApproval

stryda = StrydaClient(
    api_key=os.environ["STRYDA_API_KEY"],
    base_url=os.environ.get("STRYDA_BASE_URL", "https://api.stryda.ai"),
)

stripe.api_key = os.environ["STRIPE_KEY"]


def refund(charge_id: str, cents: int):
    try:
        return governed(
            stryda,
            tool="stripe.create_refund",
            action_type="payment_refund",
            args={"charge_id": charge_id, "amount_cents": cents},
            cost_estimate=cents / 100,
            agent_id="billing-agent",
            idempotency_key=f"refund:{charge_id}:{cents}",
            execute=lambda: stripe.Refund.create(charge=charge_id, amount=cents),
        )
    except PolicyDenied as e:
        print(f"Stryda denied refund: {e.reason}")
    except PendingApproval as e:
        print(f"Refund needs approval: {e.escalation_id}")

Manual two-step

check = stryda.check_action(
    tool="internal.delete_customer",
    action_type="hard_delete",
    args={"customer_id": customer_id},
)

if check.decision != "authorized":
    ...  # handle denied / escalated

import time
started = time.monotonic()
try:
    my_api.delete(customer_id)
    stryda.record_outcome(
        tool="internal.delete_customer",
        check_id=check.check_id,
        outcome="success",
        latency_ms=int((time.monotonic() - started) * 1000),
    )
except Exception as e:
    stryda.record_outcome(
        tool="internal.delete_customer",
        check_id=check.check_id,
        outcome="error",
        latency_ms=int((time.monotonic() - started) * 1000),
        error=str(e),
    )
    raise

Verifying attestations offline

Every record_outcome response includes an EdDSA JWT. The public key lives at https://api.stryda.ai/api/.well-known/jwks.json. The SDK's verifier:

from stryda_sdk import fetch_jwks, verify_attestation

jwks = fetch_jwks("https://api.stryda.ai")  # cache this
claims = verify_attestation(record.attestation, jwks, audience="mcp-governance")
# claims["audit_id"], claims["tool"], claims["decision"], claims["sub"] (user_id), …

No Stryda-specific format — any JWT library that understands EdDSA with Ed25519 will verify these tokens against the JWKS. PyJWT[crypto] works out of the box:

import jwt, httpx
jwks = httpx.get("https://api.stryda.ai/api/.well-known/jwks.json").json()
claims = jwt.decode(
    record.attestation,
    key=jwt.algorithms.OKPAlgorithm.from_jwk(
        next(k for k in jwks["keys"] if k["kid"] == record.attestation_kid)
    ),
    algorithms=["EdDSA"],
    audience="mcp-governance",
)

Error model

Exception Meaning
StrydaError Transport or HTTP error from the control plane.
PolicyDenied check_action returned denied. Do not execute the tool.
PendingApproval check_action returned escalated. Surface escalation_id to the user / agent loop.

governed() raises the first two for you. If execute() raises, record_outcome is still called with outcome="error" before the exception propagates. If both the tool and record_outcome fail, the tool exception wins — a best-effort audit write should not shadow the real error.

What this SDK does not do

  • It does not proxy your API calls. Your process still talks to OpenAI / Stripe / Twilio directly.
  • It does not cache decisions. A denied policy at T0 might be authorized at T1 after policy edits.
  • It does not retry. Use the same idempotency_key on retries — the control plane will return the stored decision instead of re-escalating.

Runtime requirements

  • Python 3.10+.
  • httpx>=0.26.
  • cryptography>=42 only if you use verify_attestation (extra: stryda-sdk[verify]).

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

stryda_sdk-0.1.0.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

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

stryda_sdk-0.1.0-py3-none-any.whl (11.4 kB view details)

Uploaded Python 3

File details

Details for the file stryda_sdk-0.1.0.tar.gz.

File metadata

  • Download URL: stryda_sdk-0.1.0.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for stryda_sdk-0.1.0.tar.gz
Algorithm Hash digest
SHA256 9cfde1becb1f028a21244b2b3a6182e5e158511db22e94397fbc694820826f1f
MD5 b86ea482975ee62f51d98ed333cdc956
BLAKE2b-256 30d092d1d2e95484b17739e170d0d318f97b0b91eaf54d23ee871fb45d4f8fd0

See more details on using hashes here.

File details

Details for the file stryda_sdk-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: stryda_sdk-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 11.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.9

File hashes

Hashes for stryda_sdk-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 b2f2c59fa98491d0ef3f7603420be0cfb19e1abc758d40206ecf4b474f7789a2
MD5 10d3865480db2ebf3ac9ed151a70e6ff
BLAKE2b-256 b2b072cc84b2d25c9adc22819e59ba53b0b59f12c9692912c97389818b68ae14

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