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


Web Application Access

Download the latest version of Teleport for your platform from the downloads page and follow the installation instructions.

Start Auth/Proxy service

Create a configuration file for a Teleport service that will be running the Auth and Proxy Services:

  data_dir: /var/lib/teleport
  enabled: "yes"
  enabled: "yes"
  # Set public address proxy will be reachable at.
  enabled: "no"

When running Teleport in production, you should adhere to the following best practices to avoid security incidents:

  • Avoid using sudo in production environments unless it's necessary.
  • Create new, non-root, users and use test instances for experimenting with Teleport.
  • Run Teleport's services as a non-root user unless required. Only the SSH Service requires root access. Note that you will need root permissions (or the CAP_NET_BIND_SERVICE capability) to make Teleport listen on a port numbered < 1024 (e.g. 443).
  • Follow the principle of least privilege. Don't give users permissive roles when more a restrictive role will do. For example, don't assign users the built-in access,editor roles, which give them permissions to access and edit all cluster resources. Instead, define roles with the minimum required permissions for each user and configure access requests to provide temporary elevated permissions.
  • When you enroll Teleport resources—for example, new databases or applications—you should save the invitation token to a file. If you enter the token directly on the command line, a malicious user could view it by running the history command on a compromised system.

You should note that these practices aren't necessarily reflected in the examples used in documentation. Examples in the documentation are primarily intended for demonstration and for development environments.

Configure your Teleport instance to start automatically when the host boots up by creating a systemd service for it. The instructions depend on how you installed your Teleport instance.

On the host where you will run your Teleport instance, enable and start Teleport:

sudo systemctl enable teleport
sudo systemctl start teleport

On the host where you will run your Teleport instance, create a systemd service configuration for Teleport, enable the Teleport service, and start Teleport:

sudo teleport install systemd -o /etc/systemd/system/teleport.service
sudo systemctl enable teleport
sudo systemctl start teleport

You can check the status of your Teleport instance with systemctl status teleport and view its logs with journalctl -fu teleport.

Generate a token

A join token is required to authorize a Teleport Application Service to join the cluster. Generate a short-lived join token and save it for example in /tmp/token:

Log in to your cluster with tsh so you can use tctl from your local machine.

You can also run tctl on your Auth Service host without running "tsh login"


tsh login --user=myuser
tctl tokens add \ --type=app \ --app-name=grafana \ --app-uri=http://localhost:3000

TLS requirements

TLS is required to secure the Teleport Access Platform and any connected applications. When setting up Teleport, the minimum requirement is a certificate for the Teleport Proxy Service and a wildcard certificate for its sub-domain. This is where everyone will log into Teleport.

Application Access and DNS

Teleport assigns a subdomain to each application you configure for Application Access. For example, if you enroll Grafana as a resource, Teleport assigns the resource to the subdomain.

If you host the Teleport cluster on your own network, you should update your DNS configuration to account for application subdomains. You can update DNS in one of two ways:

  • Create a single DNS address (A) or canonical name (CNAME) record using wildcard substitution for the subdomain name. For example, create a DNS record with the name *
  • Create a separate DNS address (A) or canonical name (CNAME) record for each application subdomain.

Modifying DNS ensures that the certificate authority—for example, Let's Encrypt—can issue a certificate for each subdomain and that clients can verify Teleport hosts regardless of the application they are accessing.

If you use the Teleport cloud platform, no DNS updates are needed because your Teleport cluster automatically provides the subdomains and signed TLS certificates for your applications under your tenant address.

In this example:

  • hosts the Teleport Auth Service and the Teleport Proxy Service that are the that form the core cluster services of the Teleport Access Platform.
  • * hosts all of the applications, for example,

If you are running Teleport on the internet, we recommend using Let's Encrypt to receive your key and certificate automatically. For private networks or custom deployments, use your own private key and certificate.

Let's Encrypt verifies that you control the domain name of your Teleport cluster by communicating with the HTTPS server listening on port 443 of your Teleport Proxy Service.

You can configure the Teleport Proxy Service to complete the Let's Encrypt verification process when it starts up.

On the host where you will start the Teleport Auth Service and Proxy Service, run the following teleport configure command. Assign to the domain name of your Teleport cluster and [email protected] to an email address used for notifications (you can use any domain):

sudo teleport configure -o file \ --acme --acme-email=[email protected] \

Port 443 on your Teleport Proxy Service host must allow traffic from all sources.

On your Teleport host, place a valid private key and a certificate chain in /var/lib/teleport/privkey.pem and /var/lib/teleport/fullchain.pem respectively.

The leaf certificate must have a subject that corresponds to the domain of your Teleport host, e.g., *

On the host where you will start the Teleport Auth Service and Proxy Service, run the following teleport configure command. Assign to the domain name of your Teleport cluster.

sudo teleport configure -o file \ \ \ --cert-file=/var/lib/teleport/fullchain.pem \ --key-file=/var/lib/teleport/privkey.pem

Create a user

A Teleport user needs their role's permission to access an application. Teleport comes with a built-in access role that grants access to all apps:

tctl --config=/path/to/teleport.yaml users add --roles=access appuser

Start the Application Service with CLI flags

Install Teleport:

Install Teleport on your Linux server:

  1. Assign edition to one of the following, depending on your Teleport edition:

    Teleport Enterprise Cloudcloud
    Teleport Enterprise (Self-Hosted)enterprise
    Teleport Community Editionoss
  2. Get the version of Teleport to install. If you have automatic agent updates enabled in your cluster, query the latest Teleport version that is compatible with the updater:
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/automaticupgrades/channel/default/version | sed 's/v//')"

    Otherwise, get the version of your Teleport cluster:
    TELEPORT_VERSION="$(curl https://$TELEPORT_DOMAIN/v1/webapi/ping | jq -r '.server_version')"
  3. Install Teleport on your Linux server:

    curl | bash -s ${TELEPORT_VERSION} edition

    The installation script detects the package manager on your Linux server and uses it to install Teleport binaries. To customize your installation, learn about the Teleport package repositories in the installation guide.

You can start the Teleport Application Service with a single CLI command:

sudo teleport start \ --roles=app \ --token=/tmp/token \ \ --app-name="grafana" \ --app-uri="http://localhost:3000" \ --labels=env=dev

Note that the --auth-server flag must point to the Teleport cluster's proxy endpoint because the Application Service always connects back to the cluster over a reverse tunnel.

Application name

An application name should make a valid sub-domain (<=63 characters, no spaces, only a-z 0-9 - allowed).

After Teleport is running, users can access the app at e.g. You can also override public_addr e.g if you configure the appropriate DNS entry to point to the Teleport proxy server.

Start the Teleport Application Service with a config file

Example teleport.yaml configuration:

version: v3
  # Data directory for the Application Proxy service. If running on the same
  # node as Auth/Proxy service, make sure to use different data directories.
  data_dir: /var/lib/teleport-app
  # Instructs the service to load the auth token from the specified file
  # during initial registration with the cluster.
  auth_token: /tmp/token
  # Proxy address to connect to. Note that it has to be the proxy address
  # because the app service always connects to the cluster over a reverse
  # tunnel.
    enabled: yes
    # Teleport provides a small debug app called "dumper" that can be used
    # to make sure application access is working correctly. It outputs JWTs,
    #  so it can be useful when extending your application.
    debug_app: true
    # This section contains definitions of all applications proxied by this
    # service. It can contain multiple items.
      # Name of the application. Used for identification purposes.
    - name: "grafana"
      # URI and port the application is available at.
      uri: "http://localhost:3000"
      # Optional application public address to override.
      public_addr: ""
      # Optional static labels to assign to the app. Used in RBAC.
        env: "prod"
      # Optional dynamic labels to assign to the app. Used in RBAC.
      - name: "os"
        command: ["/usr/bin/uname"]
        period: "5s"
  enabled: "no"
  enabled: "no"
  enabled: "no"

Start the Application Service:

sudo teleport start --config=/path/to/teleport.yaml

Advanced options

Running the dumper application

For testing and debugging purposes, we provide a built-in debug app called "dumper". It can be turned on using debug_app: true.

   enabled: yes
   debug_app: true

The dumper app will dump all the request headers in the response.

Customize public address

By default applications are available at <app-name>.<proxy-host>:<proxy-port> address. To override the public address, specify the public_addr field:

- name: "jira"
  uri: "https://localhost:8001"
  public_addr: ""

Skip TLS certificate verification

Danger Zone

This is insecure and not recommended for use in production.

Teleport checks if the certificates presented by the applications are signed by a trusted Certificate Authority. When using self-signed certificates for internal applications, use insecure_skip_verify: true to skip this verification step:

- name: "app"
  uri: "https://localhost:8443"
  public_addr: ""
  insecure_skip_verify: true

Some applications are available in a subdirectory. Examples include the Kubernetes Dashboard.. The URI should be updated to include the subdirectory:

- name: "k8s"
  uri: ""
  public_addr: ""

Rewrite redirect

To support web apps that perform internal redirects, application access provides an option to rewrite the hostname of the Location header on redirect responses to the application's public address:

- name: "jenkins"
  uri: "https://localhost:8001"
  public_addr: ""
    # Rewrite the "Location" header on redirect responses replacing the
    # host with the public address of this application.
    - "localhost"
    - ""

Headers passthrough

You can configure application access to inject additional headers in the requests forwarded to a web application.

For apps defined in the teleport.yaml configuration, the headers field of each app is a list of strings. Be careful to quote the entire value to ensure it is parsed correctly.

- name: "dashboard"
  uri: https://localhost:4321
    # Inject a static header.
    - "X-Custom-Header: example"
    # Inject headers with internal/external user traits.
    - "X-Internal-Trait: {{internal.logins}}"
    - "X-External-Trait: {{external.env}}"
    # Inject header with Teleport-signed JWT token.
    - "Authorization: Bearer {{internal.jwt}}"
    # Override Host header.
    - "Host:"

In a dynamic app resource, configure header rewrites with the spec.rewrite.headers field. The value is a list of mappings that specify the name and value of each header you would like to rewrite.

kind: app
version: v3
  name: "dashboard"
  uri: https://localhost:4321
      # Inject a static header.
      - name: X-Custom-Header
        value: example
      # Inject headers with internal/external user traits.
      - name: X-Internal-Trait
        value: "{{internal.logins}}"
      - name: X-External-Trait
        value: "{{external.env}}"
      # Inject header with Teleport-signed JWT token.
      - name: Authorization
        value: "Bearer {{internal.jwt}}"
      # Override Host header.
      - name: Host

Headers injected this way override any headers with the same names that may be sent by an application. The following headers are reserved and can't be rewritten:

  • Teleport-Jwt-Assertion
  • Cf-Access-Token
  • Any header matching the pattern X-Teleport-*
  • Any header matching the pattern X-Forwarded-*

Rewritten header values support the same templating variables as role templates. In the example above, X-Internal-Trait header will be populated with the value of internal user trait logins and X-External-Trait header will get the value of the user's external env trait coming from the identity provider.

Additionally, the {{internal.jwt}} template variable will be replaced with a JWT token signed by Teleport that contains user identity information. See Integrating with JWTs for more details.

For full details on configuring Teleport roles, including how Teleport populates the external and internal traits, see the Teleport Access Controls Reference.

Configuring the JWT token

By default, Teleport includes a user's roles and traits in the JWT generated for application access. If your application doesn't care about these values, or you are encountering an error due to exceeding the size limit of HTTP headers, you can configure Teleport to omit this information from the token.

- name: "dashboard"
  uri: https://localhost:4321
    # Specify whether to include roles or traits in the JWT.
    # Options:
    # - roles-and-traits: include both roles and traits
    # - roles: include only roles
    # - traits: include only traits
    # - none: exclude both roles and traits from the JWT token
    # Default: roles-and-traits
    jwt_claims: roles-and-traits
    # Inject header with Teleport-signed JWT token.
    - "Authorization: Bearer {{internal.jwt}}"

View applications in Teleport

Teleport provides a UI for quickly launching connected applications.

They can be viewed by navigating to a cluster's web UI and selecting the "Applications" tab. The URL structure looks like this:


Logging out of applications

When you log into an application, you'll get a certificate and login session per your defined RBAC. If you want to force log out before this period you can do so by hitting the /teleport-logout endpoint: