--- layout: "docs" page_title: "Sentinel in Consul" sidebar_current: "docs-guides-sentinel" description: |- Consul Enterprise uses Sentinel to augment the built-in ACL system to provide advanced policy enforcement. Sentinel policies can currently execute on KV modify and service registration. --- # Sentinel Overview [//]: # ( ~> The Sentinel functionality described here is available only in ) [//]: # ( [Consul Enterprise](https://www.hashicorp.com/products/consul/) version 1.0.0 and later. ) <%= enterprise_alert :consul %> Consul 1.0 adds integration with [Sentinel](https://hashicorp.com/sentinel) for policy enforcement. Sentinel policies help extend the ACL system in Consul beyond the static "read", "write", and "deny" policies to support full conditional logic, and integration with external systems. ## Sentinel in Consul Sentinel policies are applied during writes to the KV Store and the service catalog in Consul. ACL policy definitions take a `sentinel` field specifying the code and the enforcement level. Here's an example: ```text sentinel { code = "main = rule { port > 1024 and port < 32768 }" enforcementlevel = "soft-mandatory" } ``` This policy ensures that all services written to the Catalog must have a port number between 1024 and 32768. If the `enforcementlevel` property is not set, it defaults to "hard-mandatory". ## Imports Consul imports all the [standard imports](https://docs.hashicorp.com/sentinel/imports/) from Sentinel. All functions in these imports are available to be used in policies. ## Injected Variables Consul passes some context as variables into Sentinel, which are available to use inside any policies you write. #### Variables injected during KV store writes | Variable Name | Type | Description | | ------------- | -------- | ----------- | | `key` | `string` | Key being written | | `value` | `string` | Value being written | | `flags` | `uint64` | [Flags](/api/kv.html#flags) | #### Variables injected during service registration | Variable Name | Type | Description | | -------------- |-------------------- | ----------- | | `node_id` | `string` | ID of the agent registering the service | | `node` | `string` | Name of the agent registering the service | | `address` | `string` | Service address | | `port` | `int` | Service port | | `service_id` | `string` | Service ID | | `service` | `string` | Service name | | `node_meta` | `map[string]string` | Node metadata map | | `tags` | `list` | Service tags | ## Examples The following are some examples of ACL policies with Sentinel rules. ### All services must register with a valid IPv6 address. ```text service "" { policy = "write" sentinel { import \"sockaddr\" code = "main = rule { sockaddr.is_ipv6(address) }" enforcementlevel = "soft-mandatory" } } ``` ### Service names must end with "Service" ```text service "" { policy = "write" sentinel { import \"strings\" code = "main = rule { strings.has_suffix(service,\"Service\") }" enforcementlevel = "soft-mandatory" } } ``` ### The service "db" must be registered with either a "Leader" or a "Follower" tag ```text service "db" { policy = "write" sentinel { main = rule { tags contains \"Leader\" or tags contains \"Follower\" } } } ``` ### The key "foo" can only be updated during business hours. ```text keys "foo" { policy = "write" sentinel { import "time" main = rule { time.hour > 8 and time.hour < 17 } } } ```