> ## Documentation Index
> Fetch the complete documentation index at: https://docs.certgov.app/llms.txt
> Use this file to discover all available pages before exploring further.

# Certificate Lifecycle

> How certificate requests flow through CertForge — from request to installation — and how CAs, Trust Profiles, and renewal work together.

# Certificate Lifecycle

Every certificate that CertForge manages passes through the same pipeline, regardless of how it was requested. Understanding this flow makes it easier to configure Trust Profiles, troubleshoot rejections, and design your PKI strategy.

## End-to-end flow

```mermaid theme={null}
flowchart TD
    classDef src  fill:#1D6FA4,stroke:#155B87,color:#fff,font-weight:600
    classDef pol  fill:#F8FAFB,stroke:#A0AEBB,color:#2A3548
    classDef gov  fill:#C07810,stroke:#9A6008,color:#fff
    classDef ok   fill:#0D8C52,stroke:#0A7040,color:#fff,font-weight:600
    classDef ca   fill:#0D8C52,stroke:#0A7040,color:#fff
    classDef dns  fill:#D97706,stroke:#B45309,color:#fff
    classDef del  fill:#5E4EC0,stroke:#4A3AAC,color:#fff
    classDef no   fill:#CC2A2A,stroke:#AA2020,color:#fff

    A1["ACME Client\ncert-manager · any ACME client"]:::src
    A2["Enrollment API\nREST · API key"]:::src
    A3["Dashboard\nManual CSR upload"]:::src
    A4["Device Connector\nAudioCodes · F5 · custom drivers"]:::src

    DTP{"DTP Policy Match\nMaps domain → Trust Profile\nSets CA · validity · governance"}:::pol

    A1 & A2 & A3 & A4 --> DTP
    DTP -->|no matching profile| NODTP["Rejected\nNo policy for this domain"]:::no

    DTP --> AUTOQ

    subgraph GOV ["Governance"]
        direction TB
        AUTOQ{"Auto-approve\nenabled?"}:::pol
        QUEUE["Approval queue\nAlert sent: Webex · Slack · email"]:::gov
        APPRV["Approved ✓"]:::ok
        REJV["Rejected\nRequester notified"]:::no

        AUTOQ -->|"Yes — 0 s delay"| APPRV
        AUTOQ -->|No| QUEUE
        QUEUE --> HVOTE{"Approver\ndecision"}:::pol
        HVOTE -->|Approve| APPRV
        HVOTE -->|Reject| REJV
    end

    APPRV --> CASEL{"CA Type\nConfigured in\nTrust Profile"}:::pol

    subgraph ISS ["Certificate Issuance"]
        direction TB
        ACMECA["ACME CA\nZeroSSL · Let's Encrypt\nDigiCert ACME"]:::ca
        INTCA["Internal CA\nCertForge built-in PKI"]:::ca
        PRIVCA["Private Connector CA\nOn-prem agent signs locally"]:::ca

        CASEL -->|ACME CA| ACMECA
        CASEL -->|Internal CA| INTCA
        CASEL -->|Connector CA| PRIVCA

        ACMECA --> DNSQ{"DNS-01\nChallenge Type"}:::pol
        DNSQ -->|"Automated\nCloudflare · RFC2136"| AUTODNS["DNS updated automatically\nACME validates in seconds"]:::ca
        DNSQ -->|"Manual"| MANDNS["Admin sets TXT record\nConfirm in dashboard\nACME then proceeds"]:::dns

        AUTODNS --> ISSUED
        MANDNS  --> ISSUED
        INTCA   --> ISSUED
        PRIVCA  --> ISSUED
        ISSUED["Certificate issued\nLeaf cert + chain PEM"]:::ok
    end

    subgraph DEL ["Delivery & Storage"]
        direction TB
        DA["ACME finalize response\ncert-manager → Kubernetes Secret"]:::del
        DB["API response body\nCaller stores the cert"]:::del
        DC["Dashboard download\nPEM in browser · Tracked in inventory"]:::del
        DD["Device installation\nConnector pushes key + leaf + chain\ndirectly onto the device"]:::del
    end

    ISSUED -->|ACME| DA
    ISSUED -->|API| DB
    ISSUED -->|Dashboard| DC
    ISSUED -->|Connector| DD
```

***

## Request protocols

All four entry points converge at the same policy and governance layer. What differs is how the request arrives and where the certificate ends up.

<CardGroup cols={2}>
  <Card title="ACME Client" icon="globe">
    **Spec:** RFC 8555 — standard ACME protocol

    **Common use:** cert-manager (Kubernetes), Certbot, any ACME client

    **Auth:** ACME account key; directory at `/acme/directory`

    **CSR:** Generated by the client — CertForge validates the domain against a Trust Profile

    **Delivery:** ACME finalize response; cert-manager stores automatically in a Kubernetes Secret
  </Card>

  <Card title="Enrollment API" icon="code">
    **Spec:** CertForge REST API — `POST /v1/enroll`

    **Common use:** CI/CD pipelines, scripts, internal tooling

    **Auth:** API key (Bearer token) or mTLS client certificate

    **CSR:** Provided by the caller in the request body (PEM)

    **Delivery:** Certificate returned in the JSON response body; caller stores it
  </Card>

  <Card title="Dashboard" icon="browser">
    **Spec:** CertForge web UI — Issuance → Enroll

    **Common use:** One-off certificates, testing, manually managed services

    **Auth:** CertForge user login (SSO or local)

    **CSR:** Paste an existing CSR or generate one via the wizard

    **Delivery:** Downloadable PEM in the browser; tracked in Inventory
  </Card>

  <Card title="Device Connector" icon="server">
    **Spec:** CertForge connector agent — polls the API every 30 seconds

    **Common use:** AudioCodes SBC, F5 BIG-IP, network appliances

    **Auth:** Connector API key (per deployment)

    **CSR:** Device generates its own CSR, or the connector generates a key + CSR externally when ACME DNS SANs are required

    **DNS challenge:** Handled server-side — manual confirmation in the dashboard or automated via a DNS provider

    **Delivery:** Connector installs the private key, leaf cert, and intermediate chain directly onto the device via its management API
  </Card>
</CardGroup>

***

## Governance

Every request — regardless of source — is evaluated by the Trust Profile's governance rules before a certificate is issued.

| Mode                | Behaviour                                                                                                                                        |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Auto-approve**    | Request is approved immediately (0 s). The approval record is still created for audit purposes.                                                  |
| **Manual approval** | Request enters the approval queue. Approvers are notified by email, Slack, or Webex. The request waits until approved, rejected, or auto-voided. |

See [Approvals](/concepts/approvals) for escalation timers, peer approval requirements, and audit details.

***

## Certificate Authorities

CertForge supports three types of CA. The Trust Profile determines which one signs each certificate.

### ACME CA (ZeroSSL, Let's Encrypt, DigiCert)

CertForge acts as an ACME client and obtains publicly-trusted certificates on your behalf using DNS-01 challenge validation.

**DNS challenge modes:**

| Mode          | How it works                                                                                                                                    |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **Automated** | CertForge updates the `_acme-challenge` TXT record via Cloudflare, Route 53, or RFC2136. Validation completes in seconds.                       |
| **Manual**    | CertForge shows the TXT record value. An admin sets it in their DNS provider and clicks "Confirm DNS Ready" in the dashboard or Approvals page. |

Configure DNS providers in **Admin → DNS Accounts**.

**Rate limits (Let's Encrypt):**

* 50 certificates per registered domain per week
* 5 duplicate certificates per week

CertForge tracks issued certificates and will warn before you hit a rate limit.

### Internal CA

CertForge signs the certificate directly using a CA keypair stored in the platform. No external calls. Issuance is instant.

**Root CA** — self-signed; best for private PKI entirely under your control. Distribute the root certificate to all machines that need to trust it.

**Intermediate CA** — signed by another CA (internal or external). Keeps your root CA offline. Create one by generating a CSR in CertForge and uploading the signed certificate.

**Key storage:** Private keys are encrypted at rest with AES-256-GCM. In multi-node deployments the encrypted keys live in the database and are decrypted in memory when needed. The encryption key is set via `CERTFORGE_STORAGE_KEY` — keep this secret.

### Private Connector CA

The connector agent running on-premises signs CSRs using a locally held CA keypair (or HashiCorp Vault PKI). The private key never leaves the on-prem environment. CertForge audits and records the issuance; the signed certificate is returned through the connector API.

**Use for:** air-gapped networks, regulated environments, or any scenario where private keys must not leave your infrastructure.

### Choosing a CA type

| Scenario                              | Recommended CA                      |
| ------------------------------------- | ----------------------------------- |
| Internet-facing web service           | ACME (Let's Encrypt or ZeroSSL)     |
| Internal microservices / mTLS         | Internal CA                         |
| IoT device or client auth             | Internal CA with `clientAuth` EKU   |
| Air-gapped or regulated network       | Internal CA or Private Connector CA |
| Kubernetes workloads via cert-manager | ACME CA via CertForge ACME endpoint |

***

## Certificate chain

CertForge always delivers the full chain: the leaf certificate plus any intermediate CA certificates. Serving only the leaf cert causes browser "Not secure" warnings even when the leaf itself is valid — the client cannot build a trust path to the root.

For device connector installations, the connector pushes the leaf cert and the chain separately so the device can serve them correctly during TLS handshakes.

***

## Auto-renewal

Certificates issued by CertForge are automatically renewed before expiry. The renewal window is set per Issuance Profile (**Renew Before Expiry**, in days). If not set, CertForge defaults to 30 days, capped at ⅓ of the certificate's validity period.

Auto-renewal can be disabled per certificate in **Inventory** (useful for certs that are intentionally short-lived or managed externally). Discovered certificates — from CT Log scans, TLS scans, or CA Connector sync — are monitored for expiry but are not renewed by CertForge.

| Indicator              | Meaning                                                       |
| ---------------------- | ------------------------------------------------------------- |
| ↻ Auto-renew (green)   | CertForge will renew this certificate automatically           |
| ↻ Manual renew (amber) | Auto-renew is off; someone must renew it manually             |
| *(blank)*              | Discovered certificate — renewal is managed outside CertForge |

***

## Revocation

CertForge supports CRL (Certificate Revocation List) distribution for internal CAs. The CRL endpoint is available at `/crl/{ca-id}/crl.pem`. Revoked certificates are excluded from inventory counts and flagged in compliance reports.
