Documentation

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.

Quick start

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  # proceed

3. 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.

Input schema

Every authorize() call takes four fields.

actorobjectrequired

The agent making the request. Fields: id (string), type (string), framework? (string, e.g. "langgraph").

actionobjectrequired

The action being requested. Fields: name (string), risk_profile? (string, e.g. "high_irreversible").

resourceobjectrequired

The resource being acted on. Fields: type (string), id (string), attributes? (object of arbitrary key-value pairs, e.g. { amount: 75, currency: "USD" }).

contextobjectoptional

Runtime context for policy evaluation. Any key-value pairs: client_id, target_jurisdiction, data_classification[], underlying_llm, etc.

Policy format

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

Comparisonresource.attributes.amount <= 50.00
Equalitycontext.target_jurisdiction == 'EU'
Array containscontext.data_classification.contains('PII')
Arithmeticcontext.session_total + resource.attributes.amount <= 500
Logical ANDcontext.jurisdiction == 'EU' && resource.attributes.authorized == false
Logical ORactor.type == 'autonomous_agent' || context.elevated == true

Decision statuses

ALLOW

Action may proceed. enforcement.action_halted is false.

DENY

Action is blocked. enforcement.action_halted is true. enforcement.user_facing_error contains the remediation message.

REDACT

Action should proceed but sensitive data must be masked before it does. The caller is responsible for performing the redaction.

RE_ROUTE

Action requires alternative handling - typically a human approval queue. The caller decides how to route.

Hosted API

Use the hosted API instead of running the SDK locally. Requires an API key from signup.

POST
/api/v1/authorize

Evaluate whether an action should proceed. Body: the full authorize() input object.

GET
/api/v1/receipts/:id

Look up a past decision by receipt ID. Returns the full decision payload for audit.

GET
/api/v1/policies/:clientId

Fetch the active policy for a client.

PUT
/api/v1/policies/:clientId

Update policy rules. Body: { policy_id, rules[] }. Takes effect on the next authorize() call.

Auth header

Authorization: Bearer <your_api_key>

Safety Test CLI

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.

Integration examples