{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://openwop.dev/spec/v1/credential-provenance.schema.json",
  "title": "CredentialProvenance",
  "description": "RFC 0079 §A. Metadata ABOUT a host-issued credential (an RFC 0046 stored reference or an RFC 0047 OAuth token) attached at the tool/egress boundary — never the secret value (SR-1; reuses the RFC 0046 `credential-payload-redaction` posture). Travels with the egress decision, not the credential material. The §C audience-binding MUST is evaluated against `audiences`.",
  "type": "object",
  "additionalProperties": false,
  "required": ["credentialId", "issuer", "audiences"],
  "properties": {
    "credentialId": { "type": "string", "minLength": 1, "description": "Stable host-issued id for the credential (the RFC 0046 `ref`, or an OAuth-grant id). Correlates audit + the Keys-page view. NOT the secret value." },
    "issuer": { "type": "string", "minLength": 1, "description": "Who minted/owns the credential — the host itself (`host`), an RFC 0047 OAuth provider id, or a BYOK principal (RFC 0046). Lets a consumer distinguish host-managed from caller-supplied credentials." },
    "audiences": { "type": "array", "minItems": 1, "items": { "type": "string", "minLength": 1 }, "description": "REQUIRED. The destination hosts/domains (or destination-class ids) the credential is valid for. The §C binding MUST is evaluated against this list — a credential MUST NOT be attached to an egress outside its audiences. Matching is exact host or an explicit `*.domain` suffix form (no arbitrary regex — injection risk; RFC 0079 §UQ1)." },
    "scopes": { "type": "array", "items": { "type": "string" }, "uniqueItems": true, "description": "MAY — RFC 0049 scopes the credential grants (e.g. `egress:stripe:charge`)." },
    "expiresAt": { "type": "string", "format": "date-time", "description": "MAY — credential expiry; an expired credential MUST NOT be attached (deny, `reason: \"expired\"`)." },
    "redactionPolicy": { "type": "string", "enum": ["always", "hash", "host-policy"], "description": "MAY — how the credential surfaces in logs/events. `always`: never appears (default posture, SR-1); `hash`: an SR-1-redacted digest MAY appear; `host-policy`: host-defined. The secret value itself is NEVER on the wire regardless." },
    "auditCorrelationId": { "type": "string", "minLength": 1, "description": "MAY — id correlating this credential's egress decisions across the run's `egress.decided` events + the host audit log." }
  }
}
