--- title: Database Access Access Controls description: Role-based access control (RBAC) for Teleport Database Access. --- # Database Access Role-Based Access Control 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"] ``` 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. ## 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}}"] ```