Skip to content

Authentication & Google Sign-in

Envy uses one identity system for the dashboard, CLI, and MCP. Google verifies who you are; Envy creates its own sessions and agent credentials. Every admitted account has full installation access. There are no roles or user-management screens.

ModeExperience
devOpens directly as Admin, without login. Local make dev selects this explicitly.
passwordSign in as admin. The password defaults to admin, with environment or secret-file overrides.
googleSign in with a Google account admitted by your domain or email allowlist.

The default outside local development remains legacy token mode. Existing token, proxy, and none configurations remain supported. Browser token entry has been removed; use password or Google mode for interactive login.

Use the control-plane URL that users open in their browsers, for example https://envy.example.com. This is the dashboard and API origin, not a preview application’s URL. Serve it over HTTPS and set the same origin on every Envy replica.

In your Google Cloud project, configure the OAuth consent screen and its audience, then create an OAuth client with application type Web application. Follow Google’s OpenID Connect setup instructions for the current console steps. If the Google app is in testing, make your test accounts eligible to use it.

Register this Authorized redirect URI, replacing the origin with your installation’s URL:

https://envy.example.com/auth/google/callback

The scheme, host, port, and path must match exactly. Copy the client ID and store the client secret in your deployment’s secret store. Google’s app audience and Envy’s allowlist both control admission; configuring one does not replace the other.

Create a Kubernetes Secret in the Envy release’s namespace from a local file containing the Google client secret:

Terminal window
kubectl -n envy-system create secret generic envy-google \
--from-file=client-secret=/path/to/google-client-secret

Merge the following into your installation values, retaining the database, mesh, image, and other installation settings:

auth:
mode: google
externalOrigin: https://envy.example.com
googleClientID: your-client-id.apps.googleusercontent.com
googleClientSecret:
name: envy-google
key: client-secret
googleAllowedDomains: example.com
googleAllowedEmails: ""

Set at least one allowlist: googleAllowedDomains checks Google’s Workspace hd claim, while googleAllowedEmails admits individual verified addresses. An account matching either list is admitted.

Apply the updated values.yaml:

Terminal window
helm upgrade envy oci://registry-1.docker.io/davey/envy-chart \
--version 0.3.0 --namespace envy-system --values values.yaml --wait

The Secret must be in the release namespace. Your ingress must route the public Envy URL to the server, and the server needs outbound HTTPS access to Google. Existing database and mesh settings stay in your values file.

  1. Open Envy in a private browser window and select Continue with Google.
  2. Sign in with an allowed account. Check the identity under Installation, then reload to verify the session persists.
  3. Try an account outside both allowlists and verify access is denied.
  4. If you use these clients, complete CLI and MCP login, including browser approval.
  5. Select Sign out everywhere and verify that the browser and saved agent credentials no longer grant access.

Automated tests use a mocked Google issuer. This smoke test needs your own Google client and accounts.

The evaluation install already enables password login. To set your own password, save it in a private file and create a Secret:

Terminal window
kubectl -n envy-system create secret generic envy-admin \
--from-file=password=/path/to/admin-password

Merge this into your existing values.yaml and rerun Helm:

auth:
mode: password
externalOrigin: http://localhost:8081
adminPasswordSecret:
name: envy-admin
key: password

Sign in as admin. Use your actual HTTPS origin for a shared installation; the loopback address above is for the evaluation port-forward. The browser URL must match auth.externalOrigin exactly. Without a password override, the default is admin. No Vite server is needed for the released image.

Terminal window
export ENVY_API_URL=https://envy.example.com
envy auth login
envy auth status

Login opens the browser, reuses your Envy browser session, and asks you to approve full installation access for the requesting client. CLI and local stdio MCP share saved credentials. Ordinary commands never launch a browser implicitly. For authenticated Vite testing, use ENVY_API_URL=http://localhost:5173 to match the configured public origin.

For remote MCP, add https://envy.example.com/mcp to a client supporting Streamable HTTP and OAuth. It discovers Envy’s authorization endpoints and opens the same login and approval flow. See the MCP guide for client setup.

Explicit machine token or token-file settings take precedence over saved login. An invalid explicit credential produces an error rather than falling back to your browser identity.

  • Browser sessions last seven days. Sign out ends the current browser session.
  • Agent access tokens last fifteen minutes and refresh automatically for an absolute maximum of thirty days. envy auth logout revokes the saved agent grant.
  • Sign out everywhere revokes all browser sessions and agent grants for your identity.
  • Password changes invalidate existing password sessions and grants. Mode changes invalidate incompatible human sessions. Google allowlists are checked again on authenticated requests and refreshes.
SymptomCheck
Google reports redirect_uri_mismatchRegister the exact ENVY_EXTERNAL_ORIGIN plus /auth/google/callback, including the browser’s port.
Google signs in but Envy denies accessCheck both allowlists. Workspace access requires hd; an email suffix alone does not qualify. Check Google’s audience/test-user settings too.
Envy opens automatically as AdminThe server is in dev mode, or Demo simulation is enabled.
Login reports an unexpected API responseUpdate the API server and verify that /auth/config returns JSON, not the application’s HTML page.
Login or sign-out fails through a proxyMatch the exact browser origin and route authentication endpoints to Envy. Preserve cookies and the request’s Origin header.
CLI uses an old token after browser loginCheck explicit ENVY_API_TOKEN, ENVY_API_TOKEN_FILE, or --token-file settings; these override saved login.

The Helm instructions above are for released installations. When running the server directly from source, set its environment instead:

Set these variables on the API server:

Terminal window
export ENVY_AUTH_MODE=google
export ENVY_EXTERNAL_ORIGIN=https://envy.example.com
export ENVY_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
export ENVY_GOOGLE_CLIENT_SECRET_FILE=/run/secrets/google-client-secret
export ENVY_GOOGLE_ALLOWED_DOMAINS=example.com

The secret file must contain the client secret and be readable by the server. ENVY_GOOGLE_CLIENT_SECRET is an alternative to the file. Explicit environment settings take precedence over JSON configuration; setting both secret forms at the same level is an error.

At least one nonempty allowlist is required:

  • ENVY_GOOGLE_ALLOWED_DOMAINS: comma-separated Google Workspace domains. Admission checks Google’s hd claim, not the suffix of an email address.
  • ENVY_GOOGLE_ALLOWED_EMAILS: comma-separated individual email addresses. Admission requires a verified email, including for personal Google accounts.

An account matching either allowlist is admitted. For individual accounts instead of an entire Workspace domain, configure only the email list:

Terminal window
export ENVY_GOOGLE_ALLOWED_EMAILS=alice@example.com,bob@gmail.com

Restart the server replicas with the updated configuration. The server needs outbound HTTPS access to Google’s discovery, token, and signing-key endpoints. Sessions are stored in the existing PostgreSQL database; the Helm migration hook applies the authentication migration during upgrade.

For Vite at http://localhost:5173, register this additional Google redirect URI and configure the server with the matching origin:

http://localhost:5173/auth/google/callback
Terminal window
export ENVY_EXTERNAL_ORIGIN=http://localhost:5173

Run make ui-dev after configuring the API server in Google mode. Vite proxies /auth, /oauth, discovery, MCP, and API requests to the backend. Use localhost consistently: 127.0.0.1 is a different origin. HTTP is supported only on loopback origins for authenticated local testing.

For direct-server password testing, set ENVY_AUTH_MODE=password, ENVY_EXTERNAL_ORIGIN to the browser-facing origin, and ENVY_ADMIN_PASSWORD_FILE to your password file. Explicit dev mode opens as Admin without login.