Every token has an ID, name, type, and rule set. The ID is a randomly generated
UUID, making it unfeasible to guess. The name is opaque to Consul and human readable.
The type is either "client" (meaning the token cannot modify ACL rules) or "management"
(meaning the token is allowed to perform all actions).
The token ID is passed along with each RPC request to the servers. Agents
can be configured with an [`acl_token`](/docs/agent/options.html#acl_token) property
to provide a default token, but the token can also be specified by a client on a
[per-request basis](/api/index.html). ACLs were added in Consul 0.4, meaning
prior versions do not provide a token. This is handled by the special "anonymous"
token. If no token is provided, the rules associated with the anonymous token are
automatically applied: this allows policy to be enforced on legacy clients.
ACLs can also act in either a whitelist or blacklist mode depending
on the configuration of
[`acl_default_policy`](/docs/agent/options.html#acl_default_policy). If the
default policy is to deny all actions, then token rules can be set to whitelist
specific actions. In the inverse, the allow all default behavior is a blacklist
where rules are used to prohibit actions. By default, Consul will allow all
actions.
The token ID is passed along with each RPC request to the servers. Consul's
[HTTP endpoints](http://localhost:4567/api/index.html) can accept tokens via the `token`
query string parameter, or the `X-Consul-Token` request header. Consul's
[CLI commands](http://localhost:4567/docs/commands/index.html) can accept tokens via the
`token` argument, or the `CONSUL_HTTP_TOKEN` environment variable.
If no token is provided, the rules associated with a special, configurable anonymous
token are automatically applied. The anonymous token is managed using the
[ACL API](/api/acl.html) like any other ACL token, but using `anonymous` for the ID.
#### ACL Rules and Scope
Tokens are bound to a set of rules that control which Consul resources the token
has access to. Policies can be defined in either a whitelist or blacklist mode
depending on the configuration of
[`acl_default_policy`](/docs/agent/options.html#acl_default_policy). If the default
policy is to "deny all" actions, then token rules can be set to whitelist specific
actions. In the inverse, the "allow all" default behavior is a blacklist where rules
are used to prohibit actions. By default, Consul will allow all actions.
The following table summarizes the ACL policies that are availabile for constructing
rules:
| Policy | Scope |
| ------------------------ | ----- |
| [`agent`](#agent-rules) | Utility operations in the [Agent API](/api/agent.html), other than service and check registration |
| [`event`](#event-rules) | Listing and firing events in the [Event API](/api/event.html) |
| [`key`](#key-value-rules) | Key/value store operations in the [KV Store API](/api/kv.html) |
| [`keyring`](#keyring-rules) | Keyring operations in the [Keyring API](/api/operator/keyring.html) |
| [`node`](#node-rules) | Node-level catalog operations in the [Catalog API](/api/catalog.html), [Health API](/api/health.html), [Network Coordinate API](/api/coordinate.html), and [Agent API](/api/agent.html) |
| [`operator`](#operator-rules) | Cluster-level operations in the [Operator API](/api/operator.html), other than the [Keyring API](/api/operator/keyring.html) |
| [`query`](#prepared-query-rules) | Prepared query operations in the [Prepared Query API](/api/query.html)
| [`service`](#service-rules) | Service-level catalog operations in the [Catalog API](/api/catalog.html), [Health API](/api/health.html), and [Agent API](/api/agent.html) |
| [`session`](#session-rules) | Session operations in the [Session API](/api/session.html) |
Since Consul snapshots actually contain ACL tokens, the
[Snapshot API](/api/snapshot.html) requires a management token for snapshot operations
and does not use a special policy.
The following resources are not covered by ACL policies:
1. The [Status API](api/status.html) is used by servers when bootstrapping and exposes
basic IP and port information about the servers, and does not allow modification
of any state.
2. The datacenter listing operation of the
[Catalog API](/api/catalog.html#list-datacenters) similarly exposes the names of known
Consul datacenters, and does not allow modification of any state.
Constructing rules from these policies is covered in detail in the
| [`acl_datacenter`](/docs/agent/options.html#acl_datacenter) | `REQUIRED` | `REQUIRED` | Master control that enables ACLs by defining the authoritative Consul datacenter for ACLs |
There are some additional configuration items related to [ACL replication](#replication) and
[Version 8 ACL support](#version_8_acls). These are discussed in those respective sections
below.
A number of special tokens can also be configured which allow for bootstrapping the ACL
system, or accessing Consul in special situations:
| Special Token | Servers | Clients | Purpose |
| ------------- | ------- | ------- | ------- |
| [`acl_agent_master_token`](/docs/agent/options.html#acl_agent_master_token) | `OPTIONAL` | `OPTIONAL` | Special token that can be used to access [Agent API](/api/agent.html) when the ACL datacenter isn't available, or servers are offline (for clients); used for setting up the cluster such as doing initial join operations |
| [`acl_agent_token`](/docs/agent/options.html#acl_agent_token) | `OPTIONAL` | `OPTIONAL` | Special token that is used for an agent's internal operations with the [Catalog API](/api/catalog.html); this needs to have at least `node` policy access so the agent can self update its registration information |
| [`acl_master_token`](/docs/agent/options.html#acl_master_token) | `REQUIRED` | `N/A` | Special token used to bootstrap th ACL system, see details below. |
| [`acl_token`](/docs/agent/options.html#acl_token) | `OPTIONAL` | `OPTIONAL` | Default token to use for client requests where no token is supplied; this is often configured with read-only access to services to enable DNS service discovery on agents |
Bootstrapping the ACL system is done by providing an initial [`acl_master_token`
configuration](/docs/agent/options.html#acl_master_token) which will be created
@ -130,48 +135,35 @@ cluster leadership. If you would like to install or change the
[`acl_master_token`](/docs/agent/options.html#acl_master_token) in the configuration
for all servers. Once this is done, restart the current leader to force a leader election.
Once the ACL system is bootstrapped, ACL tokens can be managed through the
[ACL API](/api/acl.html).
## Rule Specification
A core part of the ACL system is a rule language which is used to describe the policy
that must be enforced.
Key policies are defined by coupling a prefix with a policy. The rules are enforced
using a longest-prefix match policy: Consul picks the most specific policy possible. The
policy is either "read", "write", or "deny". A "write" policy implies "read", and there is no
way to specify write-only. If there is no applicable rule, the
[`acl_default_policy`](/docs/agent/options.html#acl_default_policy) is applied.
Service policies are defined by coupling a service name and a policy. The rules are
enforced using an longest-prefix match policy (this was an exact match in 0.5, but changed
in 0.5.1). The default rule, applied to any service that doesn't have a matching policy,
is provided using the empty string. A service policy is either "read", "write", or "deny".
A "write" policy implies "read", and there is no way to specify write-only. If there is no
applicable rule, the [`acl_default_policy`](/docs/agent/options.html#acl_default_policy) is
applied. The "read" policy in a service ACL rule allows restricting access to
the discovery of that service prefix. More information about service discovery
and ACLs can be found [below](#discovery_acls).
The policy for the "consul" service is always "write" as it is managed internally by Consul.
User event policies are defined by coupling an event name prefix with a policy.
The rules are enforced using a longest-prefix match policy. The default rule,
applied to any user event without a matching policy, is provided by an empty
string. An event policy is one of "read", "write", or "deny". Currently, only
the "write" level is enforced during event firing. Events can always be read.
Prepared query policies control access to create, update, and delete prepared
queries. Service policies are used when executing prepared queries. See
[below](#prepared_query_acls) for more details.
We make use of
the [HashiCorp Configuration Language (HCL)](https://github.com/hashicorp/hcl/)
to specify policy. This language is human readable and interoperable
with JSON making it easy to machine-generate.
A core part of the ACL system is the rule language which is used to describe the policy
that must be enforced. Most of the ACL rules are prefix-based, allowing operators to
define different namespaces within Consul's resource areas like the catalog and key/value
store, in order to delegate responsibility for these namespaces. Policies can have several
dispositions:
* `read`: allow the resource to be read but not modified
* `write`: allow the resource to be read and modified
* `deny`: do not allow the resource to be read or modified
With prefix-based rules, the most specific prefix match determines the action. This
allows for flexible rules like an empty prefix to allow read-only access to all
resources, along with some specific prefixes that allow write access or that are
denied all access.
We make use of the
[HashiCorp Configuration Language (HCL)](https://github.com/hashicorp/hcl/) to specify
rules. This language is human readable and interoperable with JSON making it easy to
machine-generate. Rules can make use of one or more policies.
Specification in the HCL format looks like:
```javascript
# Default all keys to read-only
```text
# These control access to the key/value store.
key "" {
policy = "read"
}
@ -179,41 +171,10 @@ key "foo/" {
policy = "write"
}
key "foo/private/" {
# Deny access to the dir "foo/private"
policy = "deny"
}
# Default all services to allow registration. Also permits all
# services to be discovered.
service "" {
policy = "write"
}
# Deny registration access to services prefixed "secure-".
# Discovery of the service is still allowed in read mode.
service "secure-" {
policy = "read"
}
# Allow firing any user event by default.
event "" {
policy = "write"
}
# Deny firing events prefixed with "destroy-".
event "destroy-" {
policy = "deny"
}
# Default prepared queries to read-only.
query "" {
policy = "read"
}
# Read-only mode for the encryption keyring by default (list only)
keyring = "read"
# Read-only mode for Consul operator interfaces (list only)
# This controls access to cluster-wide Consul operator information.
operator = "read"
```
@ -232,169 +193,190 @@ This is equivalent to the following JSON input:
"policy": "deny"
}
},
"service": {
"": {
"policy": "write"
},
"secure-": {
"policy": "read"
}
},
"event": {
"": {
"policy": "write"
},
"destroy-": {
"policy": "deny"
}
},
"query": {
"": {
"policy": "read"
}
},
"keyring": "read",
"operator": "read"
}
```
## Building ACL Policies
The [ACL API](/api/acl.html) allows either HCL or JSON to be used to define the content
of the rules section.
#### Blacklist Mode and `consul exec`
Here's a sample request using the HCL form:
If you set [`acl_default_policy`](/docs/agent/options.html#acl_default_policy)
to `deny`, the `anonymous` token won't have permission to read the default
`_rexec` prefix; therefore, Consul agents using the `anonymous` token
won't be able to perform [`consul exec`](/docs/commands/exec.html) actions.