Open-Source Wikis

/

Consul

/

Systems

/

Connect CA

hashicorp/consul

Connect CA

Consul's service mesh issues short-lived SPIFFE certificates to every mesh-enabled workload. The PKI machinery — root CA selection, root rotation, leaf issuance, cross-signing during provider migration — is collectively the Connect CA.

Purpose

Each mesh service has a SPIFFE URI like spiffe://<trust-domain>/ns/<ns>/dc/<dc>/svc/<service>. Envoy proxies present a leaf cert with that URI, and peers verify it against the root CA(s). Consul:

  • Picks a CA provider (built-in, Vault, AWS PCA).
  • Maintains the active root and any cross-signed predecessor roots in the state store.
  • Issues short-lived (default ~72h) leaf certs to local proxies on demand.
  • Rotates roots on schedule or on operator command.
  • Replicates roots to all DCs over WAN federation and to peers via peering.

Directory layout

agent/connect/
├── ca/                       # CA provider implementations (consul, vault, aws-pca, ...)
├── csr.go, sni.go, uri.go    # SPIFFE URI parsing + CSR helpers
├── parsing.go, testing.go
agent/leafcert/               # Leaf cert cache: the agent-side of "issue and renew"
agent/consul/
├── connect_ca_endpoint.go    # RPC endpoint for CA root reads + leaf signing
├── leader_connect_ca.go      # Leader-only loop: rotation, cross-sign, intermediate refresh (58 KB)
├── leader_connect_ca_ce.go   # CE-specific bits
├── leader_connect.go         # Connect bootstrap on leadership change
├── server_connect.go         # Server-side init for connect features
├── state/connect_ca.go       # MemDB tables: connect-ca-config, roots, leaf logs, builtin
├── state/connect_ca_events.go # Streaming events on root changes
connect/                       # Public Go module: small Connect helper library for client apps
proto-public/pbconnectca/     # gRPC public API (SignCertificate, WatchRoots)

Key abstractions

Type File Purpose
ca.Provider agent/connect/ca/provider.go Interface every CA backend implements
ca.ConsulProvider agent/connect/ca/provider_consul.go Built-in self-hosted CA backed by connect-ca-builtin table
ca.VaultProvider agent/connect/ca/provider_vault.go Vault PKI backend
ca.AWSProvider agent/connect/ca/provider_aws.go AWS Private Certificate Authority backend
CARoot / IndexedCARoots agent/structs/connect_ca.go The persisted root certificate model
CASignRequest / IssuedCert agent/structs/connect.go Leaf signing RPC contract
leafcert.Manager agent/leafcert/leafcert.go Per-agent cache of leaf certs with proactive renewal
caManager agent/consul/leader_connect_ca.go Leader-side CA orchestrator: provider lifecycle, rotation, cross-sign

How it works

sequenceDiagram
    participant Leader as Server (leader)
    participant Provider as ca.Provider
    participant State as state store
    participant Agent as Client agent
    participant Leaf as leafcert.Manager
    participant Proxy as Envoy

    Note over Leader,Provider: Bootstrap on leadership
    Leader->>Provider: GenerateRoot()
    Provider-->>Leader: root + signing key
    Leader->>State: Apply CARootSet (Raft)

    Note over Agent,Leaf: First proxy registration
    Proxy->>Agent: xDS request (needs cert)
    Agent->>Leaf: GetLeaf(serviceID)
    Leaf->>Leader: ConnectCA.Sign(CSR)
    Leader->>Provider: Sign(CSR)
    Provider-->>Leader: leaf cert
    Leader-->>Leaf: IssuedCert
    Leaf-->>Agent: cache + return
    Agent-->>Proxy: SDS secret

    Note over Leader,State: Periodic / triggered rotation
    Leader->>Provider: RotateRootCA()
    Provider-->>Leader: new root
    Leader->>Provider: CrossSignCA(oldRoot, newRoot)
    Provider-->>Leader: cross-signed bundle
    Leader->>State: Apply CARootSet
    State-->>Agent: streaming root update
    Agent->>Leaf: re-issue leafs against new chain

leader_connect_ca.go is the leader-side orchestrator — it owns the CA provider lifecycle, schedules root rotation (at 60% of root lifetime by default), runs the cross-sign dance when migrating from one provider to another, and rotates intermediates (Vault).

agent/leafcert/ is the agent-side cache. It pre-emptively re-issues leafs at half their TTL so steady-state Envoy traffic never sees an expired cert.

Provider plug-ins

Provider Backed by Notes
Consul (default) connect-ca-builtin MemDB table Self-signed root in Raft; intermediates per DC. The simplest setup, suitable for most operators.
Vault HashiCorp Vault PKI engine Vault holds the signing key; Consul calls Vault on every leaf signing. Supports both intermediate-CA and full-PKI mounts.
AWS Private CA AWS Certificate Manager Private CA Long-lived intermediates from AWS, leaves issued via AWS PCA SDK.

Adding a new provider means implementing the ca.Provider interface and registering it in agent/consul/connect_ca_endpoint.go's factory map.

ACL and auth

Leaf signing is gated by ACL policies tied to the proxy's service identity. The CSR validates that the requested SPIFFE URI matches the agent's authenticated identity (token + service registration). Identity logic lives in agent/connect/uri.go and agent/structs/identity.go.

Federation and peering

  • WAN federation: roots replicate via the federation state replication loop (agent/consul/leader_federation_state_ae.go). Each DC's primary CA cross-signs the others' roots so a single trust chain spans the federation.
  • Cluster peering: trust bundles are exchanged out-of-band when peering is established and refreshed by leader_peering.go. Peers don't share signing authority — they just trust each other's roots.

Public gRPC API

proto-public/pbconnectca/ defines:

  • Sign(CertificateSigningRequest) returns (Certificate)
  • WatchRoots(stream) — long-lived stream of root changes, used by Consul Dataplane.

The server-side handler is in agent/grpc-external/services/connectca/.

Integration points

  • xDS / proxycfg: roots and leaf go into every snapshot, surface as Envoy secret resources via agent/xds/secrets.go.
  • Cache types: agent/cache-types/connect_ca_*.go and agent/cache-types/connect_ca_root.go allow blocking-query reads of roots through the agent cache.
  • Auto-config: the auto-config/ bootstrap path uses the CA to mint TLS certs for client agents joining the cluster.
  • Operator control: consul connect ca get|set (in command/connect/ca/) reads/writes the active provider configuration.

Entry points for modification

  • Add a CA provider: implement ca.Provider in agent/connect/ca/, register it, add config decode in agent/structs/connect_ca.go.
  • Adjust rotation policy: see the caRotateRoot and caRenewIntermediate functions in agent/consul/leader_connect_ca.go.
  • Change SPIFFE URI semantics: agent/connect/uri.go is the parser; downstream code uses the parsed URIs everywhere.
  • Tune leaf TTL or proactive renewal: see agent/leafcert/leafcert.go's *Manager.refresh* paths.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Connect CA – Consul wiki | Factory