Authentication
bidsmith talks to the Google Ads API on your behalf. To do that it needs your credentials. This page explains what those credentials are, what bidsmith does with them on each run, and what it intentionally doesn’t do.
The one-time setup (registering OAuth client, minting a refresh token, finding your customer ID) is covered in Connect to Google Ads. This page is about the runtime model.
The five environment variables
Every bidsmith command that touches the API reads five env vars from the shell:
| Variable | Role |
|---|---|
GOOGLE_ADS_DEVELOPER_TOKEN | Authorizes API access. Issued by your manager account. |
GOOGLE_ADS_CLIENT_ID | Identifies the OAuth “app” — bidsmith on your machine. |
GOOGLE_ADS_CLIENT_SECRET | Paired with the client ID. |
GOOGLE_ADS_REFRESH_TOKEN | Long-lived credential bidsmith exchanges for short-lived access tokens. |
GOOGLE_ADS_CUSTOMER_ID | The 10-digit ID of the Google Ads account being managed. |
Optionally:
| Variable | Role |
|---|---|
GOOGLE_ADS_LOGIN_CUSTOMER_ID | The manager account ID, if you’re managing a sub-account via an MCC. |
You can provide these two ways, and you can mix them:
bidsmith auth loginsigns you in through your browser and saves the values to~/.bidsmith/credentials.toml(file mode0600). This is the easy path — see Connect to Google Ads.- Environment variables in your shell config (
~/.zshrc,~/.bashrc, a.envrcloaded by direnv, etc.). This is the path CI uses.
For each value, bidsmith resolves environment variable → saved file → built-in default, so an env var always wins over the saved file. CI setups therefore behave exactly as before, and you can override any single saved value with an env var when you need to. bidsmith reads all of this at command-start time, not at install time.
The account and manager-account ids (and, if you must, the
developer token) can also come from a committable
bidsmith.toml at your
project root — it slots between the env var and the saved file in the
order above, which is how one sign-in manages many accounts.
What happens on each run
When you run bidsmith plan or apply:
- Resolve the credentials (env var → saved file → built-in
default). If a required value is missing, bidsmith exits with a
clear error message and points you at
bidsmith auth login. - Exchange the refresh token for an access token. bidsmith POSTs to Google’s OAuth endpoint with the client ID, client secret, and refresh token. Google returns a short-lived access token (valid for ~1 hour).
- Use the access token to make API calls. Every Google Ads API
request bidsmith makes carries this access token in the
Authorizationheader. - Cache only the short-lived access token. The access token is
written to
.bidsmith/cache/(file mode0600) so a tight plan/apply loop doesn’t re-exchange on every run; it’s evicted at expiry. Nothing else from the run is persisted.
The long-lived refresh and developer tokens live at rest only where
you put them — your shell config, or ~/.bidsmith/credentials.toml
if you used bidsmith auth login. bidsmith reads them from those two
places and nowhere else.
What bidsmith doesn’t do with your credentials
- Only the access token is cached. The short-lived access token
is cached in
.bidsmith/cache/(mode0600) and re-minted from the refresh token when it expires. The refresh and developer tokens are never copied into that cache. - No phone-home or telemetry. bidsmith makes API calls only to Google Ads (and Google’s OAuth endpoint for the token exchange). No analytics, no error reporting, no version checks.
- No surprise credential files. The only file bidsmith writes
credentials to is
~/.bidsmith/credentials.toml, and only when you runbidsmith auth login. A pure env-var setup writes nothing. - No team-shared refresh tokens. Each person signs in with their
own Google account, so the audit trail shows who applied what.
bidsmith auth profileshares only the agency-level values — the developer token and manager-account id — never your personal refresh token; each teammate still does their own browser sign-in.
CI / automation
When apply runs in a GitHub Action or other automation, the env
vars come from the platform’s secret store. The values are
exactly the same as on a laptop — same refresh token shape, same
five vars.
A few practical notes for CI:
- Use a dedicated service-style account. Don’t use your personal refresh token in CI. Create a Google account for “bidsmith CI,” grant it access to the relevant Google Ads accounts, mint a refresh token for that account, and store that in your CI secrets.
- Restrict secret scope. GitHub Actions environment-level secrets are better than repo-level secrets if you have separate “production” and “staging” Google Ads accounts.
--auto-approveis required. CI has no terminal to prompt at.bidsmith apply --auto-approve .is the runtime shape.
Rotating credentials
If a refresh token leaks (committed to Git by accident, posted in Slack, etc.):
- Revoke it immediately. In Google: account.google.com → Security → Third-party apps with account access → revoke bidsmith.
- Mint a new one. Run
bidsmith auth loginagain — it issues a fresh refresh token and overwrites the saved file. (For an env-var setup, generate a new token via the OAuth Playground.) - Update your CI secrets if you store the token as
GOOGLE_ADS_REFRESH_TOKENthere rather than usingauth login.
The leaked token is invalid as soon as you revoke it. Your .bid
files and Google Ads account are unaffected — only the credential
itself was compromised.
The auth helper
bidsmith auth login automates the OAuth dance end-to-end: it opens
your browser, captures the redirect on a local port, exchanges the
result for a refresh token, and saves it to
~/.bidsmith/credentials.toml. The five-variable shape above is
unchanged — auth login just fills the values in for you instead of
you pasting them into a shell config.
Next
- Connect to Google Ads — the step-by-step setup guide.
- Plan and apply — what bidsmith does after authenticating.
- The GitHub flow for marketers — how CI credentials fit into the workflow.