<commit_before>---
layout: "docs"
page_title: "ACL Rules"
sidebar_current: "docs-acl-rules"
description: |-
  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.
---

-> **1.4.0 and later:** This document only applies in Consul versions 1.4.0 and later. The documentation for the legacy ACL system is [here](/docs/acl/acl-legacy.html)

# ACL Rules

Consul provides an optional Access Control List (ACL) system which can be used 
to control access to data and APIs. To learn more about Consul's ACL review the
[ACL system documentation](/docs/acl/acl-system.html)

A core part of the ACL system is the rule language, which is used to describe the policy
that must be enforced. There are two types of rules: prefix based rules and exact matching
rules. 

## Rule Specification

Rules are composed of a resource, a segment (for some resource areas) and a policy
disposition. The general structure of a rule is:

```text
<resource> "<segment>" {
  policy = "<policy disposition>"
}
```

Segmented resource areas allow operators to more finely control access to those resources.
Note that not all resource areas are segmented such as the `keyring`, `operator`, and `acl` resources. For those rules they would look like:

```text
<resource> = "<policy disposition>"
```

Policies can have several control levels:

* `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.
* `list`: allows access to all the keys under a segment in the Consul KV. Note, this policy can only be used with the `key_prefix` resource and [`acl.enable_key_list_policy`](/docs/agent/options.html#acl_enable_key_list) must be set to true.

When using 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. Exact matching rules will only apply to the exact resource specified.
The order of precedence for matching rules are, DENY has priority over WRITE or READ and 
 WRITE has priority over READ.  

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:

```hcl
# These control access to the key/value store.
key_prefix "" {
  policy = "read"
}
key_prefix "foo/" {
  policy = "write"
}
key_prefix "foo/private/" {
  policy = "deny"
}
# Or for exact key matches
key "foo/bar/secret" {
  policy = "deny"
}

# This controls access to cluster-wide Consul operator information.
operator = "read"
```

This is equivalent to the following JSON input:

```json
{
  "key_prefix": {
    "": {
      "policy": "read"
    },
    "foo/": {
      "policy": "write"
    },
    "foo/private/": {
      "policy": "deny"
    }
  },
  "key" : {
    "foo/bar/secret" : {
      "policy" : "deny"
    }
  },
  "operator": "read"
}
```

The [ACL API](/api/acl/acl.html) allows either HCL or JSON to be used to define the content
of the rules section of a policy.

Here's a sample request using the HCL form:

```text
$ curl \
    --request PUT \
    --data \
'{
  "Name": "my-app-policy",
  "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
}' http://1192.168.127.12:8500/v1/acl/policy?token=<token with ACL "write">
```

Here's an equivalent request using the JSON form:

```text
$ curl \
    --request PUT \
    --data \
'{
  "Name": "my-app-policy",
  "Rules": "{\"key\":{\"\":{\"policy\":\"read\"},\"foo/\":{\"policy\":\"write\"},\"foo/private\":{\"policy\":\"deny\"}},\"operator\":\"read\"}"
}' http://127.0.0.1:8500/v1/acl/policy?token=<management token>
```

On success, the Policy is returned:

```json
{
    "CreateIndex": 7,
    "Hash": "UMG6QEbV40Gs7Cgi6l/ZjYWUwRS0pIxxusFKyKOt8qI=",
    "ID": "5f423562-aca1-53c3-e121-cb0eb2ea1cd3",
    "ModifyIndex": 7,
    "Name": "my-app-policy",
    "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
}
```

The created policy can now be specified either by name or by ID when 
[creating a token](https://learn.hashicorp.com/consul/security-networking/production-acls#create-the-agent-token). This will grant the rules
provided to the [bearer of that token](/api/index.html#authentication).

Below is a breakdown of each rule type. 

#### ACL Resource Rules

The `acl` resource controls access to ACL operations in the
[ACL API](/api/acl/acl.html).

ACL rules look like this:

```hcl
acl = "write"
```

There is only one acl rule allowed per policy and its value is set to one of the [policy dispositions](/docs/acl/acl-rules.html#rule-specification). In the example
above ACLs may be read or written including discovering any token's secret ID. Snapshotting also requires `acl = "write"`
permissions due to the fact that all the token secrets are contained within the snapshot.

#### Agent Rules

The `agent` and `agent_prefix` resources control access to the utility operations in the [Agent API](/api/agent.html),
such as join and leave. All of the catalog-related operations are covered by the [`node` or `node_prefix`](#node-rules)
and [`service` or `service_prefix`](#service-rules) policies instead.

Agent rules look like this:

```hcl
agent_prefix "" {
  policy = "read"
}
agent "foo" {
  policy = "write"
}
agent_prefix "bar" {
  policy = "deny"
}
```

Agent rules are keyed by the node name they apply to. In the example above the rules
allow read-only access to any node name by using the empty prefix, read-write access to 
the node with the _exact_ name `foo`, and denies all access to any noe name that starts
with `bar`. 

Since [Agent API](/api/agent.html) utility operations may be required before an agent is joined to
a cluster, or during an outage of the Consul servers or ACL datacenter, a special token may be
configured with [`acl.tokens.agent_master`](/docs/agent/options.html#acl_tokens_agent_master) to allow
write access to these operations even if no ACL resolution capability is available.

#### Event Rules

The `event` and `event_prefix` resources control access to event operations in the [Event API](/api/event.html), such as
firing events and listing events.

Event rules look like this:

```hcl
event_prefix "" {
  policy = "read"
}
event "deploy" {
  policy = "write"
}
```

Event rules are segmented by the event name they apply to. In the example above, the rules allow<commit_msg>docs: Fix typo in acl/acl-rules<commit_after>---
layout: "docs"
page_title: "ACL Rules"
sidebar_current: "docs-acl-rules"
description: |-
  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.
---

-> **1.4.0 and later:** This document only applies in Consul versions 1.4.0 and later. The documentation for the legacy ACL system is [here](/docs/acl/acl-legacy.html)

# ACL Rules

Consul provides an optional Access Control List (ACL) system which can be used 
to control access to data and APIs. To learn more about Consul's ACL review the
[ACL system documentation](/docs/acl/acl-system.html)

A core part of the ACL system is the rule language, which is used to describe the policy
that must be enforced. There are two types of rules: prefix based rules and exact matching
rules. 

## Rule Specification

Rules are composed of a resource, a segment (for some resource areas) and a policy
disposition. The general structure of a rule is:

```text
<resource> "<segment>" {
  policy = "<policy disposition>"
}
```

Segmented resource areas allow operators to more finely control access to those resources.
Note that not all resource areas are segmented such as the `keyring`, `operator`, and `acl` resources. For those rules they would look like:

```text
<resource> = "<policy disposition>"
```

Policies can have several control levels:

* `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.
* `list`: allows access to all the keys under a segment in the Consul KV. Note, this policy can only be used with the `key_prefix` resource and [`acl.enable_key_list_policy`](/docs/agent/options.html#acl_enable_key_list) must be set to true.

When using 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. Exact matching rules will only apply to the exact resource specified.
The order of precedence for matching rules are, DENY has priority over WRITE or READ and 
 WRITE has priority over READ.  

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:

```hcl
# These control access to the key/value store.
key_prefix "" {
  policy = "read"
}
key_prefix "foo/" {
  policy = "write"
}
key_prefix "foo/private/" {
  policy = "deny"
}
# Or for exact key matches
key "foo/bar/secret" {
  policy = "deny"
}

# This controls access to cluster-wide Consul operator information.
operator = "read"
```

This is equivalent to the following JSON input:

```json
{
  "key_prefix": {
    "": {
      "policy": "read"
    },
    "foo/": {
      "policy": "write"
    },
    "foo/private/": {
      "policy": "deny"
    }
  },
  "key" : {
    "foo/bar/secret" : {
      "policy" : "deny"
    }
  },
  "operator": "read"
}
```

The [ACL API](/api/acl/acl.html) allows either HCL or JSON to be used to define the content
of the rules section of a policy.

Here's a sample request using the HCL form:

```text
$ curl \
    --request PUT \
    --data \
'{
  "Name": "my-app-policy",
  "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
}' http://127.0.0.1:8500/v1/acl/policy?token=<token with ACL "write">
```

Here's an equivalent request using the JSON form:

```text
$ curl \
    --request PUT \
    --data \
'{
  "Name": "my-app-policy",
  "Rules": "{\"key\":{\"\":{\"policy\":\"read\"},\"foo/\":{\"policy\":\"write\"},\"foo/private\":{\"policy\":\"deny\"}},\"operator\":\"read\"}"
}' http://127.0.0.1:8500/v1/acl/policy?token=<management token>
```

On success, the Policy is returned:

```json
{
    "CreateIndex": 7,
    "Hash": "UMG6QEbV40Gs7Cgi6l/ZjYWUwRS0pIxxusFKyKOt8qI=",
    "ID": "5f423562-aca1-53c3-e121-cb0eb2ea1cd3",
    "ModifyIndex": 7,
    "Name": "my-app-policy",
    "Rules": "key \"\" { policy = \"read\" } key \"foo/\" { policy = \"write\" } key \"foo/private/\" { policy = \"deny\" } operator = \"read\""
}
```

The created policy can now be specified either by name or by ID when 
[creating a token](https://learn.hashicorp.com/consul/security-networking/production-acls#create-the-agent-token). This will grant the rules
provided to the [bearer of that token](/api/index.html#authentication).

Below is a breakdown of each rule type. 

#### ACL Resource Rules

The `acl` resource controls access to ACL operations in the
[ACL API](/api/acl/acl.html).

ACL rules look like this:

```hcl
acl = "write"
```

There is only one acl rule allowed per policy and its value is set to one of the [policy dispositions](/docs/acl/acl-rules.html#rule-specification). In the example
above ACLs may be read or written including discovering any token's secret ID. Snapshotting also requires `acl = "write"`
permissions due to the fact that all the token secrets are contained within the snapshot.

#### Agent Rules

The `agent` and `agent_prefix` resources control access to the utility operations in the [Agent API](/api/agent.html),
such as join and leave. All of the catalog-related operations are covered by the [`node` or `node_prefix`](#node-rules)
and [`service` or `service_prefix`](#service-rules) policies instead.

Agent rules look like this:

```hcl
agent_prefix "" {
  policy = "read"
}
agent "foo" {
  policy = "write"
}
agent_prefix "bar" {
  policy = "deny"
}
```

Agent rules are keyed by the node name they apply to. In the example above the rules
allow read-only access to any node name by using the empty prefix, read-write access to 
the node with the _exact_ name `foo`, and denies all access to any node name that starts
with `bar`. 

Since [Agent API](/api/agent.html) utility operations may be required before an agent is joined to
a cluster, or during an outage of the Consul servers or ACL datacenter, a special token may be
configured with [`acl.tokens.agent_master`](/docs/agent/options.html#acl_tokens_agent_master) to allow
write access to these operations even if no ACL resolution capability is available.

#### Event Rules

The `event` and `event_prefix` resources control access to event operations in the [Event API](/api/event.html), such as
firing events and listing events.

Event rules look like this:

```hcl
event_prefix "" {
  policy = "read"
}
event "deploy" {
  policy = "write"
}
```

Event rules are segmented by the event name they apply to. In the example above, the rules allow
{'fraction_non_alphanumeric': 0.11823188613117802, 'fraction_numerical': 0.008296974465345826, 'mean_word_length': 3.829706390328152, 'pattern_counts': {'":': 52, '<': 17, '<?xml version=': 0, '>': 19, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 4, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '661813', 'n_tokens_mistral': 4375, 'n_tokens_neox': 4197, 'n_words': 1803}