Open-Source Wikis

/

Consul

/

Features

/

Intentions

hashicorp/consul

Intentions

Intentions are the mesh's authorization layer: "is service A allowed to talk to service B over the mesh?" They are evaluated at L4 (allow/deny based on identity) and L7 (rules over HTTP method/path/header).

Pieces

Piece Where
Service-intentions config entry agent/structs/config_entry_intentions.go
Legacy intention table (compatibility) agent/consul/state/intention.go, agent/consul/state/intention_ce.go
RPC endpoint agent/consul/intention_endpoint.go
HTTP endpoint agent/intentions_endpoint.go
Migration leader loop agent/consul/leader_intentions.go
RBAC translation for Envoy agent/xds/rbac.go (43 KB)
API client api/connect_intention.go
CLI command/intention/

Concept

A service-intentions config entry has a destination service and a list of source ⇒ action pairs:

Kind = "service-intentions"
Name = "db"
Sources = [
  { Name = "web",       Action = "allow" },
  { Name = "metrics-*", Action = "allow", Permissions = [{ Action = "allow", HTTP = { PathPrefix = "/metrics" } }] },
  { Name = "*",         Action = "deny"  },
]

The db service accepts traffic from web, accepts only /metrics from any service whose name matches metrics-*, and denies everything else.

L7 permissions allow filtering by HTTP method, path, header presence/value, query parameters, and JWT claims (when used with a service-intentions JWT block referencing a jwt-provider config entry).

Default policy

The cluster-wide default action when no intention matches is configurable via the mesh config entry's AllowEnableV2TenancyMetadataDefaults (or a similar default_intention_policy field) and the global acl.default_policy for non-mesh aspects. Code: agent/structs/config_entry_mesh.go.

Compilation to RBAC

Envoy enforces intentions via its RBAC filter. agent/xds/rbac.go translates intentions into Envoy RBAC rules:

  • Identity match — SPIFFE URI prefix (matches the source service identity from the leaf cert).
  • L7 match — HTTP path, method, header, JWT claims.
  • Mode — ALLOW or DENY.

The compiled RBAC filter goes into the inbound listener of the destination's sidecar in agent/xds/listeners.go.

Legacy intentions

Before service-intentions config entries (Consul 1.9+), intentions were rows in a dedicated table with a unique-source/destination key. Code stayed for compatibility:

  • agent/consul/state/intention.go — legacy table.
  • agent/consul/leader_intentions.go — migration loop that copies legacy entries into config entries.
  • agent/consul/intention_endpoint.go — handles both legacy and config-entry-based reads/writes transparently.

The legacy CLI surface remains under command/intention/ (create, delete, match, check); new clusters should use consul config write with a service-intentions HCL.

Wildcards and matching

  • * source matches every service in the namespace/partition.
  • Prefix wildcards: web-* matches any service whose name starts with web-.
  • Action precedence: more-specific source wins over less-specific. Exact name beats prefix beats *.
  • Within a source, L7 permissions are evaluated top-to-bottom; first match decides.

The matching logic lives in agent/structs/config_entry_intentions.go::SortedMatches and is exercised heavily in agent/structs/config_entry_intentions_test.go.

Streaming and propagation

Intentions are config entries — they propagate via agent/consul/config_entry_events.go and the streaming subscribe topic. When an intention changes, every relevant proxycfg.state rebuilds its snapshot, the xDS server emits new RBAC filters, and Envoy applies them within seconds without dropping connections.

Operator workflow

# Quick allow
consul intention create web db

# Read all intentions for db
consul intention match -destination -type service db

# Apply via config entry (recommended)
consul config write intentions.hcl

# Check whether traffic would be allowed (offline match)
consul intention check web db

consul intention list reads the unified set; the CLI hides the legacy/config-entry split.

ACL gating

Editing intentions for a destination service requires intentions:write on that service. The check is enforced server-side in agent/consul/intention_endpoint.go and surfaced via acl.IntentionDefault* methods in acl/acl.go.

Integration points

  • Service mesh — every sidecar's inbound listener has the RBAC filter built from intentions.
  • API gateway — uses the same intention machinery to enforce per-route policies between the gateway listener and the upstream service.
  • JWT providers — referenced by service-intentions for claims-based authorization.
  • Audit logging — intention writes are logged (Enterprise has a fuller audit trail; CE emits standard log lines).

Entry points for modification

  • Add a new L7 match dimension: extend agent/structs/config_entry_intentions.go and the RBAC translator in agent/xds/rbac.go.
  • Tune migration cadence: agent/consul/leader_intentions.go.
  • Add tests: agent/structs/config_entry_intentions_test.go already covers most edge cases — extend the table-driven cases there.

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

Intentions – Consul wiki | Factory