Open-Source Wikis

/

Consul

/

Features

/

ACL system

hashicorp/consul

ACL system

Consul ACLs control who can read and write what — services, KV keys, intentions, sessions, peerings, and so on. The system supports tokens, policies, roles, auth methods (for federated identity), binding rules, and templated policies.

Pieces

Piece Where
Authorizer engine acl/acl.go (55 KB), acl/acl_cache.go
Templated policies acl/acl_templated_policy.go, acl/acltemplatedpolicy/
Authorizer filtering acl/aclfilter/
RPC endpoint agent/consul/acl_endpoint.go (65 KB), agent/consul/acl.go (36 KB)
HTTP endpoint agent/acl_endpoint.go (39 KB)
State store agent/consul/state/acl.go (52 KB), agent/consul/state/acl_schema.go
Auth methods agent/consul/authmethod/, agent/consul/auth/
Token store (per-agent) agent/token/
ACL replication agent/consul/acl_replication.go, agent/consul/replication.go
Public Go API api/acl.go
CLI command/acl/... (token, policy, role, auth-method, binding-rule, templated-policy)

Concepts

graph LR
    Token[Token<br/>uuid + accessor id]
    Policy[Policy<br/>HCL/JSON rules]
    Role[Role<br/>collection of policies]
    Service[Service identity]
    Node[Node identity]
    AuthMethod[Auth method<br/>OIDC, JWT, K8s SA]
    BindingRule[Binding rule]
    Templated[Templated policy]

    Token -->|attached| Policy
    Token -->|attached| Role
    Token -->|attached| Service
    Token -->|attached| Node
    Token -->|attached| Templated
    Role -->|references| Policy
    Role -->|references| Service
    Role -->|references| Node
    AuthMethod -.login.-> Token
    BindingRule -.maps claims.-> Token

A token is the credential. It can attach policies and roles directly (the simple case) and/or service identities and node identities (which expand into well-known templated permissions).

A policy holds HCL rules:

service_prefix "web-" { policy = "write" }
key_prefix "myapp/" { policy = "read" }
node_prefix "" { policy = "read" }

A role is a named bundle of policies, services, and nodes — useful when many tokens share the same permission set.

An auth method (OIDC, JWT, K8s ServiceAccount) lets external identities exchange a credential for a Consul token via POST /v1/acl/login. Binding rules map claims from the auth method into roles, services, or namespaces.

Templated policies are reusable parameterized policies (e.g., builtin/service takes a service name and grants read+write on that service). They were introduced to compress the most common policy shapes.

Authorizer engine

acl/acl.go defines the Authorizer interface and a tree-of-policies implementation. The interface is rich:

type Authorizer interface {
    ServiceWrite(name string, ctx *AuthorizerContext) EnforcementDecision
    KeyRead(key string, ctx *AuthorizerContext) EnforcementDecision
    NodeRead(node string, ctx *AuthorizerContext) EnforcementDecision
    PreparedQueryRead(name string, ctx *AuthorizerContext) EnforcementDecision
    OperatorWrite(ctx *AuthorizerContext) EnforcementDecision
    // ... many more
}

When a request arrives, the agent or server resolves the token to an Authorizer (cached in acl/acl_cache.go) and calls the relevant method. Decisions are Allow, Deny, or Default (fall through to the cluster default policy).

Token resolution

sequenceDiagram
    participant Caller as Client
    participant Agent as Agent
    participant Cache as ACL token cache
    participant Server as Server
    participant State as state store

    Caller->>Agent: HTTP request, X-Consul-Token: <token>
    Agent->>Cache: lookup authorizer
    alt cache miss
        Cache->>Server: ACL.TokenRead
        Server->>State: token + policies + roles
        State-->>Server: resolved
        Server-->>Cache: authorizer (compiled)
    end
    Cache-->>Agent: authorizer
    Agent->>Agent: enforce per endpoint

The agent caches authorizers for performance (acl/acl_cache.go) and invalidates on token / policy / role updates via streaming subscribe events (agent/consul/acl_events.go).

Auth methods

Built-in types:

  • JWT (agent/consul/authmethod/kubernetes, agent/consul/authmethod/oidc, agent/consul/authmethod/jwt)
  • Kubernetes service account — verifies a JWT against a K8s API server.
  • OIDC — does discovery + JWKS verification.

The flow:

  1. External identity presents a credential at POST /v1/acl/login with auth_method set.
  2. The auth method validates and returns claims.
  3. Binding rules (agent/consul/state/acl.go::ACLBindingRule) match claim selectors and bind the resulting token to roles/services.
  4. A token is minted with a TTL and returned.

Replication

In multi-DC setups one DC is the primary: it owns ACL writes for global tokens/policies/roles. Secondary DCs run a replication loop (agent/consul/acl_replication.go) that pulls global definitions and locally caches them. Local tokens (created in a non-primary DC) don't replicate.

Operator workflow

# Bootstrap (only once per cluster)
consul acl bootstrap

# Create a policy
consul acl policy create -name web -rules @web.policy.hcl

# Create a token attached to a policy
consul acl token create -description "web app" -policy-name web

# Use it
CONSUL_HTTP_TOKEN=<token> consul kv put myapp/foo bar

The CLI surface is the largest of any subsystem (see CLI).

Integration points

  • Every endpoint — virtually every RPC has an ACL check. Look for authz.<Action> in *_endpoint.go.
  • DNS — uses the agent default token to filter responses.
  • Service mesh — the Connect CA leaf signing is gated by service:write on the requested identity.
  • V2 resource framework — uses the same acl.Authorizer via per-type ACL hooks.
  • Streaming — token mutations push invalidation events to subscribers.

Entry points for modification

  • Add a new authorizer method: extend acl.Authorizer (be ready to update many call sites).
  • Add a new auth method type: implement under agent/consul/authmethod/<type>/ and register in agent/consul/auth/.
  • Add a new templated policy: see acl/acltemplatedpolicy/ — it's a small DSL.
  • Tune the cache: acl/acl_cache.go. Be aware of staleness vs. throughput trade-offs.

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

ACL system – Consul wiki | Factory