Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/gravitational/teleport/llms.txt

Use this file to discover all available pages before exploring further.

Teleport Application Access lets you expose internal web applications to authorized users without opening firewall rules, deploying a VPN, or managing per-app credentials. The Teleport Application Service establishes a reverse tunnel to the Proxy Service and registers each configured application as a resource in your cluster. Users access protected apps through the Teleport Web UI or via a local proxy — after authenticating with your SSO provider and satisfying any MFA or access request requirements.

How Teleport proxies web applications

When a user navigates to a protected application, the request flows through the Teleport Proxy Service to the Application Service running in the same private network as the app:
[Browser / tsh] ──► [Proxy Service] ──► [App Service] ──► [Internal App]

                      [Auth Service]
                      Validates JWT,
                      enforces roles
Key properties:
  • No VPN required — the Application Service calls out to the Proxy; no inbound firewall rules are needed for the app host.
  • SSO-backed access — every access is tied to an authenticated Teleport identity.
  • JWT injection — Teleport adds a signed JWT header to every proxied request so your application can trust the caller’s identity without its own auth layer.
  • Audit trail — all application access events are recorded in the Teleport audit log.

Prerequisites

  • A running Teleport cluster. See Deploy a Cluster.
  • A host (VM or container) in the same network as the app, where the Application Service will run.
  • tctl authenticated to your Teleport cluster.
  • A wildcard DNS record pointing *.teleport.example.com (or *.mytenant.teleport.sh) to your Proxy Service. Teleport assigns each app a subdomain like grafana.teleport.example.com.

Enrolling a web application

The example below protects a Grafana instance running on localhost:3000. The same steps apply to any internal HTTP or TCP service.
1

Generate a join token for the Application Service

tctl tokens add \
  --type=app \
  --app-name=grafana \
  --app-uri=http://localhost:3000
Save the printed token to a file on the host where the Application Service will run:
# On your admin workstation
tctl tokens add --type=app --format=text > /tmp/app-token

# Copy it to the Application Service host
scp /tmp/app-token apphost:/tmp/app-token
2

Install Teleport on the Application Service host

curl https://goteleport.com/static/install.sh | bash -s (=teleport.version=)
3

Configure the Application Service

Generate a teleport.yaml configuration on the Application Service host:
sudo teleport configure \
  --output=file \
  --proxy=mytenant.teleport.sh:443 \
  --token=/tmp/app-token \
  --roles=app \
  --app-name=grafana \
  --app-uri=http://localhost:3000
The generated /etc/teleport.yaml enables only the Application Service:
version: v3
teleport:
  proxy_server: teleport.example.com:443
  auth_token: /tmp/app-token

app_service:
  enabled: true
  apps:
    - name: grafana
      description: "Grafana dashboards"
      uri: http://localhost:3000
      # Optional: apply labels for RBAC targeting
      labels:
        env: production
        team: sre

auth_service:
  enabled: false
proxy_service:
  enabled: false
ssh_service:
  enabled: false
To protect multiple apps on the same host, add additional entries under apps:
app_service:
  enabled: true
  apps:
    - name: grafana
      uri: http://localhost:3000
      labels:
        team: sre
    - name: internal-dashboard
      uri: http://localhost:8080
      labels:
        team: platform
    - name: kibana
      uri: http://kibana.internal:5601
      labels:
        env: staging
4

Start the Application Service

sudo systemctl enable teleport
sudo systemctl start teleport
Verify the app appears in Teleport:
tsh apps ls
# Application  Description          Public Address                      Labels
# ──────────── ──────────────────── ─────────────────────────────────── ──────────────
# grafana      Grafana dashboards   grafana.teleport.example.com        env=production
5

Access the application

From the Teleport Web UI:
  1. Sign in at your cluster address.
  2. Navigate to the Applications tab.
  3. Click Launch on the Grafana tile.
Teleport opens the app in your browser, injecting a signed JWT so the app knows your identity.From the CLI:
# Log in to the app and retrieve a short-lived certificate
tsh apps login grafana

# Or use the certificate with curl
tsh apps login grafana
curl \
  --cert ~/.tsh/keys/teleport.example.com/alice-app/grafana/alice.crt \
  --key  ~/.tsh/keys/teleport.example.com/alice.key \
  https://grafana.teleport.example.com/api/health
Local port forwarding (for CLI tools or scripts):
# Start a local proxy on port 8080
tsh proxy app grafana --port=8080
# Started local proxy on 127.0.0.1:8080

# Now reach the app at http://localhost:8080
curl http://localhost:8080/api/health

JWT-based authentication headers

Every request proxied by Teleport includes a signed JSON Web Token in the Teleport-JWT-Assertion header. Your application can verify this JWT against Teleport’s JWKS endpoint to trust the caller’s identity without maintaining its own user database. The JWT payload contains:
{
  "sub": "alice",
  "username": "alice",
  "roles": ["access", "app-admin"],
  "iss": "teleport.example.com",
  "exp": 1719000000,
  "traits": {
    "email": ["alice@example.com"],
    "groups": ["sre", "platform"]
  }
}
Retrieve the public keys to verify the JWT:
curl https://teleport.example.com/webapi/jwt/certs
JWT verification lets you build identity-aware applications without integrating an external identity provider directly. See the JWT Integration documentation for library examples.

Controlling access with roles

Teleport roles control which apps a user can access using label selectors on the app_labels field:
kind: role
version: v7
metadata:
  name: sre-apps
spec:
  allow:
    app_labels:
      team: sre
  deny: {}
Users assigned the sre-apps role can access any app labeled team: sre. You can combine label selectors, require access requests for sensitive apps, or scope access to specific subpaths.

Protecting TCP applications

For non-HTTP services (databases not yet supported natively, SMTP servers, internal APIs), use Teleport’s TCP app mode:
app_service:
  enabled: true
  apps:
    - name: internal-smtp
      uri: tcp://smtp.internal:25
      labels:
        protocol: smtp
Connect with tsh proxy app:
tsh proxy app internal-smtp --port=1025
# Proxying connections on 127.0.0.1:1025 to internal-smtp

Next steps

Access Controls & RBAC

Define fine-grained role policies to control which users can launch which apps.

SSO Integration

Gate application access behind Okta, GitHub, or any SAML/OIDC provider.

Access Requests

Require manager approval before granting access to sensitive internal tools.

Machine Identity

Allow CI/CD pipelines to access internal apps using short-lived bot certificates.

Build docs developers (and LLMs) love