Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.
This guide configures the Autopilot dashboard to sign users in with Google OAuth/OIDC
instead of Xano. It is an alternative to the default Xano method; exactly one method is
active per cluster. Authorization (who can do what) is unchanged — a Google-authenticated
user is resolved against the same AccessPolicy by email.Auth is gated by auth.enabled (default false). Enabling Google on a cluster is a
deliberate, per-cluster opt-in. Rollback is instant: flip the method back to xano or set
auth.enabled=false and redeploy.
In the GCP Console → APIs & Services → Credentials → Create credentials → OAuth client ID:
Application type: Web application
Authorized redirect URIs: add <base>/api/v1/auth/callback for every hostname that will use Google on this cluster, e.g. https://ops.xano.com/api/v1/auth/callback. (The path is always /api/v1/auth/callback.)
In the cluster’s env file (deploy/envs/<tier>/<cluster>.yaml) or a values override:
auth: enabled: true method: google dashboardBaseURL: "https://ops.xano.com" # the external base; callback is <base>/api/v1/auth/callback superAdmins: # bootstrap admins (unkillable, never edited via the API) - you@xano.com google: clientId: "<client-id>.apps.googleusercontent.com" allowedDomain: "xano.com" # enforced Google Workspace hd allowAnyDomain: false # keep false to enforce the domain (recommended) clientSecret: secretName: ops-ai-google-oauth # the Secret created in step 2 secretKey: client-secret
Hosted-domain enforcement is on by default. Either set allowedDomain, or explicitly
set allowAnyDomain: true to accept any Google account (including consumer @gmail.com,
which carry no hd claim). The controller refuses to start a method=google cluster
unless one of these is satisfied (and clientId + the secret are present) — a fail-fast
startup error, not a silent lockout.
Open the dashboard → you should be redirected to /login, which now shows “Sign in with Google” with the Google glyph.
Click it → Google’s account chooser appears (scoped to the allowed domain via the hd hint) → after consent you land back on /app/.
A first-time user with no grant lands on the access-request screen; an admin approves them on the Access Control → Pending Requests page.
Lockout insurance: set superAdmins (e.g. you@xano.com) — a super-admin resolves to
admin even with no AccessPolicy CRD present, so admin-gated features (terminal, logs)
work immediately. Every other user is resolved against the cluster’s AccessPolicy and needs
a matching grant.
Session length is bounded by the Google ID token’s expiry (~1 hour), so users re-authenticate roughly hourly even though AUTH_COOKIE_MAX_AGE caps the upper bound at 12h.
In-flight logins (the ~10-minute window between clicking sign-in and completing the callback) are invalidated if the controller restarts — the user simply clicks sign-in again. This is expected for the single-replica controller (the handshake key is ephemeral/in-memory by design).
Rollback: set auth.method: xano (with auth.xano.accountOrigin) or auth.enabled: false and redeploy. The Google code is dormant unless method=google.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Autopilot by Xano","colors":{"primary":"#0055FF","light":"#4D8AFF","dark":"#0044CC"},"favicon":"https://mintcdn.com/autopilot/S03iboz6ngzwzwdq/favicon.svg?fit=max\u0026auto=format\u0026n=S03iboz6ngzwzwdq\u0026q=85\u0026s=05f1b6360b96b1ea72ed6155929335cd","footer":{"socials":{"x":"https://x.com/xano","website":"https://xano.com"}},"styling":{"latex":true},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"autopilot","hasAudioNarration":false,"actualSubdomain":"autopilot","customDomains":["autopilot.docs.xano.com"],"gitSource":{"type":"github","owner":"xano-labs","repo":"autopilot-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"latestBuiltDeploymentHistoryId":"6a7242d8af37077868e5a5ad","collectionId":"2a5a7bf5-e8ee-479e-9455-2c684d54b5dc","liveDeploymentHistoryId":"6a7242d8af37077868e5a5ad","schemaVersion":"v3"},"entitlements":{},"buildId":"6aea21979c8dff74524fba15:success","clientVersion":"0.0.4074","searchFilterCounts":[{"language":"default","tag":"Documentation","count":24},{"language":"default","tag":"Platform","count":10},{"language":"default","tag":"Reference","count":10},{"language":"default","tag":"Operations","count":9},{"language":"default","tag":"Get Started","count":4},{"language":"default","tag":"Migrating from CAST AI","count":1}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"comment-mode","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"operations/dashboard-auth-google","slug":"/operations/dashboard-auth-google","pageMetadata":{"title":"Dashboard Auth — Google OAuth","description":"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.","href":"/operations/dashboard-auth-google"},"description":{"compiledSource":"\"use strict\";\nconst {jsx: _jsx} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsx(_components.p, {\n children: \"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\"\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx,jsxs:_jsxs}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){const _components={code:`code`,li:`li`,ol:`ol`,p:`p`,pre:`pre`,span:`span`,strong:`strong`,ul:`ul`,..._provideComponents(),...props.components},{CodeBlock,Heading,Warning}=_components;if(!CodeBlock)_missingMdxReference(`CodeBlock`,true);if(!Heading)_missingMdxReference(`Heading`,true);if(!Warning)_missingMdxReference(`Warning`,true);return _jsxs(_Fragment,{children:[_jsxs(_components.p,{children:[`This guide configures the Autopilot dashboard to sign users in with `,_jsx(_components.strong,{children:`Google OAuth/OIDC`}),`\ninstead of Xano. It is an alternative to the default Xano method; exactly one method is\nactive per cluster. Authorization (who can do what) is unchanged — a Google-authenticated\nuser is resolved against the same `,_jsx(_components.code,{children:`AccessPolicy`}),` by email.`]}),`\n`,_jsxs(_components.p,{children:[`Auth is gated by `,_jsx(_components.code,{children:`auth.enabled`}),` (default `,_jsx(_components.strong,{children:`false`}),`). Enabling Google on a cluster is a\ndeliberate, per-cluster opt-in. Rollback is instant: flip the method back to `,_jsx(_components.code,{children:`xano`}),` or set\n`,_jsx(_components.code,{children:`auth.enabled=false`}),` and redeploy.`]}),`\n`,_jsx(Heading,{level:`2`,id:`prerequisites`,children:`Prerequisites`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsx(_components.li,{children:`A Google Cloud project where you can create OAuth credentials.`}),`\n`,_jsxs(_components.li,{children:[`The dashboard’s external base URL (the dashboard hostname), e.g. `,_jsx(_components.code,{children:`https://ops.xano.com`}),`. The OAuth redirect URI is always `,_jsx(_components.code,{children:`\u003cbase>/api/v1/auth/callback`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`A Google Workspace domain to enforce (e.g. `,_jsx(_components.code,{children:`xano.com`}),`) — strongly recommended.`]}),`\n`]}),`\n`,_jsx(Heading,{level:`2`,id:`1-create-the-oauth-client`,children:`1. Create the OAuth client`}),`\n`,_jsxs(_components.p,{children:[`In the GCP Console → `,_jsx(_components.strong,{children:`APIs \u0026 Services → Credentials → Create credentials → OAuth client ID`}),`:`]}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Application type:`}),` Web application`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Authorized redirect URIs:`}),` add `,_jsx(_components.code,{children:`\u003cbase>/api/v1/auth/callback`}),` for `,_jsx(_components.strong,{children:`every`}),` hostname that will use Google on this cluster, e.g. `,_jsx(_components.code,{children:`https://ops.xano.com/api/v1/auth/callback`}),`. (The path is always `,_jsx(_components.code,{children:`/api/v1/auth/callback`}),`.)`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[`Note the generated `,_jsx(_components.strong,{children:`Client ID`}),` and `,_jsx(_components.strong,{children:`Client secret`}),`.`]}),`\n`,_jsx(Heading,{level:`2`,id:`2-create-the-client-secret-secret`,children:`2. Create the client-secret Secret`}),`\n`,_jsxs(_components.p,{children:[`The client secret is injected from a Kubernetes Secret (read by the kubelet) — it is\n`,_jsx(_components.strong,{children:`never`}),` placed in Helm values or git.`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`2`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`2`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`kubectl`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --context=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`cluster`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` create`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` secret`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` generic`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ops-ai-google-oauth`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D7BA7D`},children:` \\\\`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` -n`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:` ops-ai`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --from-literal=client-secret=`}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`'\u003cthe-client-secret>'`})]}),`\n`]})})}),`\n`,_jsxs(_components.p,{children:[`The key name (`,_jsx(_components.code,{children:`client-secret`}),`) is the Helm default (`,_jsx(_components.code,{children:`auth.google.clientSecret.secretKey`}),`).`]}),`\n`,_jsx(Heading,{level:`2`,id:`3-set-helm-values`,children:`3. Set Helm values`}),`\n`,_jsxs(_components.p,{children:[`In the cluster’s env file (`,_jsx(_components.code,{children:`deploy/envs/\u003ctier>/\u003ccluster>.yaml`}),`) or a values override:`]}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`13`,language:`yaml`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`yaml`,children:_jsxs(_components.code,{language:`yaml`,numberOfLines:`13`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:`auth`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` enabled`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`true`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` method`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`google`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` dashboardBaseURL`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"https://ops.xano.com\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # the external base; callback is \u003cbase>/api/v1/auth/callback`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` superAdmins`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:`# bootstrap admins (unkillable, never edited via the API)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:` - `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`you@xano.com`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` google`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` clientId`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"\u003cclient-id>.apps.googleusercontent.com\"`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` allowedDomain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`\"xano.com\"`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # enforced Google Workspace hd`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` allowAnyDomain`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`false`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # keep false to enforce the domain (recommended)`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` clientSecret`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`:`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` secretName`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`ops-ai-google-oauth`}),_jsx(_components.span,{style:{color:`#6E7781`,\"--shiki-dark\":`#6A9955`},children:` # the Secret created in step 2`})]}),`\n`,_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#116329`,\"--shiki-dark\":`#569CD6`},children:` secretKey`}),_jsx(_components.span,{style:{color:`#1F2328`,\"--shiki-dark\":`#D4D4D4`},children:`: `}),_jsx(_components.span,{style:{color:`#0A3069`,\"--shiki-dark\":`#CE9178`},children:`client-secret`})]}),`\n`]})})}),`\n`,_jsx(Warning,{children:_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Hosted-domain enforcement is on by default.`}),` Either set `,_jsx(_components.code,{children:`allowedDomain`}),`, or explicitly\nset `,_jsx(_components.code,{children:`allowAnyDomain: true`}),` to accept any Google account (including consumer `,_jsx(_components.code,{children:`@gmail.com`}),`,\nwhich carry no `,_jsx(_components.code,{children:`hd`}),` claim). The controller refuses to start a `,_jsx(_components.code,{children:`method=google`}),` cluster\nunless one of these is satisfied (and `,_jsx(_components.code,{children:`clientId`}),` + the secret are present) — a fail-fast\nstartup error, not a silent lockout.`]})}),`\n`,_jsx(Heading,{level:`2`,id:`4-deploy-and-verify`,children:`4. Deploy and verify`}),`\n`,_jsx(_components.p,{children:`Deploy the cluster as usual:`}),`\n`,_jsx(CodeBlock,{filename:``,numberOfLines:`1`,language:`shellscript`,children:_jsx(_components.pre,{className:`shiki shiki-themes github-light-default dark-plus`,style:{backgroundColor:`#ffffff`,\"--shiki-dark-bg\":`#0B0C0E`,color:`#1f2328`,\"--shiki-dark\":`#D4D4D4`},language:`shellscript`,children:_jsxs(_components.code,{language:`shellscript`,numberOfLines:`1`,children:[_jsxs(_components.span,{className:`line`,children:[_jsx(_components.span,{style:{color:`#953800`,\"--shiki-dark\":`#DCDCAA`},children:`scripts/deploy-cluster.sh`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:` --context=`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`\u003c`}),_jsx(_components.span,{style:{color:`#0550AE`,\"--shiki-dark\":`#569CD6`},children:`cluster`}),_jsx(_components.span,{style:{color:`#CF222E`,\"--shiki-dark\":`#D4D4D4`},children:`>`})]}),`\n`]})})}),`\n`,_jsx(_components.p,{children:`Verify:`}),`\n`,_jsxs(_components.ol,{children:[`\n`,_jsxs(_components.li,{children:[`Open the dashboard → you should be redirected to `,_jsx(_components.code,{children:`/login`}),`, which now shows `,_jsx(_components.strong,{children:`“Sign in with Google”`}),` with the Google glyph.`]}),`\n`,_jsxs(_components.li,{children:[`Click it → Google’s account chooser appears (scoped to the allowed domain via the `,_jsx(_components.code,{children:`hd`}),` hint) → after consent you land back on `,_jsx(_components.code,{children:`/app/`}),`.`]}),`\n`,_jsxs(_components.li,{children:[`A first-time user with no grant lands on the access-request screen; an admin approves them on the `,_jsx(_components.strong,{children:`Access Control → Pending Requests`}),` page.`]}),`\n`]}),`\n`,_jsxs(_components.p,{children:[_jsx(_components.strong,{children:`Lockout insurance:`}),` set `,_jsx(_components.code,{children:`superAdmins`}),` (e.g. `,_jsx(_components.code,{children:`you@xano.com`}),`) — a super-admin resolves to\n`,_jsx(_components.code,{children:`admin`}),` even with no `,_jsx(_components.code,{children:`AccessPolicy`}),` CRD present, so admin-gated features (terminal, logs)\nwork immediately. Every other user is resolved against the cluster’s `,_jsx(_components.code,{children:`AccessPolicy`}),` and needs\na matching grant.`]}),`\n`,_jsx(Heading,{level:`2`,id:`notes-\u0026-limitations`,children:`Notes \u0026 limitations`}),`\n`,_jsxs(_components.ul,{children:[`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Session length`}),` is bounded by the Google ID token’s expiry (~1 hour), so users re-authenticate roughly hourly even though `,_jsx(_components.code,{children:`AUTH_COOKIE_MAX_AGE`}),` caps the upper bound at 12h.`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`In-flight logins`}),` (the ~10-minute window between clicking sign-in and completing the callback) are invalidated if the controller restarts — the user simply clicks sign-in again. This is expected for the single-replica controller (the handshake key is ephemeral/in-memory by design).`]}),`\n`,_jsxs(_components.li,{children:[_jsx(_components.strong,{children:`Rollback:`}),` set `,_jsx(_components.code,{children:`auth.method: xano`}),` (with `,_jsx(_components.code,{children:`auth.xano.accountOrigin`}),`) or `,_jsx(_components.code,{children:`auth.enabled: false`}),` and redeploy. The Google code is dormant unless `,_jsx(_components.code,{children:`method=google`}),`.`]}),`\n`]})]})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent};function _missingMdxReference(id,component){throw new Error(`Expected `+(component?`component`:`object`)+\" `\"+id+\"` to be defined: you likely forgot to import, pass, or provide it.\")}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Dashboard Auth — Google OAuth","description":"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.","href":"/operations/dashboard-auth-google"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[{"title":"Prerequisites","slug":"prerequisites","depth":2,"children":[]},{"title":"1. Create the OAuth client","slug":"1-create-the-oauth-client","depth":2,"children":[]},{"title":"2. Create the client-secret Secret","slug":"2-create-the-client-secret-secret","depth":2,"children":[]},{"title":"3. Set Helm values","slug":"3-set-helm-values","depth":2,"children":[]},{"title":"4. Deploy and verify","slug":"4-deploy-and-verify","depth":2,"children":[]},{"title":"Notes \u0026 limitations","slug":"notes-\u0026-limitations","depth":2,"children":[]}],"codeExamples":{}},"jsLinks":[],"subdomain":"autopilot","siteName":"Autopilot by Xano","title":"Dashboard Auth — Google OAuth - Autopilot by Xano","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-08-04T19:12:29.863Z","originalFileLocation":"operations/dashboard-auth-google.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Autopilot by Xano\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Dashboard Auth — Google OAuth - Autopilot by Xano\">\u003cmeta data-mint-head property=\"og:description\" content=\"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Autopilot by Xano\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://autopilot.docs.xano.com/operations/dashboard-auth-google\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://autopilot.mintlify.site/_mintlify/api/og/v2?division=Operations\u0026amp;title=Dashboard+Auth+%E2%80%94+Google+OAuth\u0026amp;description=Configure+the+Autopilot+dashboard+to+sign+users+in+with+Google+OAuth%2FOIDC.\u0026amp;theme=d50e4d2426518ce716fb0454\u0026amp;signature=6a9e18857542c79041e0faf9431abd9b0f9daa124066ed23cc96604c70e3757f\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Dashboard Auth — Google OAuth - Autopilot by Xano\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://autopilot.mintlify.site/_mintlify/api/og/v2?division=Operations\u0026amp;title=Dashboard+Auth+%E2%80%94+Google+OAuth\u0026amp;description=Configure+the+Autopilot+dashboard+to+sign+users+in+with+Google+OAuth%2FOIDC.\u0026amp;theme=d50e4d2426518ce716fb0454\u0026amp;signature=6a9e18857542c79041e0faf9431abd9b0f9daa124066ed23cc96604c70e3757f\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/autopilot/bB_fwsCi2uBSKTjf/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Autopilot by Xano\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0055FF\">\u003clink data-mint-head rel=\"canonical\" href=\"https://autopilot.docs.xano.com/operations/dashboard-auth-google\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/operations/dashboard-auth-google.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://autopilot.docs.xano.com/#organization\",\"name\":\"Autopilot by Xano\",\"url\":\"https://autopilot.docs.xano.com\"},{\"@type\":\"WebSite\",\"@id\":\"https://autopilot.docs.xano.com#website\",\"name\":\"Autopilot by Xano\",\"url\":\"https://autopilot.docs.xano.com\",\"publisher\":{\"@id\":\"https://autopilot.docs.xano.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google#webpage\",\"url\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google\",\"name\":\"Dashboard Auth — Google OAuth\",\"description\":\"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\",\"dateModified\":\"2026-08-04T19:12:29.863Z\",\"isPartOf\":{\"@id\":\"https://autopilot.docs.xano.com#website\"},\"breadcrumb\":{\"@id\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Operations\",\"item\":\"https://autopilot.docs.xano.com/operations/runbook\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Dashboard Auth — Google OAuth\",\"item\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google\"}]},{\"@type\":[\"Article\",\"TechArticle\"],\"@id\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google#article\",\"headline\":\"Dashboard Auth — Google OAuth\",\"name\":\"Dashboard Auth — Google OAuth\",\"description\":\"Configure the Autopilot dashboard to sign users in with Google OAuth/OIDC.\",\"url\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google\",\"mainEntityOfPage\":{\"@id\":\"https://autopilot.docs.xano.com/operations/dashboard-auth-google#webpage\"},\"dateModified\":\"2026-08-04T19:12:29.863Z\",\"publisher\":{\"@id\":\"https://autopilot.docs.xano.com/#organization\"},\"isPartOf\":{\"@id\":\"https://autopilot.docs.xano.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Autopilot by Xano\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Autopilot by Xano","nav":{"global":null,"tabs":[{"tab":"Documentation","groups":[{"group":"Get Started","pages":[{"title":"Right-size your entire Kubernetes cluster — without a single restart","mode":"wide","href":""},{"title":"How Autopilot Works","href":"/guides/how-it-works"},{"title":"Getting Started","href":"/guides/getting-started"},{"title":"Verify It's Working","href":"/guides/quickstart-verify"}]},{"group":"Platform","pages":[{"title":"Pod Resizing","href":"/platform/pod-resizing"},{"title":"Node Scaling","href":"/platform/node-scaling"},{"title":"Cluster Rebalancing","href":"/platform/rebalancing"},{"title":"HPA Auto-Optimization","href":"/platform/hpa-autoscaling"},{"title":"HPA Audit","href":"/platform/hpa-audit"},{"title":"Scheduled Scaling","href":"/platform/scheduled-scaling"},{"title":"HPA Behavior Overrides","href":"/platform/scheduled-scale-behavior"},{"title":"Resource Overrides","href":"/platform/resource-overrides"},{"title":"Storage \u0026 PVC Management","href":"/platform/storage"},{"title":"Observability \u0026 Cost","href":"/platform/observability"}]},{"group":"Operations","pages":[{"title":"Operations Runbook","href":"/operations/runbook"},{"title":"Node Scale-Down Behavior","href":"/operations/node-scale-down"},{"title":"Resource Audit","href":"/operations/resource-audit"},{"title":"Limit \u0026 Storage Exceptions","href":"/operations/exceptions"},{"title":"Pod Tools — Terminal, Logs \u0026 Files","href":"/operations/pod-tools"},{"title":"Access Control","description":"Dashboard authentication, role- and namespace-scoped authorization, self-service access requests, and an audited login trail — all opt-in behind a single feature gate.","href":"/operations/access-control"},{"title":"Dashboard Auth — Google OAuth","href":"/operations/dashboard-auth-google"},{"title":"Troubleshooting","description":"Diagnose common problems with node scaling, rebalancing, the autoscaler, CRDs, and leader election.","href":"/operations/troubleshooting"},{"title":"Disaster Recovery","href":"/operations/disaster-recovery"}]},{"group":"Migrating from CAST AI","pages":[{"title":"Autopilot vs CAST AI","href":"/guides/castai-comparison"}]}]},{"tab":"Reference","pages":[{"title":"Reference","href":"/reference/opsctl-cli"}]}]},"basePath":"","title":"Dashboard Auth — Google OAuth - Autopilot by Xano","buildId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","deploymentId":"dpl_BLQvU86QFwq3AhPofSTw6q8dGWKm","dynamics":[],"chunks":[]}