Skip to main content

MandateZ Protocol Specification

Version: 0.1.0 Status: Draft Date: 2026-03-21 Authors: MandateZ Contributors

Abstract

MandateZ is an open protocol for cryptographic identity, authorization, and audit logging of autonomous AI agents. It defines a vendor-neutral standard for proving which agent performed an action, enforcing what agents are permitted to do, and producing tamper-proof compliance audit trails. This specification defines the wire format, cryptographic operations, policy evaluation semantics, and human oversight behavior that any conforming implementation MUST support.

1. Terminology

  • Agent: An autonomous software entity (LLM-based or otherwise) that performs actions on behalf of an owner.
  • Owner: The individual or organization that controls one or more agents.
  • Event: A signed record of a single agent action.
  • Policy: An ordered set of rules that determine whether an action is allowed, blocked, or flagged.
  • Oversight Gate: A mechanism that pauses execution and requests human approval before proceeding.
  • Transport: The system that receives and stores signed events.
The key words “MUST”, “MUST NOT”, “SHOULD”, “SHOULD NOT”, and “MAY” in this document are to be interpreted as described in RFC 2119.

2. Agent Identity

2.1 Agent ID Format

An agent identifier MUST conform to the following format:
  • The prefix ag_ is fixed and MUST be present.
  • <nanoid> is a 21-character string drawn from the alphabet A-Za-z0-9_- (URL-safe base64).
  • This provides 126 bits of entropy, sufficient for collision resistance at scale.
Regex: ^ag_[A-Za-z0-9_-]{21}$

2.2 Cryptographic Keypair

Each agent MUST possess an Ed25519 keypair:
  • Public key: 32 bytes, encoded as standard base64 (RFC 4648 Section 4).
  • Private key: 64 bytes (32-byte seed + 32-byte public key), encoded as standard base64.
  • The public key MUST be derivable from the private key (bytes 32-63 of the 64-byte secret key).
Implementations MUST use Ed25519 as defined in RFC 8032.

2.3 Identity Generation

A conforming implementation MUST:
  1. Generate an Ed25519 keypair using a cryptographically secure random number generator.
  2. Assign a unique agent_id using the format defined in Section 2.1.
  3. Return the agent_id, base64-encoded public_key, and base64-encoded private_key.
The private key MUST NOT be transmitted over the network or written to logs.

3. Agent Event Schema

3.1 Event Structure

Every agent action produces exactly one event. An event is a JSON object with the following fields:

3.2 Action Types

Implementations MUST NOT extend this enum without a protocol version bump.

3.3 Outcomes


4. Event Signing

4.1 Canonicalization

Before signing, the event MUST be canonicalized as follows:
  1. Construct a JSON object containing all event fields except signature.
  2. Serialize to a JSON string with keys sorted alphabetically at the top level.
  3. Encode the resulting string as UTF-8 bytes.
Pseudocode:
Implementations MUST use lexicographic key sorting to ensure deterministic output across platforms and languages.

4.2 Signing

  1. Compute the Ed25519 detached signature over the canonical message bytes using the agent’s private key.
  2. Base64-encode the 64-byte signature (standard base64, RFC 4648 Section 4).
  3. Set the signature field of the event to this value.
  4. Set the public_key field to the agent’s base64-encoded public key.

4.3 Verification

To verify an event:
  1. Remove the signature field from the event.
  2. Canonicalize the remaining fields per Section 4.1.
  3. Base64-decode the signature and public_key fields.
  4. Verify the Ed25519 detached signature against the canonical message bytes and the public key.
  5. Return true if valid, false otherwise.
A conforming verifier MUST return false (not throw an exception) on any error, including malformed base64, incorrect key length, or tampered data.

4.4 Event Construction

When creating a new event, the implementation MUST:
  1. Generate a new UUID v4 for event_id.
  2. Set timestamp to the current UTC time in ISO 8601 format.
  3. Derive public_key from the agent’s private key.
  4. Canonicalize, sign, and attach the signature.
  5. Validate the complete event against the schema before returning.

5. Policy Engine

5.1 Policy Structure

A policy is an ordered collection of rules belonging to an owner:

5.2 Rule Fields

5.3 Resource Pattern Matching

Resource patterns support three forms: Path segments are delimited by /.

5.4 Evaluation Semantics

  1. Rules MUST be evaluated in declaration order.
  2. The first rule that matches both the action_type and resource wins.
  3. If no rule matches, the default outcome is allowed.
  4. Effect mapping: allow -> allowed, block -> blocked, flag -> flagged.
  5. Multiple policies are evaluated in the order they were added. First match across all policies wins.

6. Human Oversight Gate

6.1 Configuration

The oversight gate is configured with:

6.2 Gate Behavior

When an action’s action_type is in require_human_approval:
  1. Fire alerts to all configured channels. Channel failures MUST be collected, not thrown — one failing channel MUST NOT prevent others from firing.
  2. Wait for human decision by racing an approval callback against the timeout.
  3. Resolve outcome:
    • If a human approves: allowed
    • If a human rejects: blocked
    • If timeout expires: apply timeout_action (block -> blocked, allow -> allowed)
  4. If no approval callback is provided, timeout_action MUST be applied immediately.

6.3 Alert Channels

An alert channel is any system that implements the send(alert) interface:
The protocol defines two standard channels:
  • Slack: POST to a webhook URL with mrkdwn-formatted text.
  • Webhook: POST the alert as JSON to an arbitrary URL.
Implementations MAY define additional channels (email, PagerDuty, SMS, etc.).

6.4 Integration with Policy

The oversight gate operates after policy evaluation:
  1. If the policy engine returns blocked, the oversight gate is skipped.
  2. If the policy engine returns allowed or flagged, and the action type requires approval, the oversight gate fires.
  3. The oversight gate’s outcome overrides the policy outcome.

7. Transport Contract

7.1 Requirements

A conforming transport MUST:
  1. Accept a fully signed, schema-validated AgentEvent.
  2. Persist the event durably.
  3. Return the event on success or throw/return an error on failure.
  4. MUST NOT modify the event payload (including signature).

7.2 Supabase Reference Transport

The reference transport inserts events into a PostgreSQL table via Supabase: Row Level Security MUST be enabled so each owner sees only their own events.

7.3 Alternative Transports

Implementations MAY provide transports for other storage backends (S3, Kafka, filesystem, etc.) as long as they satisfy the contract in Section 7.1.

8. Client Integration Flow

The full track() flow for a conforming client:

9. Security Considerations

  • Private keys MUST be stored securely and MUST NOT be transmitted or logged.
  • Event signatures provide tamper detection, not encryption. Event payloads are plaintext.
  • The metadata field MAY contain sensitive data. Implementations SHOULD apply appropriate access controls.
  • Transport channels (Supabase, webhooks) SHOULD use TLS.
  • Slack webhook URLs are bearer tokens and MUST be treated as secrets.

10. Versioning

This specification follows Semantic Versioning:
  • Major: Breaking changes to the event schema, signing algorithm, or policy semantics.
  • Minor: New action types, outcome types, or optional fields.
  • Patch: Clarifications and editorial fixes.
The current version is 0.1.0 (pre-release, subject to change).

Appendix A: Example Event

Appendix B: Example Policy

Appendix C: Reference Implementations


This specification is open for public contribution. File issues and pull requests at github.com/mandatez/core.