GitHub Enterprise OIDC Issue: A Roadblock for Secure Trusted Publishing and Developer OKRs
GitHub Enterprise OIDC Issue: A Roadblock for Secure Trusted Publishing and Developer OKRs
In the evolving landscape of secure software supply chains, OpenID Connect (OIDC) trusted publishing has emerged as a critical mechanism for authenticating automated deployments without long-lived credentials. However, a recent discussion on the GitHub Community highlights a significant challenge for GitHub Enterprise Cloud users that directly impacts their ability to maintain robust security postures while achieving their developer OKRs.
The Core Problem: Enterprise-Scoped OIDC Issuers
The issue, brought to light by user makstech, describes a failure in OIDC token exchange when GitHub Enterprise has the include_enterprise_slug setting enabled on its OIDC issuer. This setting, recommended as a security best practice, scopes OIDC tokens by including the enterprise slug in the issuer URL. Instead of the standard https://token.actions.githubusercontent.com, the issuer claim (iss) in the OIDC token becomes enterprise-scoped, like https://token.actions.githubusercontent.com/.
The problem arises because package registries like npmjs.com (and PyPI, as noted in pypi/warehouse#17700) currently only trust the standard issuer URL. Consequently, when a GitHub Actions workflow attempts to publish a package using a token from an enterprise-scoped issuer, the token exchange fails with a 401 Unauthorized error:
POST https://registry.npmjs.org/-/npm/v1/oidc/token/exchange/package/%40my-scope%2Fmy-package
Status: 401 Unauthorized
Response: {"message":"OIDC token exchange error - unauthorized"}All other critical claims, such as repository, repository_owner, and environment, correctly match the trusted publisher configuration, confirming that the issue lies squarely with the issuer URL mismatch.
Impact on Developer Workflows and Security Posture
This bug forces GitHub Enterprise Cloud customers into an unacceptable trade-off: either disable include_enterprise_slug to enable npm trusted publishing, thereby degrading the security posture for all other OIDC consumers (e.g., AWS, Azure, GCP), or forgo the benefits of trusted publishing for npm packages. This directly hinders efforts to establish secure and efficient software supply chains, a key component of many developer OKRs focused on security compliance and release velocity.
The steps to reproduce are straightforward:
- Operate a GitHub organization under a GitHub Enterprise with
include_enterprise_slugenabled. - Configure a trusted publisher on npmjs.com for a package within that organization's repository.
- Execute a GitHub Actions workflow with
id-token: writepermission that callsnpm publish. - Observe the OIDC token exchange failure due to the enterprise-scoped
issclaim.
A Clear Path Forward: Adapting Registries to Enterprise Security
The suggested fix is both logical and crucial for enterprise adoption of OIDC trusted publishing: package registries should be updated to accept issuer URLs matching the pattern https://token.actions.githubusercontent.com/. Crucially, these enterprise-scoped issuers share the same JWKS signing keys as the standard issuer, meaning the core trust mechanism remains intact. Registries could further enhance security by optionally validating the enterprise claim within the JWT against the slug in the issuer URL.
For organizations striving to meet ambitious developer OKRs around security automation and deployment efficiency, resolving this OIDC issuer mismatch is paramount. It's not merely a technical bug; it's a barrier to adopting best-in-class security practices without compromising on productivity. As a vital software measurement tool for security, OIDC's full potential must be unlocked for enterprise users.
The community's swift feedback on such issues is invaluable, and we anticipate platform providers will prioritize addressing this to ensure a seamless and secure experience for all developers.
