How access is decided
Two things must both be true for someone to reach the admin UI:- Their provider authenticates them
- Their verified email matches the allowlist
/admin#access.
OAUTH_ALLOWED_EMAILS and OAUTH_ALLOWED_DOMAINS only seed that list. They apply until the first Save changes on the Access page, and from then on the stored list is the only authority.
Both are comma-separated. Each entry is trimmed and lowercased, and empty entries are dropped.
Every entry carries a role:
- An address seeded from
OAUTH_ALLOWED_EMAILSgets the admin role. - A domain seeded from
OAUTH_ALLOWED_DOMAINSadmits people only as user. - Only a listed address can be admin — a domain never confers it.
node dist/access-recovery.js --email <address> to restore it.
Create a provider application
Pick the provider you want to sign in with. Configuring both is fine — operators then choose at the sign-in screen.- Google
- Microsoft
Google has 2 provider specific environment variables, both retrievable in the Create the OAuth Client step:
GOOGLE_OAUTH_CLIENT_IDGOOGLE_OAUTH_CLIENT_SECRET
1
Create a Google Cloud project
In the Google Cloud console, open the project picker in the top bar and choose New Project. Name it something recognizable, such as
ai-implement-sso.If your company has Google Workspace, set the parent organization so the project is governed by it. No billing is required for what follows.2
Configure the consent screen
Open Google Auth Platform. Depending on the project, it opens either a Get started wizard or the Overview page.Work through the Get started wizard’s screens:External fits when some operators sign in with addresses outside a single Workspace organization. The orchestrator’s allowlist is then the only gate, and the consent screen needs the Publish app step below.
- App information — an app name and a user support email.
- Audience — choose Internal or External, below.
- Contact information — an email for Google’s notices.
- Finish — accept the user-data policy and click Create.
- Branding — the app name and support email.
- Audience — the user type, below.
- Clients — the OAuth client, created in a later step.
- Data Access — the scopes, declared in a later step.
- Overview — has the Create OAuth client button, used in a later step.
- Verification Center and Settings — not part of this setup.
example.com reached through an orchestrator at ai-implement.example-dev.com choose on example.com.Internal fits when every operator signs in with an account in your Google Workspace organization. Google admits only accounts in that organization, so a domain check runs ahead of the orchestrator’s allowlist, and no Publish app step or test users are needed.Internal has one condition: the Cloud project must belong to that organization. Create the project while signed in with a Workspace account and choose the organization as its Location, or the console leaves Internal disabled.With Internal, the Google error “restricted to users within its organization” means the operator signed in with an account outside the Workspace organization.
3
Publish the consent screen
This step applies to the External audience only — an Internal app needs no publishing.On the Audience page, click Publish app to move the consent screen from testing to production.The three scopes this app requests are non-sensitive (
openid, email, profile), so Google requires no verification and the publish takes effect immediately.Publishing clears two limits that testing mode imposes:- The 100-account cap on who can authenticate
- The “unverified app” interstitial shown at sign-in
4
Declare the scopes
On the Data Access page, click Add or remove scopes and select the three the orchestrator requests:
openid.../auth/userinfo.email.../auth/userinfo.profile
5
Create the OAuth client
Create OAuth client on the Overview page and Create client on the Clients page open the same form.The form asks for the application type first. The name and redirect URI fields appear only after you choose Web application.Give the client an internal name — this one isn’t shown to operators.Under Authorized redirect URIs, add two entries per orchestrator — one for admin sign-in and one for the MCP client flow:Leave Authorized JavaScript origins empty. The orchestrator exchanges the authorization code server-side, so that field is unused.Create the client, then copy the Client ID and Client secret into
GOOGLE_OAUTH_CLIENT_ID and GOOGLE_OAUTH_CLIENT_SECRET.Wire the orchestrator
Alongside the provider credentials above, every orchestrator needs the callback base URL and the allowlist seed:/admin#access to adopt this seed as the stored list, then add any later operators there rather than in Fly secrets.
Each variable is described in Environment variables.
Add the orchestrator as a project connector
The/mcp endpoint can be added to claude.ai as a project connector, which needs one secret beyond the sign-in setup above. Without it, the connection fails at dynamic client registration with invalid_redirect_uri, before any sign-in screen appears.
The registration endpoint accepts loopback callbacks by default, so Claude Code needs no equivalent configuration. A browser-based client such as claude.ai calls back over HTTPS, and that origin has to be allowlisted explicitly.
1
Allowlist the claude.ai origins
Set The callback claude.ai registers is
MCP_ALLOWED_REDIRECT_ORIGINS as a secret with the origins claude.ai registers from:https://claude.ai/api/mcp/auth_callback, and allowlisting its origin is all you do.This is not the same as the provider redirect URIs you added earlier. Those let the orchestrator finish sign-in with Google or Microsoft.This allowlist decides which client origins may register with the orchestrator at all, which happens before any sign-in begins.
2
Add the connector in claude.ai
In claude.ai, add the orchestrator’s
/mcp URL as a project connector and complete the sign-in. Registration now succeeds, and the flow continues to your configured Google or Microsoft sign-in.The shared access code
ADMIN_ACCESS_CODE still works and is the right choice for local development, but it is deprecated for deployed orchestrators — it identifies nobody and cannot be revoked for one person.
The admin UI is enabled when the access code or any sign-in provider is configured, so you can leave the code in place while operators move across, then remove it.
What’s next
Environment variables
Every sign-in variable, with its accepted values and defaults.
Admin UI reference
What each panel in the admin UI does once you’re signed in.