How to Configure Multiple OAuth Clients for Different Domains in gogcli
You can configure multiple OAuth clients in gogcli by mapping each Google Workspace domain to a specific client ID/secret pair using the --domain flag when adding credentials, allowing the CLI to automatically resolve the correct client based on the account domain.
The steipete/gogcli tool supports multi-tenant environments where administrators manage separate Google Workspace domains. By configuring multiple OAuth clients for different domains in gogcli, you can ensure that authentication requests use the appropriate credentials without manually switching configuration files.
How gogcli Resolves OAuth Clients for Different Domains
The resolution logic follows a strict hierarchy defined in internal/config/clients.go. When you run any command that requires authentication, gogcli executes three steps:
- Load the global configuration via
config.ReadConfigininternal/config/config.go. - Select a client name using
ResolveClientForAccount(lines 80-106 ininternal/config/clients.go), checking in this order:- An explicit
--clientflag override - A per-account mapping (
cfg.AccountClients[email]) - A per-domain mapping (
cfg.ClientDomains[domain])
- An explicit
- Fall back to the default client (
"default") if no specific mapping exists.
Mapping Flow Implementation
| Step | Function | Source File | Purpose |
|---|---|---|---|
| Load config | config.ReadConfig |
internal/config/config.go |
Reads ~/.config/gog/config.json or $XDG_CONFIG_HOME/gog/config.json. |
| Resolve client | config.ResolveClientForAccount |
internal/config/clients.go (lines 92-106) |
Handles overrides, per-account mapping, per-domain mapping, and default fallback. |
| CLI glue | authclient.ResolveClient / ResolveClientWithOverride |
internal/authclient/authclient.go |
Pulls the --client context override and calls the resolver. |
| Store credentials | config.WriteClientCredentialsFor |
internal/config/credentials.go |
Persists JSON files under $XDG_CONFIG_HOME/gog/credentials-<client>.json. |
| Record domain map | config.SetClientDomain |
internal/config/clients.go |
Normalizes domain and client names, then writes into cfg.ClientDomains. |
Adding OAuth Credentials for a Specific Domain
To configure a new OAuth client for a specific domain, use the auth credentials command with the --domain flag. This implementation resides in AuthCredentialsSetCmd.Run at internal/cmd/auth.go (lines 78-120).
# Add credentials for the example.com domain
gog auth credentials ~/Downloads/client_secret_example.json --domain example.com
What happens internally:
config.ParseGoogleOAuthClientJSONparses your downloaded OAuth client JSON.- Credentials are stored as
~/.config/gog/credentials-example.com.json. config.SetClientDomainupdates the configuration file, adding"example.com": "example.com"to theclient_domainsmap.
Mapping Multiple Domains to a Single OAuth Client
If you manage multiple Google Workspace domains with the same OAuth application, you can map several domains to one client name using a comma-separated list.
# Store credentials under the custom name "myapp" and map two domains to it
gog auth credentials myapp.json --domain example.com,othercorp.org
Resulting configuration:
{
"client_domains": {
"example.com": "myapp",
"othercorp.org": "myapp"
}
}
The credentials file is saved as credentials-myapp.json, and both domains resolve to this client when ResolveClientForAccount checks the cfg.ClientDomains map.
Overriding the Default Client at Runtime
You can bypass automatic domain resolution by explicitly specifying a client name with the global --client flag. This sets a context override that takes precedence over all mappings.
# Force the use of the "myapp" client regardless of the account domain
gog --client myapp calendar list
The --client flag is defined in RootFlags.Client within internal/cmd/root.go (lines 30-35). The authclient.ResolveClient function checks this override before consulting the configuration mappings.
Listing Configured OAuth Clients and Domain Mappings
To audit your current setup, use the credentials list command. This walks the configuration directory and merges file data with domain mappings from cfg.ClientDomains.
gog auth credentials list
Example JSON output:
{
"clients": [
{
"client": "example.com",
"path": "/home/user/.config/gog/credentials-example.com.json",
"default": false,
"domains": ["example.com"]
},
{
"client": "myapp",
"path": "/home/user/.config/gog/credentials-myapp.json",
"default": false,
"domains": ["example.com","othercorp.org"]
}
]
}
This command is implemented in internal/cmd/auth.go (lines 143-170) via config.ListClientCredentials().
Key Implementation Files
| File | Role | Link |
|---|---|---|
internal/config/clients.go |
Normalizes client/domain names, resolves the correct client for an account, stores domain→client mappings. | https://github.com/steipete/gogcli/blob/main/internal/config/clients.go |
internal/config/credentials.go |
Parses OAuth client JSON, reads/writes per-client credential files. | https://github.com/steipete/gogcli/blob/main/internal/config/credentials.go |
internal/cmd/auth.go |
Implements gog auth credentials sub-command, handling --domain flag and persisting mappings. |
https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go |
internal/authclient/authclient.go |
Glue code that resolves clients based on context overrides and config. | https://github.com/steipete/gogcli/blob/main/internal/authclient/authclient.go |
internal/cmd/root.go |
Defines the global --client flag and passes it into the command context. |
https://github.com/steipete/gogcli/blob/main/internal/cmd/root.go |
Summary
- Domain-specific OAuth clients are configured using
gog auth credentials <file> --domain <domain>, which stores credentials and updates the domain-to-client mapping in~/.config/gog/config.json. - Resolution hierarchy follows this order: explicit
--clientflag > per-account mapping (AccountClients) > per-domain mapping (ClientDomains) > default client. - Multi-domain clients allow one OAuth application to serve several Google Workspace domains by comma-separating domains in the
--domainflag. - Runtime overrides via
--clientbypass automatic resolution, useful for testing or administrative tasks. - Storage locations follow XDG standards: credentials live in
credentials-<client>.jsonand configuration inconfig.jsonunder$XDG_CONFIG_HOME/gog/(defaulting to~/.config/gog/).
Frequently Asked Questions
Can I use the same OAuth client for multiple Google Workspace domains?
Yes. When adding credentials with gog auth credentials, provide multiple domains separated by commas: --domain example.com,othercorp.org. This maps both domains to the same client name in the ClientDomains configuration, allowing ResolveClientForAccount to select the correct credentials regardless of which domain's user is authenticating.
How does gogcli determine which OAuth client to use for an account?
The resolution logic in internal/config/clients.go checks four sources in order: first, an explicit --client command-line flag; second, a per-account override in cfg.AccountClients; third, a domain-based lookup in cfg.ClientDomains using the email's domain; finally, the literal string "default". This hierarchy ensures administrators can override automatic selection when necessary.
Where are OAuth credentials stored when using multiple clients?
Each client stores its credentials in a separate JSON file under $XDG_CONFIG_HOME/gog/ (typically ~/.config/gog/). The filename format is credentials-<client>.json, where <client> is the normalized client name specified during setup. The main configuration file config.json maintains the client_domains map that links email domains to these client names.
Can I override the client selection without changing the configuration file?
Yes. Use the global --client flag available on all commands. For example, gog --client myapp calendar list forces the use of the "myapp" client credentials regardless of the account domain or existing mappings. This override is processed in internal/authclient/authclient.go before any configuration-based resolution occurs.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →