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:

  1. Certificate Store — holds all certificates available to coreX Platform, whether issued through Let’s Encrypt or uploaded manually as CRT + key pairs.
  2. Listener Binding — each HAProxy listener can be assigned a certificate and, independently, a cipher suite baseline.
  3. 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.

Credential storage

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.

Keep port 80 open

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.

Unencrypted keys only

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

BaselineTargetNotes
FIPSFIPS 140-2/140-3 validated algorithms onlyRestricts to FIPS-approved ciphers and key exchanges
FedRAMPFedRAMP High / Tailored control baselinesAligns with FedRAMP TLS guidance, minimum TLS 1.2
PCIPCI DSS 4.x requirementsEnforces TLS 1.2+, disables weak ciphers (RC4, 3DES, NULL, export)
ModernForward secrecy and TLS 1.3 preferencePrefers TLS 1.3, requires ECDHE, drops legacy protocols
CustomOperator-definedFull control over min/max TLS version and cipher lists
Baseline updates

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
HSTS is sticky

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.

Registration is automatic

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:

GradeMeaning
A+Excellent — no issues, HSTS enabled, strong config
ANo issues found
A-Minor configuration issues
BNotable issues (e.g. SHA1 signatures, old protocols)
CMultiple issues
D–FSerious vulnerabilities
TTrust 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

RoleView scansStart scansDelete scansEdit retention
AdminYesYes (if profile complete)YesYes
OperatorYesYes (if profile complete)NoNo
ViewerYesNoNoNo

Report Contents

Clicking the eye icon on a completed scan opens the full SSL Labs report in a modal. The report includes:

SectionWhat it shows
EndpointsIP address, grade, status, and per-endpoint details
ProtocolsTLS versions supported (1.0, 1.1, 1.2, 1.3) with security assessment
Cipher SuitesNegotiated cipher lists per TLS version, ordered by preference
Named GroupsKey exchange groups (e.g. X25519, P-256) for TLS 1.3
VulnerabilitiesHeartbleed, POODLE, CRIME, BREACH, DROWN, Freak, Logjam, RC4, HSTS, HPKP, forward secrecy
Server ConfigurationDH param strength, key sizes, OCSP stapling, ALPN, session resumption
Certificate ChainFull chain validation, signature algorithms, key types/sizes, SANs, trust paths
Certificate TransparencySCT (Signed Certificate Timestamp) presence and count
HSTSmax-age, include subdomains, preload status
HPKPPublic key pinning policy (if configured)
Client SimulationsHandshake results for common browsers and clients
HTTP TransactionResponse headers, compression, redirect behavior
Scans reflect the live listener, not the stored cert

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

  1. Navigate to Certificates in the sidebar
  2. Click Issue Certificate and select Let’s Encrypt
  3. Enter the domain(s), one per line:
    app.example.com
    api.example.com
  4. Choose HTTP-01 via HAProxy and select the listener that owns port 80
  5. Confirm the ACME account (first issuance registers a new account)
  6. Click Issue — coreX Platform writes the challenge token, lets Let’s Encrypt validate, and installs the certificate
  7. Navigate to Listeners, open the HTTPS listener, and select the new certificate in the TLS > Certificate dropdown
  8. Toggle Enable SSL, set the port to 443, and click Save
  9. Click Apply Changes
Verify the chain

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

  1. Prepare your files in PEM format:
    -----BEGIN CERTIFICATE-----
    (server certificate)
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    (intermediate certificate)
    -----END CERTIFICATE-----
  2. In Certificates, click Upload Certificate
  3. Enter a friendly name (e.g. internal-app (Private CA))
  4. Drag the CRT file into the Certificate Chain field
  5. Drag the private key into the Private Key field
  6. Add metadata (tags, expiry-notification email) if desired
  7. Click Upload — coreX Platform validates the key/cert pair and stores the certificate
  8. Assign to a listener via Listeners > TLS > Certificate dropdown

Step-by-Step: Configure a Cipher Suite Baseline

  1. Open the HTTPS listener in Listeners
  2. Scroll to TLS Configuration and expand it
  3. In the Cipher Suite Baseline dropdown, choose FedRAMP
  4. Toggle HSTS on. Set max-age to 31536000, check Include subdomains
  5. Review the effective policy preview
  6. Click Save, then Apply Changes

Step-by-Step: Run an SSL Labs Scan

  1. Navigate to Certificates in the sidebar
  2. Click SSL Labs on the certificate row you want to assess
  3. The SSL Labs page shows the certificate’s CN and SANs, plus the list of scannable hosts (wildcard prefixes stripped)
  4. 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
  5. Click Scan on the host you want to assess
  6. The scan appears in the history table with status DNSIN_PROGRESSREADY (or ERROR). The page polls automatically — no manual refresh needed
  7. Once the scan reaches READY, click the eye icon to open the full report
  8. Review the grade, vulnerabilities, protocols, and cipher suites in the report modal
  9. 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
Scans hit the public internet

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