Skip to main content
App Connectors automate certificate issuance and renewal for applications running on the same host as the certforge-connector agent. The connector generates the private key and CSR locally, submits the CSR to CertForge for issuance through your configured CA and Domain Trust Policy, writes the signed cert and key to the paths you specify, then runs a reload command so the application picks up the new certificate — all without manual steps or cron jobs.

Prerequisites

  • certforge-connector v0.3.3 or later installed and enrolled — see certforge-connector
  • A Domain Trust Policy covering the domain(s) you want to manage — see Domain Trust Profiles
  • The application process running as, or readable by, a user the connector can write files as (usually root when the connector runs as root)

Step 1 — Register the application in CertForge

  1. Go to Integrations → App Connectors in CertForge.
  2. Click + Add Application.
  3. Fill in the fields:
  1. Click Save + Request Cert to save the app and immediately queue an issuance job. Use Save Only if you want to configure the app without triggering issuance yet (for example, to set up the file paths before the cert is needed).
No changes to certforge-connector.yaml are required — all app configuration is stored in CertForge and delivered to the connector with each job.

Step 2 — Approve the request (if required)

If the Domain Trust Policy requires human approval, the job enters Pending Approval and appears in the Approvals queue. An authorized approver must approve it before issuance proceeds. If the DTP is set to auto-approve, issuance starts immediately.

Step 3 — Verify delivery

On the next connector poll (within poll_interval, default 30 s), the connector:
  1. Picks up the cert_ready job
  2. Writes the private key to key_path (mode 0600)
  3. Writes the full cert bundle (leaf + chain) to cert_path (mode 0644)
  4. Writes the chain only to chain_path if configured
  5. Runs the reload command
  6. Marks the job done — the app’s status updates to Active with the cert expiry date
Verify the cert is live:
The connector log will show each step:

Application recipes

The + Add App form includes a Use a template dropdown that pre-fills the paths and reload command for common applications. Templates are a starting point — adjust paths to match your actual configuration before saving. The connector runs reload commands via sh -c, so pipes, &&, and environment variable substitution all work. If the command exits non-zero, the job is marked Failed in CertForge and an alert fires if configured.

nginx

cert.pem receives the full bundle (leaf + intermediates + root), which is what ssl_certificate expects. chain.pem receives the intermediates-only chain for apps that configure ssl_trusted_certificate separately. Adjust the directory to match your site’s ssl_certificate directive — a common alternative is /etc/nginx/certs/ or /etc/ssl/nginx/.

Apache (Debian / Ubuntu)

Point SSLCertificateFile at cert.pem and SSLCertificateKeyFile at key.pem. If using a separate chain file, set SSLCertificateChainFile to chain.pem (Apache 2.4.8+ supports the full chain in SSLCertificateFile so a separate chain file is often unnecessary).

Apache (RHEL / CentOS / AlmaLinux)

Same configuration directives as the Debian variant; only the service name (httpd vs apache2) and default config paths differ.

HAProxy

HAProxy reads the certificate and private key from a single combined file — it does not accept separate cert and key files. Use the reload command to concatenate them immediately after delivery: Point the bind line at bundle.pem:
The connector writes cert.pem and key.pem separately; the reload command concatenates them into bundle.pem before signalling HAProxy.

Postfix + Dovecot (mail server)

Both Postfix and Dovecot read the same cert and key files, so a single App Connector entry covers both. The reload command signals both services: In main.cf:
In dovecot.conf (or conf.d/10-ssl.conf):

PostgreSQL

PostgreSQL requires the key file to be owned by the postgres user and mode 0600. Run the connector as root (typical) and add an ownership step to the reload command:
In postgresql.conf:

MySQL / MariaDB

MySQL requires a restart (not reload) to pick up new TLS certificates. In my.cnf:
For MariaDB, use systemctl restart mariadb instead.

Envoy

Alternatively, if running under systemd: systemctl reload envoy.

Node.js / custom applications

For a Node.js HTTPS server or any custom application that reads cert files directly, use paths that match your application’s configuration and a reload command appropriate for how your process manager restarts the app: If the application watches for file changes and reloads automatically, the reload command can be omitted.

Managing App Connectors

From Integrations → App Connectors you can:

Renewal

CertForge schedules automatic renewal based on the cert expiry date and the renewal lead configured in the Domain Trust Policy (default 30 days). When the renewal window opens, CertForge queues a new pending_csr job and the connector picks it up on its next poll — no manual steps required. To trigger early renewal at any time, click Renew on the app in the CertForge UI.

How the private key is handled

The connector generates the RSA private key on the local host and writes it to key_path before submitting the CSR. This means:
  • The key never leaves the host
  • If the connector restarts between CSR submission and cert delivery, the key is already in place
  • When using an ACME CA (Let’s Encrypt, ZeroSSL), the CA generates its own key internally and returns it with the certificate — CertForge forwards this key to the connector, which writes it to key_path, ensuring the key on disk always matches the issued certificate

Troubleshooting

Job stuck in pending_csr — the connector isn’t running or can’t reach CertForge. Check journalctl -u certforge-connector and verify the enrollment credentials are valid. Reload command failed — the command exited non-zero. The error output is recorded in the job’s Error field in CertForge. Common causes: wrong path, missing permissions, or the application isn’t running. Fix the command under Edit, then click Renew. Key values mismatch on reload — if you see SSL_CTX_use_PrivateKey failed: key values mismatch in your application logs, the key on disk doesn’t match the cert. This can happen if the cert was written by a different process after the connector wrote the key. Click Renew to start a fresh issuance cycle — the connector will generate a new key and matching cert. App shows error status — check the Last Error field on the App Connectors page for the failure message, and the connector log for more context.