# AP2 Mandates Extension: Cryptographic Consent for UCP Checkout Flows

> Explore the AP2 Mandates extension for UCP. Secure checkout flows with cryptographic consent, ensuring explicit user approval for purchases and fund transfers.

- Repository: [Universal Commerce Protocol (UCP)/ucp](https://github.com/Universal-Commerce-Protocol/ucp)
- Tags: api-reference
- Published: 2026-04-26

---

**The AP2 Mandates extension adds a cryptographically-bound consent layer to the Universal Commerce Protocol (UCP), requiring businesses to embed signed merchant authorizations and platforms to supply SD-JWT credentials that prove explicit user approval for purchases and fund transfers.**

The AP2 Mandates extension in the `Universal-Commerce-Protocol/ucp` repository transforms standard checkout flows into tamper-evident, legally auditable transactions. When activated, this extension mandates that all session data carries cryptographic proof of consent, preventing plaintext checkout flows and ensuring that every party in the transaction can verify authorization through detached JWS signatures and Selective Disclosure JWT (SD-JWT) credentials.

## How AP2 Mandates Fits Into the UCP Architecture

The extension integrates into UCP through capability negotiation and strict namespace isolation, fundamentally altering the security posture of the checkout session once activated.

### Capability Negotiation and Security Locking

Activation occurs only when both the business and platform advertise the `dev.ucp.shopping.ap2_mandate` capability in their respective `/.well-known/ucp` profiles. Once negotiated, the session becomes **Security Locked**, prohibiting any plain (unprotected) checkout flow. According to the specification in [`docs/specification/ap2-mandates.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/ap2-mandates.md), this binding ensures that cryptographic verification is mandatory for the entire session lifecycle.

### Namespace Design and Data Structure

All AP2-specific fields reside under a top-level `ap2` object in both requests and responses. This design keeps the base checkout schema clean while allowing simultaneous operation with other security extensions. As defined in [`source/schemas/shopping/ap2_mandate.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/ap2_mandate.json), this namespace contains:
- `merchant_authorization`: The business's detached JWS signature
- `checkout_mandate`: The platform's SD-JWT credential bound to the checkout
- `payment_mandate`: The SD-JWT credential bound to the payment instrument

### Cryptographic Primitives and Canonicalization

The extension enforces strict cryptographic standards per [`docs/specification/signatures.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/signatures.md). All JSON data undergoing signature or mandate insertion must be canonicalized using the **JSON Canonicalization Scheme (JCS)** (RFC 8785) to ensure reproducible byte streams. Supported signature algorithms are limited to **ES256, ES384, and ES512** (ECDSA with P-256, P-384, and P-521 curves), using JWS detached content and JWK key formats.

## Recommended Use Cases for AP2 Mandates

The AP2 Mandates extension is designed for scenarios requiring immutable proof of consent and cross-party verification.

- **High-value or regulated commerce**: When transactions require legally-recognizable proof of user consent and immutable audit trails, the SD-JWT mandates provide tamper-evident evidence that the user approved exact checkout terms and fund transfers.
- **Multi-party payment flows**: For platforms, PSPs, and card networks exchanging consent artifacts across trust boundaries, mandates travel with the checkout object and payment tokens, allowing each party to verify identical signed data.
- **Digital wallet integrations**: When integrating with wallets issuing Verifiable Digital Credentials (VDCs), the Key-Binding (`+kb`) feature binds mandates to user-controlled credentials, satisfying wallet-centric security models.
- **Platform-as-a-Service environments**: When platforms must cryptographically prove to downstream businesses that users gave explicit authorization, the platform can generate or forward user-signed mandates that businesses can independently verify.

## Implementation Examples

The following examples demonstrate the practical implementation of merchant authorizations and mandate verification as specified in the AP2 Mandates extension.

### Merchant Authorization in Checkout Response

Businesses must sign the checkout payload and embed the detached JWS in the response. The payload excludes the `ap2` object to prevent circular references.

```json
{
  "id": "chk_abc123",
  "status": "ready_for_complete",
  "currency": "USD",
  "line_items": [],
  "totals": [],
  "ap2": {
    "merchant_authorization": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im1yY2hhbnRfMjAyNSJ9..eyJz... (detached JWS)"
  }
}

```

The `ap2.merchant_authorization` field contains a detached JWS where the payload is the canonicalized checkout object without the `ap2` block. The `kid` parameter must reference a public key listed in the business's `signing_keys`, and the algorithm must be one of ES256, ES384, or ES512.

### Checkout Mandate in Complete Request

The platform supplies verifiable mandates in the `complete` request, binding the checkout to cryptographic proof of user consent.

```json
{
  "payment": {
    "instruments": [
      {
        "id": "instr_1",
        "handler_id": "gpay_1234",
        "type": "card",
        "selected": true,
        "credential": {
          "type": "PAYMENT_GATEWAY",
          "token": "examplePaymentMethodToken"
        }
      }
    ]
  },
  "ap2": {
    "checkout_mandate": "eyJhbGciOiJFUzI1NiIsInR5cCI6InZjK3NkLWp3dCJ9…"
  }
}

```

The `ap2.checkout_mandate` field carries an SD-JWT (`+kb`) credential embedding the full checkout object, including the merchant's signature. The business validates this credential, extracts the embedded checkout, and verifies the merchant authorization against its `signing_keys`.

### Verification Flow

The following pseudocode illustrates the verification algorithm businesses implement according to [`docs/specification/ap2-mandates.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/ap2-mandates.md):

```text
function verifyComplete(request, businessProfile):
    // 1️⃣ Ensure AP2 was negotiated
    if "dev.ucp.shopping.ap2_mandate" not in intersection:
        reject("mandate_required")

    // 2️⃣ Verify checkout mandate (SD‑JWT)
    mandate = decodeSDJWT(request.ap2.checkout_mandate)
    if !mandate.validSignature() or mandate.expired:
        reject("mandate_invalid_signature")

    // 3️⃣ Extract embedded checkout and verify merchant signature
    checkout = mandate.claims.checkout
    jws = checkout.ap2.merchant_authorization
    header, _, signature = splitDetachedJWS(jws)
    payload = checkout without "ap2"
    signingInput = base64url(header) + "." + base64url(jcsCanonicalize(payload))
    pubKey = findKey(businessProfile.signing_keys, header.kid)
    if !verifySignature(signingInput, signature, pubKey, header.alg):
        reject("merchant_authorization_invalid")

```

This flow ensures that both the platform's mandate and the business's authorization signature are cryptographically valid before processing the transaction.

## Key Files and Schema References

Implementation of the AP2 Mandates extension relies on these critical source files:

- **[`docs/specification/ap2-mandates.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/ap2-mandates.md)**: The human-readable specification covering discovery, cryptography, and verification flows.
- **[`source/schemas/shopping/ap2_mandate.json`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/source/schemas/shopping/ap2_mandate.json)**: JSON Schema defining the `ap2` object structure, including `merchant_authorization`, `checkout_mandate`, and validation rules.
- **[`docs/specification/signatures.md`](https://github.com/Universal-Commerce-Protocol/ucp/blob/main/docs/specification/signatures.md)**: Reference for message-signature infrastructure including JWS, JCS (RFC 8785), and JWK formats.

## Summary

- The **AP2 Mandates extension** requires the `dev.ucp.shopping.ap2_mandate` capability to activate Security Locked sessions.
- Businesses must provide **detached JWS signatures** in `ap2.merchant_authorization`, signing the checkout payload without the `ap2` object using ES256/ES384/ES512 algorithms.
- Platforms must supply **SD-JWT credentials** (`+kb`) in `ap2.checkout_mandate` that cryptographically prove user consent.
- All JSON must be canonicalized using **JCS (RFC 8785)** before signing or embedding in mandates.
- The extension is mandatory for high-value commerce, regulated industries, multi-party payment flows, and digital wallet integrations requiring verifiable consent.

## Frequently Asked Questions

### What capability key activates the AP2 Mandates extension?

Both the business and platform must advertise `dev.ucp.shopping.ap2_mandate` in their `/.well-known/ucp` profiles. This mutual advertisement triggers Security Locking, which prohibits unprotected checkout flows for that session.

### How does the merchant authorization signature work?

The business creates a detached JWS using ES256, ES384, or ES512 algorithms, placing it in `ap2.merchant_authorization`. The signed payload must be the canonicalized checkout object **excluding** the `ap2` field to avoid circular dependencies. The `kid` in the JWS header must reference a key in the business's published `signing_keys`.

### What cryptographic algorithms does AP2 Mandates require?

The extension mandates ECDSA signatures using ES256 (P-256), ES384 (P-384), or ES512 (P-521) curves. All JSON canonicalization must follow RFC 8785 (JCS), and SD-JWT mandates must use the Key-Binding (`+kb`) extension for credential binding.

### When should businesses avoid using AP2 Mandates?

Low-risk, low-value transactions where cryptographic overhead outweighs security benefits may not require AP2 Mandates. The extension should not be used when either party cannot support the mandatory JCS canonicalization, SD-JWT processing, or ECDSA signature verification required by the specification.