Skip to content

feat: add Azure Federated Workload Identity support for OIDC SSO login#7966

Open
cosmincatalin wants to merge 53 commits into
graphql-hive:mainfrom
cosmincatalin:main
Open

feat: add Azure Federated Workload Identity support for OIDC SSO login#7966
cosmincatalin wants to merge 53 commits into
graphql-hive:mainfrom
cosmincatalin:main

Conversation

@cosmincatalin

Copy link
Copy Markdown

Background

When deployed in Kubernetes with Azure Workload Identity, the OIDC SSO integration should be able to authenticate to the identity provider (e.g., Microsoft Entra ID) using a federated token (client_assertion) instead of storing a client_secret. This eliminates the need for secrets management for the OAuth2 token exchange.

Description

Adds a useFederatedCredential option to OIDC integrations. When enabled, the token exchange uses the AZURE_FEDERATED_TOKEN_FILE (injected by the Azure Workload Identity webhook) as a client_assertion JWT bearer instead of client_secret.

  • DB migration: use_federated_credential boolean column on oidc_integrations, client_secret made nullable
  • Storage/Entity: OIDCIntegration.encryptedClientSecret now string | null, added useFederatedCredential: boolean
  • GraphQL schema: clientSecret optional in CreateOIDCIntegrationInput, useFederatedCredential field on type + inputs
  • OIDC provider: Validates that either clientSecret or useFederatedCredential is provided on create
  • Auth server token exchange (supertokens-at-home.ts): Reads federated token file and sends client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer + client_assertion=<token> instead of client_secret
  • UI: Shows federated credential status badge, handles nullable clientSecretPreview

Token exchange with federated credentials:

POST /token
  grant_type=authorization_code
  client_id=<app-registration-client-id>
  client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer
  client_assertion=<contents-of-AZURE_FEDERATED_TOKEN_FILE>
  code=<auth-code>
  code_verifier=<pkce-verifier>

#2)

* feat: add Azure Federated Identity (OAuthBearer) support for Kafka/EventHub

Add support for the `oauthbearer` SASL mechanism in both the usage and
usage-ingestor services, enabling Azure Workload Identity authentication
to Event Hub when deployed in Kubernetes.

Changes:
- Add `@azure/identity` dependency to usage and usage-ingestor packages
- Add `oauthbearer` SASL mechanism to environment config (Zod schemas)
- Create `oauth-bearer-provider.ts` using DefaultAzureCredential
- Update Kafka client initialization to support oauthbearer mechanism
- Update Pulumi deployment to conditionally configure oauthbearer

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/b3983d22-e4bf-4a52-90f1-c93895adeff8

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* refactor: improve OAuth bearer provider error handling and documentation

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/b3983d22-e4bf-4a52-90f1-c93895adeff8

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* revert: remove incorrect Kafka OAuthBearer changes

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/755ee5ba-e92c-4df8-b742-e04e182b5a13

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* feat: add Azure Federated Workload Identity support for OIDC SSO login

When deployed in Kubernetes with Azure Workload Identity, the OIDC
integration can now authenticate to the identity provider using a
federated token (client_assertion) instead of a client_secret.

Changes:
- DB migration: add use_federated_credential column, make client_secret nullable
- Entity/model: update OIDCIntegration to include useFederatedCredential
- GraphQL: make clientSecret optional in create input, add useFederatedCredential field
- OIDC provider: allow creation without client secret when federated
- Auth server: use client_assertion with AZURE_FEDERATED_TOKEN_FILE
- UI: show federated credential status, allow saving without client secret

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/755ee5ba-e92c-4df8-b742-e04e182b5a13

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* fix: use strict equality for null check in OIDC provider

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/755ee5ba-e92c-4df8-b742-e04e182b5a13

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces support for OIDC federated credentials, specifically Azure Workload Identity, allowing authentication without a client secret. Key changes include database migrations to make client secrets optional, GraphQL schema updates, and server-side logic to utilize federated token files during token exchange. Feedback highlights a style guide violation regarding direct process.env access, a performance concern with synchronous file I/O in an asynchronous handler, and a missing validation check in the update logic to ensure a valid authentication method is always configured.

Comment thread packages/services/server/src/supertokens-at-home.ts Outdated
Comment thread packages/services/server/src/supertokens-at-home.ts Outdated
cosmincatalin and others added 4 commits April 11, 2026 16:55
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
…irect process.env access (#3)

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/8b554117-9357-40a5-9879-83f5ac168987

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>
* Add validation in updateOIDCIntegration to ensure valid auth method after update

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/3b791a1d-2b1b-4152-af23-11dcd32bc977

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* Improve error message for missing auth method validation

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/3b791a1d-2b1b-4152-af23-11dcd32bc977

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>
@cosmincatalin

Copy link
Copy Markdown
Author

@n1ru4l, with #7745 in, can you look into merging this one in?

@n1ru4l n1ru4l left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this contribution! I added some initial comments with an initial review, it would be great if you could address these. We cannot give an exact timeline yet, but we will try to test this on our cluster and see if it feasible to merge and support soon.

Comment thread packages/services/server/src/supertokens-at-home.ts Outdated
Comment thread packages/services/server/src/supertokens-at-home.ts Outdated
Comment thread packages/migrations/src/actions/2026.04.09T00-00-00.oidc-federated-credential.ts Outdated
cosmincatalin and others added 7 commits April 16, 2026 10:29
…rated token management (#5)

* refactor: move federated token reading to WorkloadIdentityFederationProvider with polling

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/75f0bc25-7acb-495c-bd74-6767a633f1d3

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

* fix: trim whitespace from federated token file content

Agent-Logs-Url: https://github.com/cosmincatalin/console/sessions/75f0bc25-7acb-495c-bd74-6767a633f1d3

Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: cosmincatalin <525590+cosmincatalin@users.noreply.github.com>
@cosmincatalin
cosmincatalin requested a review from n1ru4l May 12, 2026 07:39

@n1ru4l n1ru4l left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have been thinking more about Federation Workload Identity and how we want to support it in the future as a Hive Console Cloud feature that we provide all users, which means at some point Hive Console comes with its own built in OIDC discovery and JWKS endpoint, with assigned subjects for each organization.


However, I still see in value in this solution as it solves a problem today and is much simpler for self-hosters, without the complexity that the above direction requires.

I have the following feedback and changes I would like to see.

Set the organization for which the file can be used for via an environment variable

Instead of the current approach, where every org can opt-into using the token file, I would prefer this to be more explicit via required configuration.

To me it feels a bit unsettling, that any organization existing on the Hive Console deployment could use this identity file.

My proposal is that new environment variable OIDC_WORKLOAD_FEDERATION_ORGANIZATION_ID, would isolate which exact organization can use the Azure Workload Identity.

OIDC_WORKLOAD_FEDERATION_IDENTITY_PROVIDER=azure
OIDC_WORKLOAD_FEDERATION_ORGANIZATION_ID=<organization-uuid>
AZURE_FEDERATED_TOKEN_FILE=/var/run/secrets/azure/tokens/azure-identity-token

All these three values need to be set during startup.

Startup should fail when:

  • The organization ID is malformed
  • The file is unreadable
  • The file is empty

Remove the use_federated_credential column from pg

Instead whether a org uses federation credentials is read from the configuration.

Remove the nullability for the CreateOIDCIntegrationInput.clientSecret (for now)

Since this is for now a very specific implementation for certain self-hosting environments, I do not (yet) want this to affect the existing API contract we have in Cloud (until we have a solution that also works for our Cloud deployment).

Instead, I think it is an okay tradeoff to require passing a dummy value (which is then never used).


@cosmincatalin These changes would make it comfortable enough for me to accept this contribution. Let me know if you have additional thoughts or pushback on these.

cosmincatalin and others added 4 commits July 20, 2026 21:01
The `useFederatedCredential` flag is no longer stored on OIDC integration entities or exposed in the API/UI. Instead, the decision to use federated credentials is now externalized and controlled solely by environment variables, specifically `OIDC_WORKLOAD_FEDERATION_ORGANIZATION_IDS`. This simplifies the OIDC integration model by making client secrets always required unless an organization is explicitly listed for federated authentication via environment configuration.
@cosmincatalin
cosmincatalin requested a review from n1ru4l July 20, 2026 20:28
@cosmincatalin

Copy link
Copy Markdown
Author

Based on your suggestions, @n1ru4l , I have greatly simplified the PR, to the point where it's way easier to review.

Instead of being able to provide a single organization that can use federation workloads, I thought it's appropriate to be able to do it for any number, by providing a comma separated list of organizations UUIDs in OIDC_WORKLOAD_FEDERATION_ORGANIZATION_IDS.

Earlier migrations, UI code and other complexities have been removed.

Let me know if this is fine.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants