Supply-Y Protocol

Developer Documentation

Protocol 1.0
Documentation

Search Supply-Y

All documentation
MarkdownDemo
Native Mode Security

Cryptographic Profile

The exact bytes, algorithms and verification order behind end-to-end encrypted Packages.

supply-y-crypto/0.1Test vectors

Profile: supply-y-crypto/0.1

Status: Normative Native Mode profile for Supply-Y Protocol 1.0

This profile defines how one Supply-Y Package is canonicalized, encrypted for exactly two organizations, signed by the sender and verified without giving Supply-Y a decryption key.

The requirement words MUST, MUST NOT, SHOULD and MAY are normative when capitalized.

Security goal

For a Native Mode exchange:

  • the sender and intended recipient can decrypt the same Package;
  • Supply-Y can authenticate the sender, route the Package and record its digest without reading the Package;
  • an unlisted organization key cannot decrypt it;
  • changes to routing metadata, recipient headers, ciphertext or signature are detected;
  • the sender can reopen the retained ciphertext during the agreed retention period.

This profile protects confidentiality and integrity. It does not prove that a business statement inside the Package is true.

Required algorithm suite

PurposeRequired valueStandard
JSON canonicalizationJCSRFC 8785
Package digestSHA-256RFC 9530
Content encryptionA256GCMRFC 7518
Per-recipient key managementECDH-ES+A256KWRFC 7518
Encryption curveP-256RFC 7518
Sender signatureES256RFC 7518
Key representationJWKRFC 7517
Encryption containerGeneral JWE JSONRFC 7516
Signature containerFlattened JWS JSONRFC 7515

The initial suite uses P-256 because it is widely available in enterprise KMS, HSM and JOSE implementations. Algorithm agility is versioned at the profile level; implementations MUST NOT silently substitute another algorithm.

The algorithms none, RSA1_5, password-based key management and unauthenticated encryption are prohibited. Compression before encryption is prohibited in this profile.

Key separation

Each Agent has separate keys for:

  • sender signatures;
  • Package encryption and decryption.

The same private key MUST NOT be used for both purposes. Private keys remain in customer-controlled KMS or HSM systems. Supply-Y stores public JWKs, key IDs, validity windows, status and rotation history only.

Every key ID in a Package MUST resolve to an active or historically valid key belonging to the expected organization and Agent. A key marked revoked before created_at MUST cause rejection.

KMS and HSM operation boundary

The reference TypeScript SDK accepts a senderSigner and recipientDecrypter instead of requiring production private JWK export. The signer receives only the exact canonical exchange payload and required protected header. The decrypter receives the complete General JWE and the authenticated recipient key ID. Customer adapters perform the private-key operation inside their KMS or HSM boundary.

The SDK MUST reject a signer result that changes the payload, algorithm, key ID or protected header. After decryption it MUST independently verify the two-recipient JWE profile, authenticated metadata, content digest, canonicalization and object contract. A decrypter result is therefore not trusted merely because it came from the configured adapter.

The committed SDK suite proves this adapter boundary and negative substitution cases. It does not prove interoperability with any specific KMS or HSM product; that remains production certification evidence.

Canonical plaintext and digest

  1. The complete inner Supply-Y object MUST pass its object schema and Skill profile.
  2. The object MUST be serialized with JCS.
  3. The canonical UTF-8 bytes become the JWE plaintext.
  4. SHA-256 is calculated over those exact bytes.
  5. The readable exchange metadata carries the digest in RFC 9530 form: sha-256=:BASE64:.

NaN, Infinity, duplicate object keys and negative zero MUST be rejected before canonicalization.

The inner Reasoning Package or Response Object MUST NOT contain an integrity, payload_hash, policy_decision_hash or signature field. A Package cannot unambiguously contain a hash or signature of itself. The authoritative integrity evidence is the metadata content digest, encrypted asset digest where applicable, outer exchange-envelope signature, policy receipt reference and append-only audit record.

The inner object also MUST NOT contain base_transport, connector URLs, EDC asset IDs or other routing fields. Native and Catena-X carry the same canonical business object; transport selection belongs to authenticated delivery metadata and, for Catena-X, the signed control manifest.

Readable authenticated metadata

The following routing metadata remains readable to Supply-Y:

  • package_id and thread_id;
  • sender and recipient organization and Agent IDs;
  • protocol, schema and Skill versions;
  • creation and expiry timestamps;
  • content type and content digest;
  • transport mode and policy receipt ID when present.

The JCS serialization of this metadata MUST be supplied as JWE Additional Authenticated Data. Changing the metadata after encryption therefore causes decryption failure.

Readable metadata MUST NOT include Package facts, reasoning, evidence values, customer names, exact capacity, inventory, price or other business plaintext.

Encrypt for sender and recipient

The sender creates one General JWE JSON object with one ciphertext and exactly two recipient entries:

  1. a sender recipient entry, using the sender's current encryption public key;
  2. an intended-recipient entry, using the recipient's verified encryption public key.

Both entries use ECDH-ES+A256KW. The shared content uses A256GCM. A conforming implementation MUST generate a fresh content-encryption key, ephemeral ECDH key and GCM IV from a cryptographically secure random source for every Package. Reuse is prohibited.

The sender entry exists only so the sender can reopen its own retained Package. It does not grant Supply-Y access.

Sign the exchange envelope

The sender constructs this exchange envelope:

{
  "metadata": { "package_id": "pkg_...", "content_digest": "sha-256=:...:" },
  "jwe": { "protected": "...", "recipients": [], "iv": "...", "ciphertext": "...", "tag": "..." }
}

The envelope is serialized with JCS and signed as a Flattened JWS JSON object using ES256. The protected JWS header MUST contain:

  • alg: ES256;
  • the sender signing kid;
  • typ: application/supply-y+jws;
  • cty: application/supply-y.exchange-envelope+json;
  • syv with the protocol version.

The outer JWS protects the readable metadata and the complete General JWE object, including recipient headers that are not independently protected by JWE.

Recipient processing order

A recipient MUST process an exchange in this order:

  1. enforce HTTP size and rate limits;
  2. parse the JWS without acting on the payload;
  3. resolve sender identity and signing key;
  4. allowlist ES256 and verify the JWS;
  5. reject expired, replayed or incompatible metadata;
  6. confirm that the authenticated recipient ID matches the local organization;
  7. decrypt only its own JWE recipient entry using allowlisted ECDH-ES+A256KW and A256GCM;
  8. compare authenticated metadata AAD and recompute the SHA-256 digest;
  9. parse the canonical plaintext as untrusted JSON;
  10. validate the object schema and scenario Skill before any Agent action.

An implementation MUST NOT select an algorithm only because it appears in an unverified header.

Failure behavior

Signature, key, digest, expiry, recipient, decryption and schema failures produce a generic rejection receipt with a stable reason code. Responses and logs MUST NOT reveal private keys, plaintext, raw ciphertext fragments or detailed cryptographic oracle information.

A failed verification MUST NOT advance the thread or trigger an Agent tool. Retrying the same signed exchange under the same idempotency key returns the original result.

Rotation and retention

New Packages use only active keys. A key may move through active, retiring, retired and revoked states. valid_from and valid_until define when a key may sign or receive new Packages. revoked_at records when Supply-Y learned of a revocation; invalid_from records the earliest Package creation time that must no longer be trusted. They are deliberately separate because compromise can be discovered after it began.

For new ingress, the signing key MUST be eligible both at Package created_at and when Supply-Y first observes the Package. A retired or revoked key cannot submit a backdated Package. Historical verification after retirement or revocation is allowed only when the tamper-evident audit trail proves that Supply-Y accepted the same Package digest before the applicable cutoff. A Package created at or after invalid_from is rejected even if an earlier system accepted it before the compromise was discovered.

Old Packages record the key IDs used at creation. Organizations retain retired decryption keys for at least the Package retention period or explicitly rewrap retained content keys during a controlled migration. Destroying an old private decryption key makes retained ciphertext permanently unreadable unless a valid rewrap already exists; Supply-Y cannot recover it.

The machine-readable key lifecycle profile is in test-vectors/key-lifecycle-0.1.json. npm run validate:key-lifecycle proves 24 rotation, revocation, historical-verification, private-key-retention and OpenAPI contract outcomes, including a distinct replacement P-256 signing key verified through both JOSE and WebCrypto.

Conformance vector

The repository includes test-vectors/crypto-profile-0.1.json. It contains test-only private keys, one signed exchange and the expected plaintext and metadata.

npm run validate:crypto runs three independent paths: the JOSE reference implementation, a WebCrypto implementation that parses the wire format itself, and a Python cryptography implementation. All three prove that:

  • the sender signature verifies;
  • the envelope is RFC 8785 canonical JSON;
  • sender and recipient decrypt identical plaintext;
  • the content digest matches;
  • an unrelated key cannot decrypt;
  • signature and ciphertext tampering are rejected.

The WebCrypto verifier does not import the JOSE or JSON-canonicalization libraries. The Python verifier is a separate language implementation and does not call either Node verifier. Both independently parse the wire format and perform ECDH, the RFC 7518 Concat KDF, AES-KW, AES-GCM, ECDSA and digest checks. Agreement across Node JOSE, Node WebCrypto and Python cryptography is stronger evidence than a sender and receiver using the same JOSE code path.

The Python conformance dependency is pinned in tools/requirements-conformance.txt. The verifier and published private keys are test-only and MUST NOT be used as production crypto code or deployment keys.

Published test-vector keys MUST NEVER be used in any deployment.

Remaining production evidence

The Protocol 1.0 requirements above are stable. Production certification still requires additional implementation evidence:

  • KMS and HSM integration vectors;
  • multi-generation DEK rewrap and customer KMS or HSM lifecycle evidence;
  • key rotation and historical-decryption checks in another language;
  • additional canonicalization vectors for Unicode and numeric edge cases;
  • replay, expiry and large-payload cases;
  • independent security review before production certification.
On this page