Certificates & TLS
Overview
coreX Platform provides a unified interface for managing TLS certificates and the cryptographic configuration that secures your traffic. Whether you are terminating TLS at the edge for public-facing services or locking down internal listeners with strict cipher baselines, coreX Platform brings certificate issuance, renewal, upload, and cipher policy under a single pane.
The TLS subsystem is composed of three cooperating layers:
- Certificate Store — holds all certificates available to coreX Platform, whether issued through Let’s Encrypt or uploaded manually as CRT + key pairs.
- Listener Binding — each HAProxy listener can be assigned a certificate and, independently, a cipher suite baseline.
- Cipher & HSTS Policy — predefined baselines (FIPS, FedRAMP, PCI, Modern, Custom) plus HSTS controls enforce a consistent security posture per listener.
All configuration is rendered into HAProxy runtime directives and validated before apply, so a misconfigured cipher list or a missing key will never make it to a running proxy.
Let’s Encrypt
coreX Platform integrates with the ACME protocol to issue and renew certificates from Let’s Encrypt without leaving the UI. Two challenge types are supported.
Certbot Standalone Issuance
For the HTTP-01 challenge, coreX Platform drives Certbot in standalone mode. Certbot briefly binds to the listener’s address (or a dedicated challenge port) to answer the ACME HTTP-01 request, proves control of the domain, and writes the resulting certificate into the coreX Platform certificate store.
The standalone flow is the simplest path when:
- The domain resolves to an IP coreX Platform can bind to
- Port 80 (or the challenge port) is reachable from the internet
- You want a single-command issuance with no external DNS API
DNS Challenge Plugins
When HTTP-01 is impractical — wildcard certificates, firewalled origins, or domains whose authoritative DNS is managed externally — coreX Platform can perform the DNS-01 challenge using Certbot DNS plugins. coreX Platform wraps the plugin invocation and credentials handling so you only need to supply provider-specific API credentials.
Supported DNS-01 providers include common Certbot DNS plugins for major DNS hosting providers, RFC 2136 dynamic DNS, acme-dns delegation, and others. The full list of supported providers is shown in the provider dropdown when configuring a DNS challenge.
DNS provider credentials are stored encrypted at rest in the coreX Platform secrets vault. They are only decrypted in-memory at issuance and renewal time and are never written to disk in plaintext.
When using a DNS challenge, coreX Platform sets the _acme-challenge TXT record through the provider API, polls for propagation, and cleans up the record after validation completes. Wildcard certificates (*.example.com) require the DNS-01 challenge and are fully supported.
Automatic Renewal
Every Let’s Encrypt certificate in the store carries a renewal policy. coreX Platform evaluates certificates daily and triggers renewal when a certificate is within 30 days of expiry (configurable per certificate). Renewal uses the same challenge type and credentials as the original issuance.
On success, the new certificate is hot-swapped into any listener currently bound to the old certificate — no reload of HAProxy is required for SNI-based listeners, and a graceful reload is performed automatically for non-SNI listeners.
ACME HTTP-01 Challenge via HAProxy
In addition to standalone mode, coreX Platform can serve the ACME HTTP-01 challenge token directly through HAProxy. This is the recommended mode for production listeners that already own port 80, because it avoids the brief port handoff required by standalone Certbot.
When enabled on a listener, coreX Platform injects an ACL into the HAProxy frontend that intercepts requests matching /.well-known/acme-challenge/* and serves the challenge file from a coreX-managed directory. All other traffic on that listener continues to be routed normally.
Even when your production traffic is HTTPS-only on 443, leave a listener on port 80 (or redirect 80 to 443) so HTTP-01 challenges and OCSP stapling fetches can complete.
Custom Certificates
Not every deployment can use Let’s Encrypt. Internal services, private CA environments, and certificates procured through an enterprise PKI all need to be imported directly. coreX Platform accepts any standard X.509 certificate in PEM format.
A custom certificate upload consists of:
- Certificate chain (CRT) — the server certificate followed by any intermediate certificates, concatenated in PEM format
- Private key — the matching RSA or EC private key in PEM format, unencrypted (PKCS#8 or PKCS#1). Encrypted keys are not supported because HAProxy must load the key without a passphrase prompt
- Optional metadata — a friendly name, expiry notification contacts, and tags
After upload, coreX Platform validates that the key matches the certificate modulus, parses the chain, and records the not-before / not-after dates so expiry warnings can be surfaced in the dashboard.
HAProxy cannot prompt for a passphrase at runtime, so coreX Platform rejects encrypted private keys. If your key is passphrase-protected, strip the passphrase with openssl rsa -in encrypted.key -out plain.key before uploading.
Cipher Suites
The cipher suite baseline defines which TLS protocol versions and cipher algorithms a listener will negotiate. coreX Platform ships five baselines, each curated for a specific compliance or modernity target.
Predefined Baselines
| Baseline | Target | Notes |
|---|---|---|
| FIPS | FIPS 140-2/140-3 validated algorithms only | Restricts to FIPS-approved ciphers and key exchanges |
| FedRAMP | FedRAMP High / Tailored control baselines | Aligns with FedRAMP TLS guidance, minimum TLS 1.2 |
| PCI | PCI DSS 4.x requirements | Enforces TLS 1.2+, disables weak ciphers (RC4, 3DES, NULL, export) |
| Modern | Forward secrecy and TLS 1.3 preference | Prefers TLS 1.3, requires ECDHE, drops legacy protocols |
| Custom | Operator-defined | Full control over min/max TLS version and cipher lists |
Predefined baselines are maintained by coreX Platform and updated as standards evolve. When a baseline is updated, listeners using it pick up the new policy on the next apply. Custom baselines are never modified automatically.
HSTS
HTTP Strict Transport Security (HSTS) instructs compliant browsers to always connect over HTTPS for a given domain. coreX Platform exposes HSTS as a per-listener toggle:
- Enable / disable — master switch
- Max-age — seconds the policy is cached by browsers. Default
31536000(one year) - Include subdomains — applies the policy to all subdomains
- Preload — signals readiness for inclusion in browser HSTS preload lists
Once a browser caches an HSTS policy, it will refuse plain HTTP connections to your domain until the max-age expires. Do not enable HSTS until you are confident all subdomains (if included) serve valid TLS.
Per-Listener Cipher Selection
A listener’s cipher baseline is selected on the listener’s TLS configuration panel, independent of its certificate. This separation lets you run a public listener on the Modern baseline while an internal compliance-scoped listener runs the FedRAMP baseline — both potentially using the same certificate.
SSL Labs Scanning
coreX Platform integrates the SSL Labs v4 API to assess the live TLS configuration of your certificates as deployed on your HAProxy listeners. From any certificate in the store, you can launch an SSL Labs assessment against the hostnames covered by that certificate and review the full report — grade, protocols, cipher suites, vulnerabilities, certificate chain, HSTS, HPKP, and client simulations — without leaving the UI.
How It Works
Certificates page
│ click "SSL Labs" on a certificate row
▼
┌──────────────────────────────────────────────────────────────┐
│ CertificateSslLabs page │
│ │
│ 1. Derive scannable hosts from the certificate's CN + SANs │
│ • wildcard prefixes (*.example.com) are stripped to the │
│ base domain (SSL Labs cannot scan a literal wildcard) │
│ • duplicates are removed, preserving order │
│ │
│ 2. User clicks "Scan" on a host │
│ • backend calls SSL Labs /analyze?host=…&publish=off │
│ • publish=off — your scan results are never made public │
│ • on the "email not registered" error, the backend │
│ auto-registers the user's email with SSL Labs and │
│ retries once │
│ │
│ 3. Frontend polls the scan until terminal │
│ • 5s interval during DNS resolution │
│ • 10s interval during IN_PROGRESS │
│ • stops at READY or ERROR (max 10 minutes) │
│ │
│ 4. Completed scan is stored in the database with the full │
│ SSL Labs Host report JSON for offline review │
└──────────────────────────────────────────────────────────────┘
User Profile Requirements
SSL Labs requires contact information for the account that submits scans. Before you can run a scan, your user profile must include:
- Email — used as the SSL Labs account identifier
- First name and Last name
- Organization
If any field is missing, the scan button is disabled and a banner directs you to complete your profile via the user menu. The backend auto-registers your email with SSL Labs on the first scan — you do not need to create an SSL Labs account manually.
When SSL Labs returns a “not registered” error, the backend registers the user’s email, first name, last name, and organization with SSL Labs and retries the scan automatically. You only need to complete your profile once.
Grades
When a scan completes (status READY), coreX Platform extracts the best grade across all endpoints in the report. Grades follow the SSL Labs scale:
| Grade | Meaning |
|---|---|
| A+ | Excellent — no issues, HSTS enabled, strong config |
| A | No issues found |
| A- | Minor configuration issues |
| B | Notable issues (e.g. SHA1 signatures, old protocols) |
| C | Multiple issues |
| D–F | Serious vulnerabilities |
| T | Trust issues (certificate not trusted by browsers) |
The grade is displayed inline in the scan history table and color-coded (green for A, amber for B, orange for C/D, red for E/F/T).
Scan Retention
Completed scans (READY or ERROR) are retained per host, with older scans pruned automatically. The retention limit is controlled by the ssllabs_max_scans_per_host setting:
- Default: 5 completed scans per host
- Range: 1–100
- Pruning: only completed scans are pruned; in-progress scans are never deleted
- Configuration: editable by an admin from the SSL Labs page settings, or via the API (
PUT /certificates/{cert_id}/ssllabs/settings)
Permissions
| Role | View scans | Start scans | Delete scans | Edit retention |
|---|---|---|---|---|
| Admin | Yes | Yes (if profile complete) | Yes | Yes |
| Operator | Yes | Yes (if profile complete) | No | No |
| Viewer | Yes | No | No | No |
Report Contents
Clicking the eye icon on a completed scan opens the full SSL Labs report in a modal. The report includes:
| Section | What it shows |
|---|---|
| Endpoints | IP address, grade, status, and per-endpoint details |
| Protocols | TLS versions supported (1.0, 1.1, 1.2, 1.3) with security assessment |
| Cipher Suites | Negotiated cipher lists per TLS version, ordered by preference |
| Named Groups | Key exchange groups (e.g. X25519, P-256) for TLS 1.3 |
| Vulnerabilities | Heartbleed, POODLE, CRIME, BREACH, DROWN, Freak, Logjam, RC4, HSTS, HPKP, forward secrecy |
| Server Configuration | DH param strength, key sizes, OCSP stapling, ALPN, session resumption |
| Certificate Chain | Full chain validation, signature algorithms, key types/sizes, SANs, trust paths |
| Certificate Transparency | SCT (Signed Certificate Timestamp) presence and count |
| HSTS | max-age, include subdomains, preload status |
| HPKP | Public key pinning policy (if configured) |
| Client Simulations | Handshake results for common browsers and clients |
| HTTP Transaction | Response headers, compression, redirect behavior |
SSL Labs assesses the TLS configuration as served by your HAProxy listener on the public internet — including the cipher baseline, HSTS, and protocol versions you configured. A certificate with an A+ grade may still score lower if the listener’s cipher baseline allows weak ciphers. Review the Cipher Suites section to align your listener config with your target grade.
Step-by-Step: Issue a Let’s Encrypt Certificate
- Navigate to Certificates in the sidebar
- Click Issue Certificate and select Let’s Encrypt
- Enter the domain(s), one per line:
app.example.com api.example.com - Choose HTTP-01 via HAProxy and select the listener that owns port 80
- Confirm the ACME account (first issuance registers a new account)
- Click Issue — coreX Platform writes the challenge token, lets Let’s Encrypt validate, and installs the certificate
- Navigate to Listeners, open the HTTPS listener, and select the new certificate in the TLS > Certificate dropdown
- Toggle Enable SSL, set the port to
443, and click Save - Click Apply Changes
After binding, run openssl s_client -connect app.example.com:443 -servername app.example.com and confirm the full chain is served.
Step-by-Step: Upload a Custom Certificate
- Prepare your files in PEM format:
-----BEGIN CERTIFICATE----- (server certificate) -----END CERTIFICATE----- -----BEGIN CERTIFICATE----- (intermediate certificate) -----END CERTIFICATE----- - In Certificates, click Upload Certificate
- Enter a friendly name (e.g.
internal-app (Private CA)) - Drag the CRT file into the Certificate Chain field
- Drag the private key into the Private Key field
- Add metadata (tags, expiry-notification email) if desired
- Click Upload — coreX Platform validates the key/cert pair and stores the certificate
- Assign to a listener via Listeners > TLS > Certificate dropdown
Step-by-Step: Configure a Cipher Suite Baseline
- Open the HTTPS listener in Listeners
- Scroll to TLS Configuration and expand it
- In the Cipher Suite Baseline dropdown, choose FedRAMP
- Toggle HSTS on. Set max-age to
31536000, check Include subdomains - Review the effective policy preview
- Click Save, then Apply Changes
Step-by-Step: Run an SSL Labs Scan
- Navigate to Certificates in the sidebar
- Click SSL Labs on the certificate row you want to assess
- The SSL Labs page shows the certificate’s CN and SANs, plus the list of scannable hosts (wildcard prefixes stripped)
- If you see a “complete your profile” banner, update your user profile (email, first name, last name, organization) via the user menu, then return to this page
- Click Scan on the host you want to assess
- The scan appears in the history table with status
DNS→IN_PROGRESS→READY(orERROR). The page polls automatically — no manual refresh needed - Once the scan reaches
READY, click the eye icon to open the full report - Review the grade, vulnerabilities, protocols, and cipher suites in the report modal
- If the grade is below your target, adjust the listener’s cipher baseline and HSTS settings, apply the config, and re-scan to confirm the improvement
SSL Labs connects to your HAProxy listener from the internet. The host must be publicly resolvable and reachable on port 443 (or 80 for HTTP-01). Internal/private certificates with no public-facing listener cannot be scanned.
Verification
1. Confirm the certificate and chain:
openssl s_client -connect app.example.com:443 -servername app.example.com -showcerts < /dev/null
2. Confirm the negotiated cipher and protocol:
openssl s_client -connect app.example.com:443 -servername app.example.com < /dev/null 2>/dev/null | grep -E 'Protocol|Cipher'
3. Confirm HSTS:
curl -sI https://app.example.com | grep -i strict-transport-security
4. Confirm weak ciphers are rejected:
openssl s_client -connect app.example.com:443 -servername app.example.com -tls1_1 < /dev/null 2>&1 | grep -i 'protocol\|alert\|handshake'
A baseline enforcing TLS 1.2+ should refuse the TLS 1.0/1.1 handshake.
5. Confirm the SSL Labs grade:
Run a scan from the Certificates > SSL Labs page (see Step-by-Step: Run an SSL Labs Scan), or check the public report at https://www.ssllabs.com/ssltest/analyze.html?d=app.example.com. Target an A or A+ grade for production listeners.
Next Steps
- Listeners — Configure listener bindings and SNI
- Security Rules — Layer access control on top of TLS
- Metrics & Logging — Monitor TLS handshake stats