hashicorp/consul
Auto-config and auto-encrypt
Joining a TLS-protected Consul cluster is a chicken-and-egg problem: a new agent needs a TLS cert to talk to servers, but normally needs to talk to servers to get one. Consul ships two bootstrap protocols to solve this — auto-encrypt (older) and auto-config (newer, more capable).
Purpose
| Protocol | Distributes | Auth method | Status |
|---|---|---|---|
| Auto-encrypt | Just TLS certs | Pre-shared CA bundle in agent config | Still maintained for backwards compatibility |
| Auto-config | TLS certs + initial agent config | JWT signed by an external IdP | Recommended for new deployments. Supports JWT-based auto-join workflows. |
Both protocols issue server-signed leaf certs that share the cluster's Connect CA roots, so once bootstrapped the new agent can verify normal RPC traffic.
Directory layout
agent/auto-config/
├── auto_config.go # The agent-side state machine: bootstrap, persist, refresh
├── persist.go # Persist negotiated config to disk
├── run.go # Background renewal loop
├── server_provider.go # Discover servers via fallback methods
├── tls.go # TLS plumbing
agent/consul/
├── auto_config_endpoint.go # Server-side RPC endpoint that issues bootstrap material
├── auto_config_backend.go # Validation + cert signing helpers
├── auto_encrypt_endpoint.go # Older auto-encrypt RPC endpoint
proto/private/pbautoconf/ # Auto-config protobuf wire format
proto/private/pbconfig/ # Initial config payload formatKey abstractions
| Type | File | Purpose |
|---|---|---|
AutoConfig |
agent/auto-config/auto_config.go |
Agent-side controller that drives bootstrap and refresh |
AutoConfigBackend |
agent/consul/auto_config_endpoint.go |
Server-side handler that authenticates the request and signs certs |
pbautoconf.AutoConfigRequest |
proto/private/pbautoconf/auto_config.proto |
The wire format: identity claims + signing CSR |
pbconfig.Config |
proto/private/pbconfig/ |
The bootstrap payload (encryption key, ACL token, gossip key, ...) |
Bootstrap flow
sequenceDiagram
participant New as New agent
participant IdP as Identity provider (OIDC, K8s SA, GCP, ...)
participant Server as Consul server (auto-config endpoint)
New->>IdP: Get JWT (configured assertor)
IdP-->>New: signed JWT
New->>New: generate keypair + CSR
New->>Server: AutoConfig.InitialConfiguration(JWT, CSR)
Server->>Server: validate JWT against configured authorizer
Server->>Server: ConnectCA.Sign(CSR)
Server-->>New: TLS cert + initial config + CA bundle
New->>New: persist to data dir, switch to authenticated mode
Note over New,Server: subsequent RPCs use the issued TLS certThe configured authorizer can be one of:
- JWT — verify the token via configured JWKS / static keys.
- OIDC — verify with discovery + JWKS fetch.
- Kubernetes service account — verify via the K8s API.
- (Auto-encrypt's variant uses a pre-shared
auto_encrypt.tls = trueflag plus existing CA cert.)
The set of validators is set up in the server's auto-config block and authenticated in agent/consul/auto_config_endpoint.go.
Refresh
Once bootstrapped, the agent periodically renews its leaf cert through the standard Connect CA path (see Connect CA). The auto-config bootstrap is one-shot — it only runs once unless the persisted config is removed.
Operator workflow
# Server config
auto_config = {
authorizer {
enabled = true
static {
jwt_validation_pub_keys = ["..."]
claim_mappings = { "sub" = "node_name" }
bound_audiences = ["consul-auto-config"]
}
}
}
connect = { enabled = true }# New agent config
auto_config = {
enabled = true
intro_token = "<jwt>"
server_addresses = ["192.0.2.10:8501"]
}The new agent dials a server, presents its JWT, gets back a TLS cert and initial config (gossip key, ACL replication token, primary DC, etc.), and the agent then proceeds as if it had been started with those settings all along.
Integration points
- Connect CA: auto-config issues real Connect CA leafs, so trust roots are unified across server/server, agent/server, and mesh proxy traffic.
- Tokens: the bootstrap response can include an ACL token tagged with the agent's identity. The
agent/token/store stores it. - Persistence:
agent/auto-config/persist.gowrites a versioned file under the data dir; on reboot, the agent reuses it instead of re-bootstrapping.
Entry points for modification
- Add a new authorizer: extend the
authorizerswitch inagent/consul/auto_config_endpoint.goand add a corresponding decoder inagent/structs/. - Change the bootstrap payload: edit
proto/private/pbconfig/, regenerate, and updateagent/auto-config/auto_config.go::generateAgentConfig. - Migrate auto-encrypt callers: the auto-encrypt endpoint stays for compatibility; new features should target auto-config.
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.