-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Context
GitHub Actions workflows can use OpenID Connect (OIDC) to exchange short-lived tokens directly with cloud providers (AWS, Azure, GCP, HashiCorp Vault, etc.) instead of storing long-lived credentials as secrets. The OIDC token issued by GitHub contains a sub (subject) claim that cloud providers use to authorize access.
By default, the subject claim follows the format repo:/:, but GitHub provides REST API endpoints to customize which claim keys are included in the subject. This customization can be configured at both the organization and repository level, allowing fine-grained control over the identity claims presented to cloud providers.
The GitHub PowerShell module currently has no coverage of the Actions OIDC API endpoints.
Request
The module should provide commands to get and set the OIDC subject claim customization template at both the organization and repository levels. This allows automation of OIDC trust configuration across multiple repositories and organizations — a common need when managing cloud provider integrations at scale.
Additionally, the module should provide a way to discover which claim keys are available on a given GitHub instance, so that argument completion can guide the user when specifying claim keys.
What is expected
- A command to retrieve the current OIDC subject claim customization template for an organization or repository
- A command to set (create or update) the OIDC subject claim customization template for an organization or repository
- Support for the
include_claim_keysarray and the repository-leveluse_defaultflag - A command to discover the available claim keys for a given GitHub instance via the OpenID Connect Discovery endpoint
- Argument completion for the
IncludeClaimKeysparameter, powered by the discovery function
API endpoints to cover
| Method | Endpoint | Synopsis |
|---|---|---|
GET |
/orgs/{org}/actions/oidc/customization/sub |
Get the customization template for an OIDC subject claim for an organization |
PUT |
/orgs/{org}/actions/oidc/customization/sub |
Set the customization template for an OIDC subject claim for an organization |
GET |
/repos/{owner}/{repo}/actions/oidc/customization/sub |
Get the customization template for an OIDC subject claim for a repository |
PUT |
/repos/{owner}/{repo}/actions/oidc/customization/sub |
Set the customization template for an OIDC subject claim for a repository |
OIDC discovery endpoint
The list of available claim keys is not hardcoded — it is dynamically discoverable via the OpenID Connect Discovery endpoint exposed by each GitHub instance's OIDC token issuer:
| Instance | Discovery URL |
|---|---|
| github.com | https://token.actions.githubusercontent.com/.well-known/openid-configuration |
GHE.com ({subdomain}.ghe.com) |
https://token.actions.{subdomain}.ghe.com/.well-known/openid-configuration |
The discovery response contains a claims_supported array listing all valid claim keys for that instance. This is used by Get-GitHubOidcClaim and powers argument completion for the IncludeClaimKeys parameter.
Note
The OIDC discovery endpoint is public and requires no authentication.
API response shapes
Organization GET returns:
{
"include_claim_keys": [
"repo",
"context"
]
}Repository GET returns (includes use_default):
{
"use_default": false,
"include_claim_keys": [
"repo",
"context"
]
}Repository PUT body requires:
{
"use_default": false,
"include_claim_keys": [
"repo",
"context"
]
}Note
When use_default is true, the include_claim_keys field is ignored by the API.
Available claim keys
The following claim keys are returned by the github.com discovery endpoint (as of writing). The actual list is dynamic and instance-specific — always use the discovery endpoint to get the current set:
sub, aud, exp, iat, iss, jti, nbf, ref, sha, repository, repository_id, repository_owner, repository_owner_id, enterprise, enterprise_id, run_id, run_number, run_attempt, actor, actor_id, workflow, workflow_ref, workflow_sha, head_ref, base_ref, event_name, ref_type, ref_protected, environment, environment_node_id, job_workflow_ref, job_workflow_sha, repository_visibility, runner_environment, issuer_scope, check_run_id
Required permissions
| Endpoint | Fine-grained token permission | Classic scope |
|---|---|---|
| Org GET | Administration org (read) |
read:org |
| Org PUT | Administration org (write) |
write:org |
| Repo GET | Actions repo (read) |
repo |
| Repo PUT | Actions repo (write) |
repo |
Acceptance criteria
- OIDC subject claim templates can be retrieved for organizations and repositories
- OIDC subject claim templates can be set for organizations and repositories
- The
use_defaultflag is supported for repository-level configuration - Available claim keys are discoverable via
Get-GitHubOidcClaimfor any GitHub instance (github.com and GHE.com) Get-GitHubOidcClaimis accessible without authentication and works across all context types- The
IncludeClaimKeysparameter onSet-GitHubOidcSubjectClaimhas argument completion powered by the discovery endpoint - The commands follow existing module conventions for parameter naming and context resolution
Technical decisions
Object type grouping: The new functions belong under the Actions object type folder, since the OIDC API is part of the GitHub Actions REST API. Create an OIDC subfolder under Actions for both public and private functions.
Public function naming:
Get-GitHubOidcClaim— retrieves the list of supported OIDC claim keys from the discovery endpointGet-GitHubOidcSubjectClaim— retrieves the OIDC subject claim templateSet-GitHubOidcSubjectClaim— creates or updates the OIDC subject claim template
Private function naming (one function per API call):
Get-GitHubOidcSubjectClaimForOrganization—GET /orgs/{org}/actions/oidc/customization/subSet-GitHubOidcSubjectClaimForOrganization—PUT /orgs/{org}/actions/oidc/customization/subGet-GitHubOidcSubjectClaimForRepository—GET /repos/{owner}/{repo}/actions/oidc/customization/subSet-GitHubOidcSubjectClaimForRepository—PUT /repos/{owner}/{repo}/actions/oidc/customization/sub
OIDC claims discovery function (Get-GitHubOidcClaim): This function follows the Get-GitHubStatus pattern — a public function that calls Invoke-RestMethod directly on a non-API endpoint (the OIDC discovery URL). No private function counterpart is needed because: (1) the endpoint is public and requires no authentication, (2) there is only one operation (get the claims list), and (3) the Status/ functions set the precedent for this pattern. The function accepts an optional Context parameter to determine the hostname; when no context is provided, it defaults to github.com. URL derivation: github.com → token.actions.githubusercontent.com; any other hostname → token.actions.{hostname}.
Argument completer for IncludeClaimKeys: A completers.ps1 file in src/functions/public/Actions/OIDC/ registers an argument completer for the IncludeClaimKeys parameter on Set-GitHubOidcSubjectClaim. The completer calls Get-GitHubOidcClaim with the context from $fakeBoundParameters and filters results using the configured CompletionMode (following the pattern in Gitignore/completers.ps1).
Parameter set naming (public functions): Use the synopsis of the corresponding private function:
Get-GitHubOidcSubjectClaim:'Get the customization template for an OIDC subject claim for an organization''Get the customization template for an OIDC subject claim for a repository'
Set-GitHubOidcSubjectClaim:'Set the customization template for an OIDC subject claim for an organization''Set the customization template for an OIDC subject claim for a repository'
Parameter naming:
Owner— with aliasesOrganizationandUser(standard convention)Repository— with aliasRepoif neededIncludeClaimKeys—[string[]]array of claim keys to include in the subjectUseDefault—[switch]for the repository-leveluse_defaultflagContext— standard context parameter
API call pattern: Use REST API via Invoke-GitHubAPI (not GraphQL), since this is a simple REST-only endpoint. Follow the splat pattern from existing private functions: Method, APIEndpoint, Body, Context.
No class needed: The API response is a simple object with 1–2 properties (include_claim_keys and optionally use_default). Return the response directly as a PSCustomObject rather than creating a dedicated class. The output is small and flat, and a class would add complexity without meaningful benefit.
ShouldProcess: Apply [CmdletBinding(SupportsShouldProcess)] only to Set-GitHubOidcSubjectClaim and the Set- private functions. The Get- functions must not use it.
Breaking changes: None — this is entirely new functionality.
Test approach: Unit tests with mocked API responses covering:
- Get template for organization
- Get template for repository
- Set template for organization
- Set template for repository with
UseDefault=$falseand custom claim keys - Set template for repository with
UseDefault=$true(claim keys ignored) Get-GitHubOidcClaimaccessibility — verify that the discovery endpoint is reachable and returns claim keys across all auth context types (no context, PAT, UAT, IAT, App), confirming the public endpoint works regardless of authentication state
Implementation plan
Claims discovery
- Create
src/functions/public/Actions/OIDC/Get-GitHubOidcClaim.ps1— public function that retrieves supported claim keys from the OIDC discovery endpoint, following theGet-GitHubStatuspattern (directInvoke-RestMethod, optionalContextfor hostname derivation) - Create
src/functions/public/Actions/OIDC/completers.ps1— argument completer forIncludeClaimKeysonSet-GitHubOidcSubjectClaim, powered byGet-GitHubOidcClaim
Private functions
- Create
src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForOrganization.ps1—GET /orgs/{org}/actions/oidc/customization/sub - Create
src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForOrganization.ps1—PUT /orgs/{org}/actions/oidc/customization/sub - Create
src/functions/private/Actions/OIDC/Get-GitHubOidcSubjectClaimForRepository.ps1—GET /repos/{owner}/{repo}/actions/oidc/customization/sub - Create
src/functions/private/Actions/OIDC/Set-GitHubOidcSubjectClaimForRepository.ps1—PUT /repos/{owner}/{repo}/actions/oidc/customization/sub
Public functions
- Create
src/functions/public/Actions/OIDC/Get-GitHubOidcSubjectClaim.ps1with parameter sets dispatching to the twoGet-private functions - Create
src/functions/public/Actions/OIDC/Set-GitHubOidcSubjectClaim.ps1with parameter sets dispatching to the twoSet-private functions, usingSupportsShouldProcess
Tests
- Add tests for
Get-GitHubOidcClaim— verify the discovery endpoint is accessible and returns a non-emptyclaims_supportedarray. Test without context (defaults to github.com), and with each auth context type (PAT, UAT, IAT, App) to confirm all users can access and use the function regardless of authentication state - Add unit tests for
Get-GitHubOidcSubjectClaimForOrganization - Add unit tests for
Set-GitHubOidcSubjectClaimForOrganization - Add unit tests for
Get-GitHubOidcSubjectClaimForRepository - Add unit tests for
Set-GitHubOidcSubjectClaimForRepository - Add integration-level tests for
Get-GitHubOidcSubjectClaim(parameter set dispatch) - Add integration-level tests for
Set-GitHubOidcSubjectClaim(parameter set dispatch,ShouldProcess)
Documentation
- Add
.SYNOPSIS,.DESCRIPTION,.NOTESwith API doc links, and.LINKto all functions - Add usage examples to all public functions
Metadata
Metadata
Assignees
Labels
Type
Projects
Status