Skip to main content

FORMA — AI agent compliance SDK. Zero-config tracking, EU AI Act/DPDP/RBI compliance, cryptographic audit trails.

Project description

FORMA SDK — v2.3.0

Make non-compliance impossible — in one line of code.

FORMA doesn't just record what your AI did; it blocks non-compliant decisions before they execute. Add enforce=[...] and PII leaks, prompt injections, and policy violations are stopped at runtime — then every decision is HMAC-signed and mapped to RBI, DPDP, EU AI Act, and ISO 42001.

License: MIT Python 3.8+


Install

pip install forma-sdk

Import name is trustlayer:

import trustlayer as tl

Quickstart — runtime enforcement (zero-touch)

import trustlayer as tl

# One call. Enforcement is process-wide on every LLM/tool call — no decorators,
# no context managers, no edits inside your business logic.
tl.init(
    api_key="tl_live_YOUR_KEY",   # from forma.2bd.net → Settings
    human_sponsor="ops@company.com",
    enforce=["rbi_ml_risk", "dpdp"],   # ← blocks violations BEFORE they run
)

# Prove enforcement is live — 4 adversarial probes, no network:
result = tl.verify()
assert result["verified"], f"Gate not working: {result['summary']}"

# Your existing code is unchanged.
result = run_underwriting_model(application)

Now, before any LLM or tool call executes:

  • An Aadhaar / PAN / GSTIN / IFSC / Indian Passport / card number → blocked (DPDP)
  • "Ignore previous instructions…" / jailbreaks → blocked
  • "Auto-approve without review" → blocked (RBI human-review rule)

A blocked action raises ComplianceViolation. The gate runs locally in < 1 ms — no network hop. Tool calls get a 1.25× threat multiplier; dangerous tool names (exec, shell, rm, delete, drop) add a further +0.35.

Init-time validation: enforce=["dpdpp"] (typo) raises ValueError immediately with a link to the docs — misconfigurations are caught before any traffic flows.

Multiple agents — tl.register() / agents= (still zero edits)

Map your existing functions to agents without touching their bodies:

import trustlayer as tl
from my_app import approve_loan, validate_kyc, detect_fraud

tl.init(
    api_key="tl_live_YOUR_KEY",
    agents={
        "kyc-validator":  validate_kyc,                                        # bare callable
        "loan-approval":  {"fn": approve_loan, "enforce": ["rbi_ml_risk", "dpdp"],
                           "risk_level": "HIGH"},
        "fraud-detector": {"fn": detect_fraud, "enforce": ["dpdp"]},
    },
)

# Or register after init (decorator form also works):
tl.register("loan-approval", approve_loan, enforce=["rbi_ml_risk"], risk_level="HIGH")

# Call them exactly as before — each governed and attributed independently.
result = approve_loan(application)
from trustlayer import ComplianceViolation

try:
    result = approve_loan(application)
except ComplianceViolation as e:
    print(e.reason)   # "PII detected in LLM prompt: Aadhaar number. ..."

Observability API (v2.3.0)

Three functions let you inspect the in-process gate from health checks, startup scripts, or unit tests — no network calls needed.

tl.verify() — Prove enforcement is active

Runs 4 adversarial self-test probes against the local gate. Use at startup to confirm the gate is wired before any real traffic flows.

tl.init(api_key="tl_live_...", enforce=["dpdp"])
result = tl.verify()
# → {verified: True, probes_passed: 4, probes_total: 4, summary: "4/4 probes passed — gate is active"}

# Probes (all local — no network):
#   1. Aadhaar PII → must block
#   2. Indian PAN → must block
#   3. Canonical jailbreak → must block
#   4. Clean benign prompt → must allow
#   5. Unauthorized tool (if authorized_actions set) → must block

tl.status() — Real-time enforcement state

Returns a live snapshot of the gate — decision counts, top blocked rules, circuit-breaker state:

s = tl.status()
# → {
#     "version": "2.3.0",
#     "enforcement_active": True,
#     "decisions_total": 1847,
#     "decisions_blocked": 23,
#     "decisions_warned": 4,
#     "decisions_allowed": 1820,
#     "top_rule_hits": {"pii_in_prompt": 18, "threat_prompt_injection": 5},
#     "circuit_breaker_open": False,
#     "kill_switch_active": False,
#     "last_policy_sync": "2026-06-17T10:15:32Z",
#     ...
# }

tl.preview() — Dry-run gate check

Simulate what the gate would decide for any prompt — no side effects, no ComplianceViolation, no audit log entry:

r = tl.preview("My Aadhaar is 1234 5678 9012")
# → {"decision": "block", "rule_id": "pii_in_prompt", "reason": "PII detected: Aadhaar number..."}

r = tl.preview("What is the loan status?")
# → {"decision": "allow", "rule_id": None, "reason": None}

# Test a tool call (higher threat multiplier):
r = tl.preview("drop tables", action_type="tool_call", tool_name="exec_sql")
# → {"decision": "block", ...}

trustlayer verify-decisions — Tamper-evident audit CLI

Every gate decision is HMAC-SHA256 signed before buffering. This CLI command fetches the log and verifies every signature:

trustlayer verify-decisions
# ✓ 47 decisions verified (0 tampered, 0 unsigned)
#   Blocked: 8 | Warned: 3 | Allowed: 36
#   Top rule: pii_aadhaar (5 hits)

trustlayer verify-decisions --agent loan-approval-agent --limit 500
# exits 1 if any decision fails verification — wire into CI

Zero-config tracking (no enforcement)

import trustlayer as tl
tl.init(api_key="tl_live_YOUR_KEY")

# Every OpenAI / Anthropic / LangChain / LiteLLM call is auto-captured —
# tokens, cost, latency, anomaly score — with no other code changes.

Human approvals (EU AI Act Article 14 / RBI human review)

tl.init(
    api_key="tl_live_YOUR_KEY",
    require_approval_when=lambda ctx: ctx.get("amount", 0) > 1_000_000,
    approval_message="Loan above ₹10L requires human review.",
)
result = approve_loan(application)   # pauses for sign-off on high-stakes calls

Policy packs

Pack Region Enforces
dpdp India Aadhaar / PAN / GSTIN / IFSC / Passport / card / phone / DoB blocked; consent-bypass blocked
rbi_ml_risk India Banking auto-approval-without-review blocked; fund-disbursal routed to approval
eu_ai_act EU human-oversight bypass (Art. 14) & logging suppression (Art. 12) blocked
iso42001 Global concealing AI involvement blocked

PII patterns (17 — India + global)

Aadhaar · PAN · GSTIN (15-char) · IFSC code · Indian Passport · Driving License · Date of Birth (with context) · Visa card · Mastercard · Amex · CVV · phone · email · SSN · generic credit card · IBAN · passport (generic)


Kill switch

Pass kill_switch=True to tl.init(). When you trigger a kill from the dashboard, the next LLM/tool call raises KillSwitchTriggered in < 100 ms.

CI/CD compliance gate

trustlayer gate --pre-deploy --fail-below 80
trustlayer verify-decisions --limit 500   # tamper check in CI

Production reliability (v2.3.0)

Feature Behaviour
Policy sync circuit breaker Stops retry storms after 5 consecutive server failures; auto-resets after 5 min. Gate stays up using the last known policy.
Disk-backed decision buffer Unflushed decisions are persisted to ~/.forma/pending_decisions.jsonl on flush failure and replayed on next startup — no audit data lost on transient outages.
HMAC-signed entries Every buffered gate decision is signed with your API key before queuing — tamper-detectable by verify-decisions CLI or cache.verify_log().

tl.init() parameters (all 25)

Parameter Description
api_key FORMA API key (or FORMA_API_KEY env).
api_url Backend URL override.
agent_name Display name for ambient auto-captured runs.
human_sponsor Accountable human on the audit record.
auto_capture (True) Auto-patch OpenAI/Anthropic/LiteLLM/LangChain.
kill_switch (False) Start global process-level kill-switch watcher.
gate (True) Pre-check every auto-captured call through the compliance gate.
compliance Frameworks for scoring/reports (EU_AI_ACT, DPDP, RBI_MRM, ISO_42001).
ambient_runs (True) Create signed runs for auto-captured calls.
enforce Policy packs blocked locally (dpdp, rbi_ml_risk, eu_ai_act, iso42001). Typos raise ValueError at init time.
agents Zero-edit multi-agent map. {"name": fn} or {"name": {"fn": fn, "enforce": [...], ...}}.
purpose Plain-English purpose stored in the identity passport.
risk_level ("MEDIUM") LOW | MEDIUM | HIGH | CRITICAL.
authorized_actions Allow-list of tool names; gate blocks others.
drift_threshold (0.15) Behavioural drift threshold.
max_cost_usd Hard per-run cost cap.
require_approval_when Predicate ctx→bool; True pauses for human approval.
approval_message / approval_title Text in the Approvals inbox.
approval_timeout (3600) Seconds to wait for a decision.
approval_poll_interval (5) Seconds between inbox polls.
approval_via ("forma") Approval channel.
timeout (10) HTTP timeout seconds.
max_retries (2) Transport retry attempts.
fail_closed (False) Block when the gate is unreachable (default: fail open).

tl.register(name, fn, **cfg) — the second entry point

Binds one existing function to a governed agent. Works as a decorator too. Accepts the same full governance argument set as init(agents={...}) per-agent config (unknown keyword → TypeError).

When to use which

Use… When
tl.init(agents={...}) All agent functions importable at init() call. Simplest.
tl.register(name, fn, ...) Function defined/imported after init(), decorator form, or dynamic registration.

Node.js / TypeScript

Coming soon. Runtime enforcement (enforce) and approvals are Python-only today.


Dashboard & docs

License

MIT — see LICENSE.

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

forma_sdk-2.3.9.tar.gz (117.8 kB view details)

Uploaded Source

Built Distribution

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

forma_sdk-2.3.9-py3-none-any.whl (70.0 kB view details)

Uploaded Python 3

File details

Details for the file forma_sdk-2.3.9.tar.gz.

File metadata

  • Download URL: forma_sdk-2.3.9.tar.gz
  • Upload date:
  • Size: 117.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for forma_sdk-2.3.9.tar.gz
Algorithm Hash digest
SHA256 4791ab224fb7003b7422c06191b45e2cffcf9c8344b0de708ec80e378921de67
MD5 5450a55aee9044e6aa71a6de9e1202ea
BLAKE2b-256 cefd559d81b5918761fe35c1f3ce36c9e2b0728066342d2c0886758b4dad0672

See more details on using hashes here.

File details

Details for the file forma_sdk-2.3.9-py3-none-any.whl.

File metadata

  • Download URL: forma_sdk-2.3.9-py3-none-any.whl
  • Upload date:
  • Size: 70.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.9.6

File hashes

Hashes for forma_sdk-2.3.9-py3-none-any.whl
Algorithm Hash digest
SHA256 0fd92c689f96313003388d13a15b7a3d4e41bfdf6aa795a18acf0ec3a81f2765
MD5 e5642118dec77c8207c22d53678ae88e
BLAKE2b-256 24715daa8e568808a70a59966da4b45a5e25bcb26dea60498263336b3dcc4fb6

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