graphql-hive / graphql-hive/console
support OIDC workload identity federation for CLI (short-lived access tokens)
- Dominant language
- TypeScript
- Stars
- 483
- Forks
- 145
- Avg merge
- 2d 5h
- Merged PRs (30d)
- 65
Description
## The Problem
Issuing long-lived access tokens for interacting with the Hive Console GraphQL API (e.g. schema publish; schema check or similar) and storing these on a CD/CI provider such as GitHub, GitLab or other providers introduces a security risk.
These static credentials require rotation and are prone to leakage through logs. Organization administrators want to avoid this management overhead.
## Why Open ID Connect?
OpenID Connect is standardised way that SaaS platforms (Hive Console) to trust identities issued by external identity providers (e.g. AWS IAM; Azure EntraID) using short-lived JWT tokens.
By accepting these Identity Providers issued access tokens and mapping the issues access tokens to the internal Hive Console permissions layer, our users can eliminate long-lived access tokens, reduce security risk, and provide fine-grained, auditable access for automated systems like GitHub actions and co.
In short, the identity provider issues a stateless short-lived JWT token that is sent to Hive Console APIs, Hive Console can then sorely based on that JWT token authenticate and authorise a request and map it to Hive Consoles internal permission system as depicted in the following diagram:
```mermaid
sequenceDiagram
participant IdP as Identity Provider
participant Client as Client (e.g. GitHub Action run)
participant API as Hive GraphQL API
IdP->>Client: Issue JWT (signed with private key)
Client->>API: Request + JWT
Note right of API: Decode JWT
Note right of API: Read `iss` claim
API->>IdP: Fetch public key (via iss / JWKS)
IdP-->>API: Return public key
Note right of API: Verify signature
Note right of API: Validate claims (exp, aud, ...)
Note right of API: Map claims → internal permission model
API-->>Client: Response (if authorized)
```
## How it works
This is a more detailed breakdown of the required steps.
### Access Token is issued by Identity Provider
The identity provider (e.g. GitHub Actions IDP) issues a access token that is created for a job run.
This access token is a JWT (JSON Web Token) token, whose payload must contains the following properties:
* `iss` (issuer) → who issued it
* `sub` (subject) → who the subject is (in this example below; a git branch/github action run); the IDP usually decides what that is
* `aud` (audience) → where can this token be used on (on a organization in Hive Console)
* I think we should go with a naming schema that includes the organization slug or ID, so we can easily map iss and sub on our end.
* e.g. hive-console://org/ (Actively avoiding something like https:// in here so nobody tries to open this URL in the browser 😄)
* An alternative could be urn:hive-console:org: (https://en.wikipedia.org/wiki/Uniform_Resource_Name)
* Basically user-preference; but we need to make sure the string is compatible with input restrictions on AWS or Azure, when the identity provider is configured; it is what we require the org admin to configure on their IDP
* `exp` (expiration) → until when the token is valid (timestamp in seconds)
Example payload:
```json
{
"iss": "https://token.actions.githubusercontent.com",
"sub": "repo:acme/api:ref:refs/heads/main",
"aud": "hive-console://org/",
"exp": 1775663291
}
```
The `aud`, `iss` and `sub` property together form the “identity key”, it is later on used on the Hive Console side for mapping the access token to actual permissions
This access token is send to the Hive Console GraphQL API e.g. via the CLI
```
POST https://api.graphql-hive.com/graphql
Authorization: Bearer JWT_TOKEN
```
## Manage Federation Issuer and Subject to Hive Permissions mapping
The Hive Console organization administrator sets up a mapping for issuer (`iss`) and subject (`sub`) to actual Hive Console role assignments. Each role assignment consists of a Hive Console Role and a set of assigned resources (projects, targets, services etc.).
UI Mockup:
## Authorising Identity Provider Access Tokens for Requests to the Hive Console GraphQL API
When a request with a `Authorization: Bearer ` header access token is sent to the Hive Console GraphQL API, the following authentication flow is performed:
1. **Verify JWT Signature.** On the Hive Console API side, we first verify whether the JWT is valid. We do so by fetching the JWKS (JSON Web Key Set) from the iss endpoint within the access token payload and verify the signature.
2. **Verify the access token is not expired.** Base on the exp property
3. **Verify the access token is allowed to act on behalf of the organization.**
1. Based on the `aud` claim, we lookup the organization
2. Based on the `iss` and `sub` claim, we look if a mapping to role + resources to these organization exists
1. if the mapping does not exists; the request is unauthorized and rejected
4. **Map the JWT token to Hive Console permissions.**
1. if the `iss` and `sub` mapping exists for that organization; we load the role and resource assignments and translate them to our runtime permission check system
5. **Business logic does authorisation checks.** This part stays as is and needs no further adjustments.
## Additional Requirements
Some users want to use non-standard IDP OIDC claims for mapping the access token to the Hive Console permission layer.
E.g. instead of using the `sub` claim, a `role` claim that is a list of strings shall be used.
We need to see if we should support this custom requirement, and if so in a generic and more flexible way, where users can configure how the subjects(s) is detemined before the mapping happens.
## Resources
- http://jwt.io/introduction
- https://docs.github.com/en/actions/concepts/security/openid-connect
- https://docs.github.com/en/actions/reference/security/oidc#example-subject-claims
- https://docs.github.com/en/actions/how-tos/secure-your-work/security-harden-deployments/oidc-in-aws
- https://www.youtube.com/watch?v=aOoRaVuh8Lc
- https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation
- https://docs.github.com/en/actions/concepts/security/openid-connect
Contributor guide
Assessment
This issue has not been assessed yet.