Skip to main content
Version: v0.16.4

Provisioning Lifecycle Profile

The Provisioning Lifecycle profile (org.peacprotocol/provisioning-lifecycle) provides observer-scope signed records for infrastructure provisioning events: credential issuance, secret rotation, service authorization, key lifecycle, and access management. Introduced in v0.14.2 as the 16th PEAC extension group.

Package: @peac/schema (validator) — use with @peac/protocol to issue records.


Observer scope​

Provisioning lifecycle records describe what provisioning systems reported. PEAC does not issue credentials, rotate secrets, or authorize services. Your provisioning infrastructure owns those decisions. PEAC provides portable, offline-verifiable signed evidence of what was reported at each provisioning boundary.


Install​

Terminal
pnpm add @peac/schema @peac/protocol

Type URIs​

10 *-observed type URIs are registered under the org.peacprotocol/provisioning-lifecycle extension group (Section 31, PROV-LIFE-001..010):

Type URIDescription
org.peacprotocol/provisioning-credential-issuance-observedA credential was issued by an external provider
org.peacprotocol/provisioning-credential-rotation-observedAn existing credential was rotated
org.peacprotocol/provisioning-secret-rotation-observedA secret was rotated in a secrets manager
org.peacprotocol/provisioning-service-authorization-observedA service was authorized to access another service
org.peacprotocol/provisioning-access-grant-observedAn access grant was issued
org.peacprotocol/provisioning-access-revocation-observedAn access grant was revoked
org.peacprotocol/provisioning-key-creation-observedA cryptographic key was created
org.peacprotocol/provisioning-key-deletion-observedA cryptographic key was deleted or archived
org.peacprotocol/provisioning-service-binding-observedA service binding was created (e.g., database credential injection)
org.peacprotocol/provisioning-lifecycle-complete-observedA provisioning lifecycle workflow completed

Quick start​

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

// Build the extension object
const provisioningExt = {
'org.peacprotocol/provisioning-lifecycle': {
event_kind: 'credential-issuance',
provider_ref: 'urn:provider:vault.corp.example.com',
credential_ref: 'ref:credential/db-svc-account',
storage_surface: {
kind: 'external_secret_store',
provider_ref: 'ref:provider/hashicorp-vault',
surface_ref: 'ref:path/secret/data/myapp/db',
},
observed_at: new Date().toISOString(),
},
};

// Validate before issuing
const result = validateProvisioningLifecycle(provisioningExt);
if (!result.success) {
console.error(result.error);
process.exit(1);
}

// Issue the signed record
const { jws } = await issue({
iss: 'https://provisioning.corp.example.com',
kind: 'evidence',
type: 'org.peacprotocol/provisioning-credential-issuance-observed',
sub: 'ref:credential/db-svc-account',
extensions: provisioningExt,
privateKey: signingKey,
kid: 'peac-2026-03',
});

console.log(jws); // Compact JWS -- verifiable offline

Core fields​

FieldRequiredTypeDescription
event_kindYesstringEvent kind identifier (see type URIs above)
provider_refYesopaque refReference to the provisioning provider
observed_atYesISO 8601When the provisioning event was observed
credential_refNoopaque refReference to the credential being issued/rotated
storage_surfaceNoobjectWhere the credential is stored (see below)
authorization_refNoopaque refReference to the authorization grant
expires_atNoISO 8601When the provisioned credential expires
sub_eventNostringSub-state within the event kind (e.g., requested, granted)

Opaque reference grammar​

All *_ref fields use the opaque reference grammar. Raw values (API keys, tokens, emails, paths) are not allowed inline. Use one of these prefixes:

PrefixUse
urn:URN-style identifier
ref:Logical path reference
did:DID identifier
sha256:SHA-256 content digest
https:URL reference
// Correct: opaque reference
provider_ref: 'ref:provider/hashicorp-vault'
provider_ref: 'urn:provider:vault.corp.example.com'
provider_ref: 'did:web:vault.corp.example.com'

// Incorrect: inline value (rejected)
provider_ref: 'hvs.CAESIJ...' // token value -- rejected
provider_ref: '/secret/data/myapp' // raw path -- rejected

Storage surface object​

The storage_surface object describes where a credential is stored without exposing the credential itself:

storage_surface: {
kind: 'external_secret_store', // see kind values below
provider_ref: 'ref:provider/hashicorp-vault', // opaque ref
surface_ref: 'ref:path/secret/data/myapp/db', // opaque ref
material_redaction: 'sha256_ref', // how credential material is redacted
}

Storage surface kind values:

KindDescription
external_secret_storeExternal secrets manager (Vault, AWS Secrets Manager, etc.)
local_encrypted_fileLocally encrypted credential file
local_plaintext_fileLocal plaintext file (flag for audit)
environment_file.env or environment variable file
runtime_secret_bindingInjected at runtime (e.g., Kubernetes secret mount)
noneNo persistent storage
unknownStorage surface not determinable

Credential material scanner​

validateProvisioningLifecycle() includes a recursive credential material scanner that rejects records containing inline secrets. The scanner checks all string values for patterns matching JWTs, Bearer tokens, PEM private keys, .env-style assignments, and connection strings with credentials.

This is a hard gate: if your extension object contains inline credential material in any nested field, validation will fail with provisioning.token_material_blocked or provisioning.inline_credential_blocked.

// This will fail validation
const bad = {
'org.peacprotocol/provisioning-lifecycle': {
event_kind: 'credential-issuance',
provider_ref: 'ref:provider/vault',
// Do NOT put actual token values in any field
note: 'eyJhbGciOiJIUzI1NiIs...', // JWT -- blocked
observed_at: new Date().toISOString(),
},
};
const result = validateProvisioningLifecycle(bad);
// result.success === false
// result.error.issues[0].code === 'provisioning.token_material_blocked'

Error codes (21 stable codes)​

CodeMeaning
provisioning.inline_credential_blockedForbidden top-level key with inline credential value
provisioning.token_material_blockedInline token material detected in a string field
provisioning.forbidden_key_nameField name is on the forbidden key list
provisioning.field_too_largeField value exceeds byte limit
provisioning.replacement_character_in_stringString contains Unicode replacement character
provisioning.structure_too_deepNesting depth exceeds maximum
provisioning.structure_too_largeTotal node count exceeds maximum
provisioning.opaque_ref_grammar_violationReference field does not match opaque ref grammar
provisioning.invalid_storage_surfacestorage_surface.kind is not a valid enum value
provisioning.invalid_material_redactionmaterial_redaction is not a valid value
provisioning.invalid_event_kindTop-level event_kind is not a known value
provisioning.invalid_sub_eventsub_event is not valid for this event_kind
provisioning.invalid_scheme_idscheme_id violates the bounded grammar
provisioning.invalid_amount_minoramount_minor is not a valid non-negative decimal string
provisioning.invalid_observed_atobserved_at is not a valid ISO 8601 timestamp
provisioning.invalid_retrieved_atretrieved_at is not a valid ISO 8601 timestamp
provisioning.invalid_expires_atexpires_at is not a valid ISO 8601 timestamp
provisioning.invalid_currencycurrency is not a valid ISO 4217 code
provisioning.unrecognized_fieldUnknown field in the extension object
provisioning.missing_required_fieldRequired field is absent
provisioning.invalid_utf8String contains invalid UTF-8 sequences (fixture loader)

Conformance​

Section 31 (PROV-LIFE-001..010) covers the 10 normative conformance requirements for provisioning lifecycle records. These are part of the 290 conformance requirements across 32 sections in PEAC v0.14.4.


Non-goals​

Provisioning lifecycle records do not:

  • Issue or provision credentials themselves
  • Rotate secrets on your behalf
  • Connect to or authenticate against any secrets manager
  • Guarantee that the reported provisioning event occurred correctly
  • Replace audit logs from your provisioning infrastructure