# 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. 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:

     ```
     $ TELEPORT_DOMAIN=teleport.example.com:443
     $ TELEPORT_VERSION="$(curl -s https://$TELEPORT_DOMAIN/v1/webapi/find | jq -r '.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.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
     ```

* 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.

  ---

* To check that you can connect to your Teleport cluster, sign in with `tsh login`, then verify that you can run `tctl` commands using your current credentials. For example, run the following command, assigning teleport.example.com to the domain name of the Teleport Proxy Service in your cluster and email\@example.com to your Teleport username:
  ```
  $ tsh login --proxy=teleport.example.com --user=email@example.com
  $ tctl status
  Cluster  teleport.example.com
  Version  18.7.3
  CA pin   sha256:abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678abdc1245efgh5678
  ```
  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 by running the appropriate commands for your authentication provider:

**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.

## 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)
