GCP Custom OAuth Client Setup#
By default, scafctl auth login gcp runs a native browser OAuth flow using Google’s well-known ADC client credentials — the same ones used by gcloud auth application-default login. This works out of the box with no gcloud installation required.
You may want to set up your own OAuth client if:
- Your organization restricts which OAuth client IDs are allowed
- You need specific OAuth consent screen branding or approval
- You want full control over the client lifecycle and scopes
Note: If you were previously seeing
invalid_grant - reauth related error (invalid_rapt)errors, upgrading scafctl to the latest version resolves this — the native browser OAuth flow is no longer affected by gcloud’s RAPT token expiry.
Prerequisites#
- Google Cloud SDK (
gcloud) installed and authenticated - A GCP project where you have permissions to create OAuth credentials
scafctlinstalled and available in your PATH
Step 1: Select or Create a GCP Project#
Pick an existing project or create a new one to host the OAuth client:
# List existing projects
gcloud projects list
# Or create a new one
gcloud projects create my-scafctl-project --name="scafctl OAuth"
# Set your working project
gcloud config set project my-scafctl-project# List existing projects
gcloud projects list
# Or create a new one
gcloud projects create my-scafctl-project --name="scafctl OAuth"
# Set your working project
gcloud config set project my-scafctl-projectStep 2: Configure the OAuth Consent Screen#
Before creating an OAuth client, you must configure the consent screen. This defines what users see when they authenticate.
# Enable the required API
gcloud services enable iap.googleapis.com
# For an internal app (only users in your org):
gcloud alpha iap oauth-brands create \
--application_title="scafctl" \
--support_email="your-email@example.com"# Enable the required API
gcloud services enable iap.googleapis.com
# For an internal app (only users in your org):
gcloud alpha iap oauth-brands create `
--application_title="scafctl" `
--support_email="your-email@example.com"Note: If your project has never had an OAuth consent screen configured, you may need to set it up via the Google Cloud Console the first time. Choose Internal (org-only) or External (any Google account) depending on your use case.
Console Alternative#
If the gcloud commands above don’t work for your setup (the consent screen API has limited CLI support), configure it in the Console:
- Go to APIs & Services > OAuth consent screen
- Select Internal (recommended for org use) or External
- Set the app name to
scafctl - Add your support email
- Add scopes:
openidhttps://www.googleapis.com/auth/cloud-platformhttps://www.googleapis.com/auth/userinfo.email
- Save
Step 3: Create the OAuth Client ID#
Create a Desktop application OAuth client:
gcloud alpha iap oauth-clients create \
"projects/$(gcloud config get-value project)/brands/$(gcloud config get-value project)" \
--display_name="scafctl-cli"gcloud alpha iap oauth-clients create `
"projects/$(gcloud config get-value project)/brands/$(gcloud config get-value project)" `
--display_name="scafctl-cli"Note: The
gcloud alpha iap oauth-clientscommands may have limited availability. The recommended approach is to use the Console.
Console Approach (Recommended)#
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth client ID
- Set Application type to Desktop app
- Set Name to
scafctl-cli - Click Create
- Note the Client ID and Client Secret
The output will look like:
Client ID: 123456789-abc123def456.apps.googleusercontent.com
Client Secret: GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxxxxNote: Despite the name, the client secret for desktop OAuth apps is not confidential — it is embedded in the application. This is standard for public OAuth clients (see Google’s documentation ).
Step 4: Configure scafctl#
Option A: Config File (Recommended)#
Add the OAuth client to your scafctl configuration file. The config file is typically located at ~/.config/scafctl/config.yaml:
auth:
gcp:
clientId: "123456789-abc123def456.apps.googleusercontent.com"
clientSecret: "GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxxxx"
defaultScopes:
- "openid"
- "https://www.googleapis.com/auth/cloud-platform"
- "https://www.googleapis.com/auth/userinfo.email"Then log in normally:
scafctl auth login gcpscafctl auth login gcpOption B: CLI Flag (One-off)#
Pass the client ID directly on the command line:
scafctl auth login gcp --client-id "123456789-abc123def456.apps.googleusercontent.com"scafctl auth login gcp --client-id "123456789-abc123def456.apps.googleusercontent.com"Note: When using the
--client-idflag without a config file, the client secret will be empty. This works for OAuth clients configured as public clients but may fail if Google requires the secret. The config file approach is preferred because it allows setting bothclientIdandclientSecret.
Step 5: Authenticate#
With the custom client configured, run:
scafctl auth login gcpscafctl auth login gcpThis will:
- Start a local HTTP server on a random port
- Open your browser to Google’s OAuth consent page
- After you approve, exchange the authorization code (with PKCE) for tokens
- Store the refresh token in your system’s secret store (Keychain on macOS, Credential Manager on Windows, Secret Service on Linux)
- Cache the access token for immediate use
Verify Authentication#
scafctl auth status gcpscafctl auth status gcpExpected output:
Handler Status Identity IdentityType Expires
gcp Authenticated user@example.com user 2026-02-20 11:35:00How It Differs from the Default#
| Feature | Default (built-in ADC client) | Custom OAuth Client | gcloud ADC (--flow gcloud-adc) |
|---|---|---|---|
| Requires gcloud installed | No | No | Yes |
| Refresh token storage | scafctl’s secret store | scafctl’s secret store | gcloud’s ADC file |
| Affected by RAPT expiry | No | No | Yes |
| Custom OAuth consent screen | No | Yes | No |
| Custom scopes | Yes | Yes | Limited |
| Service account impersonation | Via flag | Via flag or config | Via flag |
Service Account Impersonation#
You can combine a custom OAuth client with service account impersonation. This lets you authenticate as yourself but act as a service account:
auth:
gcp:
clientId: "123456789-abc123def456.apps.googleusercontent.com"
clientSecret: "GOCSPX-xxxxxxxxxxxxxxxxxxxxxxxxxx"
impersonateServiceAccount: "deploy@my-project.iam.gserviceaccount.com"
defaultScopes:
- "openid"
- "https://www.googleapis.com/auth/cloud-platform"Or via the CLI:
scafctl auth login gcp --impersonate-service-account deploy@my-project.iam.gserviceaccount.comscafctl auth login gcp --impersonate-service-account deploy@my-project.iam.gserviceaccount.comConfiguration Reference#
| Field | Description | Default |
|---|---|---|
auth.gcp.clientId | OAuth 2.0 client ID for interactive auth | (empty — uses gcloud ADC) |
auth.gcp.clientSecret | OAuth 2.0 client secret | (empty) |
auth.gcp.defaultScopes | Scopes requested during login | openid, cloud-platform |
auth.gcp.impersonateServiceAccount | Service account email to impersonate | (empty) |
auth.gcp.project | Default GCP project ID | (empty) |
Troubleshooting#
invalid_grant - reauth related error (invalid_rapt)#
This error only occurs when using --flow gcloud-adc (gcloud’s ADC file). Fix by either:
- Re-authenticating gcloud:
gcloud auth application-default login, thenscafctl auth login gcp --flow gcloud-adc - Using the default flow instead (no
--flowflag needed):scafctl auth login gcp
invalid_client Error#
The client ID or secret is incorrect. Verify them in the Google Cloud Console .
redirect_uri_mismatch Error#
This typically means the OAuth client is not configured as a Desktop app. Verify the application type in the Console — it must be “Desktop” for the local redirect flow to work.
access_denied Error#
The user declined consent, or the OAuth consent screen is not configured. Ensure:
- The consent screen is set up (Step 2)
- The required scopes are added to the consent screen
- If the app is Internal, the user is in the org
Browser Doesn’t Open#
If the browser doesn’t open automatically, check the terminal output for a URL you can copy and paste manually. You can also try setting the BROWSER environment variable.
Next Steps#
- Authentication Tutorial — Full authentication guide for all providers
- Provider Reference — Using auth tokens in HTTP providers
- Config Tutorial — Managing scafctl configuration