Authentication for the Coinbase Developer Platform (CDP) x402 facilitator.
CDP's hosted facilitator (facilitator_url/0) requires an
Authorization: Bearer <JWT> header on every request. The JWT is an EdDSA
or ES256 signed token carrying the API key id and a uris claim binding it
to the exact request.
API keys
Credentials are passed to new/1 via the :api_key_id and
:api_key_secret options. In applications that want a single source of
truth at runtime, put them in application configuration and let the
facilitator resolve them (see the otp_app option on
X402.Facilitator.start_link/1):
# config/runtime.exs
config :my_app, MyX402,
auth: {X402.Facilitator.Auth.CDP,
api_key_id: System.fetch_env!("CDP_API_KEY_ID"),
api_key_secret: System.fetch_env!("CDP_API_KEY_SECRET")}Two API key secret formats are supported, matching the CDP SDK:
- Ed25519 — base64 of the 64-byte private key (32-byte seed + 32-byte public key). This is the default for new API keys.
- EC (P-256) — a PEM
EC PRIVATE KEY(SEC1) or PKCS#8 private key. Used by legacy API keys.
The secret format is detected automatically; no configuration is required.
Usage
X402.Facilitator.start_link(
finch: MyFinch,
url: X402.Facilitator.Auth.CDP.facilitator_url(),
auth: {X402.Facilitator.Auth.CDP, api_key_id: "...", api_key_secret: "..."}
)The JWT is generated per facilitator operation with a fresh nonce and
timestamps. Transport retries reuse it within its 120-second validity
window. The aud claim is intentionally omitted to match the reference CDP
SDK's x402 facilitator client.
Summary
Functions
Returns the CDP x402 facilitator base URL.
Builds the Authorization (and Correlation-Context) headers for a request.
Builds CDP auth state from :api_key_id and :api_key_secret options.
Types
@type key_format() :: :ed25519 | :ecdsa_p256
API key secret format.
@type t() :: %X402.Facilitator.Auth.CDP{ api_key_id: String.t(), key_format: key_format(), key_material: binary() }
CDP auth state.
Functions
@spec facilitator_url() :: String.t()
Returns the CDP x402 facilitator base URL.
Note that this URL is never used as a default; a facilitator must be
configured with an explicit url: option.
@spec headers(t(), X402.Facilitator.Auth.request_info()) :: {:ok, [{String.t(), String.t()}]}
Builds the Authorization (and Correlation-Context) headers for a request.
The JWT binds the request method, host, and path in its uris claim and is
signed fresh each time headers are built; transport retries within one
facilitator operation reuse the same token inside its 120-second validity
window.
Builds CDP auth state from :api_key_id and :api_key_secret options.
Returns {:error, reason} when credentials are missing or the secret is not
a valid Ed25519 or P-256 key. For config-driven credentials, see the
otp_app option on X402.Facilitator.start_link/1.