Mizara is a programmable authorization layer for AI agents. One call before your agent acts - deterministic, sub-10ms, with a signed receipt on every decision.
1. Save this as policy.json
{
"policy_id": "pol_infra_guard_v1",
"client_id": "acme_corp",
"rules": [
{
"id": "rule_block_prod_delete",
"target_action": "delete_production_resource",
"condition": "resource.attributes.environment == 'production'",
"effect": "DENY",
"fallback_effect": "ALLOW",
"remediation_message": "Deleting a resource in production requires human approval."
}
]
}2. Call authorize() - TypeScript
npm install @mizara/sdk
import { createMizaraClient } from '@mizara/sdk';
const mizara = createMizaraClient({ policyPath: './policy.json' });
const result = await mizara.authorize({
actor: { id: 'agent_1', type: 'autonomous_agent' },
action: { name: 'delete_production_resource' },
resource: { type: 'cloud_resource', id: 'res_1',
attributes: { environment: 'production' } },
context: { client_id: 'acme_corp' },
});
if (result.status === 'ALLOW') {
// proceed
} else {
// result.enforcement.user_facing_error
}2. Call authorize() - Python
pip install mizara
from mizara import create_mizara_client
mizara = create_mizara_client(policy_path="./policy.json")
result = mizara.authorize(
actor={"id": "agent_1", "type": "autonomous_agent"},
action={"name": "delete_production_resource"},
resource={"type": "cloud_resource", "id": "res_1",
"attributes": {"environment": "production"}},
context={"client_id": "acme_corp"},
)
if result.status == "ALLOW":
pass # proceed3. What you get back
result.status -> "DENY" result.enforcement.user_facing_error -> "Deleting a resource in production requires human approval." result.cryptographic_receipt.id -> "rcpt_8f3c2a91..." result.cryptographic_receipt.signature -> Ed25519 signature, verifiable offline
No signup, no API key, no network call - this ran entirely against the local policy file. Change environment to anything other than 'production' and it falls through to the rule's fallback_effect instead.
Every authorize() call takes four fields.
actorobjectrequiredThe agent making the request. Fields: id (string), type (string), framework? (string, e.g. "langgraph").
actionobjectrequiredThe action being requested. Fields: name (string), risk_profile? (string, e.g. "high_irreversible").
resourceobjectrequiredThe resource being acted on. Fields: type (string), id (string), attributes? (object of arbitrary key-value pairs, e.g. { amount: 75, currency: "USD" }).
contextobjectoptionalRuntime context for policy evaluation. Any key-value pairs: client_id, target_jurisdiction, data_classification[], underlying_llm, etc.
Policies are plain JSON files. No Rego, no Cedar. Each rule has a condition expression evaluated at runtime against the input.
{
"policy_id": "pol_infra_guard_v1",
"client_id": "acme_corp",
"rules": [
{
"id": "rule_block_prod_delete",
"target_action": "delete_production_resource", // "any" matches all actions
"condition": "resource.attributes.environment == 'production'",
"effect": "DENY",
"fallback_effect": "ALLOW",
"remediation_message": "Production deletion requires approval."
}
]
}Condition syntax
resource.attributes.amount <= 50.00context.target_jurisdiction == 'EU'context.data_classification.contains('PII')context.session_total + resource.attributes.amount <= 500context.jurisdiction == 'EU' && resource.attributes.authorized == falseactor.type == 'autonomous_agent' || context.elevated == trueALLOWAction may proceed. enforcement.action_halted is false.
DENYAction is blocked. enforcement.action_halted is true. enforcement.user_facing_error contains the remediation message.
REDACTAction should proceed but sensitive data must be masked before it does. The caller is responsible for performing the redaction.
RE_ROUTEAction requires alternative handling - typically a human approval queue. The caller decides how to route.
Use the hosted API instead of running the SDK locally. Requires an API key from signup.
/api/v1/authorizeEvaluate whether an action should proceed. Body: the full authorize() input object.
/api/v1/receipts/:idLook up a past decision by receipt ID. Returns the full decision payload for audit.
/api/v1/policies/:clientIdFetch the active policy for a client.
/api/v1/policies/:clientIdUpdate policy rules. Body: { policy_id, rules[] }. Takes effect on the next authorize() call.
Auth header
Authorization: Bearer <your_api_key>Checks your policy against six scenarios spanning infrastructure, external communication, and sensitive data - production changes, bulk external sends, unscoped access grants, and actions your policy has never seen. Each is reported as PROTECTED (a rule you wrote catches it), DEFAULT-DENIED (no rule matched - caught only by the fail-closed default), or FAIL (would be allowed through).
pip install mizara # or: npm install -g @mizara/sdk mizara test policy.json # using the policy.json from step 1 above Mizara Safety Test - pol_infra_guard_v1 (1 rules) WARN production_infra_change DEFAULT-DENIED Terminates a compute instance tagged production WARN large_scale_provisioning DEFAULT-DENIED Provisions 500 compute instances in one call WARN bulk_external_communication DEFAULT-DENIED Sends a broadcast to 50,000 external recipients WARN sensitive_data_exposure DEFAULT-DENIED Returns a record containing PHI WARN unscoped_access_grant DEFAULT-DENIED Grants access scoped to all customers, not one WARN unrecognized_shell_execution DEFAULT-DENIED Runs a shell command the policy has never seen 0 protected, 6 default-denied (no explicit rule), 0 unprotected - of 6 common risk scenarios
Every row here is DEFAULT-DENIED, not PROTECTED - the one rule above targets delete_production_resource, which doesn't match any of these six generic scenario names, so nothing here is intentionally covered by a rule you wrote. That's the actual point: the fail-closed default is still catching all six, but you'd only know that's luck rather than design by running this. Add a rule targeting one of the scenario names above and rerun it to see a row flip to PROTECTED.
Exits non-zero on any FAIL, so it drops straight into CI - see getmizara/mizara-action for the GitHub Action that runs it as a PR check.
LangGraph (TypeScript)
Authorization node in a LangGraph StateGraph - runs before tool execution.
View on GitHub →
LangGraph (Python)
Same pattern in Python - works with the langgraph package.
View on GitHub →
OpenAI Agents SDK (TypeScript)
Enforced tool guardrail - blocks the call before it executes, not an optional tool the model can skip.
View on GitHub →
OpenAI Agents SDK (Python)
Same enforced guardrail pattern in Python.
View on GitHub →
LangChain create_agent (Python)
wrap_tool_call middleware - enforced the same way, for the newer create_agent API.
View on GitHub →
GitHub Action
Run the Safety Test CLI as a PR check - fails the check if any scenario is unprotected.
View on GitHub →