ECL Trust Policy Profile 1

Requirement-IDs: compiled Version: 1.0 Status: normative profile of ECL-1 Version 1.0

This profile describes the caller-controlled trust-policy input to envelope verification (INTEGRITY-ENVELOPE-1 section 11) and to the offline bundle verifier. Standalone envelope verification binds each payload to the purpose of its role (TP1-010); the bundle verifier additionally binds every object role and principal within each media type.

TP1-001§ — The verifier MUST use only its caller's current trust policy and explicitly supplied earlier versions of that same policy; a bundle MUST NOT carry, select, or substitute trust roots, and an embedded policy reference that matches none of those supplied versions MUST be reported as a policy mismatch, with ecl.error.signature-policy-invalid.v1.

TP1-002§ — A trust-policy document MUST validate against https://externalcontrollayer.ai/ns/schema/trust-policy/1 with no unknown members. A loader MUST refuse a document that fails the strict JSON checks of INTEGRITY-ENVELOPE-1 (IE1-037), in their order, or fails the schema with ecl.error.schema-invalid.v1, except that a declared limit gives the error of TP1-007.

TP1-003§ — A trust-policy document MUST have unique key identifiers and public keys, active supported signature suites, canonically decoded keys of the correct length, a valid P-256 curve point or a canonical Ed25519 curve point of non-small order, a validity end later than its start when present, registered key purposes, and at most one revocation per known key. A loader MUST refuse a document that fails any of these conditions with ecl.error.semantic-invalid.v1.

TP1-004§ — Bundle verification MUST accept a key only for an object's declared role within its payload media type, and MUST reject a decision-request key used for a decision response even though both use the DCMP-2 media type.

TP1-005§ — Bundle verification MUST reject a signing key whose bound principal differs from the object's issuer or producer identifier.

TP1-006§ — Bundle verification MUST evaluate each trust dependency of a bundle: each signing key of each envelope and observation, and each signing key of each time attestation that a trusted-time countersignature carries (INTEGRITY-ENVELOPE-1 section 9). Every key that signed anything in the bundle is a trust dependency, whether or not its signature counts toward the policy: its historical status is the result of INTEGRITY-ENVELOPE-1 IE1-040 step 6 for that signature at the dependency's time together with the revocation check below, and a signature that does not verify makes its dependency historically invalid with ecl.error.integrity-invalid.v1. IE1-015 still decides from the signatures that count whether the envelope or the attestation is valid, so the verdict does not change; a scope item that rests on a dependency (EBMP-2 EBMP2-076) is established only when that dependency is historically valid. A dependency is historically valid only when both hold: it is valid at the dependency's time under the policy version that its object names (TP1-001), a revocation in that version effective at or before that time making it invalid; and the caller's current policy holds no revocation, effective at or before the dependency's time, of a key that has the dependency's key identifier or its public key. The dependency's time is the time at which INTEGRITY-ENVELOPE-1 IE1-034 evaluates its signature, for a signer of an object, and the attested time, for a signer of a time attestation. A revocation states that the key is not trusted from its effective time, whatever reason it gives, so a revocation in the current policy reaches evidence that an earlier version still accepts; a claimant that does not know when a compromise began revokes from the earliest suspected time (ECL-1 ECL1N-0159). Only a revocation carries later knowledge of a compromise: a key's later retirement, a validity interval that the current policy ends or shortens, or the key's absence from the current policy does not make a dependency historically invalid. Bundle verification MUST also report each dependency's current status at the caller's evaluation time under the current policy, which MUST use the caller's current policy whatever version the object's embedded reference names and MUST find the key in it with the public key that the historical check used; the matching of TP1-001 applies to historical validity only. The report MUST name, for each dependency, the policy version of its historical check, the current policy version whose revocations it applied, and the effective time of any such revocation. Each dependency's report member at MUST be the time at which its signer was evaluated, or null when it was not evaluated, including when the envelope's status was decided before any signer was evaluated.

TP1-007§ — A verifier interface MUST enforce declared byte limits before parsing. The verifier published with ECL-1, for the command line (packages/ecl-ts) and for the browser (web/verifier), declares a limit of 256 KiB for each trust-policy input and of 1 MiB for its evidence-bundle input. A verifier MUST refuse an input that exceeds a declared limit, including a limit of its strict JSON parser (INTEGRITY-ENVELOPE-1 IE1-037), with ecl.error.resource-limit-exceeded.v1.

The byte limits apply to the interfaces that read bytes, such as a command-line interface. An interface that accepts parsed objects applies the envelope, observation, node and depth limits that it declares (EBMP-2 EBMP2-062). An embedded reference identifies a supplied policy version; it never supplies that policy's keys. The current policy and the history versions are caller inputs.

The seven registered purposes are ecl.purpose.decision-request.v1, ecl.purpose.decision-response.v1, ecl.purpose.control.v1, ecl.purpose.evidence-event.v1, ecl.purpose.observation.v1, ecl.purpose.trusted-time.v1, which signs time attestations (INTEGRITY-ENVELOPE-1 section 9), and ecl.purpose.approval.v1, which marks an approval service's key: a verifier admits an approval record as the proof of an approval obligation only when every key that signed it holds that purpose (EBMP-2 EBMP2-070). The approval purpose qualifies a key that also holds the evidence-event purpose and lets a key sign no payload by itself, so a verifier refuses a trust policy in which a key holds it alone. INTEGRITY-ENVELOPE-1 IE1-039 gives the purpose that the key of each kind of payload holds. Adding revocations changes the policy digest.

TP1-008§ — Ed25519 verification MUST require canonical scalar S < L and check the cofactorless equation [S]B = R + [k]A, where k is the little-endian SHA-512 challenge reduced modulo L. It MUST NOT substitute a cofactor-multiplied verification equation. Canonical decoding and non-small order of the policy's public key remain mandatory under TP1-003.

RFC 8032 §5.1.7 requires the cofactored equation [8][S]B = [8]R + [8][k]A and permits the cofactorless [S]B = R + [k]A instead, with k the unreduced digest. With k reduced modulo L, the check above is that cofactorless equation for a public key of prime order. For a key with a small-order component, which TP1-003 admits, it can differ from it, and every signature it accepts still satisfies the cofactored equation. The edge corpus includes fourteen refused small-order encodings, accepted and refused mixed-order signatures, and a refused torsion-R signature. The Go edge checks exercise the same bytes with crypto/ed25519; they do not establish a complete Go trust-policy or envelope capability.

Five of the purposes each belong to one component role: the decision-request purpose to the requester of a decision, which may be the enforcement point or the governed AI system itself, the decision-response purpose to the decision point, the control purpose to the control plane that issues DCMP-2 control messages, the observation purpose to an observer and the trusted-time purpose to a time authority. The requester also answers the challenges of the decision point, so a challenge response is signed under the decision-request purpose and a challenge under the decision-response purpose. The evidence-event purpose is not a role of its own: the component that records an evidence event signs it. A key that held two roles would let the holder of one role sign for the other, such as a requester forging decision responses.

TP1-009§ — A trust-policy key MUST NOT carry more than one of the decision-request, decision-response, control, observation and trusted-time purposes; the evidence-event purpose MAY accompany one of them. A verifier MUST refuse a trust-policy document with a key that carries two of these purposes as ecl.error.semantic-invalid.v1 (ECL1N-0157).

TP1-010§ — Envelope verification under a trust policy, standalone or within a bundle, MUST count a signature over a DCMP-2 message only when its key carries the purpose that INTEGRITY-ENVELOPE-1 IE1-039 gives its message type: the decision-request purpose for a decision request or a challenge response, the decision-response purpose for a decision response or a challenge, and the control purpose for a control message; a signature by any other key MUST NOT count toward that object's threshold or required keys.

Evidence

Kind What the citation establishes
Vectors Reproducible object acceptance and exact error attribution
Verifier tests A verifier's behavior where no vector applies; this is not a deployment assessment

TP1-002 and TP1-003 have vectors in the trust-policy suite, including the small-order key refusal. TP1-009 and TP1-010 have vectors in the key-roles suite: policies whose one key carries two roles, and envelopes of each DCMP-2 message type that a key with and without the role signed. The evidence-bundle suite refuses a bundle that carries its own trust policy (TP1-001) and a decision response signed with a key bound to another principal (TP1-005), and tells a key revoked before the evidence was signed, which makes the bundle invalid, from one revoked after it, which is a current-trust failure (TP1-006). The envelope suite refuses a signature by a key without the object's purpose (TP1-004) and checks the Ed25519 rules of TP1-008. TP1-007, the limits on the bytes that a verifier loads, has no vector: an assessor checks that the verifier refuses a trust policy or a bundle over its limit before it parses the input. These checks establish a verifier's behavior, not the identity or independence of an assessor or the trustworthiness of production keys.