Skip to content

Charge authority (v1 frozen)

Verifiable authorization-to-charge continuity, without becoming an AI gateway.

Freeze: charge-authority-v1-freeze.md · Reviewer map: charge-authority-v1-reviewer-map.md

Product truth

QuantZK binds a prior signed spend authority to a metered charge and issues a portable receipt anyone can verify, without warehousing your logs or sitting in the request path.

QuantZK verifies charge authorities issued by an authorized spend authority. That issuer MAY be the enterprise, a delegated finance authority, a workload-control system, or QuantZK-managed issuance. Managed issuance is commercial, not a protocol requirement.

LayerQuestion
Authorization (quantzk_charge_authority_v1)What was allowed?
QZR-1 receiptWhat was charged?
VDIWhy was the decision permitted?

Do not overload QZR-1 with the full authorization model. The receipt binds a grant; it is not the grant, and it does not by itself prove that the CAS happened.

Charge Authority v1:

  1. A signed spend authority is bound to the declared pre-execution intent committed by the receipt. Binding uses the fingerprint-committed authority_id and execution_intent_digest; continuity compares the fingerprint to the recomputed grant identity; intent digests compare in §4.4 hex form (optional 0x stripped).
  2. The canonical charge committed by the QZR-1 billing fingerprint (billing_verify_fingerprint.expected_charge_micros) satisfies that authority’s applicable constraints. Cap checks MUST use that fingerprint integer only; meter or billing convenience copies MUST NOT backfill a missing or conflicting charge.
  3. Atomic single-use consumption is established only when authenticated consumption evidence is present. In v1, “authenticated” means the verifier trusts the consumption-evidence channel (operator-supplied log / store peek under profile policy), the same trust class as a revocation snapshot. It does not mean an unsigned consumedAuthorityIds map is cryptographically self-authenticating. Classification PASSes only for CONSUMED_BY_THIS_EVENT matching authority_id + event_id + execution_intent_digest.
  4. External request-path enforcement remains an integrator responsibility and is not cryptographically established by Charge Authority v1. No receipt field, attestation, preflight history, or mirror such as gateway_enforced / path_enforced / may_execute may manufacture MAY_EXECUTE or “path enforced” semantics after the fact. Receipt-time evaluate always reports may_execute = false.

Land vs expand

SurfaceMessage
Website / sales (land)VERIFY EVERY API CHARGE. Verifiable API billing.
Protocol / roadmap (expand)Authorize every machine spend. Verify every machine charge.

Keep the homepage on billing. Grow the grant object for spend authority.

Issuance order

text
ENTERPRISE / DELEGATED / QUANTZK-MANAGED ISSUER


                CHARGE AUTHORITY v1
                 "what is allowed?"
             signed + independently verifiable


                  LOCAL ENFORCEMENT
             gateway / meter / runtime


                     EXECUTION


                    METER EVENT


                       QZR-1
                 "what was charged?"


                INDEPENDENT VERIFIER
                    ┌────┴────┐
                    │         │
                AUTHORITY   CHARGE
                  PASS       PASS

QuantZK is not a mandatory synchronous proxy on every request.

QuantZK does not ensure that only authorized calls reach the vendor API unless the integrator’s gateway/runtime actually gates execution on successful preflight.

Without that enforcement, QuantZK can detect non-conforming evidence afterward. It cannot reach through the network and stop an out-of-band API call. execution_eligible / MAY_EXECUTE is a preflight decision the integrator MUST enforce on the request path for execution exclusivity to be real.

Three evaluation points (normative)

Historical validity, permission to spend now, and attest-time consumption are different decisions.

text
PREFLIGHT (before paid action)          ATTESTATION (after meter)           RECEIPT / HISTORICAL
preflightChargeAuthority()              POST /billing/attest                evaluateQzr1
validate intent binding/trust           bind actual meter event
consume_if_available(id,event,intent)   verify prior intent consumption
→ execution_eligible / may_execute      meter_event_digest + QZR-1          historical_authority_valid
                                                                          current_authority_status

Authorization and atomic consume occur before execution against execution_intent_digest. Attestation verifies that consumption, binds the actual meter_event_digest, and checks computed_charge_micros <= max_charge_micros. execution_eligible MUST NOT be applied retrospectively after the paid action.

PREFLIGHT / EXECUTION DECISION

preflightChargeAuthority() or POST /api/vdi/billing/preflight. Atomically consumes before the integrator executes the paid call.

text
signature                 PASS
intent binding            PASS   (constraints knowable pre-execution)
current_revocation        PASS
authority_trust_mode      pinned_roots   (open_signature MUST NOT yield execution_eligible unless explicitly opted in)
atomic store              present
consume_if_available(authority_id, event_id, execution_intent_digest)
                          → execution_eligible / may_execute

Generate event_id before the external call. Build quantzk_execution_intent_v1 from fields knowable before execution (no usage_units):

text
execution_intent_digest =
  "0x" || SHA-256( JCS(execution_intent) )

execution_intent MUST include: event_id, authority_id, tenant_id, contract_version, tariff_id, tariff_version, tariff_digest, unit_price_micros, currency. Optional when constrained on the grant: subject_id, endpoint, vendor_id, model_id, tool_id, cost_center, policy_digest, max_charge_micros.

The consumption row MUST store (authority_id, event_id, execution_intent_digest).

Idempotency:

text
same authority_id + event_id + execution_intent_digest → IDEMPOTENT
same authority_id + event_id + different execution_intent_digest → FAIL
same authority_id + different event_id → REPLAY FAIL

Preflight does not require usage_units or a post-execution meter event. Variable-consumption workloads (LLM tokens, tool calls) authorize the action under constraints up to max_charge_micros, not a predetermined charge.

A grant is consumed when execution authority is exercised, not when a successful billable outcome is guaranteed. If execution fails after preflight, the grant remains consumed in v1 (retryable reservations are a later primitive).

evaluateAuthorityDecision() is read-only and MUST NOT set execution_eligible / may_execute.

ATTESTATION / CONSUMPTION

POST /api/vdi/billing/attest (and async accept) after the meter event exists:

  1. Recompute execution_intent_digest from the meter event’s intent-field subset; verify preflight consumed (authority_id, event_id, execution_intent_digest).
  2. Bind grant to the actual meter/tariff/charge (bindChargeAuthorityToExecution).
  3. Reject if currently revoked.
  4. Verify computed_charge_micros <= max_charge_micros when capped.
  5. Produce QZR-1 binding meter_event_digest separately.
text
meter_event_digest = "0x" || SHA-256( JCS(meter_event) )

Attest MUST NOT consume again and MUST NOT report execution_eligible. Missing preflight consumption is REJECT.

RECEIPT / HISTORICAL CHECK

Used by QZR-1 evaluateQzr1. Always context = receipt. may_execute is always false here.

text
historical_authority_valid    PASS
current_authority_status      REVOKED
                          → historically authorized
                          → not currently acceptable

QZR-1 Standard MAY PASS a historically bound receipt whose grant is now REVOKED. It MUST NOT be read as permission to spend again.

Canonical payload, digest, and id (normative)

One named structure is the source of every derived value.

canonical_authority_payload

Deep JSON copy of the grant object with these keys removed (MUST NOT be signed, MUST NOT enter the digest):

  • authority_id
  • authority_digest
  • signature.value

Remaining signature metadata (algorithm, domain, kid, public_key) is part of the payload. The signature value is attached after signing.

Keys MUST NOT be present with JSON null. Absence of an optional key means unconstrained (see Optional fields).

Signing message

UTF-8 bytes of the Unicode string:

text
QZK_CHARGE_AUTHORITY_V1
<JCS(canonical_authority_payload)>

That is: the exact ASCII domain QZK_CHARGE_AUTHORITY_V1, one LF (U+000A), then RFC-8785-style canonical JSON as implemented by QuantZK JCS (protocol/lib/canonicalize.js). No trailing newline after the JSON.

Ed25519 signs those UTF-8 bytes. A signature valid for another QuantZK artifact type MUST NOT verify as a charge grant.

Digest and id

text
authority_digest_hex = lowercase hex SHA-256( UTF-8(signing message) )
authority_digest     = "0x" || authority_digest_hex     // 66 chars: 0x + 64 hex
authority_id         = "qza:" || authority_digest_hex   // qza: + 64 lowercase hex

Digest algorithm is FIPS 180-4 SHA-256 over the UTF-8 signing message (the same bytes Ed25519 signs). Not SHA-3, not SHAKE, not truncated SHA-256, not a keyed MAC. Implementations MUST:

  • exclude signature.value, authority_id, and authority_digest from the hashed/signed object
  • use lowercase hex, no Base64
  • use the full 32-byte digest (64 hex chars); truncation is invalid
  • reject a grant whose authority_id or authority_digest does not recompute to these values

issuer and issuer_role are inside canonical_authority_payload and are therefore covered by the signature. They are claims, not trust roots.

execution_intent (preflight commitment)

Schema: quantzk_execution_intent_v1. Commits to fields knowable before paid execution. Does not include usage_units, token counts, or other post-execution quantities.

Required keys: schema, event_id, authority_id, tenant_id, contract_version, tariff_id, tariff_version, tariff_digest, unit_price_micros, currency.

Optional (include when constrained on the grant or supplied at preflight): subject_id, endpoint, vendor_id, model_id, tool_id, cost_center, policy_digest, max_charge_micros.

text
execution_intent_digest = "0x" || SHA-256( JCS(execution_intent) )
meter_event_digest      = "0x" || SHA-256( JCS(meter_event) )   // after execution

At attest, recompute execution_intent from the meter event’s intent-field subset (executionIntentFromMeterEvent) and verify it matches the consumption row. Emit execution_intent and execution_intent_digest on the QZR-1 envelope and on billing_verify_fingerprint. Receipt evaluation MUST use the fingerprint expected_charge_micros for max_charge_micros (the hashed charge), MUST FAIL if billing.expected_charge_micros disagrees with the fingerprint, MUST FAIL if fingerprint.authority_id disagrees with the embedded grant, and MUST FAIL if execution_intent_digest disagrees across envelope / billing / fingerprint.

Trust roots (normative)

issuer and issuer_role are claims made by the signed authority object. They acquire trust significance only through an accepted issuer key and an explicit trust mode. issuer_role: enterprise cannot by itself establish enterprise authority.

Trust MUST NOT be inferred from whether authorized_authority_public_keys happens to be empty.

authority_trust_modeMeaning
open_signatureCryptographic signature validity only. The allow-list is ignored. Default.
pinned_rootsThe grant signature.public_key MUST be in authorized_authority_public_keys. An empty list authorizes nobody.

Profile guidance (not additional modes):

ProfileTypical authority trust
Minimal / receiptGrant MAY be NOT_CHECKED; open_signature is useful for “internally valid but unanchored”
Standard receiptBinding as specified; open_signature unless the profile sets pinned_roots
Execution / MAY_EXECUTEpinned_roots required. open_signature MUST NOT yield may_execute unless allow_open_signature_may_execute is explicitly true
Strictpinned_roots + fresh attestation revocation; authority current-revocation remains a separate snapshot

QZR-1 evaluate reads trustRoots.authority_trust_mode. If omitted, open_signature applies even when the key array is non-empty; pinning requires the mode. That default is for receipt evaluation only.

Atomic single-use consumption (normative)

v1 usage_mode = single_use is operationally enforced at preflight by:

text
consume_if_available(authority_id, event_id, execution_intent_digest)

State transition (compare-and-set before paid execution):

text
AVAILABLE

    │ atomic compare-and-set at preflight

CONSUMED_BY_THIS_EVENT

PostgreSQL: INSERT … ON CONFLICT (authority_id) DO NOTHING, then read existing row to distinguish idempotent vs replay vs digest mismatch.

Recommended lifecycle (variable consumption):

text
signed grant

preflightChargeAuthority (atomic consume on execution_intent_digest)

execution_eligible

paid action (usage emerges)

meter event → meter_event_digest

attest (verify intent consumption + bind actual charge ≤ max)

QZR-1 binds charge_authority + execution_intent_digest + meter_event_digest

A grant is consumed when execution authority is exercised, not when a successful billable outcome is guaranteed. If execution fails after preflight, the grant remains consumed. From a security perspective this is fail-closed on spend authorization. Operationally it is a liveness / usability failure (authority consumed without a billable result). v1 does not release or retry that grant.

Security properties and non-properties (normative)

This section is normative. Reviewers MUST treat it as the claim boundary for Charge Authority v1.

Frozen core promise

  1. A signed spend authority is bound to the declared pre-execution intent committed by the receipt. Binding uses the fingerprint-committed authority_id and execution_intent_digest; continuity compares the fingerprint to the recomputed grant identity; intent digests compare in §4.4 hex form (optional 0x stripped).
  2. The canonical charge committed by the QZR-1 billing fingerprint (billing_verify_fingerprint.expected_charge_micros) satisfies that authority’s applicable constraints. Cap checks MUST use that fingerprint integer only; meter or billing convenience copies MUST NOT backfill a missing or conflicting charge.
  3. Atomic single-use consumption is established only when authenticated consumption evidence is present. In v1, “authenticated” means the verifier trusts the consumption-evidence channel (operator-supplied log / store peek under profile policy), the same trust class as a revocation snapshot. It does not mean an unsigned consumedAuthorityIds map is cryptographically self-authenticating. Classification PASSes only for CONSUMED_BY_THIS_EVENT matching authority_id + event_id + execution_intent_digest.
  4. External request-path enforcement remains an integrator responsibility and is not cryptographically established by Charge Authority v1. No receipt field, attestation, preflight history, or mirror such as gateway_enforced / path_enforced / may_execute may manufacture MAY_EXECUTE or “path enforced” semantics after the fact. Receipt-time evaluate always reports may_execute = false.

Cryptographically bind authority → intent → meter → charge. Operationally enforce single-use consumption. Explicitly delegate request-path enforcement to the integrator. Never claim more than the selected evidence profile establishes.

Committed-value dominance. No security decision may be made from an uncommitted mirror when a cryptographically committed representation of the same semantic fact exists. Conflicting representations fail verification. JSON null and "" are present-and-invalid, not absence. Registry: QZR-1 §4.4.

Continuity chain

text
signed charge_authority

execution_intent_digest          (pre-execution; on QZR-1 wire)

consume_if_available(authority_id, event_id, intent_digest)

meter_event_digest               (post-execution)

expected_charge_micros

QZR-1 / Phase-2 binding          (meter commitments; not in-circuit intent)

Portable/offline QZR-1 without consumption evidence can establish:

text
charge_authority

execution_intent_digest

meter_event projection matches intent

meter_event_digest

expected_charge_micros

QZR-1

It cannot independently prove that the CAS happened merely because execution_intent_digest is embedded. That requires authority_consumption_check = PASS from authenticated consumption evidence.

LinkEnforcement
Grant authenticityCryptographic / Ed25519
Authority identity / trustTrust-root policy (pinned_roots at execution; profile-selected at receipt)
Intent integrityCryptographic digest (execution_intent_digest on the QZR-1 wire)
Single-use grant consumptionAtomic operational store at preflight; receipt-time check against a trusted consumption-evidence channel
Intent → meter consistencyVerifier logic (execution_intent_binding)
Meter integrityQZR-1 fingerprint + meter_event_digest
Charge ≤ authority capVerifier logic (max_charge_micros)
Phase-2 predicatesCircuit, where enabled (meter public commitments; not intent digest)
Current revocationSnapshot / trust state
Actual request-path gatingIntegrator (required for MAY_EXECUTE semantics)
Meter truthfulness (that reported units equal physical usage)Out of scope
Reservation / settlement / releaseOut of scope

TOCTOU and gateway enforcement

Preflight atomically claims the grant for an execution intent. It does not create a cryptographic lease on the vendor API.

QuantZK does not ensure that only authorized calls reach the vendor API unless the integrator’s gateway/runtime actually gates execution on successful preflight.

QuantZK provides: grant validity, intent commitment, atomic single-use claim, post-execution constraint verification, portable charge evidence.

The integrator provides: successful preflight → actual request-path enforcement.

Without that enforcement, QuantZK can detect non-conforming evidence afterward. It cannot stop an out-of-band API call.

Windows that remain after preflight CAS:

  • Integrator executes without preflight, or executes a different action than the intent.
  • Grant revoked after execution started (attest fails; sunk cost possible).
  • event_timestamp window is checked at attest, not preflight.

Consumption evidence vs authority binding

These are different assurance properties. Do not collapse them.

text
authority                 PASS | FAIL | NOT_CHECKED   // cryptographic + constraint binding
execution_intent_binding  PASS | FAIL | NOT_CHECKED   // declared digest matches meter projection
authority_consumption     NOT_CHECKED | AVAILABLE | CONSUMED_BY_THIS_EVENT | CONSUMED_BY_OTHER_EVENT
authority_consumption_check  PASS | FAIL | NOT_CHECKED

What “authenticated consumption evidence” means in v1 (normative).

Receipt-time Claim 3 does not embed a portable signed ConsumptionEvidence object in the QZR-1 envelope. The verifier receives consumption state through a channel the profile trusts (for example an integrity-trusted store peek, or an operator-supplied log under the same policy class as revocation snapshots). Under that channel:

EvidenceReceipt authority_consumptionauthority_consumption_check
Channel absent (undefined / omitted)NOT_CHECKEDNOT_CHECKED
Empty logAVAILABLEFAIL
Row for this authority_id + event_id + matching execution_intent_digestCONSUMED_BY_THIS_EVENTPASS
Wrong authority_id / event / intent digest, or bare event_id when intent is requiredAVAILABLE or CONSUMED_BY_OTHER_EVENTFAIL

A bare event_id string MUST NOT classify as CONSUMED_BY_THIS_EVENT when an execution_intent_digest is expected. Portable, domain-separated, signature-verified consumption envelopes are out of scope for v1; claiming them would be a new wire artifact.

ProfileConsumption
QZR-1 Standard historical receiptauthority_consumption_check ∈ {PASS, NOT_CHECKED}; FAIL fails Standard
Enterprise enforcement profileMAY require authority_consumption_check == PASS
Execution / execution_eligibleAtomic consume required before MAY_EXECUTE

A portable receipt with authority_consumption_check = NOT_CHECKED is cryptographically bound to a prior authority. It is not proof that the authority was consumed exactly once.

v1 limitations (explicit)

  • No reserve → authorize → execute → settle → release.
  • No cryptographic proof of gateway path enforcement.
  • No in-circuit execution_intent_digest binding.
  • No offline proof of single-use consumption unless authenticated consumption evidence is supplied.
  • Crash after consume is fail-closed on authorization and a liveness/usability failure operationally.

Charge Authority v1 freeze boundary

Claims 1–4 are the frozen v1 claim set:

  1. Authority ↔ committed execution intent continuity
  2. Fingerprint-committed charge ↔ authority constraints
  3. Consumption PASS only from a trusted evidence channel (not a self-authenticating unsigned map)
  4. Request-path enforcement remains outside the cryptographic claim

Do not add new semantic claims inside v1. A portable signed ConsumptionEvidence envelope (upgrading Claim 3 from trusted-channel to cryptographic evidence) is the first deliberately scoped v1.1 candidate.

Time (normative)

All grant timestamps (issued_at, valid_from, valid_until) MUST be integer Unix seconds (non-negative). Fractional numbers are invalid. JSON numbers MUST be integers; implementations MUST reject 1700000000.5.

Well-formed grant:

text
issued_at <= valid_from <= valid_until

Let s be permitted clock skew in seconds (default 60, overridable via trust-root authority_clock_skew_seconds). Meter event_timestamp is converted to integer Unix seconds (ISO-8601 is floored to seconds). Then both:

text
event_timestamp >= valid_from - s
event_timestamp <= valid_until + s

and independently:

text
event_timestamp >= issued_at - s

The independent predating rule is required even when valid_from equals issued_at (they can diverge). This is consistency of authenticated timestamps, not proof that an untrusted source clock is correct.

max_charge_micros (normative)

When the key is present:

text
computed_charge_micros <= max_charge_micros

computed_charge_micros is the same canonical integer bound into QZR-1 as fingerprint expected_charge_micros. It is not a floating-point price, not a re-derived invoice unless that derivation already produced this integer, and not billing.expected_charge_micros or meter_event.expected_charge_micros when those disagree with or substitute for the fingerprint. At receipt bind, if max_charge_micros is present and the fingerprint charge is absent or not a safe integer, verification FAILs (no fallback, no string coercion).

Both values MUST be integers in 0 … 2^53-1 (Number.MAX_SAFE_INTEGER). Overflow or non-integers → FAIL (QZA_ERR_MAX_CHARGE). No multiplication/division is performed at the grant bound; the cap applies to the already-canonical settled charge. Taxes, credits, and discounts are outside this v1 cap unless already folded into expected_charge_micros.

This grant cap is distinct from tariff_snapshot.max_charge_micros.

Optional fields: absence semantics (normative)

For subject_id, endpoint, vendor_id, model_id, tool_id, cost_center, max_charge_micros, policy_digest:

  • Key absent → unconstrained by this grant.
  • JSON null is not absence. Present-and-null is invalid.
  • Empty string is not absence. Present-and-"" is invalid.

Issuance MUST omit unconstrained keys rather than emit null or "".

Consumption state machine (normative)

v1 grants are single-use by declaration:

Fieldv1 rule
usage_modeMUST be single_use
authority_idUnique (qza: + SHA-256 hex as above)
nonceUnique, always issued

Underlying state authority_consumption:

StateMeaning
NOT_CHECKEDNo consumption log supplied, or binding already failed
AVAILABLELog present; this authority_id is not recorded as consumed
CONSUMED_BY_THIS_EVENTLog maps this authority_id to this meter event_id
CONSUMED_BY_OTHER_EVENTLog maps this authority_id to a different event (or consumed with unknown event)

Do not collapse AVAILABLE with CONSUMED_BY_THIS_EVENT. A verifier reading an existing receipt MUST NOT treat “the grant has never been consumed” as “this receipt properly consumed it.”

Derived checks:

ContextPASSFAIL
ExecutionAVAILABLECONSUMED_BY_THIS_EVENT, CONSUMED_BY_OTHER_EVENT
ReceiptCONSUMED_BY_THIS_EVENTAVAILABLE, CONSUMED_BY_OTHER_EVENT

NOT_CHECKED is permitted when no log is supplied (receipt-time). QZR-1 Standard fails closed on authority_consumption_check = FAIL (including receipt + AVAILABLE).

Execution-time AVAILABLE is necessary but not sufficient for MAY_EXECUTE (see Atomic single-use consumption).

Do not treat a signed nonce as a proof of non-replay. Reusable, time-window-unlimited, and cumulative-cap modes are not specified in v1.

Who signs

FieldMeaning
issuerDisplay-name claim (not a trust root)
issuer_roleClaim: self_issued | enterprise | delegated_finance | workload_control | quantzk_managed
issuer_kidKey id (also signature.kid)
signatureEd25519 over the domain-separated canonical_authority_payload
delegation_chainOptional; not verified in v1

API POST /billing/authorize sets issuer_role: quantzk_managed when QuantZK’s key signs. Local SDK signing defaults to self_issued.

Revocation

Historically valid authorization ≠ currently acceptable authorization.

When an authority revocation snapshot is supplied (revokedAuthorityIds / revokedAuthorityKids; not the attestation revokedKids list):

StatusMeaning
historical_authority_validBinding/signature were valid at evaluation
authority_revocationPASS / FAIL membership in the snapshot
current_authority_statusCLEAR / REVOKED / NOT_CHECKED

Without a snapshot: authority_revocation = NOT_CHECKED. Receipt-time Standard does not fail solely because current authority status is NOT_CHECKED or REVOKED. Execution-time MUST fail closed on REVOKED.

What authority: PASS means (receipt-time)

See AUTHORITY_PASS_CLAIMS in @quantzk/vdi-billing. Receipt-time authority: PASS is cryptographic + constraint binding. It is not MAY EXECUTE.

What it does not mean

See AUTHORITY_NON_CLAIMS: permission to execute a new paid action from a receipt check alone, execution_eligible / MAY_EXECUTE under open_signature or a non-atomic view, that a portable receipt proves atomic consumption when authority_consumption_check is NOT_CHECKED, that a successful billable outcome is guaranteed after consumption, budget reservation or retryable spend after failed execution, path enforcement, in-circuit intent binding, clock-source proof, current non-revocation without a snapshot, delegation-chain verify, that issuer_role confers trust, gateway controls.

reserve → authorize → execute → settle → release is a later primitive. v1 does not implement it.

Canonical fields

Wire names are snake_case integers. SDK maps camelCase 1:1:

SDKWire
tenantIdtenant_id
contractVersioncontract_version
unitPriceMicrosunit_price_micros
currencycurrency

Do not use IEEE-754 price: 0.00012 as the canonical API. unitPriceMicros: 120 only.

Optional (omit when unconstrained): subject_id, endpoint, vendor_id / model_id / tool_id, cost_center, max_charge_micros, policy_digest, delegated_authority, delegation_chain.

Modes

ModeBehavior
DefaultAttest without charge_authorityauthority = NOT_CHECKED
Recommendedauthorizepreflight → execute → record({ authority }) (same execution-intent fields at preflight and attest)
EnforcedVDI_BILLING_REQUIRE_AUTHORITY=true rejects attest without a grant

POST /billing/preflight atomically consumes before execution. POST /billing/attest verifies that consumption. Response includes execution_eligible (preferred) and may_execute (alias).

API / SDK

js
const grant = await qzk.authorize({
  tenantId: 'cus_acme',
  unitPriceMicros: 120,
  currency: 'USD',
  subjectId: 'agent_814',
  endpoint: '/v1/responses',
  modelId: 'gpt-x',
  maxChargeMicros: 5_000_000,
});

const gate = await qzk.preflight({
  authority: grant,
  eventId: 'evt_1',
  tenantId: 'cus_acme',
  endpoint: '/v1/responses',
  modelId: 'gpt-x',
  // no units; usage is unknown until after execution
});
if (!gate.execution_eligible) throw new Error('not authorized to spend');

// …execute the paid call; record actual usage…

const receipt = await qzk.record({
  eventId: 'evt_1',
  tenantId: 'cus_acme',
  endpoint: '/v1/responses',
  modelId: 'gpt-x',
  units: 5678,
  unitPriceMicros: 120,
  authority: grant,
});

HTTP: POST /api/vdi/billing/authorizePOST /api/vdi/billing/preflight → execute → POST /api/vdi/billing/attest with charge_authority.

Library: preflightChargeAuthority(), verifyChargeAuthorityConsumption(), buildExecutionIntent(), chargeAuthorityExecutionIntentDigestHex(), chargeAuthorityEventDigestHex() (meter), and read-only evaluateAuthorityDecision() for receipt-time checks.

Spec

Normative binding rules: QZR-1 §4.3.

Verification keys are embedded in attestations. Verify offline. No QuantZK servers required.