Repository navigation
Conversation
Add encrypted database and read-only environment credential providers for one GitHub installation, transactional identity repositories, and their storage contracts. Co-authored-by: Ben Thomas <ben.thomas@microsoft.com> Co-authored-by: Nishiki <hello@nshki.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|
The Entra setup script is still being tested. Please focus review on whether its Plan output, Apply convergence, assignment reconciliation, ownership checks, and repeat-run behavior are safe and idempotent before operators use it in a tenant. |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved OIDC flaws can remove valid Entra memberships and sessions, preserve administrator access after a role downgrade, and accept ID tokens without expiration.
11 open issues
Reject stale sessions after Entra role downgrades · New Prevent GitHub reconciliation from removing OIDC memberships · New Require an expiration claim on OIDC ID tokens · New Remove read-only origin fields from Graph role payloads · New Handle empty and case-sensitive redirect URI comparisons · New Include all new grants when planning service principal creation · New Provide a secure workflow for obtaining invitation subject IDs · New Audit bootstrap and recovery enrollment refusals · New Reject admission policies incompatible with OIDC · New Map initiation discovery failures to provider-unavailable responses · New Register routes only for the configured identity provider · New
1 file not reviewed
hub/package-lock.json: Generated file
What changed in this PR
Adds single-tenant Microsoft Entra sign-in as an explicitly selected alternative to GitHub, while retaining Hub-owned membership and opaque browser sessions.
Changes:
- Adds OIDC configuration, provider revisions, authorization flows, token validation, and app-role admission.
- Updates authentication routes, session metadata, identity storage, and the sign-in interface for provider selection.
- Adds Microsoft Graph setup tooling, supporting tests, and operator documentation.
| File | Description |
|---|---|
hub/server/routes/index.ts |
Registers OIDC initiation and callback routes. |
hub/server/routes/authentication.test.ts |
Covers callback bounds, validation, cookies, and log omission. |
hub/server/routes/api/session/get/index.ts |
Exposes configured provider metadata. |
hub/server/routes/api/auth/oidc/post/index.ts |
Reuses protected sign-in initiation. |
hub/server/routes/api/auth/oidc/callback/get/index.ts |
Applies the larger OIDC code limit. |
hub/server/routes/api/auth/github/callback/get/index.ts |
Delegates to shared handling with GitHub’s code limit. |
hub/server/routes/api/auth/callback/get/index.ts |
Centralizes callback validation, cookies, and redirects. |
hub/server/repositories/external-identities/types.ts |
Adds identity email attributes. |
hub/server/repositories/external-identities/save-external-identity/index.ts |
Refreshes stored email data. |
hub/server/repositories/authorization-attempts/consume-attempt/index.ts |
Accepts bootstrap and recovery purposes. |
hub/server/repositories/authentication-providers/get-latest-revision/index.ts |
Fetches the highest stored provider revision. |
hub/server/integrations/oidc/create-client/types.ts |
Defines OIDC configuration, client, and profile contracts. |
hub/server/integrations/oidc/create-client/index.ts |
Implements discovery, code exchange, and token verification. |
hub/server/integrations/oidc/create-client/index.test.ts |
Covers token validation, caching, rotation, and outages. |
hub/server/domains/identity/create-store/types.ts |
Adds latest-provider-revision lookup. |
hub/server/domains/identity/create-records/index.ts |
Binds the new revision query. |
hub/server/domains/authentication/start-oidc-authorization/index.ts |
Creates browser-bound OIDC authorization attempts. |
hub/server/domains/authentication/read-oidc-configuration/index.ts |
Validates the Entra environment profile. |
hub/server/domains/authentication/read-oidc-configuration/index.test.ts |
Covers configuration requirements and rejected values. |
hub/server/domains/authentication/read-authentication-provider/index.ts |
Requires explicit provider selection. |
hub/server/domains/authentication/read-authentication-provider/index.test.ts |
Tests supported and invalid provider values. |
hub/server/domains/authentication/ensure-oidc-provider-revision/index.ts |
Persists revisions and rejects configuration drift. |
hub/server/domains/authentication/ensure-oidc-provider-revision/index.test.ts |
Covers revision reuse, rollback, and credential fingerprints. |
hub/server/domains/authentication/ensure-oidc-provider-revision/index.db.test.ts |
Checks revision reuse after database-backed restart. |
hub/server/domains/authentication/create-service/types.ts |
Adds OIDC dependencies and provider metadata. |
hub/server/domains/authentication/create-service/oidc.test.ts |
Covers OIDC admission, membership lifecycle, and replay rejection. |
hub/server/domains/authentication/create-service/index.ts |
Dispatches authorization to the selected provider. |
hub/server/domains/authentication/create-runtime/index.ts |
Composes provider configuration and runtime clients. |
hub/server/domains/authentication/complete-oidc-authorization/index.ts |
Resolves identities, evaluates membership, and creates sessions. |
hub/script/tests/setup-entra-oidc.test.mjs |
Adds source-level setup-script contract checks. |
hub/script/setup-entra-oidc.ps1 |
Adds Graph preflight, planning, application, and owned-resource removal. |
hub/schema/migrations/20261027221500_oidc_identity_attributes/migration.sql |
Adds nullable external-identity email storage. |
hub/schema/external-identity.prisma |
Models the email attribute. |
hub/README.md |
Updates Hub’s authentication and feature overview. |
hub/package.json |
Adds the jose dependency. |
hub/package-lock.json |
Locks the new dependency. |
hub/docs/README.md |
Links the Entra operator guide. |
hub/docs/membership-and-administration.md |
Documents OIDC admission and lifecycle boundaries. |
hub/docs/identity.md |
Describes provider selection and OIDC identity contracts. |
hub/docs/entra-oidc.md |
Documents setup, configuration, roles, and lifecycle limits. |
hub/docs/development.md |
Explains provider selection for local development. |
hub/docs/architecture.md |
Reflects configured-provider authentication in Hub’s architecture. |
hub/app/javascript/pages/sign-in-page/types.ts |
Adds the provider-label presentation prop. |
hub/app/javascript/pages/sign-in-page/stories.tsx |
Uses an enterprise sign-in label in story fixtures. |
hub/app/javascript/pages/sign-in-page/index.tsx |
Renders provider-aware sign-in copy. |
hub/app/javascript/pages/sign-in-page/index.test.tsx |
Tests provider labels and unconfigured behavior. |
hub/app/javascript/application/authentication/index.tsx |
Uses session metadata to select sign-in initiation. |
hub/.env.example |
Adds explicit provider selection and OIDC configuration examples. |
Review effort: Max (auto)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
48021df to
6d9e822
Compare
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved schema, audit-context, and identity-lookup defects can roll back first-time and role-changing sign-ins and cause returning users to receive 500 errors after client-ID changes.
11 open issues
Membership source constraint excludes jit-assignment · New Client ID changes violate identity uniqueness · New Invalid audit context rolls back claim-driven promotion · New Repository synchronization authorization boundaries are conflated · New Case-insensitive validation accepts invalid secret reference · New Case-insensitive role lookup misses role drift · New Case-insensitive redirect deduplication removes distinct callbacks · New Setup safety tests are missing from CI · New Denied verification audit rolls back with transaction · New Admission policy validation occurs after revision persistence · New OIDC scope validation omits required profile scope · New
11 resolved since last review
Require an expiration claim on OIDC ID tokens Prevent GitHub reconciliation from removing OIDC memberships Reject stale sessions after Entra role downgrades Register routes only for the configured identity provider Map initiation discovery failures to provider-unavailable responses Reject admission policies incompatible with OIDC Audit bootstrap and recovery enrollment refusals Provide a secure workflow for obtaining invitation subject IDs Include all new grants when planning service principal creation Handle empty and case-sensitive redirect URI comparisons Remove read-only origin fields from Graph role payloads
1 file not reviewed
hub/package-lock.json: Generated file
Review effort: Max (auto)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
PowerShell turns empty claim collections into null, causing Entra OIDC application creation and existing-application Plan/Apply flows to fail.
1 open issue
2 resolved since last review
1 file not reviewed
hub/package-lock.json: Generated file
Review effort: Max (auto)
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
ffec328 to
12b0b5e
Compare
There was a problem hiding this comment.
🔵 Needs a closer look
Human assessment is needed to evaluate credential-exposure and membership-audit risks that are not covered by the published review.
No open issues 🎉
1 resolved since last review
1 file not reviewed
hub/package-lock.json: Generated file
Review effort: Max (auto)


Why
Replica Hub needs production sign-in that does not require every user to have a GitHub account. This adds a standards-based OpenID Connect path for a single Microsoft Entra tenant while keeping Hub membership as the persisted authority for installation access.
What changes
Operators can select one explicit user sign-in provider and configure a single-tenant Entra application. Hub performs OIDC discovery, authorization code exchange with PKCE, browser-bound state, nonce and replay checks, signed ID-token validation, bounded JWKS caching and rotation, and strict issuer, audience, authorized-party, and lifetime checks. The Entra issuer is limited to the expected tenant-specific Microsoft login URL, and long real-world Entra authorization codes use a separate safe callback bound from GitHub.
Hub.UserandHub.Administratorapp roles control admission and administrator mapping. Hub stores identity by provider, tenant issuer, and immutable subject; login, email, name, and picture remain mutable display data. Just-in-time assignment or invitation-required admission can create membership, while suspended and removed memberships and the final-administrator rule remain Hub-owned protections. Provider tokens are discarded after identity and role extraction, and browser access continues through opaque Hub sessions.The included Microsoft Graph PowerShell script can preflight, plan, apply, or safely remove script-owned setup. It configures the callback, assignment requirement, app roles, and requested group assignments while preserving unrelated roles. The real GitHub and Entra pilot completed sign-in, bootstrap, session creation, and the long callback-code flow using manual portal configuration. The setup script is still being tested: its contract and PowerShell preflight were exercised, but the live tenant pilot did not use it to create the application, so operators and reviewers should inspect Plan output and intended tenant changes before Apply.
GitHub user authentication, GitHub source credentials, synchronized repository permissions, prototype authorization, and artifact workload credentials remain separate boundaries. This change does not add provider account linking, a provider chooser, SCIM, background Graph access, or refresh-token storage.
Storybook screenshots
Hub/Pages/Identity/Sign in — Signed out — dark theme — 1280 × 720
Hub/Pages/Identity/Sign in — Signed in — dark theme — 1280 × 720
Hub/Pages/Identity/Sign in — Unconfigured — dark theme — 1280 × 720
Hub/Pages/Identity/Membership administration — Default — dark theme — 1280 × 720