How systems talk: OAuth, API keys and scopes
Choose between an API key and OAuth for a connector, grant the fewest scopes that do the job, and decide where the token lives and who can read it.
On this page
Every connector starts with a credential, and the credential sets how much damage the automation can do on its worst day. Two kinds cover almost every business system: an API key, which is a password for software, and an OAuth 2.0 token, a scoped, expiring permission that a person grants. The useful questions are whom the credential acts as, what it can touch, and who besides the automation can read it.
The running example
This module follows the 14-person marketing agency from how to use this course as it connects its automations to three systems: the time tracker; the accounting system, with two years of invoices, bills and payments, about 12,000 records; and the CRM, with 50,000 contacts, most of them newsletter sign-ups and old leads. The automation most pages connect is the Friday invoice run from the arithmetic of a task: 40 invoices a week, $520 a month of the operations manager's time. Staff hours are assumed at $30 loaded and the founder's at $100.
The key pasted into the workflow
The first version of the invoice automation is built in an afternoon. The founder generates an API key in the accounting system's settings and pastes it into the workflow tool. It works on the first run. What was granted:
- Everything the founder can do: invoices, contacts, bank feeds and payroll, deletes, adding users.
- Forever. The key does not expire, and revoking it means finding every place it was pasted.
- Tied to one person. When the founder's account is removed or its keys rotated, every automation using the key stops on the same day.
- Readable wherever it sits: by every editor of the workflow, and in any run log that prints request headers.
None of this shows until a contractor copies the key into a test script that ends up in a public repository, and a stranger can read the agency's payroll. The fix is a credential that can do less, expires, and belongs to the automation rather than to a person.
The authorization-code flow in four steps
OAuth 2.0, specified in RFC 6749 (opens in a new tab), replaces the pasted key with a grant. The authorization-code flow is the one a connector uses when a person approves access for a company account:
- The connector sends you to the provider, redirecting your browser to its authorization page with the connector's client id, the scopes it wants, and a random
statevalue it will check on the way back. - You approve, and the provider sends back a code. You sign in on the provider's own page, so the connector never sees your password. The redirect back carries a one-time code that expires within minutes; the RFC recommends at most 10.
- The connector exchanges the code for tokens, server to server, sending the code and its own client secret to the token endpoint and receiving an access token and, usually, a refresh token. The tokens never pass through the browser.
- The connector calls the API with the access token in an
Authorization: Bearerheader, and the provider checks each call against the scopes granted in step 2.
Two details each stop an attack. The state value ties the callback to the request the connector started, so nobody can feed their own code into your callback. PKCE (RFC 7636 (opens in a new tab)) adds a one-time secret created in step 1 and proved in step 3, so a stolen code is useless; current security guidance (RFC 9700 (opens in a new tab)) requires it for public clients and recommends it for the rest. Buying a connector, ask about both; building one, both are a library setting.
Refresh tokens: short access, long permission
The access token is short-lived; an hour is common, and the provider decides. When it expires, the connector sends the refresh token to the token endpoint and gets a new access token without asking you again. The token that travels on every request is useful to a thief for an hour at most. The refresh token travels only to the token endpoint, with the client secret, and lives only on the connector's server.
Refresh is also where connectors fail silently. Providers revoke refresh tokens when the approving user leaves or removes the app, and some after a period of disuse. Many rotate the refresh token on every use, so a connector that keeps the old one is locked out at the next refresh. A refresh that fails on Saturday is found the next Friday, when 40 invoices do not go out and the operations manager makes them by hand: 40 × 6 minutes = 4 hours, $120, plus a week of late invoices. An alarm on the first failed refresh turns that into a five-minute re-approval.
Whoever clicks "approve" lends the connector their identity. Approved by the founder, it inherits the founder's reach and breaks when that account changes. Approved by a dedicated integration user with only the roles it needs, it survives staff changes and shows in the audit log under its own name.
Scopes: ask for the job, not the account
A scope is a named slice of permission, such as "read contacts", shown on the consent screen and enforced on every call. The invoice automation needs to read contacts and create invoices, not bank feeds, payroll, deletes or user administration. With two scopes, a leaked token lets a thief create draft invoices, which the operations manager would see on Friday, and read client addresses. It does not open 14 people's salaries.
Scopes are only as fine as the provider made them. Where the smallest scope that allows creating an invoice also allows deleting one, the limit moves into your code: the tool the model calls exposes create_draft_invoice and nothing else, as prompt injection and least privilege argues for agent tools in general. The model never sees the token; the tool layer attaches it. Module 8 applies the same rule to every credential the agency holds, in least-privilege credentials and data leaving the tenant.
Where the token lives, and who can read it
Count the readers, because each one is a path to the token:
| Where the token sits | Who can read it |
|---|---|
| Pasted into a workflow step | every editor of the workflow, and every run log that prints headers |
| An environment variable on a shared server | everyone with a shell on the box, and every crash dump |
| A secrets store, fetched at call time | the connector's service identity, each read logged |
In the agency's first version, the key could be read by the founder, the operations manager, two contractors and anyone reading 18 months of run logs. A credential store that masks the value once saved, and a secrets store for the refresh token, leave one service identity and the founder. Proving who the connector is and deciding what it may do are separate checks, as authentication and authorization sets out; a scope is the second, carried inside the token.
When an API key is the right answer
When the provider lets you scope a key, rotate it without downtime and attach it to a service account rather than a person. A job with no person to approve it, such as a nightly export from your own database, fits a scoped key or OAuth's client-credentials grant; the authorization-code flow exists to collect a person's consent.
Once the connector can call the system, the next problem is learning what changed in it: webhooks versus polling.
In practice
Before approving a connector, bought or built by a contractor, ask four things. Which scopes does it request, and would fewer work? Which user will the grant act as? Where is the refresh token stored, and who can read it? What happens when a refresh fails, and who is told? A vendor that cannot answer the third is keeping your access somewhere you cannot audit.
The mistake that costs money is connecting with the founder's own admin credential. It grants everything, it can be read wherever it was pasted, and it fails all at once when the founder's account changes, so every automation stops on the same day and the unwatched ones stay stopped.
Check yourself
1. The accounting system offers a never-expiring API key with full access, or OAuth with two scopes: read contacts, write invoices. The contractor prefers the key: "simpler, and the automation is internal". Which do you approve?
OAuth with the two scopes, approved by a dedicated integration user. "Internal" says who built it, not who can read the credential: the key would sit in the workflow, the run logs and the contractor's laptop, and it opens payroll for as long as it lives. Accept a key only if it can be cut to the same two permissions and rotated without downtime.
2. A run log containing the connector's access token is pasted into a public support forum. What is exposed, for how long, and what do you do first?
The two scopes, until that access token expires, at most an hour after issue. The refresh token was never in the log; it only travels to the token endpoint. Revoke the grant, re-approve, and stop the logs printing headers. The admin key in the same log would have exposed everything until someone noticed.