---
layout: docs
page_title: Connect - Intentions
sidebar_title: Intentions - Security Policies
description: >-
  Intentions define access control for services via Connect and are used to
  control which services may establish connections. Intentions can be managed
  via the API, CLI, or UI.
---

# Intentions

Intentions define access control for services via Connect and are used
to control which services may establish connections. Intentions can be
managed via the API, CLI, or UI.

Intentions are enforced by the [proxy](/docs/connect/proxies)
or [natively integrated application](/docs/connect/native) on
inbound connections. After verifying the TLS client certificate, the
[authorize API endpoint](/api-docs/agent/connect#authorize) is called which verifies the connection
is allowed by testing the intentions. If authorize returns false the
connection must be terminated.

The default intention behavior is defined by the default
[ACL policy](https://learn.hashicorp.com/consul/security-networking/production-acls). If the default ACL policy is "allow all",
then all Connect connections are allowed by default. If the default ACL policy
is "deny all", then all Connect connections are denied by default.

## Intention Basics

Intentions can be managed via the [API](#), [CLI](#),
or UI. Please see the respective documentation for each for full details
on options, flags, etc.
Below is an example of a basic intention to show the basic attributes
of an intention. The full data model of an intention can be found in the
[API documentation](#).

```shell-session
$ consul intention create -deny web db
Created: web => db (deny)
```

The intention above is a deny intention with a source of "web" and
destination of "db". This says that connections from web to db are not
allowed and the connection will be rejected.

When an intention is modified, existing connections will not be affected.
This means that changing a connection from "allow" to "deny" today
_will not_ kill the connection. Addressing this shortcoming is on
the near term roadmap for Consul.

### Wildcard Intentions

An intention source or destination may also be the special wildcard
value `*`. This matches _any_ value and is used as a catch-all. Example:

```shell-session
$ consul intention create -deny web '*'
Created: web => * (deny)
```

This example says that the "web" service cannot connect to _any_ service.

### Metadata

Arbitrary string key/value data may be associated with intentions. This
is unused by Consul but can be used by external systems or for visibility
in the UI.

```shell-session
$ consul intention create \
  -deny \
  -meta description='Hello there' \
  web db
...

$ consul intention get web db
Source:             web
Destination:        db
Action:             deny
ID:                 31449e02-c787-f7f4-aa92-72b5d9b0d9ec
Meta[description]:  Hello there
Created At:         Friday, 25-May-18 02:07:51 CEST
```

## Precedence and Match Order

Intentions are matched in an implicit order based on specificity, preferring
deny over allow. Specificity is determined by whether a value is an exact
specified value or is the wildcard value `*`.
The full precedence table is shown below and is evaluated
top to bottom, with larger numbers being evaluated first.

| Source Namespace | Source Name | Destination Namespace | Destination Name | Precedence |
| ---------------- | ----------- | --------------------- | ---------------- | ---------- |
| Exact            | Exact       | Exact                 | Exact            | 9          |
| Exact            | `*`         | Exact                 | Exact            | 8          |
| `*`              | `*`         | Exact                 | Exact            | 7          |
| Exact            | Exact       | Exact                 | `*`              | 6          |
| Exact            | `*`         | Exact                 | `*`              | 5          |
| `*`              | `*`         | Exact                 | `*`              | 4          |
| Exact            | Exact       | `*`                   | `*`              | 3          |
| Exact            | `*`         | `*`                   | `*`              | 2          |
| `*`              | `*`         | `*`                   | `*`              | 1          |

The precedence value can be read from the [API](/api/connect/intentions)
after an intention is created.
Precedence cannot be manually overridden today. This is a feature that will
be added in a later version of Consul.

In the case the two precedence values match, Consul will evaluate
intentions based on lexicographical ordering of the destination then
source name. In practice, this is a moot point since authorizing a connection
has an exact source and destination value so its impossible for two
valid non-wildcard intentions to match.

The numbers in the table above are not stable. Their ordering will remain
fixed but the actual number values may change in the future.

-> **Consul Enterprise** - Namespaces are an Enterprise feature. In Consul OSS any of the rows in
the table with a `*` for either the source namespace or destination namespace are not applicable.

## Intention Management Permissions

Intention management can be protected by [ACLs](https://learn.hashicorp.com/consul/security-networking/production-acls).
Permissions for intentions are _destination-oriented_, meaning the ACLs
for managing intentions are looked up based on the destination value
of the intention, not the source.

Intention permissions are by default implicitly granted at `read` level
when granting `service:read` or `service:write`. This is because a
service registered that wants to use Connect needs `intentions:read`
for its own service name in order to know whether or not to authorize
connections. The following ACL policy will implicitly grant `intentions:read`
(note _read_) for service `web`.

```hcl
service "web" {
  policy = "write"
}
```

It is possible to explicitly specify intention permissions. For example,
the following policy will allow a service to be discovered without granting
access to read intentions for it.

```hcl
service "web" {
  policy = "read"
  intentions = "deny"
}
```

Note that `intentions:read` is required for a token that a Connect-enabled
service uses to register itself or it's proxy. If the token used does not
have `intentions:read` then the agent will be unable to resolve intentions
for the service and so will not be able to authorize any incoming connections.

~> **Security Note:** Explicitly allowing `intentions:write` on the token you
provide to a service instance at registration time opens up a significant
additional vulnerability. Although you may trust the service _team_ to define
which inbound connections they accept, using a combined token for registration
allows a compromised instance to to redefine the intentions which allows many
additional attack vectors and may be hard to detect. We strongly recommend only
delegating `intentions:write` using tokens that are used by operations teams or
orchestrators rather than spread via application config, or only manage
intentions with management tokens.

## Performance and Intention Updates

The intentions for services registered with a Consul agent are cached
locally on that agent. They are then updated via a background blocking query
against the Consul servers.

Connect connection attempts require only local agent
communication for authorization and generally impose only impose microseconds
of latency to the connection. All actions in the data path of connections
require only local data to ensure minimal performance overhead.

Updates to intentions are propagated nearly instantly to agents since agents
maintain a continuous blocking query in the background for intention updates
for registered services.

Because all the intention data is cached locally, the agents can fail static.
Even if the agents are severed completely from the Consul servers, inbound
connection authorization continues to work for a configured amount of time.
Changes to intentions will not be picked up until the partition heals, but
will then automatically take effect when connectivity is restored.
