What should I know about token security?
Short answer
Section titled “Short answer”Treat an API token like a password: it grants anyone who knows it access with your
permissions. The most important rules: minimal scopes (read if writing isn’t
needed), set an expiration date, use a separate token per use case, store it only
in a secret store (never in code or Git) — and
revoke tokens you no longer use right
away.
Prerequisites
Section titled “Prerequisites”The rules in detail
Section titled “The rules in detail”-
Least privilege via scope. When creating a token, choose only
readif the integration merely reads data (reports, exports, monitoring). Usewriteonly for tools that actually change data. Keep in mind: without a scope selection, full access within your role applies. -
Set an expiration date. Give every token an end date — especially for tests and one-off migrations. A forgotten token then expires on its own.
-
One token per purpose. “CI Pipeline,” “Grafana Export,” “Asset Import” — separate tokens can be revoked individually without breaking other integrations, and the Last used column stays meaningful.
-
Store it securely. The value appears only once. Store it exclusively in a password manager or secret management system (GitHub/GitLab Secrets, Vault, a
.envfile outside the repo). Never in code, tickets, chats, or logs. -
Clean up and rotate regularly. Review the list periodically: revoke tokens without a recent Last used date; replace long-lived tokens on a regular schedule (create a new one → switch the integration over → revoke the old one).
Security-relevant patterns for practice:
curl -X POST https://demo.notory.io/api/v1/api-tokens \ -H "Authorization: Bearer inv_bestehender_token" \ -H "Content-Type: application/json" \ -d '{ "name": "Grafana (read-only)", "scopes": "read", "expires_at": "2026-12-31T23:59:59Z" }'curl -H "Authorization: Bearer inv_dein_token" \ https://demo.notory.io/api/v1/api-tokens# → check "last_used_at" and "expires_at" for each entryA read token that attempts to write deterministically receives:
{ "detail": "API token scope does not permit this operation" }Remember: the token belongs in the Authorization header — never in the URL (URLs
end up in server and proxy logs).
What happens behind the scenes?
Section titled “What happens behind the scenes?”This is how Notory protects tokens server-side — and where you’re still responsible:
- Only the hash is stored. Server-side, only the SHA-256 hash exists; a database leak doesn’t reveal the token values. The flip side: Notory itself can never show the value again either — protecting your copy is up to you.
- Scope enforcement on every request.
read→ only GET/HEAD/OPTIONS;write→ also mutating methods. This is checked before the actual action, in addition to your account’s role/permissions and tenant isolation (RLS). - Immediate invalidation. Revocation deletes the token; expiration and account
deactivation take effect on the next request (
401). There is no grace period. - Usage trail.
last_used_atis updated on every use — your basis for cleanup rounds. API access is also subject to the instance’s regular logging and rate limiting. - No privilege escalation possible. A token can never do more than its owner: the account’s role, assigned roles, and tenant limit every call. For low-risk integrations, it’s therefore worth using a dedicated account with a narrow role (e.g., Viewer) as the token owner.