Skip to content
v0.15.0New in v0.14.2Observer scope

Provisioning Lifecycle Profile

Portable signed records for agent provisioning events. PEAC records what your system reported happened during credential issuance, secret storage, access grants, and certificate provisioning — observable evidence, not authorization.

Extension namespace: org.peacprotocol/provisioning-lifecycle (16th extension group). Profile 0.1. New in v0.14.2.

Observer scope

PEAC records what the caller system reports happened. Upstream authorization, validation, settlement, vault management, and lifecycle enforcement belong to the upstream system. A provisioning record proves what your code reported observing — not that the underlying provisioning system authorized or completed it.

Install

pnpm add @peac/schema @peac/protocol

Event Types

Ten registered type URIs cover the provisioning event surface. All use the *-observed suffix to make the observer-scope semantics explicit.

Type URI suffixWhat it records
provisioning-catalog-observedA provisioning catalog or offering was observed
provisioning-provider-link-observedA link to an upstream provisioning provider was observed
provisioning-account-observedA provisioning account or workload identity was observed
provisioning-resource-observedA provisioned resource was observed
provisioning-credential-observedA credential (API key, token, certificate) issuance or rotation was observed
provisioning-payment-authorization-observedA payment authorization for provisioning was observed
provisioning-budget-observedA budget allocation or limit was observed
provisioning-subscription-observedA subscription lifecycle event was observed
provisioning-domain-observedA domain registration, transfer, or release was observed
provisioning-deployment-observedA deployment lifecycle event was observed

Sub-states (requested, provisioned, granted, revoked, cancelled) go in the sub_event field inside the extension object, not as separate type URIs.

Basic Usage

provisioning-record.tsTypeScript
import { issue } from '@peac/protocol';
import { generateKeypair } from '@peac/crypto';
import { validateProvisioningLifecycle } from '@peac/schema';

const { privateKey } = await generateKeypair();

// Build the provisioning lifecycle extension object
const provisioningExtension = {
  event_kind: 'provisioning-credential-observed',
  sub_event: 'issued',
  provider_ref: 'urn:provider:acme-vault:v1', // opaque ref, no raw IDs
  storage_surface: {
    kind: 'external_secret_store',
    provider_ref: 'urn:vault:acme:prod',
    surface_ref: 'urn:vault:acme:prod:slot:api-key-42',
    material_redaction: 'never_capture', // never_capture | redacted_capture | hashed_capture
  },
  observed_at: new Date().toISOString(),
};

// Validate before issuing; fails closed on credential material
const validation = validateProvisioningLifecycle(provisioningExtension);
if (!validation.success) {
  throw new Error(validation.error.issues[0].message);
}

// Issue the signed Wire 0.2 record
const { jws } = await issue({
  iss: 'https://platform.example.com',
  kind: 'evidence',
  type: 'org.peacprotocol/provisioning-credential-observed',
  sub: 'agent:ci-runner:prod',
  pillars: ['provenance', 'compliance'],
  extensions: {
    'org.peacprotocol/provisioning-lifecycle': provisioningExtension,
  },
  privateKey,
  kid: 'peac-2026-03',
});

// jws is a portable signed Wire 0.2 record

Credential Material Safety

The provisioning lifecycle validator includes a recursive credential-material scanner. It inspects every string field for patterns that suggest live credential material and rejects them with structured error codes.

provisioning.token_material_blocked

Bearer token / JWT compact pattern

provisioning.inline_credential_blocked

Inline credential in value field

provisioning.forbidden_key_name

Forbidden top-level key (e.g. raw_key, secret_value)

provisioning.field_too_large

Field exceeds byte limit (64 KB)

provisioning.opaque_ref_grammar_violation

Reference does not match opaque ref grammar

provisioning.invalid_storage_surface

storage_surface.kind not in allowed enum

All sensitive references use the opaque reference grammar: urn:, ref:, did:, sha256:, peac:, or https:. Raw identifiers, inline secrets, and bearer tokens are always rejected.

Error Codes

21 stable error codes under the provisioning.* namespace. All are stable across patch versions.

provisioning.* error codes
inline_credential_blocked    token_material_blocked
forbidden_key_name           field_too_large
replacement_character_in_string  structure_too_deep
structure_too_large          opaque_ref_grammar_violation
invalid_storage_surface      invalid_material_redaction
invalid_event_kind           invalid_sub_event
invalid_scheme_id            invalid_amount_minor
invalid_observed_at          invalid_retrieved_at
invalid_expires_at           invalid_currency
unrecognized_field           missing_required_field
invalid_utf8 (fixture-loader only)

Conformance

RequirementDetail
PROV-LIFE-001event_kind MUST be one of the 10 registered provisioning event kinds
PROV-LIFE-002The recursive credential-material scanner MUST reject inline token or secret material
PROV-LIFE-003Sensitive references MUST match the opaque reference grammar (urn:, ref:, did:, sha256:, peac:, https:)
PROV-LIFE-004storage_surface.kind MUST be one of the allowed surface kinds
PROV-LIFE-005material_redaction MUST be one of never_capture, redacted_capture, hashed_capture
PROV-LIFE-006..010sub_event, timestamps (observed_at RFC 3339), amount and currency, and field-size invariants

Conformance Section 31 (PROV-LIFE-001..010). Introduced in v0.14.2; current totals are 290 requirement IDs across 32 sections.

Links

Start recording provisioning events

Add portable signed records to your agent provisioning pipeline in minutes. The provisioning lifecycle profile integrates with any provisioning system — PEAC records what your code reports, without becoming the authorization layer.