Certs
Provisioning is a process of configuration of an IoT platform in which system operator creates and sets-up different entities used in the platform - users, groups, channels and clients.
Certs Service
Issues certificates for clients. Certs service can create certificates to be used when SuperMQ is deployed to support mTLS.
Certs service will create certificate for valid client ID if valid user token is passed and user is owner of the provided client ID.
Certificate service can create certificates in PKI mode - where certificates issued by PKI, when you deploy OpenBao as PKI certificate management cert service will proxy requests to OpenBao previously checking access rights and saving info on successfully created certificate.
PKI mode
When AM_CERTS_OPENBAO_HOST is set, the certs service will issue certificates using OpenBao API.
First you'll need to set up OpenBao.
OpenBao is an open-source fork of HashiCorp Vault, providing the same PKI functionality. To learn more about PKI engines, see the HashiCorp Vault PKI documentation which applies to OpenBao as well.
To setup certs service with OpenBao following environment variables must be set:
AM_CERTS_OPENBAO_HOST=http://certs-openbao:8200
AM_CERTS_OPENBAO_PKI_PATH=<openbao_pki_path>
AM_CERTS_OPENBAO_ROLE=<openbao_role>
AM_CERTS_OPENBAO_APP_ROLE=<app_role_id>
AM_CERTS_OPENBAO_APP_SECRET=<app_secret_id>
Make sure you have an already running instance of SuperMQ, OpenBao and Certs service.
To start SuperMQ run:
make run_stable args="-d"
To start the certs service with OpenBao run:
make run_addons certs up args="-d"
The OpenBao container will automatically initialize and configure itself on first run:
-
Initialization: If this is the first time running, OpenBao will be initialized with 5 key shares and a threshold of 3 keys required to unseal. The initialization data (unseal keys and root token) will be saved in
/opt/openbao/data/init.jsonwithin the container. -
Unsealing: OpenBao will automatically unseal itself using the stored keys or the keys provided via environment variables (
AM_CERTS_OPENBAO_UNSEAL_KEY_1,AM_CERTS_OPENBAO_UNSEAL_KEY_2,AM_CERTS_OPENBAO_UNSEAL_KEY_3). -
PKI Configuration: The entrypoint script will:
- Enable the AppRole authentication method
- Enable PKI secrets engines (root CA at
pkiand intermediate CA atpki_int) - Generate a root CA certificate based on environment variables
- Create an intermediate CA and sign it with the root CA
- Configure a PKI role for certificate issuance
- Set up AppRole authentication with the specified role ID and secret ID
Important Notes:
- On first run, the unseal keys and root token are generated and stored in the container volume.
- For production deployments, you should pre-configure
AM_CERTS_OPENBAO_UNSEAL_KEY_1,AM_CERTS_OPENBAO_UNSEAL_KEY_2,AM_CERTS_OPENBAO_UNSEAL_KEY_3, andAM_CERTS_OPENBAO_ROOT_TOKENin your.envfile. - The AppRole credentials (
AM_CERTS_OPENBAO_APP_ROLEandAM_CERTS_OPENBAO_APP_SECRET) should be set and kept secure. - Secret IDs have a configurable TTL (default: 87600h / ~10 years). Monitor and rotate them before expiration.
Provision a client:
supermq-cli provision test
To stop certs service run:
make run_addons certs down
Note: Stopping the certs service will also stop the OpenBao container. All data (certificates, keys, configuration) is persisted in Docker volumes and will be available when you restart the service.
This step can be skipped if you already have a client ID.
API Structure
The Certs service exposes both authenticated and public endpoints:
Authenticated Endpoints (require user authentication)
All authenticated endpoints are prefixed with /{domainID}/certs/:
- POST
/{domainID}/certs/issue/{entityID}- Issue a new certificate for an entity - PATCH
/{domainID}/certs/{id}/renew- Renew an existing certificate by serial number - PATCH
/{domainID}/certs/{id}/revoke- Revoke a certificate by serial number - DELETE
/{domainID}/certs/{entityID}/delete- Revoke all certificates for an entity - GET
/{domainID}/certs/- List certificates (supports filtering by entity ID, pagination) - GET
/{domainID}/certs/{id}- View certificate details by serial number - POST
/{domainID}/certs/csrs/{entityID}- Issue certificate from a Certificate Signing Request (CSR)
Public Endpoints
- POST
/certs/ocsp- OCSP (Online Certificate Status Protocol) responder for certificate validation - GET
/certs/crl- Generate and retrieve Certificate Revocation List (CRL) - GET
/certs/view-ca- View CA certificate chain details - GET
/certs/download-ca- Download CA certificate chain as a ZIP file
Internal Endpoints (require secret authentication)
- POST
/certs/csrs/{entityID}- Internal endpoint for issuing certificates from CSR (authenticated via bearer token with service secret)
Health and Metrics
- GET
/health- Service health check endpoint - GET
/metrics- Prometheus metrics endpoint
Usage Examples
Request Parameters
Query Parameters for List Endpoints:
offset- Pagination offset (default: 0)limit- Number of items per page (default: 10)entity_id- Filter certificates by entity IDttl- Time to live for certificates (e.g., "8760h" for 1 year)
Issue Certificate Request Body:
{
"ttl": "8760h",
"ip_addrs": ["192.168.1.1"],
"options": {
"common_name": "example.com",
"organization": "Example Org",
"organizational_unit": "IT",
"country": "US",
"province": "California",
"locality": "San Francisco",
"street_address": "123 Main St",
"postal_code": "94102",
"dns_names": ["example.com", "www.example.com"],
"email_addresses": ["[email protected]"]
}
}
Issue from CSR Request Body:
{
"csr": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----"
}
1. Issue a certificate
supermq-cli certs issue <client_id> <user_auth_token> [--ttl=8760h]
API Endpoint: POST /{domainID}/certs/issue/{entityID}
Response:
{
"serial_number": "6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
"expiry_time": "2024-10-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866",
"revoked": false,
"issued": true
}
For example:
supermq-cli certs issue f13f0f30-f923-4504-8a7a-6aa45bcb4866 $USER_TOKEN
{
"serial_number": "6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1",
"certificate": "-----BEGIN CERTIFICATE-----\nMIIEATCCAumgAwIBAgIUbzXVnUedI1AI9zETgiLkyObPLMEwDQYJKoZIhvcNAQEL\nBQAwLjEsMCoGA1UEAxMjbWFpbmZsdXguY29tIEludGVybWVkaWF0ZSBBdXRob3Jp\ndHkwHhcNMjMwOTE0MTEwOTI5WhcNMjMxMDE0MTEwOTU4WjAvMS0wKwYDVQQDEyRi\nYTFmMmIxNi01MjA3LTQ2MDgtYTRkZS01ZmFiZmI4NjI3YzIwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQC9RxcHaTzn18vBdWWZf37K8Grc5dLW/m8vhwOJ\n8oe3iPUiE7xFijIXKw236R1NBh8fLT6/2lia/p4acZtls3yFRphooDwP7S2OiJRI\ngGb/r0SYmSnQKjHbdbixauNECGk1TDNSGvmpNSzvAZvYSJAvd5ZpYf/8Db9IBW0N\nvbI7TfIJHay8vC/0rn1BsmC3x+3nEm0W+Z5udC/UT4+pQn7QWrBsxjVT4r5WY0SQ\nkVhA9Wo+Wpzmy1CMC4X6yLmiIHmfRFlktDxKgPpyy/3zhAE2CkBpT7JEQ723Mv+m\n37oM2EJog+tgIZMExxDbw3Epqgo07B9DWpSZSBHCISeN/TzdAgMBAAGjggEUMIIB\nEDAOBgNVHQ8BAf8EBAMCA6gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\nMB0GA1UdDgQWBBTAoqWVu8ctNmw5CKUBxsUKVDX+PDAfBgNVHSMEGDAWgBS7dmaT\nr5vJJPtV5dReawbYKhxzYzA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAKGH2h0\ndHA6Ly92YXVsdDo4MjAwL3YxL3BraV9pbnQvY2EwLwYDVR0RBCgwJoIkYmExZjJi\nMTYtNTIwNy00NjA4LWE0ZGUtNWZhYmZiODYyN2MyMDEGA1UdHwQqMCgwJqAkoCKG\nIGh0dHA6Ly92YXVsdDo4MjAwL3YxL3BraV9pbnQvY3JsMA0GCSqGSIb3DQEBCwUA\nA4IBAQCKMmDzyWWmuSJPh3O9hppRJ6mkX9gut4jP2rwowNv7haj3iu+hR8+GnTix\nu5oy3bZdmRryhhW0XyJsbCKO/z+wsY/RfVgMxF/c1cbmEzki804+AB4a4yNhQD6g\noEEQBD58b6mFi/vPCRiGZmmo5TqMlA37jBRSVnKO/CoH1CAvjqmfWdSoO4IC4uD4\nJev+QNr9wlOimYcA/usmo7rmqz7IB9R/Laxcdkq9iZelKly/jhftEbKgGf2NR/d7\nEKVONjCEp6fL2iBaQSA/899oJJ7QPqE5X821HhBlXKvNmZnYRyUmAS2h1jnxtovp\nsNGcLFRgIAFdaGl1172C7mBZF4C3\n-----END CERTIFICATE-----",
"key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEAvUcXB2k859fLwXVlmX9+yvBq3OXS1v5vL4cDifKHt4j1IhO8\nRYoyFysNt+kdTQYfHy0+v9pYmv6eGnGbZbN8hUaYaKA8D+0tjoiUSIBm/69EmJkp\n0Cox23W4sWrjRAhpNUwzUhr5qTUs7wGb2EiQL3eWaWH//A2/SAVtDb2yO03yCR2s\nvLwv9K59QbJgt8ft5xJtFvmebnQv1E+PqUJ+0FqwbMY1U+K+VmNEkJFYQPVqPlqc\n5stQjAuF+si5oiB5n0RZZLQ8SoD6csv984QBNgpAaU+yREO9tzL/pt+6DNhCaIPr\nYCGTBMcQ28NxKaoKNOwfQ1qUmUgRwiEnjf083QIDAQABAoIBADKd7kSnGgiOJwkn\nUfJIrCmtPYaxVz7zb9xv6LxdRXoJgDSKvpCCMn8LnnGOP623c18tBFjeFU/tw24i\n74G1DBnAFUX1g9pmfQZe8/injePWhSuh2hK3FfowcyHPCdPJxAjixd6xJA7iD5Aj\nCABA934aJvkrof9P1dV2zgEct6sv6GPwUgSZxTYVNyU93T/pmvodvpNTYd3uk71A\nLCC5Ojv2gEOkHUWHhMntz7bl6wcH/atk//uYoYxcjZ811tL7/7xwUbyRxFD/b6kP\niptdoXBv27eWWKOtFMgF9iNkhefSKkmHZZWIL1J5CFE8fUdddeLoOa0e7a9vhYS9\n5TMzC2kCgYEA+TJf60QP3rjEgm6bJw1h48ffkPkZTsdp083GoJB77yXUH7m9Wt9g\nlYSALN+67fnkXPEe/C9SInMDRMp9VoswOHeJCFbCNdx5Klv8KKuMZMk0yCZifhx6\nBl7IsVlmlzq3EhK1ZjOVWMxvwS7MlMpPAcsc8DGhwhv9sXW3k2nMevsCgYEAwnHx\nheuaYgE/HrE/GEcPNAwy/uyBb8wxoKavl8OKEyPH+LK8powo9xss8zi+yEYHfSQP\nnJ45Rdz/HGl5QIwD4CjA3Vrm0sTMh094DPp9KhxcOwIhK/IvUJ0deKwHRWek/+c8\nwbD6HfX2Vtu5RU9z2KS7VtazjU5TkIbKP29LoAcCgYAUKAv0JrQ16rISbsnj9cQm\nPYOK4Ws3oQ+hTzKyyB0OMfwfeNGlKQ5R6b7IYmxnVWAwWFyOP3GgUbdA+DP9LRMA\nbkLKRuI8oxG16GzUCVQ4zsGTMu+ijcEdBMus9LNEpj4qmxLLKn75CMg9UwC/REHx\nvjEgCJOx9LungAMSTGt6wwKBgQCXvSGUt6pvhreCNSGeyX1EyaxWIaxU2U11J/7p\neQ/cJdUc8Cal9cTWKV/nokXHtlaLwsNoHlVlfrOasXiM9XbkzAjN9O0iV6+gfFSc\nFDHu1djnt565U7K2vxVLoTu/XsV1ajeQk5JsJRCK8cbgHsOxscP8XWobAJ/XrkhQ\nPoMOqwKBgD8goECBKj+SofUfqKCnGf3E2MWF3kTZMfPaBcuV8TaGMWRRljMmK8YT\npew6IIkAFrsIaXxQsym2JQ+j/L2AoxQkzlf2VF4SaBfUUByT3NijSBpD/d3xRlWA\n7UUO0d72YFnPTqY98Ch/fbKnaCRL/Usv8c9nCt5IdmnihYnuvxYT\n-----END RSA PRIVATE KEY-----",
"expiry_time": "2023-10-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866"
"revoked": false
}
2. Retrieve a certificate
supermq-cli certs get [<cert_serial> | client <client_id>] <user_auth_token>
API Endpoint: GET /{domainID}/certs/{serial_number}
For example:
supermq-cli certs get 6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1 $USER_TOKEN
Response:
{
"serial_number": "6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1",
"certificate": "-----BEGIN CERTIFICATE-----\nMIIEATCCAumgAwIBAgIUbzXVnUedI1AI9zETgiLkyObPLMEwDQYJKoZIhvcNAQEL\nBQAwLjEsMCoGA1UEAxMjbWFpbmZsdXguY29tIEludGVybWVkaWF0ZSBBdXRob3Jp\ndHkwHhcNMjMwOTE0MTEwOTI5WhcNMjMxMDE0MTEwOTU4WjAvMS0wKwYDVQQDEyRi\nYTFmMmIxNi01MjA3LTQ2MDgtYTRkZS01ZmFiZmI4NjI3YzIwggEiMA0GCSqGSIb3\nDQEBAQUAA4IBDwAwggEKAoIBAQC9RxcHaTzn18vBdWWZf37K8Grc5dLW/m8vhwOJ\n8oe3iPUiE7xFijIXKw236R1NBh8fLT6/2lia/p4acZtls3yFRphooDwP7S2OiJRI\ngGb/r0SYmSnQKjHbdbixauNECGk1TDNSGvmpNSzvAZvYSJAvd5ZpYf/8Db9IBW0N\nvbI7TfIJHay8vC/0rn1BsmC3x+3nEm0W+Z5udC/UT4+pQn7QWrBsxjVT4r5WY0SQ\nkVhA9Wo+Wpzmy1CMC4X6yLmiIHmfRFlktDxKgPpyy/3zhAE2CkBpT7JEQ723Mv+m\n37oM2EJog+tgIZMExxDbw3Epqgo07B9DWpSZSBHCISeN/TzdAgMBAAGjggEUMIIB\nEDAOBgNVHQ8BAf8EBAMCA6gwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC\nMB0GA1UdDgQWBBTAoqWVu8ctNmw5CKUBxsUKVDX+PDAfBgNVHSMEGDAWgBS7dmaT\nr5vJJPtV5dReawbYKhxzYzA7BggrBgEFBQcBAQQvMC0wKwYIKwYBBQUHMAKGH2h0\ndHA6Ly92YXVsdDo4MjAwL3YxL3BraV9pbnQvY2EwLwYDVR0RBCgwJoIkYmExZjJi\nMTYtNTIwNy00NjA4LWE0ZGUtNWZhYmZiODYyN2MyMDEGA1UdHwQqMCgwJqAkoCKG\nIGh0dHA6Ly92YXVsdDo4MjAwL3YxL3BraV9pbnQvY3JsMA0GCSqGSIb3DQEBCwUA\nA4IBAQCKMmDzyWWmuSJPh3O9hppRJ6mkX9gut4jP2rwowNv7haj3iu+hR8+GnTix\nu5oy3bZdmRryhhW0XyJsbCKO/z+wsY/RfVgMxF/c1cbmEzki804+AB4a4yNhQD6g\noEEQBD58b6mFi/vPCRiGZmmo5TqMlA37jBRSVnKO/CoH1CAvjqmfWdSoO4IC4uD4\nJev+QNr9wlOimYcA/usmo7rmqz7IB9R/Laxcdkq9iZelKly/jhftEbKgGf2NR/d7\nEKVONjCEp6fL2iBaQSA/899oJJ7QPqE5X821HhBlXKvNmZnYRyUmAS2h1jnxtovp\nsNGcLFRgIAFdaGl1172C7mBZF4C3\n-----END CERTIFICATE-----",
"key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
"expiry_time": "2023-10-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866",
"revoked": false
}
List certificates by entity:
supermq-cli certs get client f13f0f30-f923-4504-8a7a-6aa45bcb4866 $USER_TOKEN
API Endpoint: GET /{domainID}/certs?entity_id={client_id}&offset=0&limit=10
{
"certificates": [
{
"serial_number": "6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1",
"expiry_time": "2023-10-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866",
"revoked": false
}
],
"total": 1,
"offset": 0,
"limit": 10
}
3. Revoke a certificate
supermq-cli certs revoke <client_id> <user_auth_token>
API Endpoint: PATCH /{domainID}/certs/{serial_number}/revoke
For example:
supermq-cli certs revoke f13f0f30-f923-4504-8a7a-6aa45bcb4866 $USER_TOKEN
Response:
{
"revoked": true
}
Or via curl:
curl -X PATCH \
http://localhost:9010/{domainID}/certs/6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1/revoke \
-H "Authorization: Bearer $USER_TOKEN"
Note: The service will revoke the certificate in OpenBao, making it invalid for future use.
4. Renew a certificate
API Endpoint: PATCH /{domainID}/certs/{serial_number}/renew
Renew an existing certificate before it expires. The renewed certificate will have:
- A new serial number
- Extended validity period (default: 30 days from renewal time)
- Same subject and key parameters as the original
Important:
- Cannot renew revoked certificates
- The original certificate remains valid until its expiration
curl -X PATCH \
http://localhost:9010/{domainID}/certs/{serial_number}/renew \
-H "Authorization: Bearer $USER_TOKEN"
Response:
{
"renewed": true,
"certificate": {
"serial_number": "7a:45:e6:ae:58:ae:34:61:19:f8:42:24:93:33:f5:d9:f7:d0:3d:d2",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"key": "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
"expiry_time": "2024-11-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866",
"revoked": false
}
}
5. Delete all certificates for an entity
API Endpoint: DELETE /{domainID}/certs/{entityID}/delete
Revoke all certificates associated with a specific entity. This operation:
- Revokes all certificates in OpenBao
- Removes the entity-to-certificate mappings from the database
- Is irreversible
curl -X DELETE \
http://localhost:9010/{domainID}/certs/{entityID}/delete \
-H "Authorization: Bearer $USER_TOKEN"
Response:
{
"deleted": true
}
Error Response (no certificates found):
{
"deleted": false,
"error": "no certificates found for entity ID: f13f0f30-f923-4504-8a7a-6aa45bcb4866"
}
6. View CA Certificate Chain
API Endpoint: GET /certs/view-ca
Retrieve the CA certificate chain details (intermediate CA certificate).
curl -X GET http://localhost:9010/certs/view-ca
Response:
{
"serial_number": "1a:2b:3c:4d:5e:6f:7a:8b:9c:0d:1e:2f:3a:4b:5c:6d",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"expiry_time": "2025-07-14T11:09:58Z",
"entity_id": "Abstract Machines Certificate Authority Intermediate",
"revoked": false
}
7. Download CA Certificate Chain
API Endpoint: GET /certs/download-ca
Download the complete CA certificate chain (root + intermediate) as a ZIP file containing ca.crt.
curl -X GET http://localhost:9010/certs/download-ca -o ca.zip
Response Headers:
Content-Type: application/zip
Content-Disposition: attachment; filename=ca.zip
The downloaded ZIP file contains the CA certificate chain that can be used to verify certificates issued by this service.
8. OCSP Request
API Endpoint: POST /certs/ocsp
Check certificate status using OCSP protocol.
Using OCSP DER format:
openssl ocsp -issuer ca.crt -serial {serial_number} -reqout ocsp_request.der
curl -X POST \
http://localhost:9010/certs/ocsp \
-H "Content-Type: application/ocsp-request" \
--data-binary @ocsp_request.der
Using JSON format:
curl -X POST \
http://localhost:9010/certs/ocsp \
-H "Content-Type: application/json" \
-d '{
"serial_number": "6f:35:d5:9d:47:9d:23:50:08:f7:31:13:82:22:e4:c8:e6:cf:2c:c1"
}'
9. Generate CRL (Certificate Revocation List)
API Endpoint: GET /certs/crl
Retrieve the current certificate revocation list in PEM format. The CRL contains all certificates that have been revoked and is signed by the CA.
curl -X GET http://localhost:9010/certs/crl -o crl.pem
Response:
{
"crl_bytes": "-----BEGIN X509 CRL-----\n...\n-----END X509 CRL-----"
}
The CRL can be used by clients to check if a certificate has been revoked.
10. Issue Certificate from CSR
API Endpoint: POST /{domainID}/certs/csrs/{entityID}?ttl=8760h
Issue a certificate from a Certificate Signing Request (CSR). This allows you to:
- Use your own private key (not generated by the service)
- Control the certificate request parameters
- Maintain key ownership on your side
curl -X POST \
http://localhost:9010/{domainID}/certs/csrs/{entityID}?ttl=8760h \
-H "Authorization: Bearer $USER_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"csr": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----"
}'
Response:
{
"serial_number": "8b:56:f7:bf:69:bf:45:72:2a:g9:53:35:a4:44:g6:ea:g8:e1:4e:e3",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"expiry_time": "2024-10-14T11:09:58Z",
"entity_id": "f13f0f30-f923-4504-8a7a-6aa45bcb4866",
"revoked": false
}
Note: The key field is not returned since you generated and retained the private key when creating the CSR.
Generating a CSR:
# Generate private key
openssl genrsa -out private.key 2048
# Generate CSR
openssl req -new -key private.key -out request.csr \
-subj "/CN=example.com/O=Example Org/C=US"
# Read CSR content
cat request.csr
Certificate Validity Periods
The Certs service uses the following default validity periods:
- Root CA Certificate: 365 days (8760 hours)
- Intermediate CA Certificate: 90 days (2160 hours)
- Client Certificates: 30 days (720 hours) by default, configurable via TTL parameter
- Certificate Renewal: 30 days (720 hours) from renewal time
You can override the default TTL when issuing certificates by providing the ttl parameter (e.g., "8760h" for 1 year).
Error Handling
The service returns standard HTTP status codes and JSON error responses:
Common Error Responses:
{
"error": "failed to create certificate: certificate request failed"
}
Status Codes:
200 OK- Request successful400 Bad Request- Invalid request parameters or malformed entity401 Unauthorized- Missing or invalid authentication token404 Not Found- Certificate or entity not found409 Conflict- Entity already exists500 Internal Server Error- Server-side error
Service-Specific Errors:
ErrCertRevoked- Attempt to renew a revoked certificateErrCertExpired- Certificate expired before renewalErrNotFound- Entity or certificate not foundErrMalformedEntity- Invalid request formatErrFailedCertCreation- OpenBao certificate generation failedErrInvalidIP- Invalid IP address in request
Environment Variables Reference
The following environment variables configure the OpenBao integration:
# Certs Service Configuration
AM_CERTS_LOG_LEVEL=debug
AM_CERTS_HTTP_HOST=certs
AM_CERTS_HTTP_PORT=9010
AM_CERTS_GRPC_HOST=certs
AM_CERTS_GRPC_PORT=7012
AM_CERTS_SECRET=12345678 # Secret for internal endpoint authentication
# Database Configuration
AM_CERTS_DB_HOST=certs-db
AM_CERTS_DB_PORT=5432
AM_CERTS_DB_USER=absmach
AM_CERTS_DB_PASS=absmach
AM_CERTS_DB=certs
AM_CERTS_DB_SSL_MODE=disable
# OpenBao server configuration
AM_CERTS_OPENBAO_HOST=http://certs-openbao:8200
AM_CERTS_OPENBAO_NAMESPACE= # Optional namespace
AM_CERTS_OPENBAO_PKI_PATH=pki_int # PKI mount path
# AppRole authentication
AM_CERTS_OPENBAO_ROLE=absmach # PKI role name
AM_CERTS_OPENBAO_APP_ROLE=absmach # AppRole role ID
AM_CERTS_OPENBAO_APP_SECRET=absmach # AppRole secret ID
AM_CERTS_OPENBAO_SECRET_ID_TTL=87600h # Secret ID TTL
# CA certificate parameters
AM_CERTS_OPENBAO_PKI_CA_CN=Abstract Machines Certificate Authority
AM_CERTS_OPENBAO_PKI_CA_OU=Abstract Machines
AM_CERTS_OPENBAO_PKI_CA_O=AbstractMachines
AM_CERTS_OPENBAO_PKI_CA_C=FRANCE
AM_CERTS_OPENBAO_PKI_CA_L=PARIS
AM_CERTS_OPENBAO_PKI_CA_ST=PARIS
AM_CERTS_OPENBAO_PKI_CA_ADDR=5 Av. Anatole
AM_CERTS_OPENBAO_PKI_CA_PO=75007
AM_CERTS_OPENBAO_PKI_CA_DNS_NAMES=localhost
AM_CERTS_OPENBAO_PKI_CA_IP_ADDRESSES=127.0.0.1,::1
AM_CERTS_OPENBAO_PKI_CA_URI_SANS=
[email protected]
# Unseal keys (for production)
AM_CERTS_OPENBAO_UNSEAL_KEY_1=
AM_CERTS_OPENBAO_UNSEAL_KEY_2=
AM_CERTS_OPENBAO_UNSEAL_KEY_3=
AM_CERTS_OPENBAO_ROOT_TOKEN=
Internal Service Integration
The Certs service provides an internal endpoint for service-to-service certificate issuance. This endpoint bypasses user authentication and uses a shared secret instead.
Internal CSR Endpoint:
API Endpoint: POST /certs/csrs/{entityID}?ttl=8760h
Authentication: Bearer token with AM_CERTS_SECRET value
curl -X POST \
http://localhost:9010/certs/csrs/{entityID}?ttl=8760h \
-H "Authorization: Bearer 12345678" \
-H "Content-Type: application/json" \
-d '{
"csr": "-----BEGIN CERTIFICATE REQUEST-----\n...\n-----END CERTIFICATE REQUEST-----"
}'
Response:
{
"serial_number": "9c:67:h8:cg:7a:cg:56:83:3b:ha:64:46:b5:55:h7:fb:ha:f2:5f:f4",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"expiry_time": "2024-10-14T11:09:58Z",
"entity_id": "service-client-id",
"revoked": false
}
Use Cases:
- Automated certificate provisioning for microservices
- IoT device onboarding without user interaction
- System-level certificate management
- Integration with external provisioning systems
Security Considerations:
- The
AM_CERTS_SECRETshould be kept secure and rotated regularly - Internal endpoints should only be accessible within the private network
- Use network policies to restrict access to trusted services only
For more information about the Certification service API, please check out the API documentation.