{"token_count": 4285}

# Proxy Git Commands with Teleport for GitHub

Teleport can proxy Git commands and use short-lived SSH certificates to authenticate GitHub organizations.

In this guide, you will:

- Create a GitHub OAuth application.
- Configure SSH certificate authorities for your GitHub organizations.
- Create Teleport resources for the GitHub integration.
- Run Git commands through Teleport.

## How it works

GitHub enables organizations to configure a list of SSH Certificate Authorities (CAs) for authentication. This feature allows access to the organization's repositories using short-lived SSH certificates signed by an approved CA, such as a Teleport CA. Optionally, organizations can enforce stricter security by requiring these signed SSH certificates for access, effectively disabling the use of personal SSH keys and access tokens.

Teleport users can configure their Git repositories to proxy through Teleport. After setup, Git commands automatically route through Teleport, which impersonates their GitHub identities using short-lived SSH certificates signed by Teleport's CA for authentication with GitHub. Each Git command proxied through Teleport is also logged in Teleport's audit events.

To retrieve a user's GitHub identity, `tsh` initiates the GitHub OAuth flow by opening a browser window for the user to log in with their GitHub credentials.

![GitHub SSH certificate authorities](/docs/assets/images/how-it-works-github-proxy-fecd29043ab5696669734bff2042ea79.svg)

Note that Teleport proxies Git commands through SSH but the users should continue to access GitHub through their browsers.

## Prerequisites

- A running Teleport Enterprise (v17.2 or higher) cluster accessible at a hostname with a valid TLS certificate. If you want to get started with Teleport, [sign up](https://goteleport.com/signup) for a free trial or [set up a demo environment](https://goteleport.com/docs/get-started/deploy-community.md).

- The `tctl` and `tsh` clients.

  Installing `tctl` and `tsh` clients

  1. Determine the version of your Teleport cluster. The `tctl` and `tsh` clients must be at most one major version behind your Teleport cluster version. Send a GET request to the Proxy Service at `/v1/webapi/find` and use a JSON query tool to obtain your cluster version. Replace teleport.example.com:443 with the web address of your Teleport Proxy Service:

     **Mac/Linux**

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.server_version')"
     ```

     **Windows - Powershell**

     ```
     $ $TELEPORT_DOMAIN = "teleport.example.com:443"
     $ $TELEPORT_VERSION = (Invoke-RestMethod -Uri "https://${TELEPORT_DOMAIN}/v1/webapi/find").server_version
     ```

  2. Follow the instructions for your platform to install `tctl` and `tsh` clients:

     **Mac**

     Download the signed macOS .pkg installer for Teleport, which includes the `tctl` and `tsh` clients:

     ```
     $ curl -O https://cdn.teleport.dev/teleport-${TELEPORT_VERSION?}.pkg
     ```

     In Finder double-click the `pkg` file to begin installation.

     ---

     DANGER

     Using Homebrew to install Teleport is not supported. The Teleport package in Homebrew is not maintained by Teleport and we can't guarantee its reliability or security.

     ---

     **Windows - Powershell**

     ```
     $ curl.exe -O https://cdn.teleport.dev/teleport-v$TELEPORT_VERSION-windows-amd64-bin.zip
     Unzip the archive and move the `tctl` and `tsh` clients to your %PATH%
     NOTE: Do not place the `tctl` and `tsh` clients in the System32 directory, as this can cause issues when using WinSCP.
     Use %SystemRoot% (C:\Windows) or %USERPROFILE% (C:\Users\<username>) instead.
     ```

     **Linux**

     All of the Teleport binaries in Linux installations include the `tctl` and `tsh` clients. For more options (including RPM/DEB packages and downloads for i386/ARM/ARM64) see our [installation page](https://goteleport.com/docs/installation/single-machine.md).

     ```
     $ curl -O https://cdn.teleport.dev/teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ tar -xzf teleport-v${TELEPORT_VERSION?}-linux-amd64-bin.tar.gz
     $ cd teleport
     $ sudo ./install
     Teleport binaries have been copied to /usr/local/bin
     ```

  Connecting with TLS routing disabled

  This guide's commands assume your Teleport cluster uses TLS routing (`proxy_listener_mode: multiplex`), where the `tctl` and `tsh` clients reach every Teleport service through the Proxy Service's web address on port `443`. If you're not sure whether this applies to your cluster, check with whoever manages it.

  If your cluster uses separate listener ports instead, adjust ports as follows:

  - **`tsh` commands** (e.g., `tsh login --proxy=...`): continue using the Proxy Service web address on port `3080` (or `443` if behind a load balancer). Do not change these to port `3025`.

  - **Direct `tctl` or Auth Service API commands**: use port `3025` for the Auth Service gRPC listener:

    ```
    $ tctl status --auth-server=teleport.example.com:3025
    ```

* Access to GitHub Enterprise Cloud and permissions to modify GitHub's SSH certificate authorities and configure OAuth applications.

  ---

  GITHUB ENTERPRISE COMPATIBILITY

  GitHub integration requires a GitHub Enterprise plan and is currently supported for **GitHub Enterprise Cloud**. Support for **GitHub Enterprise Server (self-hosted)** is not available as of the current release.

  ---

* 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  18.10.0
     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](https://goteleport.com/docs/machine-workload-identity/getting-started.md) 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.

* Git locally installed

## Step 1/4. Configure a GitHub OAuth application

The GitHub integration requires a GitHub OAuth application to obtain users' GitHub identities. You can skip this step if the Teleport users use GitHub SSO to sign in Teleport.

Go to "OAuth Apps" under "Developer Settings" of your organization's settings. Click on "New OAuth App".

Fill in the details. Use the following for "Authentication callback URL". Replace teleport-proxy-address with the host and HTTPS port of your Teleport Proxy Service:

```
https://teleport-proxy-address/v1/webapi/github/
```

Once the OAuth application is created, create a client secret and remember the client ID and the secret for the next step:

![A GitHub Oauth App, highlighting Client ID and secret](/docs/assets/images/github-app-vars-3bd1d246cdcaec877caa0ad84e678924.png)

## Step 2/4. Create a GitHub integration and export the CAs

Now create a yaml file that represents the Github integration. Replace my-github-org with the organization name, and replace

oauth-app-client-id

and oauth-app-client-secret with values from the previous step.

```
# github_integration.yaml
kind: integration
sub_kind: github
version: v1
metadata:
  name: github-my-github-org
spec:
  github:
    organization: my-github-org
  credentials:
    id_secret:
      id: oauth-app-client-id
      secret: oauth-app-client-secret

```

To create the resource with `tctl`, run:

```
$ tctl create github_integration.yaml
```

Once the integration resource is created, export the CA to be used for GitHub:

```
$ tctl auth export --type github --integration github-my-github-org
```

Now go to the "Authentication Security" page of your GitHub organization. Click on "New CA" under the "SSH certificate authorities" section, and copy-paste the CA exported from the above `tctl auth export` command.

![GitHub SSH certificate authorities](/docs/assets/images/github-new-ca@2x-3f18f38bffa24c482264951eb37081ea.png)

## Step 3/4. Configure access

User access is granted through `git_server` resources. The `git_server` references the integration created in the previous step:

```
# git_server.yaml
kind: git_server
sub_kind: github
version: v2
spec:
  github:
    integration: github-my-github-org
    organization: my-github-org

```

To create the resource with `tctl`, run:

```
$ tctl create git_server.yaml
```

The user role must have `github_permissions` configured to allow access to your GitHub organization. For example:

```
# role_with_github_permissions.yaml
kind: role
metadata:
  name: github-access
spec:
  allow:
    github_permissions:
    - orgs:
      - my-github-org
version: v7

```

Assign the `github-access` role to your Teleport user. The commands to run depend on how you authenticate to Teleport, that is, whether you have a local Teleport user, a single sign-on authentication connector, or a non-interactive user:

**Local User**

1. Retrieve your local user's roles as a comma-separated list:

   ```
   $ ROLES=$(tsh status -f json | jq -r '.active.roles | join(",")')
   ```

2. Edit your local user to add the new role:

   ```
   $ tctl users update $(tsh status -f json | jq -r '.active.username') \
     --set-roles "${ROLES?},github-access"
   ```

3. Sign out of the Teleport cluster and sign in again to assume the new role.

**GitHub**

1. Open your `github` authentication connector in a text editor:

   ```
   $ tctl edit github/github
   ```

2. Edit the `github` connector, adding `github-access` to the `teams_to_roles` section.

   The team you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the team must include your user account and should be the smallest team possible within your organization.

   Here is an example:

   ```
     teams_to_roles:
       - organization: octocats
         team: admins
         roles:
           - access
   +       - github-access

   ```

3. Apply your changes by saving and closing the file in your editor.

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**SAML**

1. Retrieve your `saml` configuration resource:

   ```
   $ tctl get --with-secrets saml/mysaml > saml.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `saml.yaml` file. Because this key contains a sensitive value, you should remove the saml.yaml file immediately after updating the resource.

2. Edit `saml.yaml`, adding `github-access` to the `attributes_to_roles` section.

   The attribute you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     attributes_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - github-access

   ```

3. Apply your changes:

   ```
   $ tctl create -f saml.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**OIDC**

1. Retrieve your `oidc` configuration resource:

   ```
   $ tctl get oidc/myoidc --with-secrets > oidc.yaml
   ```

   Note that the `--with-secrets` flag adds the value of `spec.signing_key_pair.private_key` to the `oidc.yaml` file. Because this key contains a sensitive value, you should remove the oidc.yaml file immediately after updating the resource.

2. Edit `oidc.yaml`, adding `github-access` to the `claims_to_roles` section.

   The claim you should map to this role depends on how you have designed your organization's role-based access controls (RBAC). However, the group must include your user account and should be the smallest group possible within your organization.

   Here is an example:

   ```
     claims_to_roles:
       - name: "groups"
         value: "my-group"
         roles:
           - access
   +       - github-access

   ```

3. Apply your changes:

   ```
   $ tctl create -f oidc.yaml
   ```

4. Sign out of the Teleport cluster and sign in again to assume the new role.

**Non-Interactive**

For non-interactive users such as AI agents and CI/CD runners, follow these steps.

If you are using Machine ID to issue identity files to your user:

1. Add the new role to your bot. Assign mybot to the name of the Machine ID bot that issues your certificate:

   ```
   $ tctl bots update mybot --add-roles github-access
   ```

2. Force `tbot` to regenerate the certificate:

   ```
   $ pkill -HUP tbot
   ```

   The bot will also generate a certificate with the new role on its next renewal.

Otherwise, update your user and regenerate your identity file:

1. Retrieve your local user's roles as a comma-separated list. Make sure username is the Teleport user you want to assign the new role to.

   ```
   $ ROLES=$(tctl get user/username --format=json | jq -r '.[].spec.roles | join(",")')
   ```

2. Edit your local user to add the new role:

   ```
   $ tctl users update username \
     --set-roles "${ROLES?},github-access"
   ```

3. Regenerate the identity file. Make sure path/to/identity/file corresponds to the correct output path:

   ```
   $ tctl auth sign \
     --user=username \
     --out=path/to/identity/file \
     --overwrite
   ```

## Step 4/4. Connect

Use `tsh git ls` to view a list of GitHub organizations you have access to:

```
$ tsh git ls
Type   Organization  Username URL
------ ------------- -------- --------------------------------
GitHub my-github-org my-user  https://github.com/my-github-org
```

Teleport requires your GitHub identity to impersonate you. If you haven't provided it yet, run the following command:

```
$ tsh git login --github-org my-github-org
  If browser window does not open automatically, open it by clicking on the link:
   http://127.0.0.1:55555/some-id
  Your GitHub username is my-user.
```

This command opens a browser, prompting you to authenticate with GitHub via the OAuth app: ![GitHub SSO authorization view](/docs/assets/images/github-sso-auth-screen-9201472bb34dbc0ebad02a6dba04f2f5.jpg)

To clone a repository from your GitHub organization, find the SSH clone URL and run:

```
$ tsh git clone git@github.com:my-github-org/my-repo.git
Cloning into 'my-repo'...
```

To configure an existing Git repository with Teleport, go to the repository and run:

```
$ tsh git config update
The current Git directory is configured with Teleport for GitHub organization "my-github-org".
```

Once the repo is cloned or configured, you can use `git` commands as normal:

```
$ cd my-repo
$ git fetch

```

Note that the OAuth app authentication flow and Git repository configuration are one-time setups and don't need to be repeated.

## Further reading

- [Creating a GitHub OAuth app](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app)
- [GitHub SSH certificate authorities](https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-git-access-to-your-organizations-repositories/about-ssh-certificate-authorities)
