AWS Cross-Account Database Access
You can deploy the Teleport Database Service with AWS IAM credentials in one AWS account and use an AWS IAM role to grant Teleport access to databases in another AWS account.
AWS cross-account database access is available starting from Teleport 13.0
.
When the Teleport Database Service needs to discover, configure, or retrieve short-lived authentication tokens for AWS databases, it uses credentials for an AWS IAM identity to make requests to the AWS API. To access resources across AWS accounts, you can configure the Teleport Database Service to assume an AWS role in another account before it uses the AWS API for further actions.
This is not limited to a single AWS role: the Teleport Database Service can be configured to connect databases in its own AWS account and multiple external AWS accounts at the same time.
You will need to configure the Teleport Database Service to assume an AWS IAM
role and ensure that AWS IAM permissions are configured to allow the
AssumeRole
call.
You should also check that your network configuration in AWS allows the Teleport Database Service to connect to the databases.
This guide does not cover AWS network configuration, because it depends on your specific AWS network setup and the kind(s) of AWS databases you wish to connect to Teleport. For more information, see how to connect your database.
Teleport configuration
The Teleport Database Service must be configured to assume an external AWS IAM
role and, optionally, pass an external ID when it assumes that role.
The configured AWS IAM role will be assumed via an AWS STS AssumeRole
call
before the Teleport Database Service uses the AWS API to discover, configure, or retrieve
short-lived authentication tokens for AWS databases.
An "external ID" is used to address what AWS calls
the confused deputy problem.
When you configure the Teleport Database Service to use an external ID, it will
include that external ID when it calls AWS STS AssumeRole
.
The external AWS IAM role's trust policy will be used to verify that the
correct external ID was provided in the AssumeRole
call.
For information about when you should use an external ID, see:
purpose of an AWS external ID.
AWS database discovery config, static database config, and dynamic database
config all support the assume_role_arn
and external_id
settings.
- AWS Discovery
- Static Config
- Dynamic Config
Modify your Teleport Database Service configuration file to assume an external AWS IAM role when it is discovering AWS databases.
# This example configuration will discover AWS RDS databases in us-west-1
# within AWS account `222222222222` by assuming the external AWS IAM role
# "example-role".
db_service:
enabled: "yes"
aws:
- types: ["rds"]
regions: ["us-west-1"]
assume_role_arn: "arn:aws:iam::222222222222:role/example-role"
external_id: "example-external-id"
Restart the Teleport Database Service for the configuration file changes to take effect.
The AWS IAM role used to discover a database will also be used by the Teleport Database Service to provide access to that database.
Modify your Teleport Database Service configuration file to statically register an AWS database in an external account and proxy connections to it.
# This example configuration will statically register an RDS PostgreSQL instance
# in us-west-1 within AWS account `222222222222` by assuming an external AWS
# IAM role "example-role".
db_service:
enabled: "yes"
databases:
- name: "rds-postgres"
protocol: "postgres"
uri: "rds-postgres.abcdef012345.us-west-1.rds.amazonaws.com:5432"
aws:
assume_role_arn: "arn:aws:iam::222222222222:role/example-role"
external_id: "example-external-id"
Restart the Teleport Database Service for the configuration file changes to take effect.
Create a dynamic database resource to dynamically register an AWS database in an external account and proxy connections to it.
# This example configuration will dynamically register an RDS PostgreSQL instance
# in us-west-1 within AWS account `222222222222`.
# Teleport Database Service agents that match its labels with resource selectors
# will proxy the database by assuming the configured external AWS IAM role.
kind: db
version: v3
metadata:
name: "rds-postgres"
description: "Example dynamic database resource"
labels:
env: "dev"
spec:
protocol: "postgres"
uri: "rds-postgres.abcdef012345.us-west-1.rds.amazonaws.com:5432"
aws:
# Note that account_id must match the AWS account ID in `assume_role_arn`.
# Dynamic database resources do not derive `account_id` from
# `assume_role_arn` automatically (unlike static configuration).
account_id: "222222222222"
assume_role_arn: "arn:aws:iam::222222222222:role/example-role"
external_id: "example-external-id"
Save the configuration to a file like database.yaml
and create it with tctl
:
$ tctl create database.yaml
For more information about database registration using dynamic database resources, see: Dynamic Registration.
Teleport AWS IAM identity
In order to assume an AWS IAM role, the Teleport Database Service will need credentials for an AWS IAM identity of its own.
Grant the Database Service access to credentials that it can use to authenticate to AWS. If you are running the Database Service on an EC2 instance, you may use the EC2 Instance Metadata Service method. Otherwise, you must use environment variables:
- Instance Metadata Service
- Environment Variables
Teleport will detect when it is running on an EC2 instance and use the Instance Metadata Service to fetch credentials.
The EC2 instance should be configured to use an EC2 instance profile. For more information, see: Using Instance Profiles.
Teleport's built-in AWS client reads credentials from the following environment variables:
AWS_ACCESS_KEY_ID
AWS_SECRET_ACCESS_KEY
AWS_DEFAULT_REGION
When you start the Database Service, the service reads environment variables from a
file at the path /etc/default/teleport
. Obtain these credentials from your
organization. Ensure that /etc/default/teleport
has the following content,
replacing the values of each variable:
AWS_ACCESS_KEY_ID=00000000000000000000
AWS_SECRET_ACCESS_KEY=0000000000000000000000000000000000000000
AWS_DEFAULT_REGION=<YOUR_REGION>
Have multiple sources of AWS credentials?
Teleport's AWS client loads credentials from different sources in the following order:
- Environment Variables
- Shared credentials file
- Shared configuration file (Teleport always enables shared configuration)
- EC2 Instance Metadata (credentials only)
While you can provide AWS credentials via a shared credentials file or shared
configuration file, you will need to run the Database Service with the AWS_PROFILE
environment variable assigned to the name of your profile of choice.
If you have a specific use case that the instructions above do not account for, consult the documentation for the AWS SDK for Go for a detailed description of credential loading behavior.
AWS IAM permissions
AWS IAM policies must be configured for both the Teleport Database Service's AWS IAM identity and the external AWS IAM role:
- The Teleport Database Service's AWS IAM identity must have permission to assume the external role.
- The external AWS IAM role's trust policy must trust the Teleport Database Service's AWS IAM identity.
Why are both required?
Unlike assuming a role within the same AWS account, when an AWS IAM role is in a different AWS account than the IAM identity that attempts to assume it, the role's trust policy alone is not sufficient to allow assuming the role.
For more details, see: AWS cross-account policy evaluation.
Teleport can bootstrap IAM permissions for the Database Service based on its
configuration using the teleport db configure bootstrap
command. You can use
this command in automatic or manual mode:
- In automatic mode, Teleport will attempt to create appropriate IAM policies and attach them to the specified IAM identity role. This requires IAM permissions to create and attach IAM policies.
- In manual mode, Teleport will print required IAM policies. You can then create and attach them manually using the AWS management console.
- Automatic IAM setup
- Manual IAM setup
Use this command to bootstrap the permissions automatically when your Teleport Database Service runs as an IAM role (for example, on an EC2 instance with an attached IAM role).
$ teleport db configure bootstrap -c /etc/teleport.yaml --attach-to-role teleport-db-service
Use this command to display required IAM policies which you will then create in your AWS console:
$ teleport db configure bootstrap -c /etc/teleport.yaml --manual --attach-to-role arn:aws:iam::123456789012:role/teleport-db-service
Bootstrapping with assume_role_arn in config
When assume_role_arn
is configured for databases or AWS matchers,
teleport db configure bootstrap
will determine permissions required for the
bootstrap target AWS IAM identity using the following logic:
- When the target does not match
assume_role_arn
in any database resource or AWS matcher in the configuration file, the target is assumed to be the Teleport Database Service's AWS IAM identity and permissions are bootstrapped for all the configured static databases and AWS matchers. - When an
--attach-to-role
target matches anassume_role_arn
setting for static databases or AWS matchers in the configuration file, permissions will be bootstrapped only for those static databases or AWS matchers.
You will need to run the bootstrap command once with the Teleport Database
Service's IAM identity as the policy attachment target, and once for each AWS
IAM role that is used for assume_role_arn
.
Specifically, the Teleport Database Service's AWS IAM identity must be granted
sts:AssumeRole
permission for the external AWS IAM role. For example:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "sts:AssumeRole",
"Resource": "arn:aws:iam::222222222222:role/example-role"
}
]
}
You will also need to configure permissions for the external AWS IAM role, specific to the type of database(s) that it will be used to access.
For example, suppose assume_role_arn
is set to
arn:aws:iam::222222222222:role/example-role
-
you can bootstrap permissions for it automatically by running the following
command with AWS credentials for account 222222222222
configured in your
shell:
$ teleport db configure bootstrap \
-c /etc/teleport.yaml \
--attach-to-role "example-role"
AWS IAM trust policy
Modify the external AWS IAM role's trust policy to allow the Teleport Database Service's AWS IAM identity as a trusted principal. If you require an external ID, provide a condition in the statement that allows the action only when the correct external ID is given.
For example, if the Teleport Database Service will be deployed to an EC2
instance with an attached role teleport-db-service
in AWS account
123456789012
, and you want to require an external ID to assume the external
role, then the trust policy might look like:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Statement1",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:role/teleport-db-service"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "example-external-id"
}
}
}
]
}
Next steps
- Get started by connecting your database.