oz-policy-builder
Concepts

PolicySpec

The intermediate representation. Everything serializes to and from this.

PolicySpec is the toolkit's intermediate representation. The synthesizer produces it from a Recording. The code generator, the simulator, and the installer all consume it. The wire schema URI is oz-policy-builder/v1.

Top-level shape

pub struct PolicySpec {
    pub schema: String,                       // always "oz-policy-builder/v1"
    pub synthesis_mode: SynthesisMode,
    pub context_rule: ContextRuleSpec,
    pub signers: Vec<SignerSpec>,
    pub policies: Vec<PolicySlot>,
    pub lifetime_ledgers: Option<u32>,
    pub recording_ref: RecordingRef,
}

synthesis_mode

pub enum SynthesisMode {
    Auto,         // JSON: "auto"
    ComposeOnly,  // JSON: "compose_only"
    CodegenOnly,  // JSON: "codegen_only"
}

See Synthesis modes for what each does.

context_rule.context_type

A context rule applies either to every invocation of the smart account or to a specific target contract.

pub enum ContextType {
    Default,                                  // matches every invocation
    CallContract { address: String },         // matches calls to this C-address
}

JSON shape:

{ "kind": "default" }
{ "kind": "call_contract", "address": "C..." }

signers

A vector of SignerSpec. Each is one of:

pub enum SignerSpec {
    ExternalEd25519 { public_key_hex: String },   // 64 hex chars (32-byte ed25519 key)
    ExternalWebAuthn { public_key_hex: String },  // 130 hex chars (65-byte uncompressed P-256)
    Delegated { address: String },                // C-address of a contract that takes over auth
}

JSON shape (#[serde(tag = "kind", rename_all = "snake_case")]):

{ "kind": "external_ed25519", "public_key_hex": "..." }
{ "kind": "external_webauthn", "public_key_hex": "..." }
{ "kind": "delegated", "address": "C..." }

When --delegated-signer is passed to synthesize, the synthesizer emits exactly one Delegated signer instead of the recording's observed signers.

policies

A vector of PolicySlot. The OZ framework caps this at five (MAX_POLICIES = 5).

pub enum PolicySlot {
    Existing {
        primitive: ExistingPrimitive,
        params: ExistingPrimitiveParams,
    },
    Generated {
        template_family: TemplateFamily,
        constraints: Vec<Constraint>,
    },
}
  • Existing — Track A composition. References a pre-deployed OZ primitive. See Primitives.
  • Generated — Track B codegen. The synthesizer emits a fresh contract whose enforce logic is the AND of its constraints. See Constraints.

Hard limits

These come from the OZ smart-account contract; the synthesizer refuses to emit specs that violate them.

ConstantValue
MAX_POLICIES5
MAX_SIGNERS15
MAX_NAME_SIZE20 (bytes)
MAX_EXTERNAL_KEY_SIZE256 (bytes)

lifetime_ledgers

Optional u32. When set, becomes the context rule's expiration ledger sequence (relative to the install ledger). When the matched primitive is spending_limit, it also becomes the spending limit's rolling window in ledgers.

The default value passed by the CLI's --lifetime 432000 is ~30 days at testnet pace.

recording_ref

pub struct RecordingRef {
    pub hash: Option<String>,                 // when the recording came from --hash
    pub schema: String,                       // always "oz-policy-builder/recording/v1"
}

A back-reference to the recording that produced this spec. Lets a consumer of the spec re-fetch and re-derive deterministically.

On this page