Skip to main content

Beams Database Demo

Report an Issue

Teleport Beams allow you to grant AI agents access to your databases with restricted permissions to prevent their nondeterministic access patterns from causing harm.

In this guide, you will enroll a database with Teleport and prompt an AI agent to access the database from a Teleport beam. As this guide demonstrates, the restricted access you can provide to the database via Teleport RBAC ensures that the agent can only perform the expected set of operations on the database.

How it works

Teleport Beams are micro VM sandboxes for running agentic workloads, hosted on the Teleport Cloud infrastructure. When a user creates a beam, the Teleport Auth Service creates a delegation session that contains the user and their Teleport roles.

An instance of the tbot daemon on the beam receives the ID of the delegation session and queries the Auth Service to issue a fresh Teleport identity to services that run on the beam. As a result, any agentic workloads running on the beam delegate the originating user's Teleport permissions.

For Teleport-protected databases, this means that users who create a beam can run AI agents on the beam to access those databases, as long as the users have permissions to access those databases as well. With Teleport RBAC, you can limit the permissions that agentic workloads have to access your databases.

Prerequisites

You will need a Teleport Beams account. Start your free trial.

For simplicity, this guide walks you through a demo that enrolls a local PostgreSQL container with your Teleport cluster and configures RBAC for that database. Beams supports any Teleport-protected database, and comes with the PostgreSQL client tools out of the box.

To follow the local demo, you will need:

  • Docker installed on your workstation
  • Check that you can connect to your Teleport cluster and verify that you can run tctl and tsh commands using your current credentials.
    1. Assign teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email@example.com to your Teleport username.

    2. Authenticate to your Teleport cluster. This depends on whether your shell is interactive or not.

      In an interactive shell: Run the following command. By default, this triggers a multi-factor authentication prompt:

      tsh login --proxy=teleport.example.com --user=email@example.com
      tctl status

      Cluster teleport.example.com

      Version 19.0.0-dev

      CA pin sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678

      On non-interactive environments: If you are running tsh and tctl as an AI agent, in a CI/CD environment, or similar, make sure the TELEPORT_IDENTITY_FILE environment variable is assigned to a valid file path with credentials for your cluster. tsh and tctl read the file path from the environment variable and do not require a separate authentication step. If there is no identity file available, we recommend that you set up Machine ID to provision one automatically.

      When executing tctl commands with an identity file, you must pass the --auth-server flag to provide the Teleport Auth Service address, which is not included in the identity file. If you provide the Proxy Service address, tctl connects to the Proxy Service, which forwards traffic to and from the Teleport Auth Service. Update 443 to 3025 if you are contacting the Auth Service directly with tctl:

      tctl status --auth-server=teleport.example.com:443

      For tsh commands that read an identity file, you must pass the --proxy flag, which points tsh to the address of the Teleport Proxy Service:

      tsh status --proxy=teleport.example.com

      Ensure client commands can access your identity file. Replace path/to/identity/file with the path to your identity file:

      export TELEPORT_IDENTITY_FILE="${TELEPORT_IDENTITY_FILE:-path/to/identity/file}"

      Add the --auth-server or --proxy flags to all subsequent tctl and tsh commands.

    If you can connect to the cluster and run the tctl status command, you can use your current credentials to run subsequent tctl commands from your workstation. If you host your own Teleport cluster, you can also run tctl commands on the computer that hosts the Teleport Auth Service for full permissions.

Step 1/3. Enroll a database with Teleport

In this section, you will enroll a database with Teleport and configure RBAC for it. We recommend following this minimal example first for a demonstration of Beams in action.

tip

This section is not required if you already have a database enrolled and understand Teleport RBAC. If you have a database and a role you want to grant to your AI agent, skip to Step 2.

Start your local demo database

  1. On your workstation, create a local directory for the TLS credentials you want to mount on the PostgreSQL container:

    mkdir certs
  2. Retrieve mTLS credentials that your PostgreSQL container will use to trust the Teleport Database Service:

    tctl auth sign --format=db --host=postgres --out=certs/server --ttl=2160h
    TTL

    We recommend using a shorter TTL, but keep in mind that you'll need to update the database server certificate before it expires to not lose the ability to connect. Pick the TTL value that best fits your use-case.

    The command creates 3 files:

    • server.cas: The Database Client CA certificate, which your database uses to verify connections from the Teleport Database Service.
    • server.crt: A certificate for your database server, signed by the Database CA.
    • server.key: The private key for the server certificate.
  3. Create a local Docker bridge network for the PostgreSQL container and Teleport Database Service:

    docker network create local-postgres
  4. Generate a strong password for the superuser account in your PostgreSQL container. Export it in the terminal where you will run your PostgreSQL container:

    export POSTGRES_PASSWORD=<strong generated password>
  5. Spin up your database container, joining it to the local bridge network and mounting the TLS credentials you generated.

    This command assigns the POSTGRES_PASSWORD environment variable in the container because the image requires it, though we'll configure the container to enforce certificates for authentication. It also enables TLS using Teleport-issued credentials, which it changes the ownership of per the expectations of the postgres daemon. We do this inside the container to avoid unexpected ownership changes when Docker creates the bind mount:

    docker run -d \ --name postgres \ -e POSTGRES_PASSWORD \ -v ./certs:/certs \ --network local-postgres \ --entrypoint bash \ postgres:18 \ -c "chown 999:999 /certs/server.key \ && chmod 600 /certs/server.key \ && chmod 644 /certs/server.crt /certs/server.cas \ && exec docker-entrypoint.sh postgres \ -c ssl=on \ -c ssl_cert_file=/certs/server.crt \ -c ssl_key_file=/certs/server.key \ -c ssl_ca_file=/certs/server.cas"
  6. Require TLS for all connections by editing the PostgreSQL configuration file for host-based authentication and triggering a configuration reload. This authenticates all connections to the database from inside the container:

    docker exec postgres bash -c "echo 'local all all trust' > /var/lib/postgresql/18/docker/pg_hba.conf"
    docker exec postgres bash -c "echo 'hostssl all all 0.0.0.0/0 cert' >> /var/lib/postgresql/18/docker/pg_hba.conf"
    docker exec postgres psql -U postgres -c "SELECT pg_reload_conf()"

Configure the local demo database

Once the local demo database is running, we'll set it up to support our demo. We'll include two users, an admin who can perform all database operations and a read-only user who can only run SELECT queries against a single table.

  1. Create the admin role:

    docker exec postgres psql -U postgres -c "CREATE ROLE admin LOGIN SUPERUSER"
  2. Create a table to hold example data, and the read-only role that can query it:

    docker exec postgres psql -U postgres -c "CREATE TABLE users (id INT PRIMARY KEY, name TEXT, ssn TEXT)"
    docker exec postgres psql -U postgres -c "CREATE ROLE readonly LOGIN"
    docker exec postgres psql -U postgres -c "GRANT CONNECT ON DATABASE postgres TO readonly"
    docker exec postgres psql -U postgres -c "GRANT SELECT ON users TO readonly"
  3. Add some example data:

    docker exec postgres psql -U postgres -c "INSERT INTO users (id, name, ssn) VALUES (123, 'alice', '000-00-0000')"

Start the Teleport Database Service

Next, you will start the Teleport Database Service as a container on your workstation. The Teleport Database Service container initiates an SSH reverse tunnel to the Teleport Proxy Service in your cluster. When the AI agent that you'll run on your beam dials your database, the traffic flows through this reverse tunnel.

  1. Create a token for the Teleport Database Service to use to establish trust with your Teleport cluster.

    On your workstation, run the following command to retrieve a join token and write to a file called dbtoken that we'll use when starting the Database Service:

    tctl tokens add --type=db --ttl=15m --format=text > dbtoken
  2. Write a configuration file for the Teleport Database Service to your terminal's current working directory, at the path db-service-config.yaml, with the following content, replacing example.beams.sh with the address of your Teleport Proxy Service:

    teleport db configure create \ -o file:///$(pwd)/db-service-config.yaml \ --token=/tmp/token \ --proxy='example.beams.sh:443' \ --name=local-postgres \ --protocol=postgres \ --uri=postgres:5432 \ --labels=service=local-postgres

    Note that the Teleport Database Service reads the token from /tmp/token, the path on the container where you'll mount the token you generated earlier.

  3. Start the Teleport Database Service in the same local Docker network as the PostgreSQL container you launched earlier:

    docker run \ -v ./db-service-config.yaml:/etc/teleport/teleport.yaml \ -v ./dbtoken:/tmp/token \ --network local-postgres \ public.ecr.aws/gravitational/teleport-distroless:13.3.7
  4. After a minute or two, confirm that Teleport is proxying your PostgreSQL instance:

    tsh db ls
    Name Description Allowed Users Labels Connect-------------- ----------- ------------- ---------------------- -------local-postgres (none) service=local-postgres

Configure RBAC for your database

In this demo setup, we want to ensure that your AI agent can access your PostgreSQL instance only with a non-permissive role. AI agents running on a beam access Teleport-protected resources with the Teleport role of the user who accessed the beam.

In this section, you will create a user and role that can access the database as a read-only user.

  1. Define a role that can access your database only as the read-only user. Create a file called read-only-demo-postgres.yaml with the following content:

    version: v8
    kind: role
    metadata:
      name: read-only-demo-postgres
    spec:
      allow:
        db_labels:
          service: local-postgres
        db_users:
          - readonly
        db_names:
          - postgres
    
  2. Create the role:

    tctl create -f read-only-demo-postgres.yaml
  3. Create a user called dbdemo with the read-only-demo-postgres role:

    tctl users add --roles=read-only-demo-postgres,beam-user dbdemo
  4. Follow the instructions in your terminal to activate your user.

Step 2/3. Prepare your beam

Once you have a database enrolled with Teleport and a role for your AI agent user, you can create a beam, start an SSH session with it, and prompt the agent to access the database.

  1. Authenticate to Teleport as the dbdemo user you created in the last step and enter your credentials:

    tsh login --proxy=example.beams.sh --user=dbdemo
  2. Create a beam and access it:

    tsh beams add

This command starts an SSH session with the new beam.

Stay in the beam shell session for the next step.

Step 3/3. Prompt your agent

Prompt your agent to access the database.

  1. Start your LLM CLI. A beam initializes with claude and codex preinstalled. Start a session with your LLM agent that skips permission prompts. Even if your agent performs unexpected operations, nothing it does can exceed the limits you set using Teleport RBAC. Run one of the following commands:

    claude --dangerously-skip-permissions

    Or:

    codex --dangerously-bypass-approvals-and-sandbox
  2. Enter the following prompt:

    Access the PostgreSQL database with name local-postgres. Retrieve the SSN of
    user alice and update it to 999-99-9999.
    

The LLM should successfully find the current SSN but fail to update it. Here is one example agent summary:

● The readonly user doesn't have write permissions. That's the only allowed database user according to the
  Teleport configuration. I'm unable to perform the UPDATE — the database role readonly only has SELECT
  privileges on the users table.

  Summary:
  - Alice's current SSN is 000-00-0000 (id: 123)
  - The UPDATE to 999-99-9999 failed because the only available database user (readonly) lacks write permissions
   on the users table

  To complete the update, you'd need a database user with write privileges to be added to the Teleport database
  configuration.