Credential Rotation
Get in-depth info on how to rotate credentials through an API in Cards Connect
Card Present Gateway
If you want to access information about our in-store offering, you may check the API specifications here: In-store Transactions Overview
To enhance security and comply with best practices, Cards Connect provides an API endpoint that allows for fully automated, client-driven credential rotation. This process enables a zero-downtime transition to a new credential, ensuring that service is never interrupted.
This page outlines the process for building an automated system to periodically rotate your API credentials.
The Rotation Process
The rotation mechanism involves creating a new credential and setting a defined expiry for the current (old) credential. This creates a graceful transition period during which both the old and new credentials can be valid, allowing your systems to seamlessly switch to the new key without service disruption.
An automated system should follow these steps:
- Generate New Key Pair: Your system must generate a new cryptographic key pair (private and public) in the standard JSON Web Key (JWK) format. The
kid
(Key ID) of this new key will serve as the unique identifier for your new credential and must not be the same as any of your existing or previous credentialkid
s. - Call the Rotate Credential Endpoint: Your system will make a
PUT
request to the rotation endpoint. This request must be signed using the current (soon-to-be-old) private key. The request specifies the public key of the new credential, the expiry date for the new credential, and a new, nearer expiry date for the current credential. - Transition to New Key: Upon receiving a successful
201 Created
response, the rotation is complete on the Cards Connect side. Your system should:- Securely store and begin using the new private key to sign all subsequent API requests.
- The old key will remain valid until the
CurrentKeyExpiry
time you specified in the rotation request. - Once the old key has expired, it should be securely destroyed.
Endpoint Definition
To rotate the credential used to sign the current request, call the following endpoint:
PUT /api/v1/keys/credential/rotate-to/{keyId}
Parameter | Location | Description |
---|---|---|
keyId | Path | The Key ID (kid ) of the new credential. |
The request must be authenticated with a JWS signature generated using the current credential's private key.
Request Payload
The body of the request must contain the details for the new credential and the updated expiry for the current one.
Field | Type | Description | Required |
---|---|---|---|
PublicKey | Object | A JWK representation of the new public key. See section 8.3.1 for details. | Yes |
Expiration | String | The UTC date and time when the new credential will expire, in ISO 8601 format. This cannot be more than 365 days in the future. | Yes |
CurrentKeyExpiry | String | The new UTC expiry date and time for the current credential, in ISO 8601 format. We recommend a short overlap (e.g., 24-72 hours) to ensure a smooth transition. This cannot be more than 14 days in the future. | Yes |
Public Key Object
Field | Type | Description | Required |
---|---|---|---|
Kty | String | Key Type. Must be EC . | Yes |
Kid | String | Key ID. Must match the {keyId } in the URL. | Yes |
Use | String | Public Key Use. Must be sig . | Yes |
Crv | String | Cryptographic Curve. Must be P-256 . | Yes |
X | String | The X coordinate for the EC key (Base64Url). | Yes |
Y | String | The Y coordinate for the EC key (Base64Url). | Yes |
Sample Rotation Request
Here is an example of a PUT
request to rotate from a credential with kid
= e585e505-a8c2-4809-a46c-e5a0f6b43f9a
to a new credential with kid
= d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1
.
Request: PUT /api/v1/keys/credential/rotate-to/d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1
Headers: Authorization: JWS <Signed with private key for e585e505...>
Content-Type: application/json
{
"PublicKey": {
"Kty": "EC",
"Kid": "d1e1f1a1-c8a7-4b9a-8a6a-d1b1c1d1e1f1",
"Use": "sig",
"Crv": "P-256",
"X": "usM_A8GveSS31e_f53t5v50_G8Z2p4e1e8R2v_Z1z4E",
"Y": "n8t5v_A8GveSS31e_f53t5v50_G8Z2p4e1e8R2v_Z1z"
},
"Expiration": "2026-06-27T14:30:00Z",
"CurrentKeyExpiry": "2025-06-28T14:30:00Z"
}
A successful request will return a 201 Created
status code with an empty body. If the request fails, standard API error responses will be returned.
Updated 10 days ago