-
-
Notifications
You must be signed in to change notification settings - Fork 96
API
The CertMate Client Certificates API provides REST endpoints for complete certificate management with authentication, rate limiting, and audit logging.
Base URL: http://localhost:5000/api
Authentication: Bearer Token (required on all endpoints)
Content-Type: application/json
All API endpoints require Bearer token authentication.
Authorization: Bearer YOUR_TOKEN
curl -X GET http://localhost:5000/api/client-certs \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json"API endpoints have rate limits to prevent abuse:
| Endpoint | Limit | Per |
|---|---|---|
| General | 100 | minute |
| Create Certificate | 30 | minute |
| Batch Operations | 10 | minute |
| OCSP Status | 200 | minute |
| CRL Download | 60 | minute |
When rate limited, you'll receive:
HTTP 429 Too Many Requests
{
"error": "Rate limit exceeded",
"message": "Too many requests. Please try again later.",
"retry_after": 60
}
Endpoint: POST /client-certs/create
Create a new client certificate.
Request:
{
"common_name": "user@example.com",
"email": "user@example.com",
"organization": "ACME Corp",
"organizational_unit": "Engineering",
"cert_usage": "api-mtls",
"days_valid": 365,
"generate_key": true,
"notes": "Production certificate"
}Parameters:
-
common_name(required) - Certificate subject -
email(optional) - Email address -
organization(optional) - Organization name -
organizational_unit(optional) - Department name -
cert_usage(optional) - Usage type:api-mtls,vpn, or custom -
days_valid(optional) - Validity in days (default: 365) -
generate_key(optional) - Generate private key (default: true) -
notes(optional) - Additional notes
Response (201 Created):
{
"identifier": "cert-abc123",
"common_name": "user@example.com",
"serial_number": "12345678901234567890",
"created_at": "2024-10-30T18:00:00Z",
"expires_at": "2025-10-30T18:00:00Z",
"cert_usage": "api-mtls",
"status": "active"
}Example:
curl -X POST http://localhost:5000/api/client-certs/create \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"common_name": "user@example.com",
"email": "user@example.com",
"organization": "ACME Corp",
"cert_usage": "api-mtls",
"days_valid": 365
}'Endpoint: GET /client-certs
List all client certificates with optional filtering.
Query Parameters:
-
usage(optional) - Filter by usage type (e.g.,api-mtls) -
revoked(optional) - Filter by status (trueorfalse) -
search(optional) - Search in common name
Response (200 OK):
{
"certificates": [{
"identifier": "cert-001",
"common_name": "user1@example.com",
"organization": "ACME Corp",
"cert_usage": "api-mtls",
"created_at": "2024-10-30T18:00:00Z",
"expires_at": "2025-10-30T18:00:00Z",
"revoked": false,
"status": "active"
},
{
"identifier": "cert-002",
"common_name": "user2@example.com",
"organization": "ACME Corp",
"cert_usage": "vpn",
"created_at": "2024-10-29T18:00:00Z",
"expires_at": "2025-10-29T18:00:00Z",
"revoked": true,
"status": "revoked"
}
],
"total": 2
}Examples:
# List all certificates
curl http://localhost:5000/api/client-certs \
-H "Authorization: Bearer TOKEN"
# Filter by usage type
curl "http://localhost:5000/api/client-certs?usage=api-mtls" \
-H "Authorization: Bearer TOKEN"
# List only revoked
curl "http://localhost:5000/api/client-certs?revoked=true" \
-H "Authorization: Bearer TOKEN"
# Search by common name
curl "http://localhost:5000/api/client-certs?search=user1" \
-H "Authorization: Bearer TOKEN"Endpoint: GET /client-certs/<identifier>
Get complete metadata for a certificate.
Response (200 OK):
{
"type": "client_certificate",
"identifier": "cert-001",
"common_name": "user@example.com",
"email": "user@example.com",
"organization": "ACME Corp",
"organizational_unit": "Engineering",
"serial_number": "12345678901234567890",
"created_at": "2024-10-30T18:00:00Z",
"expires_at": "2025-10-30T18:00:00Z",
"cert_usage": "api-mtls",
"notes": "Production certificate",
"revocation": {
"revoked": false,
"revoked_at": null,
"reason_revoked": null
},
"renewal": {
"renewal_enabled": true,
"renewal_threshold_days": 30
}
}Example:
curl http://localhost:5000/api/client-certs/cert-001 \
-H "Authorization: Bearer TOKEN"Endpoint: GET /client-certs/<identifier>/download/<type>
Download certificate, private key, or CSR file.
Parameters:
-
identifier- Certificate ID -
type- File type:crt,key, orcsr
Response (200 OK):
- Content-Type:
application/octet-stream - File attachment with proper naming
Examples:
# Download certificate
curl http://localhost:5000/api/client-certs/cert-001/download/crt \
-H "Authorization: Bearer TOKEN" \
-o certificate.crt
# Download private key
curl http://localhost:5000/api/client-certs/cert-001/download/key \
-H "Authorization: Bearer TOKEN" \
-o private.key
# Download CSR
curl http://localhost:5000/api/client-certs/cert-001/download/csr \
-H "Authorization: Bearer TOKEN" \
-o request.csrEndpoint: POST /client-certs/<identifier>/revoke
Revoke a certificate with optional reason.
Request (optional):
{
"reason": "compromised"
}Response (200 OK):
{
"message": "Certificate revoked: cert-001",
"revoked_at": "2024-10-30T18:15:00Z",
"reason": "compromised"
}Example:
curl -X POST http://localhost:5000/api/client-certs/cert-001/revoke \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "compromised"
}'Endpoint: POST /client-certs/<identifier>/renew
Renew a certificate (same CN, new serial).
Response (201 Created):
{
"identifier": "cert-001-renewed",
"common_name": "user@example.com",
"serial_number": "98765432109876543210",
"created_at": "2024-10-30T18:20:00Z",
"expires_at": "2025-10-30T18:20:00Z",
"status": "active"
}Example:
curl -X POST http://localhost:5000/api/client-certs/cert-001/renew \
-H "Authorization: Bearer TOKEN"Endpoint: GET /client-certs/stats
Get certificate usage statistics.
Response (200 OK):
{
"total": 100,
"active": 85,
"revoked": 15,
"expiring_soon": 8,
"by_usage": {
"api-mtls": 60,
"vpn": 35,
"other": 5
},
"created_count": 100,
"renewal_enabled": 92
}Example:
curl http://localhost:5000/api/client-certs/stats \
-H "Authorization: Bearer TOKEN"Endpoint: POST /client-certs/batch
Create multiple certificates from CSV data in single request.
Request:
{
"headers": ["common_name", "email", "organization", "cert_usage", "days_valid"],
"rows": [["user1@example.com", "user1@example.com", "ACME Corp", "api-mtls", "365"],
["user2@example.com", "user2@example.com", "ACME Corp", "vpn", "365"],
["user3@example.com", "user3@example.com", "ACME Corp", "api-mtls", "365"]
]
}Response (201 Created):
{
"total": 3,
"successful": 3,
"failed": 0,
"errors": [],
"certificates": [{
"identifier": "cert-batch-001",
"common_name": "user1@example.com"
},
{
"identifier": "cert-batch-002",
"common_name": "user2@example.com"
},
{
"identifier": "cert-batch-003",
"common_name": "user3@example.com"
}
]
}Example:
curl -X POST http://localhost:5000/api/client-certs/batch \
-H "Authorization: Bearer TOKEN" \
-H "Content-Type: application/json" \
-d '{
"headers": ["common_name", "email", "organization"],
"rows": [["user1@example.com", "user1@example.com", "ACME Corp"],
["user2@example.com", "user2@example.com", "ACME Corp"]
]
}'Endpoint: GET /ocsp/status/<serial_number>
Query certificate status via OCSP.
Response (200 OK):
{
"response_status": "successful",
"certificate_status": "good|revoked|unknown",
"certificate_serial": 12345678,
"this_update": "2024-10-30T18:00:00Z",
"next_update": null,
"responder_name": "CertMate OCSP Responder"
}Example:
curl http://localhost:5000/api/ocsp/status/12345678 \
-H "Authorization: Bearer TOKEN"Endpoint: GET /crl/download/<format_type>
Download Certificate Revocation List.
Parameters:
-
format_type-pem,der, orinfo
Response:
- For
pemandder: File attachment - For
info: JSON with CRL metadata
Examples:
# Download CRL in PEM format
curl http://localhost:5000/api/crl/download/pem \
-H "Authorization: Bearer TOKEN" \
-o ca.crl
# Download CRL in DER format
curl http://localhost:5000/api/crl/download/der \
-H "Authorization: Bearer TOKEN" \
-o ca.crl
# Get CRL info
curl http://localhost:5000/api/crl/download/info \
-H "Authorization: Bearer TOKEN"CRL Info Response:
{
"status": "available",
"issuer": "CN=CertMate CA, O=CertMate",
"last_update": "2024-10-30T18:00:00Z",
"next_update": "2024-10-31T18:00:00Z",
"revoked_count": 5,
"revoked_serials": [12345678,
87654321
]
}Endpoint: GET /certificates/<domain>/download
Download certificate files for a specific domain. By default, this endpoint returns a ZIP archive containing all certificate components. A specific file can be requested using the file query parameter. JSON mode is also available for automation that wants all PEMs in one response.
Parameters:
-
domain(Path) - The domain name associated with the certificate. -
file(Query, Optional) - Specify a single file to download.- Supported values:
fullchain.pem,privkey.pem,combined.pem
- Supported values:
-
format(Query, Optional) - Set tojsonto return all certificate files in a JSON object.
Response (200 OK):
-
Default:
application/zip(A ZIP file containing all PEM files) -
With
fileparam:application/x-pem-file(The raw content of the requested file) -
With
format=json:application/jsonwithdomain,cert_pem,chain_pem,fullchain_pem, andprivate_key_pem
The JSON form is the preferred automation shape for Ansible, Salt, or any other client that wants to write PEM files directly.
Examples:
# Download all files as a ZIP archive
curl http://localhost:5000/api/certificates/example.com/download \
-H "Authorization: Bearer TOKEN" \
-o example_com_bundle.zip
# Download only the fullchain.pem file
curl "http://localhost:5000/api/certificates/example.com/download?file=fullchain.pem" \
-H "Authorization: Bearer TOKEN" \
-o fullchain.pem
# Download only the private key
curl "http://localhost:5000/api/certificates/example.com/download?file=privkey.pem" \
-H "Authorization: Bearer TOKEN" \
-o privkey.pem
# Download the full certificate bundle as JSON
curl "http://localhost:5000/api/certificates/example.com/download?format=json" \
-H "Authorization: Bearer TOKEN" \
-o example_com_bundle.json
{
"error": "Error message",
"code": "ERROR_CODE",
"status": 400
}| Code | Meaning | Example |
|---|---|---|
| 200 | Success | Certificate listed |
| 201 | Created | Certificate created |
| 400 | Bad Request | Missing required field |
| 401 | Unauthorized | Invalid/missing token |
| 404 | Not Found | Certificate doesn't exist |
| 429 | Too Many Requests | Rate limit exceeded |
| 500 | Server Error | Internal error |
| 503 | Service Unavailable | OCSP/CRL not available |
curl http://localhost:5000/api/client-certs/invalid-id \
-H "Authorization: Bearer TOKEN"
# Response
{
"error": "Certificate not found: invalid-id",
"code": 404,
"status": 404
}All API requests are logged for audit purposes.
- Timestamp
- Operation (create, revoke, download, etc.)
- Resource ID
- User/IP address
- Status (success/failure)
- Response time
- Error details (if any)
tail -f logs/audit/certificate_audit.logEach entry is JSON formatted for easy parsing:
{
"timestamp": "2024-10-30T18:00:00Z",
"operation": "create",
"resource_type": "certificate",
"resource_id": "cert-001",
"status": "success",
"user": "admin@example.com",
"ip_address": "192.168.1.1",
"details": {
"common_name": "user@example.com",
"usage": "api-mtls"
},
"error": null
}For API client authentication via mutual TLS.
cert_usage: "api-mtls"
For VPN client authentication.
cert_usage: "vpn"
You can use any custom usage type string:
cert_usage: "custom-application"
- Protect Your Token
- Keep tokens secret
- Rotate tokens regularly
- Use HTTPS in production
- Certificate Management
- Enable auto-renewal
- Monitor expiration dates
- Review audit logs regularly
- Revoke compromised certs immediately
- Rate Limiting
- Respect rate limits
- Implement exponential backoff
- Batch operations when possible
- Use Batch Operations
- Import multiple certs at once
- Reduces API calls
- Better error reporting
- Filter Results
- Use query parameters
- Filter by usage or status
- Reduces data transfer
- Cache When Appropriate
- Cache certificate metadata
- Refresh periodically
- Check expiration locally
CertMate · README · Releases · Report a bug · Request a feature
Getting started
Core configuration
Client certificates
Reference
Project