Scaling Privileged Access for Modern Infrastructure: Real-World Insights
Apr 25
Register Today
Teleport logoTry For Free
Fork me on GitHub


Run Teleport Access Graph on Self-Hosted Clusters with Helm

Using Access Graph with a self-hosted Teleport cluster requires setting up the Teleport Access Graph (TAG) service. TAG is a dedicated service which uses PostgreSQL as its backing storage and communicates with Auth Service and Proxy Service to collect information about resources and access.

This guide will help you set up the TAG service in a Kubernetes cluster using a Helm Chart, and enable the Access Graph feature in your Teleport cluster.

The full listing of supported parameters can be found in the teleport-access-graph Helm chart reference.

Teleport Access Graph is a feature of the Teleport Policy product that is only available to Teleport Enterprise customers.


  • Kubernetes >= v1.21
  • Helm >= 3.4.2
  • A running Teleport Enterprise cluster v14.3.4 or later.
    • For the purposes of this guide, we assume that the Teleport cluster is set up using the teleport-cluster Helm chart in the same Kubernetes cluster that will be used to deploy Teleport Access Graph .
  • An updated license.pem with Teleport Policy enabled.
  • A PostgreSQL database server v14 or later.
    • Access Graph needs a dedicated database to store its data. The user that TAG connects to the database with needs to be the owner of this database, or have similar broad permissions: at least the CREATE TABLE privilege on the public schema, and the CREATE SCHEMA privilege.
    • Amazon RDS for PostgreSQL is supported.
  • A TLS certificate for the Access Graph service
    • The TLS certificate must be issued for "server authentication" key usage, and must contain a X.509 v3 subjectAltName extension with the Kubernetes service name for TAG (teleport-access-graph.teleport-access-graph.svc.cluster.local by default).

Step 1/4. Add the Teleport Helm chart repository

Set up the Teleport Helm repository.

Allow Helm to install charts that are hosted in the Teleport Helm repository:

helm repo add teleport

Update the cache of charts from the remote repository so you can upgrade to all available releases:

helm repo update

Step 2/4. Set up the Teleport Access Graph service

You will need a copy of your Teleport cluster's host certificate authority (CA). TAG requires incoming connections to be authenticated via host certificates that the host CA issues to the Auth Service and Proxy Service.

The host CA can be retrieved in one of the following ways:

curl ''
tsh login
tctl get cert_authorities --format=json \ | jq -r '.[] | select(.spec.type == "host") | .spec.active_keys.tls[].cert' \ | base64 -d

Then, create the namespace and required secrets for the TAG deployment. You can skip the final command if you are instead using cert-manager to issue the certificate, or otherwise have already provisioned the TLS certificate for Teleport Access Graph in your Kubernetes cluster.

kubectl create namespace teleport-access-graph
kubectl -n teleport-access-graph create secret generic teleport-access-graph-postgres \ --from-literal uri="postgres://access_graph_user:[email protected]:5432/access_graph_db?sslmode=require"
kubectl -n teleport-access-graph create secret tls teleport-access-graph-tls --cert=./certs/cert.crt --key=./certs/cert.key

The above commands assume that you have the TLS certificate and private key for the TAG server stored under the ./certs directory.

The following script can be used to quickly generate a certificate authority and server TLS certificate for deploying TAG.

#!/usr/bin/env bash

set -e

mkdir -p ./certs
cd ./certs

openssl genrsa -aes256 -out ca.key 4096
openssl req -x509 -new -key ca.key -sha256 -days 3652 -out ca.crt -subj '/CN=root'
openssl req -new -out cert.csr -newkey rsa:4096 -nodes -keyout cert.key -subj '/CN=Access Graph'
openssl x509 -req -in cert.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out cert.crt -days 3652 -sha256 \
  -extfile <(printf 'extendedKeyUsage = serverAuth, clientAuth\nsubjectAltName = DNS:teleport-access-graph.teleport-access-graph.svc.cluster.local')

echo "Certificates issued successfully"

The script will ask to input the same password 4 times: twice to create and confirm the password to encrypt the CA private key material with, then once to use the private key to self-sign the CA certificate, and finally once to use for signing the TAG server certificate.

Please note that this script is only provided for proof-of-concept deployments, and may not follow the best security practices.

After provisioning the secrets, create the following file named tag-values.yaml file for the TAG deployment, replacing the value under the clusterHostCAs key with the Teleport Host CA certificate retrieved previously.

  secretName: "teleport-access-graph-postgres"

  # You may need to change this value if using cert-manager or other means
  # to provision TLS certificates for your Kubernetes workloads.
  existingSecretName: "teleport-access-graph-tls"

  # Replace this with the certificate retrieved in Step 1.
  # `clusterHostCAs` is an array of multiline YAML strings, `- |` must not be removed, and the indentation must be kept.
  - |
    -----END CERTIFICATE-----

Finally, deploy the TAG service using Helm:

helm install -n teleport-access-graph -f tag-values.yaml --version 1.13.0 teleport-access-graph teleport/teleport-access-graph
kubectl -n teleport-access-graph rollout status deployment/teleport-access-graph # Wait for the deployment to succeed

Step 3/4. Update the Teleport Auth Service configuration

To enable connectivity between the Teleport Auth Service and the Teleport Access Graph Service, the Auth Service configuration needs to be updated with:

  • The TAG service address
  • The path to the CA which issued the TAG service TLS certificate.
    • This path must refer to a volume containing the CA, mounted on the Teleport pods.
    • Specifying the CA certificate file can be skipped if you are using a CA that is already trusted by the Teleport cluster (e.g. via the tls.existingCASecretName option), or if the certificate was issued by a CA included in the Mozilla CA Certificate List.

Create a ConfigMap containing the CA certificate as follows:

kubectl -n teleport-cluster-namespace create configmap teleport-access-graph-ca \ --from-file=ca.pem=./certs/ca.crt

Then, update the values for the deployment of the teleport-cluster Helm chart as follows:

    # <...>

    # Add a section for configuring the Teleport Access Graph connection.
      enabled: true
      endpoint: teleport-access-graph.teleport-access-graph.svc.cluster.local:443
      # Omit the `ca` key if your Teleport cluster already trusts the issuing CA.
      ca: /var/run/access-graph/ca.pem

# Provide the TAG CA to the Teleport Auth Service as a volume.
# Omit all of the below if your Teleport cluster already trusts the issuing CA.
  - name: tag-ca
      name: teleport-access-graph-ca

  - name: tag-ca
    mountPath: /var/run/access-graph

If not using the teleport-cluster Helm chart, you will need to do the equivalent changes to your Teleport cluster deployment:

  • Add the access_graph: section at the top-level of the YAML config file for the Teleport Auth Service.
  • Mount the created ConfigMap as a volume so that the Auth Service can read the CA certificate.

Finally, redeploy the Helm chart (assuming the values are stored in values-teleport.yaml). Once the Auth Service changes succeed, restart the Proxy Service.

helm upgrade -n teleport-cluster-namespace -f values-teleport.yaml \ --version <version> teleport-cluster-deployment-name teleport/teleport-cluster
kubectl -n teleport-cluster-namespace rollout status deployment/teleport-auth # Wait for the deployment to succeed
kubectl -n teleport-cluster-namespace rollout restart deployment/teleport-proxy
kubectl -n teleport-cluster-namespace rollout status deployment/teleport-proxy # Wait for the deployment to succeed

Step 4/4. View the Access Graph in the Web UI

You can find the Access Graph in the "Access Management" tab in the Web UI.

Access Management menu item

To access the interface, your user must have a role that allows list and read verbs on the access_graph resource, e.g.:

kind: role
version: v7
  name: my-role
    - resources:
      - access_graph
      - list
      - read

The preset editor role has the required permissions by default.