Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1280,7 +1280,17 @@
},
{
"title": "Access Controls",
"slug": "/database-access/rbac/"
"slug": "/database-access/rbac/",
"entries": [
{
"title": "RBAC",
"slug": "/database-access/rbac/configuring-access/"
},
{
"title": "Automatic User Provisioning (Preview)",
"slug": "/database-access/rbac/configuring-auto-user-provisioning/"
}
]
},
{
"title": "Architecture",
Expand Down
7 changes: 5 additions & 2 deletions docs/cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
"cqlsh",
"createkey",
"createnongalleryapp",
"createrole",
"creds",
"crond",
"customizability",
Expand Down Expand Up @@ -752,5 +753,7 @@
"znmqk",
"zxvf"
],
"flagWords": ["hte"]
}
"flagWords": [
"hte"
]
}
4 changes: 4 additions & 0 deletions docs/pages/database-access/guides/postgres-self-hosted.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,7 @@ $ tsh db logout example-postgres
# Remove credentials for all database instances.
$ tsh db logout
```

## Next steps

- Set up [automatic database user provisioning](../rbac/configuring-auto-user-provisioning.mdx).
1 change: 1 addition & 0 deletions docs/pages/database-access/guides/rds.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -215,3 +215,4 @@ $ tsh db logout postgres-rds
## Next steps

(!docs/pages/includes/database-access/guides-next-steps.mdx!)
- Set up [automatic database user provisioning](../rbac/configuring-auto-user-provisioning.mdx).
138 changes: 8 additions & 130 deletions docs/pages/database-access/rbac.mdx
Original file line number Diff line number Diff line change
@@ -1,135 +1,13 @@
---
title: Database Role-Based Access Controls
description: Role-based access control (RBAC) for Teleport database access.
title: Database Access Control Guides
description: Role-based access control guides for Teleport database access.
---

Comment thread
r0mant marked this conversation as resolved.
Role-based access control (or RBAC, for short) allows administrators to set up
granular access policies for databases connected to Teleport.
These guides cover configuring access control policies for database users.

An example of a policy could be, *"database administrators have access to
everything, QA team and engineers have full access to staging databases, and
engineers can gain temporary access to the production database in case of
emergency"*.
Read the [RBAC](./rbac/configuring-access.mdx) guide to get a general understanding
of how to configure Teleport roles to grant or deny access to your database users.

For a more general description of Teleport roles and examples see [RBAC](../access-controls/introduction.mdx), as
this section focuses on configuring RBAC for database access.

## Role configuration

Teleport's "role" resource provides the following instruments for restricting
database access:

```yaml
kind: role
version: v5
metadata:
name: developer
spec:
allow:
# Label selectors for database instances this role has access to.
#
# These will be matched against the static/dynamic labels set on the
# database service.
db_labels:
environment: ["dev", "stage"]

# Database account names this role can connect as.
db_users: ["viewer", "editor"]

# Database names this role will be able to connect to.
#
# Note, this is not the same as the "name" field in "db_service", this is
# the database names within a particular database instance.
#
# Also note, this setting has effect only for PostgreSQL. It does not
# currently have any effect on MySQL databases/schemas.
db_names: ["main", "metrics", "postgres"]
```

It is possible to use wildcards to match any database names/users.

For example, the following role permits access to any database/user within a
production database except for the internal "postgres" database/user:

```yaml
kind: role
version: v5
metadata:
name: developer
spec:
allow:
db_labels:
environment: ["prod"]
db_users: ["*"]
db_names: ["*"]
deny:
db_users: ["postgres"]
db_names: ["postgres"]
```

<Admonition
type="note"
title="Deny Rules"
>
Deny rules will match greedily. In the example above, a database connection
attempting to use "postgres" database account (regardless of database instance
or database name) or "postgres" database name (regardless of database instance
or database account) will be rejected.
</Admonition>

## Database names

There's a distinction in how different database servers handle logical databases
which leads to a difference in how `db_names` role field is applied to a connection
attempt.

PostgreSQL supports multiple logical databases, and each logical database can
contain multiple schemas. In order to change to a different database, a user
disconnects from the current one and establishes a new connection. During a
PostgreSQL connection attempt, `db_names` field is checked against the name
of the logical database that the user is connecting to.

In MySQL a logical "database" and a "schema" are synonyms for each other, and
the scope of permissions a user has once connected is determined by the permission
grants set on the account within the database. As such, `db_names` role field
is not currently enforced on MySQL connection attempts.

## Template variables

Similar to other role fields, `db_*` fields support templating variables.

The `{{external.xyz}}` variables are replaced with values from external [SSO](../access-controls/sso.mdx)
providers. For OIDC, they will be expanded with a value of an "xyz" claim; for
SAML — with an "xyz" assertion value.

For example, here is what a role may look like if you want to assign allowed
database names from the user's Okta `databases` assertion:

```yaml
spec:
allow:
db_names: ["{{external.databases}}"]
```

The `{{internal.db_users}}` and `{{internal.db_names}}` variables permit sharing
allowed database accounts and names with remote clusters. They will be replaced
with the respective properties of a remote user connecting from a root cluster.

For example, suppose a user in the root cluster has the following role:

```yaml
spec:
allow:
db_users: ["postgres"]
db_names: ["postgres"]
```

The role on the leaf cluster can be set up to use the user's allowed database
accounts and names:

```yaml
spec:
allow:
db_users: ["{{internal.db_users}}"]
db_names: ["{{internal.db_names}}"]
```
The [Automatic User Provisioning](./rbac/configuring-auto-user-provisioning.mdx)
guide explains how to get Teleport to create accounts for your PostgreSQL users
on-demand.
135 changes: 135 additions & 0 deletions docs/pages/database-access/rbac/configuring-access.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
title: Database Access RBAC
description: Role-based access control (RBAC) for Teleport database access.
---

Role-based access control (or RBAC, for short) allows administrators to set up
granular access policies for databases connected to Teleport.

An example of a policy could be, *"database administrators have access to
everything, QA team and engineers have full access to staging databases, and
engineers can gain temporary access to the production database in case of
emergency"*.

For a more general description of Teleport roles and examples see [RBAC](../../access-controls/introduction.mdx), as
this section focuses on configuring RBAC for database access.

## Role configuration

Teleport's "role" resource provides the following instruments for restricting
database access:

```yaml
kind: role
version: v5
metadata:
name: developer
spec:
allow:
# Label selectors for database instances this role has access to.
#
# These will be matched against the static/dynamic labels set on the
# database service.
db_labels:
environment: ["dev", "stage"]

# Database account names this role can connect as.
db_users: ["viewer", "editor"]

# Database names this role will be able to connect to.
#
# Note, this is not the same as the "name" field in "db_service", this is
# the database names within a particular database instance.
#
# Also note, this setting has effect only for PostgreSQL. It does not
# currently have any effect on MySQL databases/schemas.
db_names: ["main", "metrics", "postgres"]
```

It is possible to use wildcards to match any database names/users.

For example, the following role permits access to any database/user within a
production database except for the internal "postgres" database/user:

```yaml
kind: role
version: v5
metadata:
name: developer
spec:
allow:
db_labels:
environment: ["prod"]
db_users: ["*"]
db_names: ["*"]
deny:
db_users: ["postgres"]
db_names: ["postgres"]
```

<Admonition
type="note"
title="Deny Rules"
>
Deny rules will match greedily. In the example above, a database connection
attempting to use "postgres" database account (regardless of database instance
or database name) or "postgres" database name (regardless of database instance
or database account) will be rejected.
</Admonition>

## Database names

There's a distinction in how different database servers handle logical databases
which leads to a difference in how `db_names` role field is applied to a connection
attempt.

PostgreSQL supports multiple logical databases, and each logical database can
contain multiple schemas. In order to change to a different database, a user
disconnects from the current one and establishes a new connection. During a
PostgreSQL connection attempt, `db_names` field is checked against the name
of the logical database that the user is connecting to.

In MySQL a logical "database" and a "schema" are synonyms for each other, and
the scope of permissions a user has once connected is determined by the permission
grants set on the account within the database. As such, `db_names` role field
is not currently enforced on MySQL connection attempts.

## Template variables

Similar to other role fields, `db_*` fields support templating variables.

The `{{external.xyz}}` variables are replaced with values from external [SSO](../../access-controls/sso.mdx)
providers. For OIDC, they will be expanded with a value of an "xyz" claim; for
SAML — with an "xyz" assertion value.

For example, here is what a role may look like if you want to assign allowed
database names from the user's Okta `databases` assertion:

```yaml
spec:
allow:
db_names: ["{{external.databases}}"]
```

The `{{internal.db_users}}` and `{{internal.db_names}}` variables permit sharing
allowed database accounts and names with remote clusters. They will be replaced
with the respective properties of a remote user connecting from a root cluster.

For example, suppose a user in the root cluster has the following role:

```yaml
spec:
allow:
db_users: ["postgres"]
db_names: ["postgres"]
```

The role on the leaf cluster can be set up to use the user's allowed database
accounts and names:

```yaml
spec:
allow:
db_users: ["{{internal.db_users}}"]
db_names: ["{{internal.db_names}}"]
```
Loading