feat: add Azure AD (Entra ID) SSO login provider#4428
Open
kent-hydra wants to merge 6 commits into
Open
Conversation
|
@kent-hydra is attempting to deploy a commit to the Hatchet Team on Vercel. A member of the Team first needs to authorize it. |
Add the Azure (Entra ID) OAuth provider as a sister to the existing
Google/GitHub providers:
- NewAzureClient builds the oauth2.Config with tenant-templated
authorize/token endpoints (login.microsoftonline.com/{tenant}/...),
defaulting to the "organizations" meta-tenant when no tenant is set.
- ConfigFileAuthAzure adds the enabled/clientID/clientSecret/scopes
fields plus an Azure-specific optional tenantID, wired via the
SERVER_AUTH_AZURE_* env vars.
- The loader constructs AzureOAuthConfig when enabled and includes
"azure" in the security-check provider list.
- "azure" is accepted by the OAuthOpts provider validation.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the /api/v1/users/azure/start and /callback endpoints to the OpenAPI spec, regenerate the server/client code, and implement the handlers: - azure_oauth_start.go mirrors the Google start handler (save state, redirect to AuthCodeURL). - azure_oauth_callback.go exchanges the code, reads claims from the Microsoft OIDC userinfo endpoint (graph.microsoft.com/oidc/userinfo), and upserts the user. Since Azure AD has no Google-style "hd" claim, domain restriction follows the GitHub pattern (check the email domain), with a preferred_username fallback when the email claim is absent. - The /meta handler advertises "azure" when the provider is enabled. Regenerated: openapi.gen.go, rest/gen.go, frontend Api.ts, data-contracts.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Render an "Azure" social auth button when the /meta endpoint reports the "azure" scheme, mirroring the Google/GitHub buttons: - Add a Microsoft logo icon and the azure entry to PROVIDER_CONFIG. - Wire azureEnabled through the auth page provider list. - Add the Azure start/callback query wrappers, including the control-plane variants used on Hatchet Cloud. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the SERVER_AUTH_AZURE_* environment variables to the self-hosting configuration reference. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The API server validates at startup that every OpenAPI operation has an authz classification in rbac.yaml, and panics otherwise. Add the Azure OAuth start/callback operations to the public (no-auth) allowlist, alongside the Google/GitHub equivalents, so the server boots with the Azure endpoints registered. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified against Microsoft's docs that graph.microsoft.com/oidc/userinfo returns only sub/name/.../email — it does NOT return preferred_username or email_verified. Accordingly: - Drop the dead preferred_username fallback and email_verified conditional (neither claim is ever present in the userinfo response). - Collapse azureUserInfoResponse into a single azureUserInfo struct. - Set EmailVerified=true explicitly, with a comment: the email is sourced from the Azure AD directory and Hatchet's authz middleware blocks unverified users, matching the Google/GitHub providers. - Check the userinfo HTTP status so a Graph failure surfaces a clear error instead of masquerading as "azure account must have an email". Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
kent-hydra
force-pushed
the
feat/azure-sso
branch
from
July 15, 2026 17:05
1faa95a to
b50d67b
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Adds Azure AD / Microsoft Entra ID as a first-class SSO login provider, alongside the existing Google and GitHub OAuth providers. Built on the same
golang.org/x/oauth2rails — no new dependencies — and modeled directly on the Google/GitHub sibling implementations.Fixes #4427
Type of change
What's Changed
SERVER_AUTH_AZURE_*):enabled/clientID/clientSecret/tenantID/scopes, mirroringSERVER_AUTH_GOOGLE_*.tenantIDis optional — defaults to theorganizationsmeta-tenant (multi-tenant), or set it to lock sign-in to a single directory.pkg/auth/oauth):NewAzureClientbuilds tenant-templated authorize/token endpoints (login.microsoftonline.com/{tenant}/oauth2/v2.0/...).GET /api/v1/users/azure/startand/callback, added to the OpenAPI spec and registered inrbac.yamlas public (no-auth) operations.userinfoendpoint (sub/name/email); domain restriction reusescheckUserRestrictionsForEmail(email-domain based, since Azure AD has nohdclaim). OAuth tokens are encrypted at rest like the other providers./api/v1/metaadvertisesazurewhen the provider is enabled.SERVER_AUTH_AZURE_*documented in the self-hosting configuration reference.Checklist
Changes have been:
docker composedeployment with a successful end-to-end sign-in against a real Azure AD tenant; also verified/api/v1/metaadvertisesazureand/api/v1/users/azure/start302-redirects to the correct Microsoft authorize URL)gofmt,go vet; frontendprettier/eslinton changed files)Notes for reviewers
api/v1/server/oas/gen/openapi.gen.go,pkg/client/rest/gen.go, frontendApi.ts/data-contracts.ts) produced bytask generate-apiafter the OpenAPI spec change.frontend/app/src/lib/api/generated/control-plane/Api.tswas hand-edited to add the twocloudUserUpdateAzureOauth*methods, because the control-plane client is generated from a separate spec that has no regeneration path in this repo. Happy to adjust if there's a preferred approach.oidc/userinfoendpoint returns neitheremail_verifiednorpreferred_username, so the callback setsEmailVerified=truedeliberately (the email is directory-sourced, and the authz middleware rejects unverified users — matching the Google/GitHub providers' behavior).🤖 AI Disclosure
I acknowledge that an LLM was used in the creation of this Pull Request, in accordance with Hatchet's AI_POLICY.md.
Details: Claude Code (Claude Opus 4.8) was used to implement the feature end-to-end — modeled on the existing Google/GitHub OAuth providers — to run the OpenAPI codegen, to verify it via a local Docker deployment against a real Azure AD tenant, and to draft this PR. All changes were reviewed by the author.
🤖 Generated with Claude Code