Skip to main content

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

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 or Authorization: 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 or Authorization: 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 or Authorization: Basic <username:token> with a space after Basic and a color separator.