Skip to content

Commit bfe5327

Browse files
sunbryeCopilotjules-pheiskr
authored
Copilot Extensions - OIDC (#54427)
Co-authored-by: Copilot <[email protected]> Co-authored-by: Jules <[email protected]> Co-authored-by: Kevin Heis <[email protected]>
1 parent 663c527 commit bfe5327

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed

content/copilot/building-copilot-extensions/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ children:
1313
- /building-a-copilot-agent-for-your-copilot-extension
1414
- /building-a-copilot-skillset-for-your-copilot-extension
1515
- /creating-a-copilot-extension
16+
- /using-oidc-with-github-copilot-extensions
1617
- /debugging-your-github-copilot-extension
1718
- /managing-the-availability-of-your-copilot-extension
1819
- /copilot-extensions-glossary
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
---
2+
title: Using OIDC with GitHub Copilot Extensions
3+
intro: >-
4+
Learn how to use OpenID Connect (OIDC) with your {% data
5+
variables.product.prodname_copilot_extension_short %} to enhance security.
6+
versions:
7+
feature: copilot-extensions
8+
topics:
9+
- Copilot
10+
shortTitle: Using OIDC
11+
type: how_to
12+
redirect_from:
13+
- /copilot/building-copilot-extensions/using-oidc-with-copilot-extensions
14+
---
15+
16+
## About OpenID Connect (OIDC) for {% data variables.product.prodname_copilot_extensions_short %}
17+
18+
OpenID Connect (OIDC) allows {% data variables.product.prodname_copilot_extensions_short %} to exchange short-lived tokens directly from their cloud provider instead of storing long-lived {% data variables.product.github %} credentials. This feature enables both Copilot agents and skillsets to more securely authenticate users and access cloud resources.
19+
20+
## Overview of OIDC
21+
22+
{% data variables.product.prodname_copilot_extensions_short %} often need to access third-party resources or APIs on behalf of users. Traditionally, this required storing {% data variables.product.github %} tokens as secrets and making additional API calls to map these tokens to user identities in your system. With OIDC, your extension can request short-lived access tokens directly from your authentication service by exchanging {% data variables.product.github %} identity information.
23+
24+
When enabled, {% data variables.product.github %}'s OIDC provider automatically generates a token containing claims about the user and the request context. Your authentication service can validate these claims and exchange them for an access token scoped specifically for your service.
25+
26+
Using OIDC is especially valuable for {% data variables.product.prodname_copilot_short %} skillsets development because it allows you to leverage your existing API endpoints without maintaining separate {% data variables.product.github %}-specific endpoints. Instead of duplicating endpoints to accept {% data variables.product.github %} tokens, you can use OIDC to translate {% data variables.product.github %} identities into your service’s native authentication tokens.
27+
28+
## Benefits of using OIDC
29+
30+
By implementing OIDC token exchange in your {% data variables.product.prodname_copilot_extension_short %}, you can:
31+
32+
* Avoid storing long-lived {% data variables.product.github %} tokens or maintain a mapping between {% data variables.product.github %} and your service's identities.
33+
* Use short-lived tokens that automatically expire and can be scoped specifically to your service's needs.
34+
* Avoid making additional calls to {% data variables.product.github %}'s API to validate tokens and fetch user information.
35+
* Enable direct integration for {% data variables.product.prodname_copilot_short %} Skills with your existing APIs without maintaining separate endpoints for {% data variables.product.github %}.
36+
* Reuse existing API endpoints by translating {% data variables.product.github %} authentication into your service's native tokens.
37+
38+
## Token exchange flow
39+
40+
The following outlines how the {% data variables.product.prodname_copilot_extensibility_platform_short %} exchanges an OIDC token for an access token to authenticate requests to your extension.
41+
42+
### Initial request
43+
44+
1. The user sends a message to your {% data variables.product.prodname_copilot_extension_short %}.
45+
1. GitHub generates an OIDC token containing user identity information.
46+
1. GitHub calls your token exchange endpoint with the OIDC token.
47+
1. Your service validates the token and returns an access token.
48+
1. GitHub includes your access token in the request to your extension.
49+
50+
```http request
51+
# HTTP header
52+
Authorization: Bearer <your-service-token>
53+
X-GitHub-Token: <github-token>
54+
```
55+
56+
### Subsequent requests
57+
58+
1. {% data variables.product.github %} caches your access token for up to 10 minutes.
59+
1. The cached token is reused for subsequent requests.
60+
1. If the token expires or becomes invalid, {% data variables.product.github %} requests a new one.
61+
62+
## Understanding OIDC tokens
63+
64+
The OIDC token from {% data variables.product.github %} is a JWT containing claims about the user and request context:
65+
66+
```json
67+
{
68+
"jti": "<unique-token-id>",
69+
"sub": "<github-user-id>",
70+
"aud": "<your-client-id>",
71+
"iss": "https://github.com/login/oauth",
72+
"nbf": 1632492967,
73+
"exp": 1632493867,
74+
"iat": 1632493567,
75+
"act": {
76+
"sub": "api.copilotchat.com"
77+
}
78+
}
79+
```
80+
81+
## Setting up OIDC for your extension
82+
83+
There are three steps to setting up OIDC for your extension.
84+
1. [Configure your token exchange endpoint](#configure-your-token-exchange-endpoint).
85+
1. [Enable OIDC in your Copilot extensions settings](#enable-oidc-in-your-copilot-extensions-settings).
86+
1. [Validate OIDC tokens](#validate-oidc-tokens).
87+
88+
### Configure your token exchange endpoint
89+
90+
Create an endpoint in your service that conforms to the [RFC 8693 OAuth 2.0 Token Exchange](https://www.rfc-editor.org/rfc/rfc8693.html).
91+
This endpoint should:
92+
* Accept `POST` requests with the following form-encoded parameters:
93+
94+
```http request
95+
grant_type=urn:ietf:params:oauth:grant-type:token-exchange
96+
&resource=<https://your-service.com/resource>
97+
&subject_token=<github-jwt-token>
98+
&subject_token_type=urn:ietf:params:oauth:token-type:id_token
99+
```
100+
101+
* Return a JSON response with your service's access token:
102+
103+
```json
104+
{
105+
"access_token": <"your-service-token">,
106+
"Issued_token_type":"urn:ietf:params:oauth:token-type:access_token",
107+
"token_type": "Bearer",
108+
"expires_in": 3600
109+
}
110+
```
111+
112+
* Return an error response when validation fails:
113+
114+
```json
115+
{
116+
"error": "invalid_request"
117+
}
118+
```
119+
120+
### Enable OIDC in your {% data variables.product.prodname_copilot_extension_short %}'s settings
121+
122+
In your {% data variables.product.prodname_copilot_extension_short %}'s configuration, enable OIDC:
123+
124+
{% data reusables.apps.settings-step %}
125+
{% data reusables.apps.enterprise-apps-steps %}
126+
1. To the right of the {% data variables.product.prodname_github_app %} you want to configure for your {% data variables.product.prodname_copilot_extension_short %}, click **Edit**.
127+
1. In the left sidebar, click **{% data variables.product.prodname_copilot_short %}**.
128+
1. Under **OpenID Connect Token Exchange**, check **Enabled**.
129+
1. In the **Token exchange endpoint** field, input your token exchange URL.
130+
1. In the **Request header key** field, input the header key for your service's token. The default is `Authorization`.
131+
1. In the **Request header value** field, input the header value format. The default is `Bearer ${token}`.
132+
133+
### Validate OIDC tokens
134+
135+
Your token exchange endpoint should validate the {% data variables.product.github %} OIDC token by following the steps below:
136+
1. Fetch the JSON Web Key Set (JWKS) from https://github.com/login/oauth/.well-known/openid-configuration.
137+
1. Verify the token signature.
138+
1. Validate required claims.
139+
* `aud`: Audience. Your {% data variables.product.prodname_copilot_extension_short %}'s client ID.
140+
* `sub`: Subject. The {% data variables.product.github %} user ID making the request. The response is limited to data that the user has permissions to access. If the user has no permissions `400 Bad Request` is shown.
141+
* `iat`: Issued At. The timestamp when the token was issued. It is typically a timestamp in the past but represents the exact moment the token was created.
142+
* `nbf`: Not Before. The timestamp before which the token is not valid. This should be a timestamp in the past.
143+
* `exp`: Expiration Time. The timestamp when the token expires. This should be a timestamp in the future.
144+
* `act`: Actor. The acting entity in delegated access. This should be a constant string.
145+
146+
## Troubleshooting
147+
148+
The following sections outline common problems and best practices for implementing OIDC for your {% data variables.product.prodname_copilot_extension_short %}.
149+
150+
### Token validation errors
151+
152+
* Ensure you're using the correct JWKS endpoint.
153+
* Verify that all the required claims are present and valid.
154+
* Check that timestamps (`iat`, `nbf`, and `exp`) are within valid ranges.
155+
156+
### Token exchange failures
157+
158+
* Return `HTTP 400` for invalid tokens.
159+
* Return `HTTP 403` if the user lacks the necessary permissions.
160+
* If {% data variables.product.github %} receives a 403 response, it will retry the request with a new token.
161+
162+
### Performance issues
163+
164+
* Implement efficient token validation to minimize latency.
165+
* Use appropriate token expiration times (recommended: 10 minutes or less).
166+
* Consider caching implications for high-traffic extensions.
167+
168+
### Best practices
169+
170+
* Scope tokens to the minimum required permissions.
171+
* Implement proper error handling and logging.
172+
* Monitor token exchange patterns for security anomalies.
173+
* Keep tokens short-lived to minimize security risks.
174+
* Validate all claims before issuing access tokens.
175+
* Consider implementing rate limiting on your token exchange endpoint.
176+
* Use HTTPS for all token exchange communications.

0 commit comments

Comments
 (0)