Skip to content
v0.14.2New 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
api_key_provisioning_observedAPI key or token issued to an agent or service account
oauth_client_provisioning_observedOAuth 2.x client registration or credential grant observed
certificate_provisioning_observedTLS/mTLS certificate issuance or rotation observed
service_account_provisioning_observedService account or workload identity created or modified
secret_storage_observedSecret or credential material stored in a vault or secret store
access_grant_observedAccess grant, permission assignment, or policy binding observed
access_revocation_observedAccess revocation or permission removal observed
payment_authorization_observationPayment authorization scheme credential provisioned or rotated
credential_rotation_observedCredential rotation or key rollover cycle observed
resource_quota_observedResource quota allocation or limit adjustment 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 { validateProvisioningLifecycle } from '@peac/schema';

// Build the provisioning lifecycle extension object
const provisioningExtension = {
  event_kind: 'api_key_provisioning_observed',
  sub_event: 'provisioned',
  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: 'full',
  },
  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 record
const result = await issue({
  sub: 'agent:ci-runner:prod',
  iss: 'https://platform.example.com',
  type: 'org.peacprotocol/provisioning-lifecycle/api_key_provisioning_observed',
  pillars: ['provenance', 'compliance'],
  extensions: {
    'org.peacprotocol/provisioning-lifecycle': provisioningExtension,
  },
  signingKey: myKey,
});

// result.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-002provider_ref MUST match opaque reference grammar
PROV-LIFE-003Recursive credential-material scanner MUST reject inline token material
PROV-LIFE-004storage_surface.kind MUST be one of the 7 allowed surface kinds
PROV-LIFE-005observed_at MUST be a valid RFC 3339 timestamp
PROV-LIFE-006..010Amount minor units, currency, sub_event, scheme_id, and material redaction invariants

Conformance Section 31 (PROV-LIFE-001..010) — 260 total requirement IDs across 29 sections in v0.14.2.

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.