This topic describes how to configure rules for Consul's access control list (ACL) system. The ACL system enables you to control access to data and APIs. Refer to the [ACL system documentation](/docs/acl/acl-system) to learn more about ACLs.
-> **1.4.0 and later:** This topic applies to Consul versions 1.4.0 and later. Refer to the [legacy ACL system documentation](/docs/acl/acl-legacy) for older versions of Consul.
ACL rules describe the level of access to resources. A rule is composed of a resource declaration and an access level defined with the `policy` keyword and a [policy disposition](#policy-dispositions). The following syntax describes the basic structure of a rule:
Many resources take an additional value that limits the scope of the rule to a resource _segment_. A resource segment can be the name of a specific set of resources, such as nodes configured with the same `name` value.
The following syntax describes how to include a resource segment in the rule:
```hcl
<resource> "<segment>" {
policy = "<policy disposition>"
}
```
Segmentation provides operators with more granular control over access to the resouce. Some resources, however, do not take a segment value. The following resource areas _can not_ be segmented:
* `acl`
* `keyring`
* `mesh`
* `operator`
Use the following syntax to create rules for non-segmented resources:
You can also use a special `list` access level to allows access to all keys under a segment in the Consul KV. The `list` access level can only be used with the `key_prefix` resource. The [`acl.enable_key_list_policy`](/docs/agent/options#acl_enable_key_list_policy) setting must be set to `true`.
You can define rules for resource segments based on exact matches or by using resource prefixes to match several resource segments beginning with the same value. Matching segments on exact values is described in the [Segments](#segments) section.
The following example rule is an exact match that denies access to `web-prod` service segments:
```hcl
service "web-prod" {
policy = "deny"
}
```
You can append the resource with `_prefix` to match all resource segments beginning with the same value. The following example rule allows `write` access to all service segments that begin with "web":
```hcl
service_prefix "web" {
policy = "write"
}
```
Prefix-based resource segments can also contain an empty string, which configures the rule to apply to all resources of the declared type. The following example rule allows `read` access to all `service` resources:
```hcl
service_prefix "" {
policy = "read"
}
```
When using prefix-based rules, the most specific prefix match determines the action. In a real-world scenario, a combination of rules would be combined to create a flexible policy. Each team or business unit would use tokesn based on polcies that enforce several rules, for example:
* A rule that denies access to a specific resource segment
* A prefix-based rule that allows write access to a class of resources
* An empty prefix that grants read-only access to all resource within the declared class
#### Matching Precedence
Exact matching rules will only apply to the exact resource specified. The order of precedence for matching rules are:
1. `deny` (highest priority)
1. `write`
1. `read`
### Formatting Rules
Define rules using the
[HashiCorp Configuration Language (HCL)](https://github.com/hashicorp/hcl/).
HCL is human readable and interoperable with JSON, making it easy to automate rule generation.
The following examples show the same rule formatted in HCL and JSON:
You can configure ACLs remotely by calling the ACL HTTP API endpoint and including rules in the payload. The endpoint takes data formatted in HCL or JSON. Refer to the [ACL HTTP API endpoint documentation](/api/acl/acl) for details about the API.
The following example adds a set of rules that apply to the `key` resource (Consul K/V) within the `my-app-policy` policy. The rules are formatted in HCL, but they are wrapped in JSON so that the data can be sent using cURL:
| `acl` | Controls access to ACL operations in the [ACL API](/api/acl/acl). <br/>See [ACL Resource Rules](#acl-resource-rules) for details. | No |
| `admin_partition`<br/>`admin_partition_prefix` | <EnterpriseAlert inline /> Controls access to one or more admin partitions. <br/>See [Admin Partition Rules](#admin-partition-rules) for details. | Yes |
| `agent`<br/>`agent_prefix` | Controls access to the utility operations in the [Agent API](/api/agent), such as `join` and `leave`. <br/>See [Agent Rules](#agent-rules) for details. | Yes |
| `event`<br/>`event_prefix` | Controls access to event operations in the [Event API](/api/event), such as firing and listing events. <br/>See [Event Rules](#event-rules) for details. | Yes |
| `key`<br/>`key_prefix` | Controls access to key/value store operations in the [KV API](/api/kv). <br/>Can also use the `list` access level when setting the policy disposition. <br/>Has additional value options in Consul Enterprise for integrating with [Sentinel](https://docs.hashicorp.com/sentinel/consul). <br/>See [Key/Value Rules](#key-value-rules) for details. | Yes |
| `keyring` | Controls access to keyring operations in the [Keyring API](/api/keyring). <br/>See [Keyring Rules](#keyring-rules) for details. | No |
| `mesh` | Provides operator-level permissions for resources in the admin partition, such as ingress gateways or mesh proxy defaults. See [Mesh Rules](#mesh-rulres) for details. | No |
| `namespace`<br/>`namespace_prefix` | <EnterpriseAlert inline /> Controls access to one or more namespaces. <br/>See [Namespace Rules](#namespace-rules) for details. | Yes |
| `node`<br/>`node_prefix` | Controls access to node-level registration and read access to the [Catalog API](/api/catalog). <br/>See [Node Rules](#node-rules) for details. | Yes |
| `operator` | Controls access to cluster-level operations available in the [Operator API](/api/operator) excluding keyring API endpoints. <br/>See [Operator Rules](#operator-rules) for details. | No |
| `query`<br/>`query_prefix` | Controls access to create, update, and delete prepared queries in the [Prepared Query API](/api/query). Access to the [node](#node-rules) and [service](#service-rules) must also be granted. <br/>See [Prepared Query Rules](#prepared-query-rules) for details. | Yes |
| `service`<br/>`service_prefix` | Controls service-level registration and read access to the [Catalog API](/api/catalog), as well as service discovery with the [Health API](/api/health). <br/>See [Service Rules](#node-rules) for details. | Yes |
| `session`<br/>`session_prefix` | Controls access to operations in the [Session API](/api/session). <br/>See [Session Rules](#session-rules) for details. | Yes |
The following topics provide additional details about the available resources.
### ACL Resource Rules
The `acl` resource controls access to ACL operations in the [ACL API](/api/acl/acl). Only one `acl` rule is allowed per policy. The value is set to one of the [policy dispositions](#policy-dispositions).
The `acl = "write"` rule is also required to create snapshots. This is because all token secrets are contained within the snapshot.
Rules for ACL resources are non-segmented.
In the following example, `write` access to the ACL API. The rule enables the operator to read or write ACLs, as well as discover the secret ID of any token.
In the following example, the agent has write access to the `ex-namespace` namespace, as well as namespaces prefixed with `ex-` in the `example` partition.
The `mesh` resource is also scoped to the admin partition rule, which grants `write` access to mesh-level resources in the partition:
The `mesh` resource controls access to ingress gateways, terminating gateways, and mesh configuration entries.
See [Admin Partition Rules](#admin-partition-rules) for an example rule that uses the `mesh` resource.
### Namespace Rules <EnterpriseAlert inline />
The `namespace` and `namespace_prefix` resource controls access to Consul namespaces. Namespaces define a scope of resources for which ACL rules apply. ACL rules, themselves, can then be defined to only to apply to specific namespaces.
-> **Consul 1.7.0 and later**: The ability to add many types of resources to separate namespaces was added to [Consul Enterprise](https://www.hashicorp.com/consul) 1.7.0.
The following examples describe how namespace rules can be defined in a policy:
```hcl
namespace_prefix "" {
# grant service:read for all services in all namespaces
service_prefix "" {
policy = "read"
}
# grant node:read for all nodes in all namespaces
node_prefix "" {
policy = "read"
}
}
namespace "foo" {
# grants permission to manage ACLs only for the foo namespace
acl = "write"
# grants permission to rename the foo namespace
policy = "write"
# grants write permissions to the KV for namespace foo
key_prefix "" {
policy = "write"
}
# grants write permissions for sessions for namespace foo
session_prefix "" {
policy = "write"
}
# grants service:write for all services in the foo namespace
service_prefix "" {
policy = "write"
}
# grants node:read for all nodes
node_prefix "" {
policy = "read"
}
}
```
#### Restrictions
The following restrictions apply when a rule is defined in any user-created namespace:
1. `operator` rules are not allowed.
2. `event` rules are not allowed.
3. `keyring` rules are not allowed.
4. `query` rules are not allowed.
5. `node` rules that attempt to grant `write` privileges are not allowed.
These restrictions do not apply to the `default` namespace created by Consul. In general all of the
above are permissions that only an operator should have and thus granting these permissions can
only be done within the default namespace.
#### Implicit Namespacing
Rules and policies created within a namespace will inherit the namespace configuration.
This means that rules and policies will be implicitly namespaced and do not need additional configuration.
The restrictions outlined above will apply to these rules and policies. Additionally, rules and policies within a
specific namespace are prevented from accessing resources in another namespace.
Node 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
read-write access to the "app" node, and deny all access to the "admin" node.
| Create static query without `Name` | 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. | 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. |
| Create static query with `Name` | 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. | 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. |
| Manage static query without `Name` | The ACL Token used to create the query or a token with management privileges must be supplied in order to perform these operations. | Any client with the ID of the query can perform these operations. |
| Manage static query with a `Name` | The ACL token used to create the query or a token with management privileges must be supplied in order to perform these operations. | Similar to create, the client token's `query` ACL policy is used to determine if these operations are allowed. |
| List queries | A token with management privileges is required to list any queries. | 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`. |
| Execute query | 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. | The captured token, client's token, or anonymous token is used to filter the results, as described above. |