Client Certificates
This guide explains how to manage Client Certificates attached to a Frontdoor. Use these steps to list, create, update, and delete client certificates. Client certificates enable mutual TLS authentication for enhanced security.
Why this matters
- Client certificates provide mutual TLS authentication, ensuring both the client and server verify each other's identity.
- They can be uploaded (existing certificates) or generated from Certificate Signing Requests (CSRs).
- Generated certificates are signed by NetFoundry's Certificate Authority and include proper key usage extensions.
- Client certificates are stored securely and referenced by shares for authentication requirements.
Assumptions
- The examples assume you have a valid bearer token. If you need help obtaining a token, see Authentication for NetFoundry REST APIs.
- Base URL for all API calls is https://gateway.production.netfoundry.io/frontdoor.
- Expected headers for all API calls:
Authorization: Bearer YOUR_ACCESS_TOKENAccept: application/hal+json or application/json
Tips
- Keep certificate names unique and descriptive (e.g., "api-client-prod", "service-mesh-cert").
- Use generated certificates for better integration with NetFoundry's PKI infrastructure.
- Ensure CSRs include all required subject information for generated certificates.
- Test certificates in staging environments before deploying to production.
Operations
List client certificates
Request example
curl -s \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
"https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates?page=0&size=20&sort=name,asc"
Response example
{
"content": [
{
"id": "cert-123e4567-e89b-12d3-a456-426614174000",
"name": "api-client-prod",
"frontdoorId": "3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c",
"createdAt": "2024-01-15T10:30:00Z",
"createdBy": "user-456"
},
{
"id": "cert-987fcdeb-51a2-43d7-8f9e-123456789abc",
"name": "service-mesh-cert",
"frontdoorId": "3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c",
"createdAt": "2024-01-16T14:20:00Z",
"createdBy": "user-789"
}
],
"pageable": {"pageNumber": 0, "pageSize": 20},
"totalElements": 2,
"totalPages": 1
}
Get a client certificate by ID
Request example
curl -s \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates/cert-123e4567-e89b-12d3-a456-426614174000
Response example
{
"id": "cert-123e4567-e89b-12d3-a456-426614174000",
"name": "api-client-prod",
"frontdoorId": "3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c",
"createdAt": "2024-01-15T10:30:00Z",
"createdBy": "user-456",
"value": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAgIJAKoK/OvD...\n-----END CERTIFICATE-----"
}
Create a client certificate (Upload existing)
Upload an existing certificate that you already possess.
Request example
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "uploaded-client-cert",
"value": "-----BEGIN CERTIFICATE-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAryQICCl6NZ5gDKrnSztO\n3Hy8PEUcuyvg/ikC+VcIo2SFFSf18a3IMYldIugqqqZCs4/4uVW3sbdLs/6PfgdX\n7O9D22ZiFWHPYA2k2N744MNiCD1UE+tJyllUhSblK48bn+v1oZHCM0nYQ2NqUkvS\nj+hwUU3RiWl7x3D2s9wSdNt7XUtW05a/FXehsPSiJfKvHJJnGOX0BgTvkLnkAOTd\nOrUZ/wK69Dzu4IvrN4vs9Nes8vbwPa/ddZEzGR0cQMt0JBkhk9kU/qwqUseP1QRJ\n5I1jR4g8aYPL/ke9K35PxZWuDp3U0UPAZ3PjFAh+5T+fc7gzCs9dPzSHloruU+gl\nFQIDAQAB\n-----END CERTIFICATE-----"
}' \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates
Create a client certificate (Generate from CSR)
Generate a certificate from a Certificate Signing Request (CSR). NetFoundry will sign the certificate with appropriate key usage extensions.
Request example
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "generated-client-cert",
"value": "-----BEGIN CERTIFICATE REQUEST-----\nMIIB1jCCAT8CAQAwgZUxEjAQBgNVBAoTCWFjY2VzczM2MDEUMBIGA1UECxMLZW5n\naW5lZXJpbmcxEDAOBgNVBAMTB250YWdlbnQxJDAiBgkqhkiG9w0BCQEWFW50YWdl\nbnRAYWNjZXNzMzYwLmNvbTELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju\naWExDzANBgNVBAcTBklydmluZTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA\nmR6AcPnwf6hLLc72BmUkAwaXcebtxCoCnnTH9uc8VuMHPbIMAgjuC4s91hPrilG7\nUtlbOfy6X3R3kbeR8apRR9uLYrPIvQ1b4NK0whsytij6syCySaFQIB6V7RPBatFr\n6XQ9hpsARdkGytZmGTgGTJ1hSS/jA6mbxpgmttz9HPECAwEAAaAAMA0GCSqGSIb3\nDQEBAgUAA4GBADxA1cDkvXhgZntHkwT9tCTqUNV9sim8N/U15HgMRh177jVaHJqb\nN1Er46vQSsOOOk4z2i/XwOmFkNNTXRVl9TLZZ/D+9mGZcDobcO+lbAKlePwyufxK\nXqdpu3d433H7xfJJSNYLYBFkrQJesITqKft0Q45gIjywIrbctVUCepL2\n-----END CERTIFICATE REQUEST-----"
}' \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates
Successful response example
{
"id": "cert-new123e4567-e89b-12d3-a456-426614174000",
"name": "generated-client-cert",
"frontdoorId": "3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c",
"createdAt": "2024-01-17T09:15:00Z",
"createdBy": "user-456"
}
Partial update of a client certificate
Update specific fields of an existing client certificate.
Request example
curl -s -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "updated-client-cert-name"
}' \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates/cert-123e4567-e89b-12d3-a456-426614174000
Full update of a client certificate
Replace the entire client certificate definition.
Request example
curl -s -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{
"name": "fully-updated-client-cert",
"value": "-----BEGIN CERTIFICATE-----\nMIIDXTCCAkWgAwIBAgIJAKoK/OvD...\n-----END CERTIFICATE-----"
}' \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates/cert-123e4567-e89b-12d3-a456-426614174000
Delete a client certificate
Request example
curl -s -X DELETE \
-H "Authorization: Bearer $TOKEN" \
-H "Accept: application/json" \
https://gateway.production.netfoundry.io/frontdoor/3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c/client-certificates/cert-123e4567-e89b-12d3-a456-426614174000
Response example
{
"id": "cert-123e4567-e89b-12d3-a456-426614174000",
"name": "api-client-prod",
"frontdoorId": "3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c",
"deletedAt": "2024-01-17T16:45:00Z",
"deletedBy": "user-456"
}
Generated Certificate Details
When creating certificates from CSRs, NetFoundry generates certificates with these characteristics:
- Issuer: C=US, ST=NC, L=Charlotte, O=NetFoundry, CN=NetFoundry
- Extended Key Usage: Server Authentication (id_kp_serverAuth)
- Key Usage:
- Digital Signature (enabled)
- Key Cert Sign (enabled)
- CRL Sign (enabled)
- Non Repudiation, Key Encipherment, Data Encipherment, Key Agreement, Encipher Only, Decipher Only (disabled)
Security Considerations
- Store private keys securely and never transmit them through the API
- Regularly rotate certificates before expiration
- Use strong key lengths (RSA 2048-bit minimum, prefer 4096-bit or ECDSA P-256/P-384)
- Validate certificate chains properly in your applications
- Monitor certificate expiration dates and set up renewal processes
Technical Notes
Paths
- GET /frontdoor/\{frontdoorId\}/client-certificates[?page=0&size=20&sort=name,asc]
- GET /frontdoor/\{frontdoorId\}/client-certificates/{id}
- POST /frontdoor/\{frontdoorId\}/client-certificates
- PATCH /frontdoor/\{frontdoorId\}/client-certificates/{id}
- PUT /frontdoor/\{frontdoorId\}/client-certificates/{id}
- DELETE /frontdoor/\{frontdoorId\}/client-certificates/{id}
Common errors
400 Bad Request (client error)
{
"error": "invalid_request",
"message": "Value for <property> must be of <type>"
}
Possible reasons include:
- Clock skew: If tokens seem instantly expired, check system time synchronization on the machine making requests.
- Token format: Authorization header must be exactly
Authorization: Bearer <token>with a space after Bearer orAuthorization: Basic <username:token>with a space after Basic and a color separator.
401 Unauthorized (missing/expired token)
{
"error": "unauthorized",
"message": "Bearer token is missing or invalid"
}
Possible reasons include:
- Clock skew: If tokens seem instantly expired, check system time synchronization on the machine making requests.
- Token format: Authorization header must be exactly
Authorization: Bearer <token>with a space after Bearer orAuthorization: Basic <username:token>with a space after Basic and a color separator.
403 Forbidden (not_authorized)
{
"error": "not_found",
"message": "Frontdoor 3d6d2b6e-6c7a-4a7f-8c3d-9a9d2e1f0b1c not found"
}
Possible reasons include:
- Invalid token: The token is not valid.
- The token does not grant access to the requested resource.
- Clock skew: If tokens seem instantly expired, check system time synchronization on the machine making requests.
- Token format: Authorization header must be exactly
Authorization: Bearer <token>with a space after Bearer orAuthorization: Basic <username:token>with a space after Basic and a color separator.