# How to Configure Multiple OAuth Clients for Different Domains in gogcli

> Easily configure multiple OAuth clients for different domains in gogcli. Map each Google Workspace domain to a unique client ID/secret using the domain flag for automatic resolution.

- Repository: [Peter Steinberger/gogcli](https://github.com/steipete/gogcli)
- Tags: how-to-guide
- Published: 2026-02-16

---

**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`](https://github.com/steipete/gogcli/blob/main/internal/config/clients.go). When you run any command that requires authentication, gogcli executes three steps:

1. **Load the global configuration** via `config.ReadConfig` in [`internal/config/config.go`](https://github.com/steipete/gogcli/blob/main/internal/config/config.go).
2. **Select a client name** using `ResolveClientForAccount` (lines 80-106 in [`internal/config/clients.go`](https://github.com/steipete/gogcli/blob/main/internal/config/clients.go)), checking in this order:
   - An explicit `--client` flag override
   - A per-account mapping (`cfg.AccountClients[email]`)
   - A per-domain mapping (`cfg.ClientDomains[domain]`)
3. **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`](https://github.com/steipete/gogcli/blob/main/internal/config/config.go) | Reads `~/.config/gog/config.json` or `$XDG_CONFIG_HOME/gog/config.json`. |
| Resolve client | `config.ResolveClientForAccount` | [`internal/config/clients.go`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/internal/authclient/authclient.go) | Pulls the `--client` context override and calls the resolver. |
| Store credentials | `config.WriteClientCredentialsFor` | [`internal/config/credentials.go`](https://github.com/steipete/gogcli/blob/main/internal/config/credentials.go) | Persists JSON files under `$XDG_CONFIG_HOME/gog/credentials-<client>.json`. |
| Record domain map | `config.SetClientDomain` | [`internal/config/clients.go`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go) (lines 78-120).

```bash

# Add credentials for the example.com domain

gog auth credentials ~/Downloads/client_secret_example.json --domain example.com

```

**What happens internally:**

- `config.ParseGoogleOAuthClientJSON` parses your downloaded OAuth client JSON.
- Credentials are stored as `~/.config/gog/credentials-example.com.json`.
- `config.SetClientDomain` updates the configuration file, adding `"example.com": "example.com"` to the `client_domains` map.

## 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.

```bash

# 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:**

```json
{
  "client_domains": {
    "example.com": "myapp",
    "othercorp.org": "myapp"
  }
}

```

The credentials file is saved as [`credentials-myapp.json`](https://github.com/steipete/gogcli/blob/main/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.

```bash

# 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`](https://github.com/steipete/gogcli/blob/main/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`.

```bash
gog auth credentials list

```

**Example JSON output:**

```json
{
  "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`](https://github.com/steipete/gogcli/blob/main/internal/cmd/auth.go) (lines 143-170) via `config.ListClientCredentials()`.

## Key Implementation Files

| File | Role | Link |
|------|------|------|
| [`internal/config/clients.go`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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 `--client` flag > 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 `--domain` flag.
- **Runtime overrides** via `--client` bypass automatic resolution, useful for testing or administrative tasks.
- **Storage locations** follow XDG standards: credentials live in `credentials-<client>.json` and configuration in [`config.json`](https://github.com/steipete/gogcli/blob/main/config.json) under `$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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/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`](https://github.com/steipete/gogcli/blob/main/internal/authclient/authclient.go) before any configuration-based resolution occurs.