---
title: GitHub | Keycard
description: Access repositories, issues, and pull requests
---

[GitHub developer console](https://github.com/settings/apps)[OAuth setup guide](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/authorizing-oauth-apps)[API docs](https://docs.github.com/en/rest)

Adding GitHub provisions a resource (the upstream GitHub API at `https://api.github.com`, with default scopes pre-set) and a provider for GitHub’s OAuth issuer - auto-provisioned on first install, or reused if you already connected another GitHub resource.

Your application calls Keycard’s [token-exchange endpoint](/sdk/oauth/index.md) with the user’s identity, gets back a token scoped to this resource, and uses it to call GitHub directly. Identity, [policy](/admin/access-policies/index.md), and audit log apply to every exchange - the OAuth client secret stays inside Keycard. Each exchange is recorded in the audit log with the user identity, the resource accessed, and the policy decision.

## Use GitHub from your code

USE FROM CODE

Call GitHub from your application with a Keycard-issued token scoped to this resource.

After installing GitHub, your application exchanges a Keycard-issued access token for a token scoped to this resource. Pass the user’s access token as the `subject_token`.

- [Python](#tab-panel-110)
- [TypeScript](#tab-panel-111)

```
from keycardai.oauth import Client, BasicAuth, TokenType
import requests


# Exchange the user's Keycard token for a GitHub token.
with Client(
    "https://<zone-id>.keycard.cloud",
    auth=BasicAuth("<your-client-id>", "<your-client-secret>"),
) as client:
    response = client.exchange_token(
        subject_token=user_access_token,
        subject_token_type=TokenType.ACCESS_TOKEN,
        resource="https://api.github.com",
    )


# Call GitHub directly with the exchanged token.
r = requests.get(
    "https://api.github.com/<endpoint>",
    headers={"Authorization": f"Bearer {response.access_token}"},
)
```

```
import { TokenExchangeClient } from "@keycardai/oauth/tokenExchange";


const client = new TokenExchangeClient("https://<zone-id>.keycard.cloud", {
  clientId: "<your-client-id>",
  clientSecret: "<your-client-secret>",
});


const response = await client.exchangeToken({
  subjectToken: userAccessToken,
  resource: "https://api.github.com",
});


// Call GitHub directly with the exchanged token.
const res = await fetch("https://api.github.com/<endpoint>", {
  headers: { Authorization: `Bearer ${response.accessToken}` },
});
```

See the [OAuth SDK → Token Exchange](/sdk/oauth/#token-exchange/index.md) reference for the full client API.

## Setup

SETUP

Register your OAuth credentials with Keycard so the resource can issue tokens.

### Create a GitHub App

1. Go to [GitHub App Settings](https://github.com/settings/apps)

2. Click **New GitHub App**

3. Fill in:

   - **GitHub App name**: A descriptive name (e.g., “Keycard”)
   - **Homepage URL**: Your application URL (e.g., `http://localhost:3000`)
   - **Callback URL**: The redirect URI provided by Keycard

4. Under **Permissions**, select the permissions your app needs (e.g., **Repository** → **Contents: Read-only**)

5. Click **Create GitHub App**

### Get credentials

1. On the app page, note the **Client ID**
2. Click **Generate a new client secret**
3. Copy the **Client Secret** immediately (it’s only shown once)

Caution

GitHub client secrets are only displayed once when generated. If you lose it, you’ll need to generate a new one.

### Register in Keycard

1. Open [Keycard Console](https://console.keycard.ai) → your zone → **Resources**
2. Click **Explore Resources**
3. Find and click **GitHub** in the catalog
4. In the configuration dialog, enter the **Client ID** and **Client Secret** from your GitHub App
5. Click **Add GitHub API**

Note

GitHub Apps grant access based on the permissions configured on the app itself, not per-request scopes. The `/user` verification endpoint returns the authenticated user’s profile, which works with basic access.

## Troubleshooting

TROUBLESHOOTING

Common errors when wiring GitHub into your zone.

Error 401: Bad credentials

The access token is invalid or expired. Try re-connecting the provider in Keycard Console. If the issue persists, verify the client credentials in Keycard Console match the ones in GitHub Developer Settings.

Error: redirect\_uri mismatch

GitHub requires the callback URL to match exactly. Copy the redirect URI from Keycard Console and paste it as the Authorization callback URL in GitHub.

## Related

RELATED

- [Catalog overview](/admin/catalog/index.md) - browse other API and MCP servers
- [Access policies](/admin/access-policies/index.md) - control who can use GitHub
- [Identity providers](/admin/identity-providers/index.md) - control who can sign in

[PreviousConfluence](/admin/catalog/api-servers/confluence/index.md)[NextGmail](/admin/catalog/api-servers/gmail/index.md)
