PKI and Certificate Authority
The pesitwizard-pki module provides a built-in certificate authority (CA) for generating and managing TLS certificates.
Overview
┌─────────────────────────────────────────────────────────────┐
│ Root CA (Root CA) │
│ Validity: 10 years │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Intermediate CA (Signing CA) │
│ Validity: 5 years │
└─────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Server │ │ Client │ │ Client │
│ TLS │ │ Partner1 │ │ Partner2 │
│ 1 year │ │ 1 year │ │ 1 year │
└──────────┘ └──────────┘ └──────────┘Configuration
CA Initialization
On first startup, the admin console can initialize the CA:
yaml
pesitwizard:
pki:
enabled: true
ca:
# Root CA information
root-dn: "CN=PeSIT Wizard Root CA,O=MyCompany,C=FR"
root-validity-years: 10
# Intermediate CA information
signing-dn: "CN=PeSIT Wizard Signing CA,O=MyCompany,C=FR"
signing-validity-years: 5
# Key storage
keystore:
path: /app/pki/ca-keystore.p12
password: ${CA_KEYSTORE_PASSWORD}Environment Variables
| Variable | Description |
|---|---|
CA_KEYSTORE_PASSWORD | CA keystore password |
PESITWIZARD_PKI_ENABLED | Enable/disable PKI |
Management via the Console
Certificates Tab
The admin console provides a "Certificates" tab per cluster:

Features:
- View all issued certificates
- Generate new certificates
- Revoke certificates
- Download in various formats
Server Certificate Generation
- Go to Clusters > [Cluster] > Certificates
- Click New certificate
- Select Type: Server
- Fill in:
- Common Name (CN):
pesitwizard.example.com - SAN: Alternative DNS names and IPs
- Validity: Duration in days
- Common Name (CN):
- Click Generate
Client Certificate Generation (partner)
- Go to Clusters > [Cluster] > Partners
- Select a partner
- Click Generate certificate
- Download the PKCS12 with password
REST API
Generate a Server Certificate
bash
POST /api/v1/clusters/{clusterId}/certificates/server
Content-Type: application/json
{
"commonName": "pesitwizard.example.com",
"subjectAlternativeNames": [
"DNS:pesitwizard.example.com",
"DNS:*.pesitwizard.example.com",
"IP:192.168.1.100"
],
"validityDays": 365
}Response:
json
{
"id": "cert-123",
"commonName": "pesitwizard.example.com",
"serialNumber": "1234567890",
"notBefore": "2024-01-15T00:00:00Z",
"notAfter": "2025-01-15T00:00:00Z",
"fingerprint": "SHA256:abc123..."
}Download a Certificate
bash
# PEM format (certificate only)
GET /api/v1/clusters/{clusterId}/certificates/{certId}/download?format=pem
# PKCS12 format (certificate + private key)
GET /api/v1/clusters/{clusterId}/certificates/{certId}/download?format=p12&password=secret
# JKS format (Java KeyStore)
GET /api/v1/clusters/{clusterId}/certificates/{certId}/download?format=jks&password=secretRevoke a Certificate
bash
POST /api/v1/clusters/{clusterId}/certificates/{certId}/revoke
Content-Type: application/json
{
"reason": "KEY_COMPROMISE"
}Programmatic Usage
CertificateAuthorityService
java
@Autowired
private CertificateAuthorityService caService;
// Generate a server certificate
X509Certificate serverCert = caService.generateServerCertificate(
"pesitwizard.example.com",
List.of("DNS:*.example.com", "IP:10.0.0.1"),
365
);
// Generate a client certificate
X509Certificate clientCert = caService.generateClientCertificate(
"CN=Partner BANK01,O=Bank,C=FR",
365
);
// Export as PKCS12
byte[] p12 = caService.exportPkcs12(clientCert, privateKey, "password");Export Formats
| Format | Extension | Content | Usage |
|---|---|---|---|
| PEM | .pem, .crt | Certificate only (Base64) | Linux, Nginx |
| PKCS12 | .p12, .pfx | Certificate + private key | Windows, Java |
| JKS | .jks | Java KeyStore | Java applications |
| DER | .der, .cer | Binary certificate | Windows |
Automatic Renewal
The system can automatically renew certificates before expiration:
yaml
pesitwizard:
pki:
auto-renewal:
enabled: true
# Renew 30 days before expiration
days-before-expiry: 30
# Daily check
check-cron: "0 0 2 * * *"Notifications
Configure expiration alerts:
yaml
pesitwizard:
pki:
notifications:
# Alert 60, 30, 7 days before expiration
warning-days: [60, 30, 7]
# Webhook or email
webhook-url: https://alerts.example.com/pkiSecurity
Best Practices
- Protect the CA keystore with a strong password
- Regularly back up the CA keystore
- Use an intermediate CA for signing (not the root)
- Immediately revoke compromised certificates
- Enable audit logging to trace operations
PKI Operations Audit
All PKI operations are traced:
json
{
"timestamp": "2024-01-15T10:30:00Z",
"action": "CERTIFICATE_GENERATED",
"actor": "admin@example.com",
"details": {
"type": "SERVER",
"commonName": "pesitwizard.example.com",
"serialNumber": "1234567890",
"validityDays": 365
}
}TLS Integration
PeSIT Server Configuration
Once the certificate is generated, configure the server:
yaml
pesitwizard:
server:
ssl:
enabled: true
key-store: /app/certs/server.p12
key-store-password: ${SSL_KEYSTORE_PASSWORD}
key-store-type: PKCS12
# Mutual client authentication (mTLS)
client-auth: need
trust-store: /app/certs/truststore.p12
trust-store-password: ${SSL_TRUSTSTORE_PASSWORD}Distribution to Partners
- Export the root CA certificate (without private key)
- Send it to partners so they can add it to their truststore
- Generate one client certificate per partner
- Send the PKCS12 securely