Skip to content
English
  • There are no suggestions because the search field is empty.

Token Authentication with Ephemeral Key (EK)

This flow is the ephemeral-key variant of the Token Mutual Authentication flow. The server issues a challenge word (CW) for the device's token ID (TID), the device proves it can produce the correct response word (RW), and the server confirms the result. On success it returns an ephemeral key (EK) protected for a public key you supply, plus a claim token.

The difference from the standard flow is:

  • The first request includes a recipientPublicKey (a PEM-encoded RSA public key). The ephemeral key is protected for this recipient.
  • The status response returns an extra EK field alongside the result.

The flow uses three endpoints, called in sequence:

  1. POST /api/device/EKRequestCW — request a challenge word (CW) for the device's TID, supplying the recipientPublicKey. Returns the CW and a transactionId.
  2. POST /api/device/EKReplyRW — submit the response word (RW) along with the CW, TID, and transactionId.
  3. GET /api/device/EKCheckAuthStatus — poll with the transactionId to retrieve the authentication result and the ephemeral key.

Every request must be authenticated at the edge with Cloudflare Access headers (see below).

Authentication headers

All three endpoints require the following Cloudflare Access service-token headers on every request:

Header Required Description
CF-Access-Client-Id Yes Your Cloudflare Access client ID.
CF-Access-Client-Secret Yes Your Cloudflare Access client secret.

If these headers are missing or invalid, the request is rejected with 403 Forbidden.


Step 1 — Request a challenge word (CW)

Generate a challenge word based on the device's token ID (TID), supplying the recipient's public key. The response includes a transactionId that you must carry through the remaining steps.

Request

POST /api/device/EKRequestCW 
Content-Type: application/json
CF-Access-Client-Id: <your-client-id>
CF-Access-Client-Secret: <your-client-secret>

Request body

{   
"requestSignedResponse": false,
"recipientPublicKey": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A...\n-----END PUBLIC KEY-----",
"TID": "800000001000000010000000000000014464b592da61f3fd5506fcb1f37f4bef"
}
Field Type Description
TID string The device token ID. Must be exactly 64 characters long.
recipientPublicKey string A PEM-encoded RSA public key. The ephemeral key (EK) is protected for this recipient.
requestSignedResponse boolean Set to true to request a signed response.

Response — 201 Created

{   
"CW": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"transactionId": "123e4567-e89b-12d3-a456-426614174000"
}
Field Type Description
CW string The challenge word generated by the server.
transactionId string (UUID) Identifies this authentication process. Use it in the next two steps.

Errors

Code Meaning
400 Bad Request The request body is invalid — for example, "TID must be exactly 64 characters long".
401 Unauthorized Authentication failed.
403 Forbidden Invalid request, commonly caused by an invalid Cloudflare Access token.

Step 2 — Reply with the response word (RW)

Compute the response word (RW) from the challenge word and submit it back, along with the CW, TID, and the transactionId from Step 1.

Request

POST /api/device/EKReplyRW 
Content-Type: application/json
CF-Access-Client-Id: <your-client-id>
CF-Access-Client-Secret: <your-client-secret>

Request body

{   
"requestSignedResponse": false,
"TID": "800000001000000010000000000000014464b592da61f3fd5506fcb1f37f4bef",
"CW": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"RW": "e498a506be93008e40739a3077e4ad40",
"transactionId": "c905f6b4-3239-417e-abd9-66fe66f43a2a"
}
Field Type Description
TID string The device token ID (same value used in Step 1).
CW string The challenge word received in Step 1.
RW string The response word computed by the device.
transactionId string (UUID) The transaction ID returned in Step 1.
requestSignedResponse boolean Set to true to request a signed response.

Response — 201 Created

{   
"transactionId": "123e4567-e89b-12d3-a456-426614174000"
}
Field Type Description
transactionId string (UUID) Confirms the transaction. Use it to check the result in Step 3.

Errors

Code Meaning
401 Unauthorized Authentication failed.
403 Forbidden Invalid request, commonly caused by an invalid Cloudflare Access token.

Step 3 — Check the authentication result

Poll this endpoint with the transactionId to retrieve the outcome of the authentication and the ephemeral key.

Request

GET /api/device/EKCheckAuthStatus?transactionId=<transactionId> 
CF-Access-Client-Id: <your-client-id>
CF-Access-Client-Secret: <your-client-secret>

Query parameters

Parameter Type Required Description
transactionId string (UUID) Yes The transaction ID identifying the authentication process.
requestSignedResponse boolean No Request a signed response.

Response — 200 OK

{   
"status": "AUTH_OK",
"claimTokenId": "123e4567-e89b-12d3-a456-426614174000",
"EK": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
}
Field Type Description
status string The result of the authentication process. See possible values below.
claimTokenId string (UUID) The claim token ID, returned when the status is CLAIM_TOKEN.
EK string The ephemeral key, protected for the recipientPublicKey supplied in Step 1.

Status values

Value Meaning
AUTH_OK Authentication succeeded.
AUTH_NOT_OK Authentication failed.
CLAIM_TOKEN A token is ready to be claimed; use the returned claimTokenId.

Errors

Code Meaning
401 Unauthorized Authentication failed.
403 Forbidden Invalid request, commonly caused by an invalid Cloudflare Access token.

Related articles

  • Token Mutual Authentication — the standard flow without an ephemeral key (requestMutualAuthCW, replyMutualAuthRW, checkMutualAuthStatus)
  • Host Authentication with Ephemeral Key (EK) — the host auth EK flow (EKRequestHostAuth, EKCheckRequestHostAuthStatus)
  • Cloudflare Access service tokens — generating your CF-Access-Client-Id and CF-Access-Client-Secret
  • Claiming a token after CLAIM_TOKEN
← Token Authentication Host Authentication →