Token Safety
Your SMBcrm OAuth access token and Private Integration Token (PIT) are full credentials for your account, not configuration strings. Anything their scopes allow, anyone holding the token can do. Treat every token you generate with the same care you’d give a database password.
Keep tokens out of anything untrusted
Section titled “Keep tokens out of anything untrusted”Never put a token where someone other than your own server can read it:
- Browser / client-side JavaScript. Any token shipped to a page is visible in the browser’s network tab and dev tools to every visitor, no matter how the request is built.
- Mobile apps. A token embedded in an app binary can be pulled out by decompiling the app or intercepting its traffic. It isn’t meaningfully more protected than a web page.
- Public or private repositories. A committed token lives on in git history even after you delete the line in a later commit.
- Logs, error trackers, and support tickets. Scrub the
Authorizationheader before logging a request, and never paste a full token into a bug report or chat message.
Store tokens as server-side secrets
Section titled “Store tokens as server-side secrets”Keep tokens out of source control entirely. Load them from environment variables or a
secrets manager (your host’s built-in secrets store, AWS Secrets Manager, HashiCorp Vault,
and similar tools all work) at runtime, and make sure your local env file is listed in
.gitignore.
# Never commit this fileSMBCRM_TOKEN=<token>const token = process.env.SMBCRM_TOKEN;
const res = await fetch('https://services.smbcrm.com/contacts/<contact_id>', { headers: { Authorization: `Bearer ${token}`, Version: 'v3', },});Request only the scopes you use
Section titled “Request only the scopes you use”Both OAuth access tokens and PITs are issued with a specific list of scopes, and each
endpoint in this reference lists the scope it requires. Grant only what your
integration actually calls: if you only ever read contacts, request contacts.readonly and
leave contacts.write out entirely. A narrower token limits the damage from a leak or a bug
in your own code. See Scopes for the full list.
Rotate tokens, and revoke immediately if one leaks
Section titled “Rotate tokens, and revoke immediately if one leaks”Rotate tokens periodically as routine hygiene, the same way you’d rotate a database password: generate the replacement, deploy it, confirm it works, then revoke the old one.
A token can leak in several ways: committed to a repo, pasted into a chat, logged in plaintext, exposed in a client. If yours does, don’t wait for your normal rotation schedule.
Use a separate token per integration
Section titled “Use a separate token per integration”Issue a distinct token for each integration, service, or environment instead of sharing a single token everywhere: one for your production backend, another for staging, another for each third-party tool you connect. If one integration is compromised, breaks, or is retired, you can revoke that one token without touching anything else that authenticates to your account.
Always use HTTPS, and prefer server-to-server calls
Section titled “Always use HTTPS, and prefer server-to-server calls”Every request to https://services.smbcrm.com is served over HTTPS; there is no
unencrypted option. Beyond that, call the API from your own server whenever you can rather
than from a browser. A server-to-server call keeps the token out of the client entirely and
avoids relying on CORS support through the gateway, which may allow fewer headers than a
direct call does. See Base URL & Headers for the exact headers
every request needs and more on the browser-request caveats.
OAuth: protect the refresh token too
Section titled “OAuth: protect the refresh token too”If you authenticate with OAuth, you’re issued a short-lived access token plus a longer-lived refresh token. The refresh token is at least as sensitive as the access token it produces. Anyone holding it can mint new access tokens for your account until it’s revoked. Store it with the same server-side-secret handling described above, and perform the refresh call itself from your server, never from a client a user controls.
Related
Section titled “Related”- Scopes — the permission a token needs for each endpoint.
- OAuth (account access) — the full authorization and token-refresh flow.
- Private Integration Tokens — generate a token without the OAuth flow.
- Base URL & Headers — required headers and the browser-request caveat.
