Service Intentions

1.9.0+: This config entry is available in Consul versions 1.9.0 and newer.

The service-intentions config entry kind (ServiceIntentions on Kubernetes) controls Connect traffic authorization for both networking layer 4 (e.g. TCP) and networking layer 7 (e.g. HTTP).

Service intentions config entries represent a collection of intentions sharing a specific destination. All intentions governing access to a specific destination are stored in a single service-intentions config entry.

A single config entry may define a mix of both L4 and L7 style intentions, but for a specific source L4 and L7 intentions are mutually exclusive. Only one will apply at a time. Default behavior for L4 is configurable (regardless of global setting) by defining a low precedence intention for that destination.

Interaction with other Config Entries

L7 intentions within a config entry are restricted to only destination services that define their protocol as HTTP-based via a corresponding service-defaults config entry or globally via proxy-defaults .

Sample Config Entries

The following examples demonstrate potential use-cases for the service-intentions configuration entry.

REST Access

In the following example, the admin-dashboard and report-generator services have different levels of access when making REST calls:

HCL

Service Intentions - 图1

  • HCL
  • Kubernetes YAML
  • JSON
  1. Kind = "service-intentions"
  2. Name = "api"
  3. Sources = [
  4. {
  5. Name = "admin-dashboard"
  6. Permissions = [
  7. {
  8. Action = "allow"
  9. HTTP {
  10. PathPrefix = "/v2"
  11. Methods = ["GET", "PUT", "POST", "DELETE", "HEAD"]
  12. }
  13. }
  14. ]
  15. },
  16. {
  17. Name = "report-generator"
  18. Permissions = [
  19. {
  20. Action = "allow"
  21. HTTP {
  22. PathPrefix = "/v2/widgets"
  23. Methods = ["GET"]
  24. }
  25. }
  26. ]
  27. }
  28. # NOTE: a default catch-all based on the default ACL policy will apply to
  29. # unmatched connections and requests. Typically this will be DENY.
  30. ]
  1. Kind = "service-intentions"
  2. Name = "api"
  3. Sources = [
  4. {
  5. Name = "admin-dashboard"
  6. Permissions = [
  7. {
  8. Action = "allow"
  9. HTTP {
  10. PathPrefix = "/v2"
  11. Methods = ["GET", "PUT", "POST", "DELETE", "HEAD"]
  12. }
  13. }
  14. ]
  15. },
  16. {
  17. Name = "report-generator"
  18. Permissions = [
  19. {
  20. Action = "allow"
  21. HTTP {
  22. PathPrefix = "/v2/widgets"
  23. Methods = ["GET"]
  24. }
  25. }
  26. ]
  27. }
  28. # NOTE: a default catch-all based on the default ACL policy will apply to
  29. # unmatched connections and requests. Typically this will be DENY.
  30. ]
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: api
  5. spec:
  6. destination:
  7. name: api
  8. sources:
  9. - name: admin-dashboard
  10. permissions:
  11. - action: allow
  12. http:
  13. pathPrefix: /v2
  14. methods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD']
  15. - name: report-generator
  16. permissions:
  17. - action: allow
  18. http:
  19. pathPrefix: /v2/widgets
  20. methods: ['GET']
  21. # NOTE: a default catch-all based on the default ACL policy will apply to
  22. # unmatched connections and requests. Typically this will be DENY.
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: api
  5. spec:
  6. destination:
  7. name: api
  8. sources:
  9. - name: admin-dashboard
  10. permissions:
  11. - action: allow
  12. http:
  13. pathPrefix: /v2
  14. methods: ['GET', 'PUT', 'POST', 'DELETE', 'HEAD']
  15. - name: report-generator
  16. permissions:
  17. - action: allow
  18. http:
  19. pathPrefix: /v2/widgets
  20. methods: ['GET']
  21. # NOTE: a default catch-all based on the default ACL policy will apply to
  22. # unmatched connections and requests. Typically this will be DENY.
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "api",
  4. "Sources": [
  5. {
  6. "Name": "admin-dashboard",
  7. "Permissions": [
  8. {
  9. "Action": "allow",
  10. "HTTP": {
  11. "PathPrefix": "/v2",
  12. "Methods": ["GET", "PUT", "POST", "DELETE", "HEAD"]
  13. }
  14. }
  15. ]
  16. },
  17. {
  18. "Name": "report-generator",
  19. "Permissions": [
  20. {
  21. "Action": "allow",
  22. "HTTP": {
  23. "PathPrefix": "/v2/widgets",
  24. "Methods": ["GET"]
  25. }
  26. }
  27. ]
  28. }
  29. ]
  30. }
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "api",
  4. "Sources": [
  5. {
  6. "Name": "admin-dashboard",
  7. "Permissions": [
  8. {
  9. "Action": "allow",
  10. "HTTP": {
  11. "PathPrefix": "/v2",
  12. "Methods": ["GET", "PUT", "POST", "DELETE", "HEAD"]
  13. }
  14. }
  15. ]
  16. },
  17. {
  18. "Name": "report-generator",
  19. "Permissions": [
  20. {
  21. "Action": "allow",
  22. "HTTP": {
  23. "PathPrefix": "/v2/widgets",
  24. "Methods": ["GET"]
  25. }
  26. }
  27. ]
  28. }
  29. ]
  30. }

gRPC

In the following use-case, access to the IssueRefund gRPC service method is set to deny. Because gRPC method calls are HTTP/2, an HTTP path-matching rule can be used to control traffic:

HCL

Service Intentions - 图2

  • HCL
  • Kubernetes YAML
  • JSON
  1. Kind = "service-intentions"
  2. Name = "billing"
  3. Sources = [
  4. {
  5. Name = "frontend-web"
  6. Permissions = [
  7. # The frontend website can execute all billing service methods except
  8. # issuing refunds.
  9. {
  10. Action = "deny"
  11. HTTP {
  12. PathExact = "/mycompany.BillingService/IssueRefund"
  13. }
  14. },
  15. {
  16. Action = "allow"
  17. HTTP {
  18. PathPrefix = "/mycompany.BillingService/"
  19. }
  20. }
  21. ]
  22. },
  23. {
  24. Name = "support-portal"
  25. Permissions = [
  26. # But the support team portal page can execute all methods.
  27. {
  28. Action = "allow"
  29. HTTP {
  30. PathPrefix = "/mycompany.BillingService/"
  31. }
  32. }
  33. ]
  34. }
  35. # NOTE: a default catch-all based on the default ACL policy will apply to
  36. # unmatched connections and requests. Typically this will be DENY.
  37. ]
  1. Kind = "service-intentions"
  2. Name = "billing"
  3. Sources = [
  4. {
  5. Name = "frontend-web"
  6. Permissions = [
  7. # The frontend website can execute all billing service methods except
  8. # issuing refunds.
  9. {
  10. Action = "deny"
  11. HTTP {
  12. PathExact = "/mycompany.BillingService/IssueRefund"
  13. }
  14. },
  15. {
  16. Action = "allow"
  17. HTTP {
  18. PathPrefix = "/mycompany.BillingService/"
  19. }
  20. }
  21. ]
  22. },
  23. {
  24. Name = "support-portal"
  25. Permissions = [
  26. # But the support team portal page can execute all methods.
  27. {
  28. Action = "allow"
  29. HTTP {
  30. PathPrefix = "/mycompany.BillingService/"
  31. }
  32. }
  33. ]
  34. }
  35. # NOTE: a default catch-all based on the default ACL policy will apply to
  36. # unmatched connections and requests. Typically this will be DENY.
  37. ]
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: billing
  5. spec:
  6. destination:
  7. name: billing
  8. sources:
  9. # The frontend website can execute all billing service methods except
  10. # issuing refunds.
  11. - name: frontend-web
  12. permissions:
  13. - action: deny
  14. http:
  15. pathExact: /mycompany.BillingService/IssueRefund
  16. - action: allow
  17. http:
  18. pathPrefix: '/mycompany.BillingService/'
  19. - name: support-protocol
  20. # But the support team portal page can execute all methods.
  21. permissions:
  22. - action: allow
  23. http:
  24. pathPrefix: '/mycompany.BillingService/'
  25. # NOTE: a default catch-all based on the default ACL policy will apply to
  26. # unmatched connections and requests. Typically this will be DENY.
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: billing
  5. spec:
  6. destination:
  7. name: billing
  8. sources:
  9. # The frontend website can execute all billing service methods except
  10. # issuing refunds.
  11. - name: frontend-web
  12. permissions:
  13. - action: deny
  14. http:
  15. pathExact: /mycompany.BillingService/IssueRefund
  16. - action: allow
  17. http:
  18. pathPrefix: '/mycompany.BillingService/'
  19. - name: support-protocol
  20. # But the support team portal page can execute all methods.
  21. permissions:
  22. - action: allow
  23. http:
  24. pathPrefix: '/mycompany.BillingService/'
  25. # NOTE: a default catch-all based on the default ACL policy will apply to
  26. # unmatched connections and requests. Typically this will be DENY.
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "billing",
  4. "Sources": [
  5. {
  6. "Name": "frontend-web",
  7. "Permissions": [
  8. {
  9. "Action": "deny",
  10. "HTTP": {
  11. "PathExact": "/mycompany.BillingService/IssueRefund"
  12. }
  13. },
  14. {
  15. "Action": "allow",
  16. "HTTP": {
  17. "PathPrefix": "/mycompany.BillingService/"
  18. }
  19. }
  20. ]
  21. },
  22. {
  23. "Name": "support-portal",
  24. "Permissions": [
  25. {
  26. "Action": "allow",
  27. "HTTP": {
  28. "PathPrefix": "/mycompany.BillingService/"
  29. }
  30. }
  31. ]
  32. }
  33. ]
  34. }
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "billing",
  4. "Sources": [
  5. {
  6. "Name": "frontend-web",
  7. "Permissions": [
  8. {
  9. "Action": "deny",
  10. "HTTP": {
  11. "PathExact": "/mycompany.BillingService/IssueRefund"
  12. }
  13. },
  14. {
  15. "Action": "allow",
  16. "HTTP": {
  17. "PathPrefix": "/mycompany.BillingService/"
  18. }
  19. }
  20. ]
  21. },
  22. {
  23. "Name": "support-portal",
  24. "Permissions": [
  25. {
  26. "Action": "allow",
  27. "HTTP": {
  28. "PathPrefix": "/mycompany.BillingService/"
  29. }
  30. }
  31. ]
  32. }
  33. ]
  34. }

L4 and L7

You can mix and match L4 and L7 intentions per source:

HCL

Service Intentions - 图3

  • HCL
  • Kubernetes YAML
  • JSON
  1. Kind = "service-intentions"
  2. Name = "api"
  3. Sources = [
  4. {
  5. Name = "hackathon-project"
  6. Action = "deny"
  7. },
  8. {
  9. Name = "web"
  10. Action = "allow"
  11. },
  12. {
  13. Name = "nightly-reconciler"
  14. Permissions = [
  15. {
  16. Action = "allow"
  17. HTTP {
  18. PathExact = "/v1/reconcile-data"
  19. Methods = ["POST"]
  20. }
  21. }
  22. ]
  23. },
  24. # NOTE: a default catch-all based on the default ACL policy will apply to
  25. # unmatched connections and requests. Typically this will be DENY.
  26. ]
  1. Kind = "service-intentions"
  2. Name = "api"
  3. Sources = [
  4. {
  5. Name = "hackathon-project"
  6. Action = "deny"
  7. },
  8. {
  9. Name = "web"
  10. Action = "allow"
  11. },
  12. {
  13. Name = "nightly-reconciler"
  14. Permissions = [
  15. {
  16. Action = "allow"
  17. HTTP {
  18. PathExact = "/v1/reconcile-data"
  19. Methods = ["POST"]
  20. }
  21. }
  22. ]
  23. },
  24. # NOTE: a default catch-all based on the default ACL policy will apply to
  25. # unmatched connections and requests. Typically this will be DENY.
  26. ]
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: api
  5. spec:
  6. destination:
  7. name: api
  8. sources:
  9. - name: hackathon-project
  10. action: deny
  11. - name: web
  12. action: allow
  13. - name: nightly-reconciler
  14. permissions:
  15. - action: allow
  16. http:
  17. pathExact: /v1/reconcile-data
  18. methods: ['POST']
  19. # NOTE: a default catch-all based on the default ACL policy will apply to
  20. # unmatched connections and requests. Typically this will be DENY.
  1. apiVersion: consul.hashicorp.com/v1alpha1
  2. kind: ServiceIntentions
  3. metadata:
  4. name: api
  5. spec:
  6. destination:
  7. name: api
  8. sources:
  9. - name: hackathon-project
  10. action: deny
  11. - name: web
  12. action: allow
  13. - name: nightly-reconciler
  14. permissions:
  15. - action: allow
  16. http:
  17. pathExact: /v1/reconcile-data
  18. methods: ['POST']
  19. # NOTE: a default catch-all based on the default ACL policy will apply to
  20. # unmatched connections and requests. Typically this will be DENY.
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "api",
  4. "Sources": [
  5. {
  6. "Name": "hackathon-project",
  7. "Action": "deny"
  8. },
  9. {
  10. "Name": "web",
  11. "Action": "allow"
  12. },
  13. {
  14. "Name": "nightly-reconciler",
  15. "Permissions": [
  16. {
  17. "Action": "allow",
  18. "HTTP": {
  19. "PathExact": "/v1/reconcile-data",
  20. "Methods": ["POST"]
  21. }
  22. }
  23. ]
  24. }
  25. ]
  26. }
  1. {
  2. "Kind": "service-intentions",
  3. "Name": "api",
  4. "Sources": [
  5. {
  6. "Name": "hackathon-project",
  7. "Action": "deny"
  8. },
  9. {
  10. "Name": "web",
  11. "Action": "allow"
  12. },
  13. {
  14. "Name": "nightly-reconciler",
  15. "Permissions": [
  16. {
  17. "Action": "allow",
  18. "HTTP": {
  19. "PathExact": "/v1/reconcile-data",
  20. "Methods": ["POST"]
  21. }
  22. }
  23. ]
  24. }
  25. ]
  26. }

Available Fields

Service Intentions - 图4

Service Intentions - 图5

  • Kind - Must be set to service-intentions

  • Name (string: <required>) - The name of the destination service for all intentions defined in this config entry. This may be set to the wildcard character (*) to match all services that don’t otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 Permissions.

  • Namespace (string: "default")

    Enterprise

    - Specifies the namespaces the config entry will apply to. This may be set to the wildcard character (*) to match all services in all namespaces that don’t otherwise have intentions defined. Wildcard intentions cannot be used when defining L7 Permissions.

  • Partition (string: "default")

    Enterprise

    - Specifies the admin partition on which the configuration entry will apply. Wildcard characters (*) are not supported. Admin partitions must specified explicitly.

  • Meta (map<string|string>: nil) - Specifies arbitrary KV metadata pairs.

  • Sources (array<SourceIntention>) - The list of all intention sources and the authorization granted to those sources. The order of this list does not matter, but out of convenience Consul will always store this reverse sorted by intention precedence, as that is the order that they will be evaluated at enforcement time.

SourceIntention

Service Intentions - 图6

Service Intentions - 图7

  • Name (string: <required>) - The source of the intention. For a Type of consul this is the name of a Consul service. The service doesn’t need to be registered.

  • Peer (string: "") - Specifies the peer of the source service. Peer is mutually exclusive with Partition.

  • Namespace (string: "")

    Enterprise

    - The namespace of the source service. If Peer is empty, Namespace defaults to the namespace of the destination service (i.e. the config entry’s namespace).

  • Partition (string: "")

    Enterprise

    - Specifies the admin partition of the source service. If Peer is empty, Partition defaults to the destination service’s partition (i.e. the configuration entry’s partition). Partition is mutually exclusive with Peer.

  • Action (string: "") - For an L4 intention this is required, and should be set to one of "allow" or "deny" for the action that should be taken if this intention matches a request.

    This should be omitted for an L7 intention as it is mutually exclusive with the Permissions field.

  • Permissions (array<IntentionPermission>) - The list of all additional L7 attributes that extend the intention match criteria.

    Permission precedence is applied top to bottom. For any given request the first permission to match in the list is terminal and stops further evaluation. As with L4 intentions, traffic that fails to match any of the provided permissions in this intention will be subject to the default intention behavior is defined by the default ACL policy.

    This should be omitted for an L4 intention as it is mutually exclusive with the Action field.

    Setting Permissions is not valid if a wildcard is used for the Name or Namespace because they can only be applied to services with a compatible protocol.

  • Precedence (int: <read-only>) - An integer precedence value computed from the source and destination naming components.

  • Type (string: "consul") - The type for the Name value. This can be only “consul” today to represent a Consul service. If not provided, this will be defaulted to “consul”.

  • Description (string: "") - Description for the intention. This is not used by Consul, but is presented in API responses to assist tooling.

  • LegacyID (string: <read-only>) - This is the UUID to uniquely identify this intention in the system. Cannot be set directly and is exposed here as an artifact of the config entry migration and is primarily used to allow legacy intention API endpoints to continue to function for a period of time after upgrading to 1.9.0.

  • LegacyMeta (map<string|string>: <read-only>) - Specified arbitrary KV metadata pairs attached to the intention, rather than to the enclosing config entry. Cannot be set directly and is exposed here as an artifact of the config entry migration and is primarily used to allow legacy intention API endpoints to continue to function for a period of time after upgrading to 1.9.0.

  • LegacyCreateTime (time: optional) - The timestamp that this intention was created. Cannot be set directly and is exposed here as an artifact of the config entry migration and is primarily used to allow legacy intention API endpoints to continue to function for a period of time after upgrading to 1.9.0.

  • LegacyUpdateTime (time: optional) - The timestamp that this intention was last updated. Cannot be set directly and is exposed here as an artifact of the config entry migration and is primarily used to allow legacy intention API endpoints to continue to function for a period of time after upgrading to 1.9.0.

IntentionPermission

Service Intentions - 图8

Service Intentions - 图9

  • Action (string: <required>) - This is one of “allow” or “deny” for the action that should be taken if this permission matches a request.

  • HTTP (IntentionHTTPPermission: <required>) - A set of HTTP-specific authorization criteria

IntentionHTTPPermission

Service Intentions - 图10

Service Intentions - 图11

  • PathExact (string: "") - Exact path to match on the HTTP request path.

    At most only one of PathExact, PathPrefix, or PathRegex may be configured.

  • PathPrefix (string: "") - Path prefix to match on the HTTP request path.

    At most only one of PathExact, PathPrefix, or PathRegex may be configured.

  • PathRegex (string: "") - Regular expression to match on the HTTP request path.

    The syntax is described below.

    At most only one of PathExact, PathPrefix, or PathRegex may be configured.

  • Methods (array<string>) - A list of HTTP methods for which this match applies. If unspecified all HTTP methods are matched. If provided the names must be a valid method.

  • Header (array<IntentionHTTPHeaderPermission>) - A set of criteria that can match on HTTP request headers. If more than one is configured all must match for the overall match to apply.

    • Name (string: <required>) - Name of the header to match

    • Present (bool: false) - Match if the header with the given name is present with any value.

      At most only one of Exact, Prefix, Suffix, Regex, or Present may be configured.

    • Exact (string: "") - Match if the header with the given name is this value.

      At most only one of Exact, Prefix, Suffix, Regex, or Present may be configured.

    • Prefix (string: "") - Match if the header with the given name has this prefix.

      At most only one of Exact, Prefix, Suffix, Regex, or Present may be configured.

    • Suffix (string: "") - Match if the header with the given name has this suffix.

      At most only one of Exact, Prefix, Suffix, Regex, or Present may be configured.

    • Regex (string: "") - Match if the header with the given name matches this pattern.

      The syntax is described below.

      At most only one of Exact, Prefix, Suffix, Regex, or Present may be configured.

    • Invert (bool: false) - Inverts the logic of the match

ACLs

Configuration entries may be protected by ACLs.

Reading a service-intentions config entry requires intentions:read on the resource.

Creating, updating, or deleting a service-intentions config entry requires intentions:write on the resource.

Intention ACL rules are specified as part of a service rule. See Intention Management Permissions for more details.

Regular Expression Syntax

The actual syntax of the regular expression fields described here is entirely proxy-specific.

When using Envoy as a proxy, the syntax for these fields is RE2.