How-to guide

OAuth2 delivery auth with private_key_jwt & a P12 certificate

Some targets — regulated APIs, financial and government systems, enterprise ERPs — require OAuth2 client credentials rather than a static bearer token, and often the private_key_jwt method signed with a certificate. Queuey fetches and caches the access token for you, then signs each delivery with it.

How it works

On a queue's delivery target, set the auth mode to OAuth2 (client credentials) and pick a client authentication method:

  • client_secret_post / client_secret_basic — a shared secret, stored as an OAuth2 client-secret credential.
  • private_key_jwt — a P12 certificate (plus its passphrase) is uploaded as a credential; Queuey builds a signed JWT client assertion and never sends the private key.

You configure the token endpoint, client id, scope, and (optionally) audience. Queuey requests a token, caches it across workers until just before it expires, and attaches Authorization: Bearer <token> to every delivery.

1 — The signed client assertion

For private_key_jwt, Queuey builds and signs this JWT with your certificate (RS256/ES256, with the x5t thumbprint in the header):

client assertion (claims)
{
  "iss": "<your-client-id>",
  "sub": "<your-client-id>",
  "aud": "https://idp.example.com/connect/token",
  "jti": "<random-uuid>",
  "iat": 1750000000,
  "nbf": 1750000000,
  "exp": 1750000120
}

2 — The token request

Queuey posts the assertion to the IdP's token endpoint as a client-credentials grant:

POST token endpoint
POST /connect/token HTTP/1.1
Host: idp.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials
&scope=<scope>
&client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
&client_assertion=<signed-JWT>
Use the discovery token_endpoint
Point the token endpoint at the IdP's actual token_endpoint (from its .well-known/openid-configuration), e.g. /connect/token — not the portal or discovery base, which will return HTML.

3 — The delivery

Each delivery now carries the bearer token. If the target needs to know which of your customers an event belongs to, forward the event's GroupKey as a header the target expects (for example X-Account-Id):

outbound delivery
POST /your/webhook HTTP/1.1
Host: api.partner.example
Authorization: Bearer <access-token-from-the-idp>
Content-Type: application/json
X-Account-Id: <forwarded GroupKey, if configured>

{ "eventType": "invoice.created", "payload": { ... } }
Security defaults
The token endpoint must be HTTPS (plain HTTP is allowed only for localhost). The certificate and passphrase are stored encrypted, and the access token is cached only for its lifetime minus a safety skew. Only the public certificate is ever sent to the IdP.

Related