Repository navigation
Conversation
Contributor
There was a problem hiding this comment.
Copilot was unable to review this pull request because there is no eligible user to bill.
An enterprise owner can allow the organization to be billed for reviews like this by enabling Copilot code review for users without a license.
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
alliscode
force-pushed
the
copilot/hub-identity-api
branch
from
October 28, 2026 18:34
1a04887 to
c3e12ce
Compare
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Bootstrap and recovery callbacks fail at runtime, the administration page fails type checking, and unresolved admission and audit defects affect access control and accountability.
17 open issues
Use a supported Primer Button variant · New Allow bootstrap and recovery authorization attempts · New Restart verification after fresh authorization expires · New Clear cached administration state after authorization failure · New Default invitations to the least-privileged member role · New Test migrations and update lifecycle fixtures · New Backfill existing audit outcomes after adding success default · New Reject future authorization timestamps · New Validate invitation IDs before querying · New Validate membership IDs before querying · New Audit denied administration requests · New Preserve suspension time during role changes · New Audit both role and status changes · New Check Hub admission before calling external repository policy · New Do not skip invitation lookup after repository admission · New Paginate membership administration results · New Paginate invitation history or separate pending invitations · New
Review effort: Max
| </Button> | ||
| <Button | ||
| type="button" | ||
| variant="danger" |
| pkceVerifier: string | ||
| nonce: string | null | ||
| purpose: "sign-in" | "verify" | "link-identity" | ||
| purpose: "sign-in" | "verify" | "link-identity" | "bootstrap" | "recovery" |
Comment on lines
+131
to
+132
| const data = (await response.json()) as { error?: string } | ||
| throw new Error(data.error ?? "Administration request failed") |
Comment on lines
+131
to
+132
| const data = (await response.json()) as { error?: string } | ||
| throw new Error(data.error ?? "Administration request failed") |
| const [provider, setProvider] = useState("github") | ||
| const [issuer, setIssuer] = useState("https://github.com") | ||
| const [subject, setSubject] = useState("") | ||
| const [role, setRole] = useState<"member" | "administrator">("administrator") |
Comment on lines
+253
to
+255
| context: { | ||
| reason: nextStatus !== target.status ? `status_${nextStatus}` : `role_${nextRole}`, | ||
| }, |
Comment on lines
+53
to
+55
| if (attempt.purpose === "sign-in") { | ||
| policyAdmitted = await admissionPolicy.admit(profile) | ||
| } |
Comment on lines
+115
to
+116
| membership?.status !== "suspended" && | ||
| !policyAdmitted |
| return (await database.installationMembership.findMany({ | ||
| include: { user: { include: { externalIdentities: true } } }, | ||
| orderBy: [{ createdAt: "desc" }, { id: "desc" }], | ||
| take: 100, |
| ): Promise<MembershipInvitationRecord[]> { | ||
| return (await database.membershipInvitation.findMany({ | ||
| orderBy: [{ createdAt: "desc" }, { id: "desc" }], | ||
| take: 100, |
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.


Why
GitHub authentication proves who a person is, but it should not decide whether that person may enter a Hub installation. Hub needs its own durable membership boundary so installation access and administration remain stable when repository permissions change.
What changes
Hub now admits a signed-in identity only when it has an active membership, matches a usable invitation, or completes authorized bootstrap or recovery enrollment. Administrators can invite immutable provider identities, assign member or administrator roles, and move memberships through active, suspended, and removed states.
Suspending or removing a member ends that person's Hub sessions. Hub prevents concurrent changes from removing the final active administrator, supports one-use bootstrap and no-administrator recovery, and records successful and denied administration outcomes as structured security audits. State-changing APIs enforce the Hub origin, CSRF protection, membership checks, and private no-store responses.
The minimal interface adds first-administrator enrollment, recovery, invitation management, and membership administration. This layer does not add prototype authorization, GitHub membership synchronization, artifact ingestion, or production OIDC.
Storybook screenshots
Hub/Pages/Identity/Membership administration / Default — dark theme, 1280 × 720
Hub/Pages/Identity/Sign in / Signed Out — enrollment and recovery expanded, 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