Skip to main content

Google sign-in

Sign in with a Google account and give selected accounts access to your application. This walkthrough uses Google's account ID (sub) to grant app/member; other Google users can reach the portal but not the protected app.

The configuration targets caddy-security v1.3.0, containing go-authcrunch v1.3.8. Local OIDC fixtures check the released driver's code exchange and access rules. Complete the final login checks with your own Google client; local fixtures do not verify Google's consent or organization policies.

Before you start​

Complete Install and verify. You need a Google Cloud project where you can manage OAuth clients, two Google accounts for access tests, and a public HTTPS portal. This guide uses https://auth.example.com/auth/ and protects /app; replace the hostname throughout.

For the provider/portal/policy relationship, see the OAuth and OIDC overview.

Configure Google Auth Platform​

In the Google Cloud console, choose your project and open Google Auth Platform. Complete Branding with your app's name, support contact, and required website information. Configure Audience for the accounts you intend to support:

AudienceUse it for
InternalAccounts in the project's Google Workspace or Cloud Identity organization, when available
ExternalGoogle accounts outside that organization, including personal accounts

Review Data Access for the basic identity scopes: openid, email, and profile. The Caddyfile requests openid email profile. It does not need Gmail, Drive, or Cloud Identity group permissions for the account-ID example. See Google's consent setup.

For an External app, review Audience → Publishing status and Test users. Google makes an exception to its usual testing restrictions for basic name/email/profile sign-in. Do not treat the test-user list as the app's access policy, or assume a seven-day testing expiry applies to these scopes. Extra scopes change the requirements; follow Google's audience rules. The AuthCrunch policy below is what restricts /app.

Register a web client​

Open Clients → Create client and choose Web application. Register:

Google OAuth client type menu with Web application selected

Earlier console: select Web application. Current navigation starts at Google Auth Platform → Clients. Select the image to view it at full size.
SettingValue
Authorized redirect URIhttps://auth.example.com/auth/oauth2/google/authorization-code-callback
Client IDCopy the complete value, including .apps.googleusercontent.com
Client secretSave the secret for the AuthCrunch server

The callback includes the portal's /auth/ mount and realm google. Match its scheme, host, path, and trailing slash exactly. The portal exchanges the code on the server; this example does not use a browser JavaScript client or require an Authorized JavaScript origin. See Google's web-client instructions.

Configure AuthCrunch​

Save the following as Caddyfile. Change auth.example.com in both the site address and policy URL. The complete file is embedded from the canonical Google example.

Caddyfile
# Set the public portal hostname and GOOGLE_ALLOWED_SUB before use.
{
admin off
persist_config off

security {
oauth identity provider google {
driver google
realm google
client_id {env.GOOGLE_CLIENT_ID}
client_secret {env.GOOGLE_CLIENT_SECRET}
scopes openid email profile
login icon text "Google"
}

authentication portal myportal {
enable identity provider google
crypto default token lifetime 900
crypto key sign-verify {env.JWT_SHARED_KEY}
cookie path /

ui {
links {
"Example app" /app icon "las la-external-link-alt"
"My identity" /auth/whoami icon "las la-user"
}
}

transform user {
match realm google
action add role authp/user
}

transform user {
match realm google
match sub {$GOOGLE_ALLOWED_SUB}
action add role app/member
}
}

authorization policy apppolicy {
set auth url https://auth.example.com/auth/
crypto key verify {env.JWT_SHARED_KEY}
allow roles app/member
}
}
}

auth.example.com {
route {
redir /auth /auth/ 308

authenticate /auth/* with myportal

@app path /app /app/*
route @app {
authorize with apppolicy
respond "You reached the Google-protected app." 200
}

respond "AuthCrunch is running. Open /app to begin." 200
}
}

Set the environment before starting the process:

export GOOGLE_CLIENT_ID='YOUR_COMPLETE_CLIENT_ID.apps.googleusercontent.com'
export GOOGLE_CLIENT_SECRET='YOUR_GOOGLE_CLIENT_SECRET'
export GOOGLE_ALLOWED_SUB='REPLACE_WITH_GOOGLE_SUB'
export JWT_SHARED_KEY="$(openssl rand -hex 32)"

Use your actual client credentials. Leave the subject placeholder for the first login, then replace it as described below. GOOGLE_ALLOWED_SUB is an account ID, not an email address or the OAuth client ID.

{$GOOGLE_ALLOWED_SUB} expands when the Caddyfile is parsed. The client ID, client secret, and signing key use runtime {env.VARIABLE} placeholders. Supply the whole Google client ID; do not append its suffix again in the Caddyfile. For a managed service, use its protected environment and keep the signing key stable across restarts.

./bin/authcrunch adapt --adapter caddyfile --config Caddyfile >/dev/null
./bin/authcrunch run --config Caddyfile

Adaptation checks parsing. Startup loads Google's discovery document and signing keys; the host needs outbound HTTPS connectivity. Public DNS and certificate issuance must work for your portal hostname. The example disables the admin endpoint, so stop with Ctrl+C and restart after configuration or environment changes.

Select the account and verify access​

  1. Open /auth/ and choose Google. Sign in with the account that should have application access.
  2. Open My identity (/auth/whoami) and copy that account's sub value. Confirm you are using the intended Google account. This login has authp/user; the unconfigured subject does not grant app/member.
  3. Set GOOGLE_ALLOWED_SUB to that exact value, stop AuthCrunch, and start it again with the updated environment.
  4. Sign out of the portal and sign in again to issue a token with the new role. Select Example app or open /app.
  5. In a separate browser session, sign in as a second Google user and verify that the app denies access.
CheckSelected accountOther account
Portal identityHas authp/user and app/memberHas authp/user only
/app, /app/, /app/nested200, protected response403, no protected response

If your Google audience prevents the second account from signing in, that tests Google's boundary. Use another account eligible for the same audience to test the AuthCrunch denial rule.

Google documents sub as stable across email changes. An email suffix does not establish Workspace membership. This release checks ID-token email presence but does not enforce email_verified or expose hd to transforms; the example therefore grants access by the selected sub. See Google's identity claims and the released claim parser.

The Google driver discovers its endpoints and sends state, nonce, and S256 PKCE. Keep these checks enabled. The example uses a 900-second portal token; changing the allowlist does not rewrite an already issued token. Portal logout clears the portal session and does not sign the browser out of Google. Use a separate browser profile when testing another account.

After the allow/deny checks pass, replace the protected respond with your application's reverse_proxy, keeping authorize before it.

Workspace domains and groups​

Organization access​

For an organization-only application, use Google's Internal audience when your project supports it. The hd authorization parameter is a login hint; requesting it is not an access check. This release does not copy the ID token's hd or email_verified into the portal claims, so an email-domain transform is not a substitute for validating Workspace membership. Keep the account allowlist or use an independently verified group-based policy.

Optional Cloud Identity groups​

The released Google driver can query the Cloud Identity membership graph when its scopes include:

scopes openid email profile https://www.googleapis.com/auth/cloud-identity.groups.readonly

Replace the existing scopes line inside oauth identity provider google. Enable the Cloud Identity API, authorize the additional scope, and verify the signed-in user can read the relevant memberships. Google's membership query guidance explains permissions. The graph endpoint requires a supported Workspace Enterprise/Education edition or Cloud Identity Premium; ordinary personal accounts are not sufficient.

The driver's group lookup uses the user's email and access token. It reads response.groups[].displayName from the returned operation and adds those display names to portal roles. It does not use immutable group IDs, filter on your configured application role, or poll an unfinished operation. A renamed group changes the match, and identical display names cannot distinguish groups.

Only after confirming the returned roles at /auth/whoami, replace the account-granting transform with one matching your group's exact display name:

transform user {
match realm google
match role "Example App Members"
action add role app/member
}

Keep the separate portal-access transform. Replacing the account rule makes the group required; retaining both rules allows either to grant access. A group lookup failure is logged and login continues, so test an API failure or missing group as well as a member. Without the required role, /app must remain denied. This optional integration needs validation against your organization's licenses, permissions, naming controls, and actual API responses.

Troubleshoot​

SymptomCheck
redirect_uri_mismatchCompare the registered callback with the public host, /auth/ mount, and realm google.
invalid_clientUse the complete client ID once and the corresponding current secret.
Google blocks consentCheck Internal/External audience, publishing status, requested scopes, and organization policy.
Selected user gets 403Compare sub with GOOGLE_ALLOWED_SUB, restart after changing the environment, then obtain a new portal token.
Another user reaches the appCheck for another transform granting app/member and ensure the policy does not allow authp/user.
Issuer validation failsCompare the ID token's issuer with discovery; this release uses exact equality, including Google's HTTPS prefix. Do not disable key or nonce checks.
Workspace group is absentCheck the extra scope, API enablement, account edition, membership permissions, returned operation, and exact display name.
Sign-in resumes after logoutThe Google session still exists; use a separate browser session for another account.

For token validation and claim extraction details, continue to Generic OpenID Connect.