1---
2layout: "docs"
3page_title: "ACL Rules"
4sidebar_current: "docs-agent-acl-rules"
5description: |-
6  Consul provides an optional Access Control List (ACL) system which can be used to control access to data and APIs. The ACL system is a Capability-based system that relies on tokens which can have fine grained rules applied to them. It is very similar to AWS IAM in many ways.
7---
8
9-> **1.4.0 and later:** This guide only applies in Consul versions 1.4.0 and later. The documentation for the legacy ACL system is [here](/docs/guides/acl-legacy.html)
10
11# ACL Rules
12
13Consul provides an optional Access Control List (ACL) system which can be used
14to control access to data and APIs. To learn more about Consul's ACL review the
15[ACL system documentation](/docs/agent/acl-system.html)
16
17A core part of the ACL system is the rule language, which is used to describe the policy
18that must be enforced. There are two types of rules: prefix based rules and exact matching
19rules.
20
21## Rule Specification
22
23Rules are composed of a resource, a segment (for some resource areas) and a policy
24disposition. The general structure of a rule is:
25
26```text
27<resource> "<segment>" {
28  policy = "<policy disposition>"
29}
30```
31
32Segmented resource areas allow operators to more finely control access to those resources.
33Note that not all resource areas are segmented such as the `keyring`, `operator`, and `acl` resources. For those rules they would look like:
34
35```text
36<resource> = "<policy disposition>"
37```
38
39Policies can have several control levels:
40
41* `read`: allow the resource to be read but not modified.
42* `write`: allow the resource to be read and modified.
43* `deny`: do not allow the resource to be read or modified.
44* `list`: allows access to all the keys under a segement in the Consul KV. Note, this policy can only be used with the `key_prefix` resource and [`acl.enabled_key_list_policy`](https://www.consul.io/docs/guides/acl.html#list-policy-for-keys) must be set to true.
45
46When using prefix-based rules, the most specific prefix match determines the action. This
47allows for flexible rules like an empty prefix to allow read-only access to all
48resources, along with some specific prefixes that allow write access or that are
49denied all access. Exact matching rules will only apply to the exact resource specified.
50The order of precedence for matching rules are, DENY has priority over WRITE or READ and
51 WRITE has priority over READ.
52
53We make use of the
54[HashiCorp Configuration Language (HCL)](https://github.com/hashicorp/hcl/) to specify
55rules. This language is human readable and interoperable with JSON making it easy to
56machine-generate. Rules can make use of one or more policies.
57
58Specification in the HCL format looks like:
59
60```text
61# These control access to the key/value store.
62key_prefix "" {
63  policy = "read"
64}
65key_prefix "foo/" {
66  policy = "write"
67}
68key_prefix "foo/private/" {
69  policy = "deny"
70}
71# Or for exact key matches
72key "foo/bar/secret" {
73  policy = "deny"
74}
75
76# This controls access to cluster-wide Consul operator information.
77operator = "read"
78```
79
80This is equivalent to the following JSON input:
81
82```javascript
83{
84  "key_prefix": {
85    "": {
86      "policy": "read"
87    },
88    "foo/": {
89      "policy": "write"
90    },
91    "foo/private/": {
92      "policy": "deny"
93    }
94  },
95  "key" : {
96    "foo/bar/secret" : {
97      "policy" : "deny"
98    }
99  },
100  "operator": "read"
101}
102```
103
104The [ACL API](/api/acl/acl.html) allows either HCL or JSON to be used to define the content
105of the rules section of a policy.
106
107Here's a sample request using the HCL form:
108
109```text
110$ curl \
111    --request PUT \
112    --data \
113'{
114  "Name": "my-app-policy",
115  "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
116}' http://127.0.0.1:8500/v1/acl/policy?token=<token with ACL "write">
117```
118
119Here's an equivalent request using the JSON form:
120
121```text
122$ curl \
123    --request PUT \
124    --data \
125'{
126  "Name": "my-app-policy",
127  "Rules": "{\"key\":{\"\":{\"policy\":\"read\"},\"foo/\":{\"policy\":\"write\"},\"foo/private\":{\"policy\":\"deny\"}},\"operator\":\"read\"}"
128}' http://127.0.0.1:8500/v1/acl/policy?token=<management token>
129```
130
131On success, the Policy is returned:
132
133```json
134{
135    "CreateIndex": 7,
136    "Hash": "UMG6QEbV40Gs7Cgi6l/ZjYWUwRS0pIxxusFKyKOt8qI=",
137    "ID": "5f423562-aca1-53c3-e121-cb0eb2ea1cd3",
138    "ModifyIndex": 7,
139    "Name": "my-app-policy",
140    "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
141}
142```
143
144The created policy can now be specified either by name or by ID when
145[creating a token](/docs/guides/acl.html#step-4-create-an-agent-token). This will grant the rules
146provided to the [bearer of that token](https://www.consul.io/api/index.html#authentication).
147
148Below is a breakdown of each rule type.
149
150#### ACL Resource Rules
151
152The `acl` resource controls access to ACL operations in the
153[ACL API](/api/acl/acl.html).
154
155ACL rules look like this:
156
157```text
158acl = "write"
159```
160
161There is only one acl rule allowed per policy and its value is set to one of the [policy dispositions](https://www.consul.io/docs/guides/acl.html#rule-specification). In the example
162above ACLs may be read or written including discovering any token's secret ID. Snapshotting also requires `acl = "write"`
163permissions due to the fact that all the token secrets are contained within the snapshot.
164
165#### Agent Rules
166
167The `agent` and `agent_prefix` resources control access to the utility operations in the [Agent API](/api/agent.html),
168such as join and leave. All of the catalog-related operations are covered by the [`node` or `node_prefix`](#node-rules)
169and [`service` or `service_prefix`](#service-rules) policies instead.
170
171Agent rules look like this:
172
173```text
174agent_prefix "" {
175  policy = "read"
176}
177agent "foo" {
178  policy = "write"
179}
180agent_prefix "bar" {
181  policy = "deny"
182}
183```
184
185Agent rules are keyed by the node name they apply to. In the example above the rules
186allow read-only access to any node name by using the empty prefix, read-write access to
187the node with the _exact_ name `foo`, and denies all access to any noe name that starts
188with `bar`.
189
190Since [Agent API](/api/agent.html) utility operations may be reqired before an agent is joined to
191a cluster, or during an outage of the Consul servers or ACL datacenter, a special token may be
192configured with [`acl_agent_master_token`](/docs/agent/options.html#acl_agent_master_token) to allow
193write access to these operations even if no ACL resolution capability is available.
194
195#### Event Rules
196
197The `event` and `event_prefix` resources control access to event operations in the [Event API](/api/event.html), such as
198firing events and listing events.
199
200Event rules look like this:
201
202```text
203event_prefix "" {
204  policy = "read"
205}
206event "deploy" {
207  policy = "write"
208}
209```
210
211Event rules are segmented by the event name they apply to. In the example above, the rules allow
212read-only access to any event, and firing of the "deploy" event.
213
214The [`consul exec`](/docs/commands/exec.html) command uses events with the "_rexec" prefix during
215operation, so to enable this feature in a Consul environment with ACLs enabled, you will need to
216give agents a token with access to this event prefix, in addition to configuring
217[`disable_remote_exec`](/docs/agent/options.html#disable_remote_exec) to `false`.
218
219#### Key/Value Rules
220
221The `key` and `key_prefix` resources control access to key/value store operations in the [KV API](/api/kv.html). Key
222rules look like this:
223
224```text
225key_prefix "" {
226  policy = "read"
227}
228key "foo" {
229  policy = "write"
230}
231key "bar" {
232  policy = "deny"
233}
234```
235
236Key rules are segmented by the key name they apply to. In the example above, the rules allow read-only access
237to any key name with the empty prefix rule, allow read-write access to the "foo" key, and deny access to the "bar" key.
238
239#### List Policy for Keys
240
241Consul 1.0 introduces a new `list` policy for keys that is only enforced when opted in via the boolean config param "acl.enable_key_list_policy".
242`list` controls access to recursively list entries and keys, and enables more fine grained policies. With "acl.enable_key_list_policy",
243recursive reads via [the KV API](/api/kv.html#recurse) with an invalid token result in a 403. Example:
244
245```text
246key_prefix "" {
247 policy = "deny"
248}
249
250key_prefix "bar" {
251 policy = "list"
252}
253
254key_prefix "baz" {
255 policy = "read"
256}
257```
258
259In the example above, the rules allow reading the key "baz", and only allow recursive reads on the prefix "bar".
260
261A token with `write` access on a prefix also has `list` access. A token with `list` access on a prefix also has `read` access on all its suffixes.
262
263#### Sentinel Integration
264
265Consul Enterprise supports additional optional fields for key write policies for
266[Sentinel](https://docs.hashicorp.com/sentinel/app/consul/) integration. An example key rule with a
267Sentinel code policy looks like this:
268
269```text
270key "foo" {
271  policy = "write"
272  sentinel {
273      code = <<EOF
274import "strings"
275main = rule { strings.has_suffix(value, "bar") }
276EOF
277      enforcementlevel = "hard-mandatory"
278  }
279}
280```
281
282For more detailed documentation, see the [Consul Sentinel Guide](/docs/guides/sentinel.html).
283
284#### Keyring Rules
285
286The `keyring` resource controls access to keyring operations in the
287[Keyring API](/api/operator/keyring.html).
288
289Keyring rules look like this:
290
291```text
292keyring = "write"
293```
294
295There's only one keyring policy allowed per rule set, and its value is set to one of the policy
296dispositions. In the example above, the keyring may be read and updated.
297
298#### Node Rules
299
300The `node` and `node_prefix` resources controls node-level registration and read access to the [Catalog API](/api/catalog.html),
301service discovery with the [Health API](/api/health.html), and filters results in [Agent API](/api/agent.html)
302operations like fetching the list of cluster members.
303
304Node rules look like this:
305
306```text
307node_prefix "" {
308  policy = "read"
309}
310node "app" {
311  policy = "write"
312}
313node "admin" {
314  policy = "deny"
315}
316```
317
318Node rules are segmented by the node name they apply to. In the example above, the rules allow read-only access to any node name with the empty prefix, allow
319read-write access to the "app" node, and deny all access to the "admin" node.
320
321Agents need to be configured with an [`acl.tokens.agent`](/docs/agent/options.html#acl_tokens_agent)
322with at least "write" privileges to their own node name in order to register their information with
323the catalog, such as node metadata and tagged addresses. If this is configured incorrectly, the agent
324will print an error to the console when it tries to sync its state with the catalog.
325
326Consul's DNS interface is also affected by restrictions on node rules. If the
327[`acl.token.default`](/docs/agent/options.html#acl_tokens_default) used by the agent does not have "read" access to a
328given node, then the DNS interface will return no records when queried for it.
329
330When reading from the catalog or retrieving information from the health endpoints, node rules are
331used to filter the results of the query. This allows for configurations where a token has access
332to a given service name, but only on an allowed subset of node names.
333
334Node rules come into play when using the [Agent API](/api/agent.html) to register node-level
335checks. The agent will check tokens locally as a check is registered, and Consul also performs
336periodic [anti-entropy](/docs/internals/anti-entropy.html) syncs, which may require an
337ACL token to complete. To accommodate this, Consul provides two methods of configuring ACL tokens
338to use for registration events:
339
3401. Using the [acl.tokens.default](/docs/agent/options.html#acl_tokens_default) configuration
341   directive. This allows a single token to be configured globally and used
342   during all check registration operations.
3432. Providing an ACL token with service and check definitions at
344   registration time. This allows for greater flexibility and enables the use
345   of multiple tokens on the same agent. Examples of what this looks like are
346   available for both [services](/docs/agent/services.html) and
347   [checks](/docs/agent/checks.html). Tokens may also be passed to the
348   [HTTP API](/api/index.html) for operations that require them.
349
350In addition to ACLs, in Consul 0.9.0 and later, the agent must be configured with
351[`enable_script_checks`](/docs/agent/options.html#_enable_script_checks) set to `true` in order to enable
352script checks.
353
354#### Operator Rules
355
356The `operator` resource controls access to cluster-level operations in the
357[Operator API](/api/operator.html), other than the [Keyring API](/api/operator/keyring.html).
358
359Operator rules look like this:
360
361```text
362operator = "read"
363```
364
365There's only one operator rule allowed per rule set, and its value is set to one of the policy
366dispositions. In the example above, the token could be used to query the operator endpoints for
367diagnostic purposes but not make any changes.
368
369#### Prepared Query Rules
370
371The `query` and `query_prefix` resources control access to create, update, and delete prepared queries in the
372[Prepared Query API](/api/query.html). Executing queries is subject to `node`/`node_prefix` and `service`/`service_prefix`
373policies, as will be explained below.
374
375Query rules look like this:
376
377```text
378query_prefix "" {
379  policy = "read"
380}
381query "foo" {
382  policy = "write"
383}
384```
385
386Query rules are segmented by the query name they apply to. In the example above, the rules allow read-only
387access to any query name with the empty prefix, and allow read-write access to the query named "foo".
388This allows control of the query namespace to be delegated based on ACLs.
389
390There are a few variations when using ACLs with prepared queries, each of which uses ACLs in one of two
391ways: open, protected by unguessable IDs or closed, managed by ACL policies. These variations are covered
392here, with examples:
393
394* Static queries with no `Name` defined are not controlled by any ACL policies.
395  These types of queries are meant to be ephemeral and not shared to untrusted
396  clients, and they are only reachable if the prepared query ID is known. Since
397  these IDs are generated using the same random ID scheme as ACL Tokens, it is
398  infeasible to guess them. When listing all prepared queries, only a management
399  token will be able to see these types, though clients can read instances for
400  which they have an ID. An example use for this type is a query built by a
401  startup script, tied to a session, and written to a configuration file for a
402  process to use via DNS.
403
404* Static queries with a `Name` defined are controlled by the `query` and `query_prefix`
405  ACL resources. Clients are required to have an ACL token with permissions on to
406  access that query name. Clients can list or read queries for
407  which they have "read" access based on their prefix, and similar they can
408  update any queries for which they have "write" access. An example use for
409  this type is a query with a well-known name (eg. `prod-master-customer-db`)
410  that is used and known by many clients to provide geo-failover behavior for
411  a database.
412
413* [Template queries](/api/query.html#templates)
414  queries work like static queries with a `Name` defined, except that a catch-all
415  template with an empty `Name` requires an ACL token that can write to any query
416  prefix.
417
418When prepared queries are executed via DNS lookups or HTTP requests, the ACL
419checks are run against the service being queried, similar to how ACLs work with
420other service lookups. There are several ways the ACL token is selected for this
421check:
422
423* If an ACL Token was captured when the prepared query was defined, it will be
424  used to perform the service lookup. This allows queries to be executed by
425  clients with lesser or even no ACL Token, so this should be used with care.
426
427* If no ACL Token was captured, then the client's ACL Token will be used to
428  perform the service lookup.
429
430* If no ACL Token was captured and the client has no ACL Token, then the
431  anonymous token will be used to perform the service lookup.
432
433In the common case, the ACL Token of the invoker is used
434to test the ability to look up a service. If a `Token` was specified when the
435prepared query was created, the behavior changes and now the captured
436ACL Token set by the definer of the query is used when looking up a service.
437
438Capturing ACL Tokens is analogous to
439[PostgreSQL’s](http://www.postgresql.org/docs/current/static/sql-createfunction.html)
440`SECURITY DEFINER` attribute which can be set on functions, and using the client's ACL
441Token is similar to the complementary `SECURITY INVOKER` attribute.
442
443Prepared queries were originally introduced in Consul 0.6.0, and ACL behavior remained
444unchanged through version 0.6.3, but was then changed to allow better management of the
445prepared query namespace.
446
447These differences are outlined in the table below:
448
449<table class="table table-bordered table-striped">
450  <tr>
451    <th>Operation</th>
452    <th>Version <= 0.6.3 </th>
453    <th>Version > 0.6.3 </th>
454  </tr>
455  <tr>
456    <td>Create static query without `Name`</td>
457    <td>The ACL Token used to create the prepared query is checked to make sure it can access the service being queried. This token is captured as the `Token` to use when executing the prepared query.</td>
458    <td>No ACL policies are used as long as no `Name` is defined. No `Token` is captured by default unless specifically supplied by the client when creating the query.</td>
459  </tr>
460  <tr>
461    <td>Create static query with `Name`</td>
462    <td>The ACL Token used to create the prepared query is checked to make sure it can access the service being queried. This token is captured as the `Token` to use when executing the prepared query.</td>
463    <td>The client token's `query` ACL policy is used to determine if the client is allowed to register a query for the given `Name`. No `Token` is captured by default unless specifically supplied by the client when creating the query.</td>
464  </tr>
465  <tr>
466    <td>Manage static query without `Name`</td>
467    <td>The ACL Token used to create the query or a token with management privileges must be supplied in order to perform these operations.</td>
468    <td>Any client with the ID of the query can perform these operations.</td>
469  </tr>
470  <tr>
471    <td>Manage static query with a `Name`</td>
472    <td>The ACL token used to create the query or a token with management privileges must be supplied in order to perform these operations.</td>
473    <td>Similar to create, the client token's `query` ACL policy is used to determine if these operations are allowed.</td>
474  </tr>
475  <tr>
476    <td>List queries</td>
477    <td>A token with management privileges is required to list any queries.</td>
478    <td>The client token's `query` ACL policy is used to determine which queries they can see. Only tokens with management privileges can see prepared queries without `Name`.</td>
479  </tr>
480  <tr>
481    <td>Execute query</td>
482    <td>Since a `Token` is always captured when a query is created, that is used to check access to the service being queried. Any token supplied by the client is ignored.</td>
483    <td>The captured token, client's token, or anonymous token is used to filter the results, as described above.</td>
484  </tr>
485</table>
486
487#### Service Rules
488
489The `service` and `service_prefix` resources control service-level registration and read access to the [Catalog API](/api/catalog.html)
490and service discovery with the [Health API](/api/health.html).
491
492Service rules look like this:
493
494```text
495service_prefix "" {
496  policy = "read"
497}
498service "app" {
499  policy = "write"
500}
501service "admin" {
502  policy = "deny"
503}
504```
505
506Service rules are segmented by the service name they apply to. In the example above, the rules allow read-only
507access to any service name with the empty prefix, allow read-write access to the "app" service, and deny all
508access to the "admin" service.
509
510Consul's DNS interface is affected by restrictions on service rules. If the
511[`acl.tokens.default`](/docs/agent/options.html#acl_tokens_default) used by the agent does not have "read" access to a
512given service, then the DNS interface will return no records when queried for it.
513
514When reading from the catalog or retrieving information from the health endpoints, service rules are
515used to filter the results of the query.
516
517Service rules come into play when using the [Agent API](/api/agent.html) to register services or
518checks. The agent will check tokens locally as a service or check is registered, and Consul also
519performs periodic [anti-entropy](/docs/internals/anti-entropy.html) syncs, which may require an
520ACL token to complete. To accommodate this, Consul provides two methods of configuring ACL tokens
521to use for registration events:
522
5231. Using the [acl.tokens.default](/docs/agent/options.html#acl_tokens_default) configuration
524   directive. This allows a single token to be configured globally and used
525   during all service and check registration operations.
5262. Providing an ACL token with service and check definitions at registration
527   time. This allows for greater flexibility and enables the use of multiple
528   tokens on the same agent. Examples of what this looks like are available for
529   both [services](/docs/agent/services.html) and
530   [checks](/docs/agent/checks.html). Tokens may also be passed to the [HTTP
531   API](/api/index.html) for operations that require them. **Note:** all tokens
532   passed to an agent are persisted on local disk to allow recovery from
533   restarts. See [`-data-dir` flag
534   documentation](/docs/agent/options.html#acl_token) for notes on securing
535   access.
536
537In addition to ACLs, in Consul 0.9.0 and later, the agent must be configured with
538[`enable_script_checks`](/docs/agent/options.html#_enable_script_checks) or
539[`enable_local_script_checks`](/docs/agent/options.html#_enable_local_script_checks)
540set to `true` in order to enable script checks.
541
542
543#### Session Rules
544
545The `session` and `session_prefix` resources controls access to [Session API](/api/session.html) operations.
546
547Session rules look like this:
548
549```text
550session_prefix "" {
551  policy = "read"
552}
553session "app" {
554  policy = "write"
555}
556session "admin" {
557  policy = "deny"
558}
559```
560
561Session rules are segmented by the node name they apply to. In the example above, the rules allow read-only
562access to sessions on node name with the empty prefix, allow creating sessions on the node named "app",
563and deny all access to any sessions on the "admin" node.
564