mirror of
https://github.com/gravitational/teleport
synced 2024-10-20 09:13:39 +00:00
docs: document label expressions (#27811)
* docs: document label expressions This commit adds documentation for the label expressions feature described in RFD 116. * Apply suggestions from code review Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com> * use v6 role Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com> * explain setting both <kind>_labels and <kind>_labels_expression --------- Co-authored-by: Paul Gottschling <paul.gottschling@goteleport.com> Co-authored-by: rosstimothy <39066650+rosstimothy@users.noreply.github.com>
This commit is contained in:
parent
60656b804c
commit
4f0105349c
|
@ -12,7 +12,7 @@ controls (RBAC) in your Teleport cluster.
|
|||
A Teleport `role` works by having two lists of rules: `allow` rules and `deny` rules.
|
||||
When declaring access rules, keep in mind the following:
|
||||
|
||||
- Everything is denied by default.
|
||||
- Nothing is allowed by default.
|
||||
- Deny rules get evaluated first and take priority.
|
||||
|
||||
A rule consists of two parts: the resources and verbs. Here's an example of an
|
||||
|
@ -25,10 +25,10 @@ allow:
|
|||
verbs: [list]
|
||||
```
|
||||
|
||||
If this rule was declared in the `deny` section of a role definition, it
|
||||
would prohibit users from getting a list of Trusted Clusters and
|
||||
sessions. You can see all of the available resources and verbs under the `allow`
|
||||
section in the example role configuration below.
|
||||
If this rule was declared in the `deny` section of a role definition, it would
|
||||
prohibit users from getting a list of active sessions. You can see all of the
|
||||
available resources and verbs under the `allow` section in the example role
|
||||
configuration below.
|
||||
|
||||
To manage cluster roles, a Teleport administrator can use the Web UI or the
|
||||
command line using [tctl resource commands](../reference/resources.mdx).
|
||||
|
@ -151,15 +151,17 @@ Label | `v3`, `v4` and `v5` Default | `v6` Default
|
|||
|
||||
## RBAC for resources
|
||||
|
||||
A Teleport role defines which resources (e.g., applications, servers, and databases) a user can have access to.
|
||||
This works by [labeling resources](../management/admin/labels.mdx) and listing
|
||||
allow/deny labels in a role definition.
|
||||
A Teleport role defines which resources (e.g., applications, servers, and
|
||||
databases) a user can access.
|
||||
This works by [labeling resources](../management/admin/labels.mdx) and
|
||||
configuring allow/deny labels in a role definition.
|
||||
|
||||
Consider the following use case:
|
||||
|
||||
The infrastructure is split into staging/production environments using labels
|
||||
like `environment=production` and `environment=staging`. You can create roles
|
||||
that only have access to one environment. Let's say you create an intern role with the allow rule for label `environment=staging`.
|
||||
like `environment=production` and `environment=staging`.
|
||||
You can create roles that only have access to one environment.
|
||||
Let's say you create an intern role with the allow rule for label `environment=staging`.
|
||||
|
||||
### Example
|
||||
|
||||
|
@ -187,8 +189,8 @@ spec:
|
|||
```
|
||||
|
||||
Teleport handles multiple label entries with logical "AND" operations.
|
||||
As an example this entry would match to databases that have the `env: prod` label and a
|
||||
`region` label of either `us-west-1` or `eu-central-1`:
|
||||
As an example, this entry would match to databases that have the `env: prod`
|
||||
label *and* a `region` label of either `us-west-1` or `eu-central-1`:
|
||||
|
||||
```yaml
|
||||
db_labels:
|
||||
|
@ -200,12 +202,13 @@ As an example this entry would match to databases that have the `env: prod` labe
|
|||
type="tip"
|
||||
title="Dynamic RBAC"
|
||||
>
|
||||
Resource labels can be dynamic, i.e. determined at runtime by an output of an executable. In this case, you can implement "permissions follow workload"
|
||||
Resource labels can be dynamic, i.e. determined at runtime by an output of an executable.
|
||||
In this case, you can implement "permissions follow workload"
|
||||
policies (eg., any server where PostgreSQL is running becomes *automatically*
|
||||
accessible only by the members of the "DBA" group and nobody else).
|
||||
</Admonition>
|
||||
|
||||
### Extended labels syntax
|
||||
### Extended label matching syntax
|
||||
|
||||
Below are a few examples for more complex filtering using various regexes.
|
||||
|
||||
|
@ -228,6 +231,65 @@ spec:
|
|||
'environment': '^test|staging$'
|
||||
```
|
||||
|
||||
### Label expressions
|
||||
|
||||
<Admonition type="warning">
|
||||
Label expressions are available starting in Teleport version `13.1.1`.
|
||||
All components of your Teleport cluster must be upgraded to version `13.1.1`
|
||||
or newer before you will be able to use label expressions.
|
||||
This includes the Auth Service and **all** Teleport agents.
|
||||
</Admonition>
|
||||
|
||||
Teleport roles also support matching resource labels with predicate expressions
|
||||
when you need to:
|
||||
|
||||
- combine logic with OR and AND operators
|
||||
- perform matching on label keys
|
||||
- implement negative matches
|
||||
|
||||
The following example role would allow access to any nodes labeled `env=staging`
|
||||
or labeled `team=<team>`, where `<team>` is one of the values of the user's
|
||||
`teams` trait:
|
||||
|
||||
```yaml
|
||||
kind: role
|
||||
version: v6
|
||||
metadata:
|
||||
name: example-role
|
||||
spec:
|
||||
allow:
|
||||
node_labels_expression: |
|
||||
labels["env"] == "staging" ||
|
||||
contains(user.spec.traits["teams"], labels["team"])
|
||||
```
|
||||
|
||||
The `<kind>_labels_expression` fields have the same purpose of the
|
||||
matching `<kind>_labels` fields, but support predicate expressions instead
|
||||
of label matchers.
|
||||
They can be used in the following fields of role `spec.allow` and `spec.deny`
|
||||
conditions:
|
||||
|
||||
- `node_labels_expression`
|
||||
- `app_labels_expression`
|
||||
- `cluster_labels_expression`
|
||||
- `kubernetes_labels_expression`
|
||||
- `db_labels_expression`
|
||||
- `db_service_labels_expression`
|
||||
- `windows_desktop_labels_expression`
|
||||
- `group_labels_expression`
|
||||
|
||||
Check out our
|
||||
[predicate language](../reference/predicate-language.mdx#label-expressions)
|
||||
guide for a more in depth explanation of the language.
|
||||
|
||||
Typically you will only want to use one of `<kind>_labels` or
|
||||
`<kind>_labels_expression` in a single role, but you are allowed to specify
|
||||
both.
|
||||
If you have both in a deny rule, the matching is greedy, if either one matches
|
||||
access will be denied.
|
||||
In an allow rule, the matching is not greedy, if both are set they both have to
|
||||
match for access to be allowed.
|
||||
|
||||
## Teleport resources
|
||||
|
||||
RBAC lets teams limit what resources are available to Teleport users. This can be helpful if, for example,
|
||||
|
|
|
@ -120,7 +120,7 @@ spec:
|
|||
windows_desktop_logins: [Administrator, '{{internal.logins}}']
|
||||
|
||||
# node_labels: a user with this role will be allowed to connect to
|
||||
# SSH nodes, which labels match expressions below.
|
||||
# SSH nodes with labels matching below.
|
||||
node_labels:
|
||||
# literal strings:
|
||||
'env': 'test'
|
||||
|
@ -128,9 +128,11 @@ spec:
|
|||
'*': '*'
|
||||
# a list of alternative options:
|
||||
'region': ['us-west-1', 'eu-central-1']
|
||||
# regular expressions start with ^ and end with $
|
||||
# Teleport uses golang regexp syntax.
|
||||
# of the list example above can be expressed as:
|
||||
# Regular expressions start with ^ and end with $.
|
||||
# Teleport uses Go's regular expression syntax:
|
||||
# https://github.com/google/re2/wiki/Syntax
|
||||
# The list example above can be expressed as:
|
||||
# 'region': '^us-west-1|eu-central-1$'
|
||||
'reg': '^us-west-1|eu-central-1$'
|
||||
|
||||
# kubernetes_groups specifies Kubernetes groups a user with this role will assume.
|
||||
|
@ -143,14 +145,17 @@ spec:
|
|||
kubernetes_users: ['IAM#{{external.foo}};']
|
||||
|
||||
# kubernetes_labels: a user with this role will be allowed to connect to
|
||||
# k8s clusters, which labels match expressions below.
|
||||
# k8s clusters with labels matching below.
|
||||
kubernetes_labels:
|
||||
# A user can only access prod environments
|
||||
'env': 'prod'
|
||||
# User can access any region in us-west, e.g us-west-1, us-west-2
|
||||
'region': 'us-west-*'
|
||||
# regular expressions start with ^ and ending with $
|
||||
# Teleport uses golang regexp syntax.
|
||||
# Regular expressions start with ^ and end with $.
|
||||
# Teleport uses Go's regular expression syntax:
|
||||
# https://github.com/google/re2/wiki/Syntax
|
||||
# The list example above can be expressed as:
|
||||
# 'region': '^us-west-1|eu-central-1$'
|
||||
'cluster_name': '^us.*\.example\.com$'
|
||||
|
||||
# kubernetes_resources indicates the Kubernetes resources that a user with
|
||||
|
@ -178,7 +183,7 @@ spec:
|
|||
'env': '{{regexp.replace(external.access["env"], "^(staging)$", "$1")}}'
|
||||
|
||||
# app_labels: a user with this role will be allowed to connect to
|
||||
# applications, which labels match expressions below.
|
||||
# applications with labels matching below.
|
||||
app_labels:
|
||||
# A user can only access prod environments
|
||||
'env': 'prod'
|
||||
|
@ -198,6 +203,30 @@ spec:
|
|||
# A user is given group membership to production related groups.
|
||||
'env': 'prod'
|
||||
|
||||
# cluster_labels: a user with this role will be allowed to connect to remote
|
||||
# clusters with labels matching below.
|
||||
cluster_labels:
|
||||
'env': 'prod'
|
||||
|
||||
# node_labels_expression has the same purpose as node_labels but
|
||||
# supports predicate expressions to configure custom logic.
|
||||
# A user with this role will be allowed to access nodes if they are in the
|
||||
# staging environment *or* if they belong to one of the user's own teams.
|
||||
node_labels_expression: |
|
||||
labels["env"] == "staging" ||
|
||||
contains(user.spec.traits["teams"] , labels["team"])
|
||||
|
||||
# The below <kind>_labels_expression fields have the same purpose of the
|
||||
# matching <kind>_labels fields, but support predicate expressions instead
|
||||
# of label matchers.
|
||||
app_labels_expression: 'labels["env"] == "staging"'
|
||||
cluster_labels_expression: 'labels["env"] == "staging"'
|
||||
kubernetes_labels_expression: 'labels["env"] == "staging"'
|
||||
db_labels_expression: 'labels["env"] == "staging"'
|
||||
db_service_labels_expression: 'labels["env"] == "staging"'
|
||||
windows_desktop_labels_expression: 'labels["env"] == "staging"'
|
||||
group_labels_expression: 'labels["env"] == "staging"'
|
||||
|
||||
# aws_role_arns allows a user with this role to assume AWS roles when
|
||||
# accessing AWS console using UI or AWS API using CLI
|
||||
aws_role_arns:
|
||||
|
@ -245,12 +274,12 @@ spec:
|
|||
|
||||
# the `claims_to_roles` mapping works the same as it does in
|
||||
# the OIDC connector, with the added benefit that the roles being mapped to
|
||||
# can also be matchers.
|
||||
# can also be matchers.
|
||||
#
|
||||
# This example leverages Teleport's regular expression support, which allows
|
||||
# This example leverages Teleport's regular expression support, which allows
|
||||
# for dynamic mapping from claims. The below mapping says that users with
|
||||
# claims that match "projects: project-(.*)" can request roles that match
|
||||
# "$1-admin", where "$1" is the first capture group in the
|
||||
# claims that match "projects: product-(.*)" can request roles that match
|
||||
# "$1-admin", where "$1" is the first capture group in the
|
||||
# regular expression.
|
||||
# Example: the "projects: product-foo" claim allows a user to request the
|
||||
# "foo-admin" role
|
||||
|
|
|
@ -10,10 +10,12 @@ The predicate language uses a slightly different syntax depending on whether it
|
|||
|
||||
- [Role resources](#scoping-allowdeny-rules-in-role-resources)
|
||||
- [Resource filtering](#resource-filtering)
|
||||
- [Label expressions](#label-expressions)
|
||||
|
||||
## Scoping allow/deny rules in role resources
|
||||
|
||||
Some fields in Teleport's role resources use the predicate language to define the scope of a role's permissions:
|
||||
Some fields in Teleport's role resources use the predicate language to define
|
||||
the scope of a role's permissions:
|
||||
|
||||
- [Dynamic Impersonation](../access-controls/guides/impersonation.mdx#filter-fields)
|
||||
- [RBAC for sessions](../access-controls/reference.mdx#filter-fields)
|
||||
|
@ -37,8 +39,8 @@ The language also supports the following functions:
|
|||
|
||||
## Resource filtering
|
||||
|
||||
Both the [`tsh`](cli.mdx#tsh) and [`tctl`](cli.mdx#tctl) CLI tools allow you to filter nodes,
|
||||
applications, databases, and Kubernetes resources using the `--query` flag. The `--query` flag allows you to
|
||||
Both the [`tsh`](cli.mdx#tsh) and [`tctl`](cli.mdx#tctl) CLI tools allow you to filter nodes,
|
||||
applications, databases, and Kubernetes resources using the `--query` flag. The `--query` flag allows you to
|
||||
perform more sophisticated searches using the predicate language.
|
||||
|
||||
For common resource fields, we defined shortened field names that can easily be accessed by:
|
||||
|
@ -68,3 +70,54 @@ The language also supports the following functions:
|
|||
| `search("foo", "bar", "some phrase")` | fuzzy match against common resource fields |
|
||||
|
||||
See some [examples](cli.mdx#filter-examples) of the different ways you can filter resources.
|
||||
|
||||
## Label expressions
|
||||
|
||||
<Admonition type="warning">
|
||||
Label expressions are available starting in Teleport version `13.1.1`.
|
||||
All components of your Teleport cluster must be upgraded to version `13.1.1`
|
||||
or newer before you will be able to use label expressions.
|
||||
This includes the Auth Service and **all** Teleport agents.
|
||||
</Admonition>
|
||||
|
||||
Label expressions can be used in Teleport roles to define access to resources
|
||||
with custom logic.
|
||||
Check out the Access Controls
|
||||
[reference page](../access-controls/reference.mdx#label-expressions)
|
||||
for an overview of label expressions and where they can be used.
|
||||
|
||||
Label expressions support a predicate language with the following fields
|
||||
available:
|
||||
|
||||
| Field | Type | Description |
|
||||
|--------------------|-------------------------|-------------|
|
||||
| `labels` | `map[string]string` | Combined static and dynamic labels of the resource (server, application, etc.) being accessed. |
|
||||
| `user.spec.traits` | `map[string][]string` | All traits of the user accessing the resource (referred to as `external` or `internal` in role template expressions). |
|
||||
|
||||
The language supports the following functions:
|
||||
|
||||
| Syntax | Return type | Description | Example |
|
||||
|--------|-------------|-------------|---------|
|
||||
| `contains(list, item)` | Boolean | Returns true if `list` contains an exact match for `item` | `contains(user.spec.traits[teams], labels["team"])` |
|
||||
| `regexp.match(list, re)` | Boolean | Returns true if `list` contains a match for `re` | `regexp.match(labels["team"], "dev-team-\d+$")` |
|
||||
| `regexp.replace(list,` `re, replacement)` | `[]string` | Replaces all matches of `re` with replacement for all items in `list` | `contains(regexp.replace(user.spec.traits["allowed-env"],` `"^env-(.*)$", "$1"), labels["env"])`
|
||||
| `email.local(list)` | `[]string` | Returns the local part of each email in `list`, or an error if any email fails to parse | `contains(email.local(user.spec.traits["email"]),` `labels["owner"])`
|
||||
| `strings.upper(list)` | `[]string` | Converts all items of the list to uppercase | `contains(strings.upper(user.spec.traits["username"]),` `labels["owner"])`
|
||||
| `strings.lower(list)` | `[]string` | Converts all items of the list to lowercase | `contains(strings.lower(user.spec.traits["username"]),` `labels["owner"])`
|
||||
| `labels_matching(re)` | `[]string` | Returns the aggregate of all label values with keys matching `re`, which can be a glob or a regular expression | `contains(labels_matching("^project-(team\|label)$"),` `"security")`
|
||||
| `contains_any(list, items)` | Boolean | Returns true if `list` contains an exact match for any element of `items` | `contains_any(user.spec.traits["projects"],` `labels_matching("project-*"))` |
|
||||
| `contains_all(list, items)` | Boolean | Returns true if `list` contains an exact match for all elements of `items` | `contains_all(user.spec.traits["projects"],` `labels_matching("project-*"))` |
|
||||
|
||||
Above, any argument named `list` can accept a list of values (like the list of
|
||||
values for a specific user trait) or a single value (like the value of a
|
||||
resource label or a string literal).
|
||||
|
||||
The language also supports the following operators:
|
||||
|
||||
| Operator | Meaning | Example |
|
||||
|----------|-------------------------------------|---------|
|
||||
| == | equal to | `labels["env"] == "staging"` |
|
||||
| != | not equal to | `labels["env"] != "production"` |
|
||||
| \|\| | or (any one condition should match) | `labels["env"] == "staging" \|\| labels["env"] == "test"` |
|
||||
| && | and (all conditions must match) | `labels["env"] == "staging" && labels["team"] == "dev"` |
|
||||
| ! | not (logical negation) | `!regexp.match(user.spec.traits["teams"], "contractor")` |
|
||||
|
|
Loading…
Reference in a new issue