One token per integration
With one token for each system that uses the API, both problems go away. The name andlastUsedAt
show which system uses each token, and revoking one of them affects only that system.
Name it after the system that uses it
Use names like
ERP contact sync or BI nightly reports. A name like “token 1” does not
help when someone needs to decide whether it can be revoked.Minimum scope
Check only what the integration uses today. Widening the permissions later takes about 30
seconds in the panel. Fixing the damage from a token with too many permissions takes a lot more
work.
What deserves extra attention
Some permissions give more power than others. Two call for special care:Writing on users amounts to administrative power
Writing on users amounts to administrative power
With
users: ["POST"], the token can invite people to the company. With users: ["PUT"], it
can change the profile of anyone already in it, including promoting someone to administrator.
An administrator, in turn, can create new tokens.Give these permissions only to HR or access provisioning integrations that truly need them. If
the routine only needs to list users, give it just GET.DELETE has no undo
DELETE has no undo
Deletions through the API do not ask for confirmation. If a faulty sync calls
DELETE /contacts/{id} over and over, there is no way to undo it.If the integration needs to delete data, keep that part in a separate routine, with a second
token and its own log.Expiry and allowlist
1
Set an expiry whenever it makes sense
Tokens for a project with a planned end, a vendor trial or a proof of concept should be created
with an expiration date from the start. A token with no expiry keeps working years after the
project ends.Write the expiration date down in the integration’s documentation. An expired token gets the
same
401 as any invalid token, and without that note it is hard to find out why the
integration stopped.2
Restrict the IP when there is a fixed IP
With the allowed IP list (allowlist) filled in, the token only works on calls coming from those
addresses. Even if it leaks, it cannot be used from anywhere else.The list accepts IPv4 addresses (
200.150.10.20) and CIDR ranges (191.30.0.0/16), with up to
50 entries.3
Rotate periodically
Rotating generates a new value for the token and keeps the name, permissions and allowlist.
The integration’s configuration stays the same and only the key changes. The old value stops
working right away, so agree on the time of the switch with whoever runs the system that uses
the token.
Where the key may live
Allowed
Environment variable, secrets vault (Vault, AWS Secrets Manager, Doppler), encrypted server
configuration.
Not allowed
Repository, front-end, mobile app, spreadsheet, chat message, support ticket,
screenshot.
Authorization header along with it. Hide that field before saving the log.
If a key has leaked
Revoke or rotate now
Do it in the panel, under Settings → Integrations → API. Revocation takes effect right away,
with no grace period.Rotate if the integration needs to keep running. Revoke if it can stop.
See what that token could reach
Open the token and check its permissions. They show exactly what could have been done with it.
A token with
reports: ["GET"], for example, gave access to reports but could not change any
contact.The lastUsedAt shows when it was last used.Fix the source
If you only rotate, without finding out how the key leaked, the problem may happen again. Check
repositories, logs, screenshots and credentials shared in chat, and fix the cause before handing
out the new key.
Periodic review
Once a quarter, open the token list and check each one:Is there still an integration using this token? The
lastUsedAt shows it.Do the permissions still match what the integration does today, or is there one left over from
an old version?
Does the expiration date make sense, or is it a token with no expiry from a project that has
already ended?
Does the person who created the token still work at the company? The panel shows who created it
and who edited it last.

