Secure rotation & revocation of Strapi API and admin tokens
Learn how to configure, automate, and audit token rotation and revocation in Strapi 5, keep keys visible for operations, satisfy GDPR requirements, and stay protected against token leakage.
By the Revisionary team · · 4 min read
Developers can achieve secure, automated rotation and revocation of Strapi 5 API and admin tokens by configuring encryption, using the built‑in regeneration endpoint, storing secrets in a vault, and relying on audit logs for visibility and compliance. The process keeps token lifetimes short, ensures old tokens are invalidated instantly, and provides a tamper‑evident trail that satisfies GDPR audit needs.
Why token rotation matters
- Limited exposure – Short‑lived tokens reduce the window an attacker can use a stolen key.
- Compliance – GDPR requires the ability to demonstrate when personal data was accessed and by whom; audit logs of token events provide that evidence.
- Operational hygiene – Automated rotation removes the need for manual key changes, lowering human error.
1. Configure persistent token visibility
Strapi only shows a token once after creation unless an encryption key is defined. To keep tokens readable by your CI/CD or secret‑management tool, set admin.secrets.encryptionKey in /config/admin.js.
// /config/admin.js
module.exports = ({ env }) => ({
admin: {
// A 32‑byte base64 string – keep it safe in a vault
secrets: {
encryptionKey: env('STRAPI_ENCRYPTION_KEY'),
},
// Optional: customise the salt used for all tokens
apiToken: {
salt: env('API_TOKEN_SALT'),
},
},
});Store STRAPI_ENCRYPTION_KEY and API_TOKEN_SALT in a secret manager (e.g., HashiCorp Vault, AWS Secrets Manager) and reference them via environment variables.
2. Choose appropriate token lifetimes
Strapi 5 lets you set token expiration to 7 days, 30 days, 90 days, or Unlimited. For production services, a 30‑day lifespan balances security and operational load.
# Example: create a 30‑day API token via the REST API
curl -X POST https://cms.example.com/admin/api-tokens \
-H "Authorization: Bearer <admin-token>" \
-H "Content-Type: application/json" \
-d '{"name":"frontend‑service","expiresIn":"30d"}'The response contains the plaintext token only once; after that it is stored encrypted using the key above.
3. Automate rotation with the regeneration endpoint
Strapi added a programmatic endpoint to rotate a token without deleting and recreating it:
POST /admin/api-tokens/:id/regenerateThe endpoint returns a fresh access key while automatically revoking the previous one.
// rotation‑script.js – run from CI every 30 days
const fetch = require('node-fetch');
require('dotenv').config();
const ADMIN_TOKEN = process.env.STRAPI_ADMIN_TOKEN; // stored in vault
const TOKEN_ID = process.env.TARGET_API_TOKEN_ID; // ID of the token to rotate
async function rotate() {
const res = await fetch(
`https://cms.example.com/admin/api-tokens/${TOKEN_ID}/regenerate`,
{
method: 'POST',
headers: { Authorization: `Bearer ${ADMIN_TOKEN}` },
}
);
if (!res.ok) throw new Error('Rotation failed');
const { accessKey } = await res.json();
console.log('New token:', accessKey);
// Store the new key back to the secret manager
// e.g., AWS Secrets Manager put‑secret-value …
}
rotate().catch(console.error);Add the script to a scheduled job (GitHub Actions, GitLab CI, Jenkins) and update the dependent services to read the refreshed secret from the vault.
4. Immediate revocation when a compromise is suspected
If a token is suspected to be leaked, revoke it instantly via the admin UI or the API:
curl -X DELETE https://cms.example.com/admin/api-tokens/<id> \
-H "Authorization: Bearer <admin-token>"Because the same apiToken.salt is shared across API and admin tokens, changing the salt invalidates all existing tokens. This is a powerful emergency measure.
// emergency‑salt‑rotation.js
require('dotenv').config();
const fetch = require('node-fetch');
const ADMIN_TOKEN = process.env.STRAPI_ADMIN_TOKEN;
const NEW_SALT = require('crypto').randomBytes(32).toString('base64');
async function rotateSalt() {
const res = await fetch('https://cms.example.com/admin/settings', {
method: 'PUT',
headers: {
Authorization: `Bearer ${ADMIN_TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ apiToken: { salt: NEW_SALT } }),
});
if (!res.ok) throw new Error('Salt rotation failed');
console.log('All tokens invalidated');
}
rotateSalt().catch(console.error);After running, generate fresh tokens for the services that still need access.
5. Enable and tune audit logging
Audit logs capture create, update, delete, and regenerate events for tokens, without storing the actual secret values. They also record the requestor’s IP address and, where permitted, request payloads – data required for GDPR‑compatible records.
5.1 Turn on audit logs (Enterprise only)
Add the following to /config/admin.js:
module.exports = ({ env }) => ({
admin: {
auditLogs: {
enabled: true,
retentionDays: env.int('AUDIT_LOG_RETENTION_DAYS', 180), // keep for 6 months
exportMaxRows: env.int('AUDIT_LOG_EXPORT_MAX', 2000000),
},
},
});The default retention is 90 days; extending it helps meet GDPR’s “record‑keeping” expectations.
5.2 Exporting logs for compliance reviews
curl -X GET https://cms.example.com/admin/audit-logs/export \
-H "Authorization: Bearer <admin-token>" \
-o audit-logs.csvThe CSV can be stored in an immutable bucket (e.g., AWS S3 with Object Lock) to provide a tamper‑evident audit trail.
6. GDPR‑focused considerations
| Requirement | How Strapi helps |
|---|---|
| Data minimisation | Tokens are never stored in plaintext after creation; only the encrypted version lives in the database. |
| Right to access | Exported audit logs give data subjects visibility into when their personal data was accessed via a token. |
| Right to erasure | Deleting a token (or rotating the salt) instantly removes its ability to authenticate, satisfying a “forget‑me” request. |
| Record‑keeping | Configurable audit‑log retention up to 180 days (or longer) aligns with typical GDPR retention policies. |
7. Best‑practice checklist
- Set
admin.secrets.encryptionKeyin/config/admin.jsand store the key in a vault. - Define a unique
apiToken.salt; rotate it only in emergencies. - Choose a token TTL of 30 days (or less) for all production services.
- Automate rotation with the
POST /admin/api-tokens/:id/regenerateendpoint. - Store fresh tokens back into the secret manager, never in code or repo.
- Enable audit logs and configure retention to meet regulatory windows.
- Export logs regularly and archive them in an immutable store.
- Document revocation procedures (UI delete, salt rotation) in your incident‑response playbook.
- Review permissions – ensure only privileged roles can create or regenerate tokens (see
/docs/reference/configuration). - Test rotation in a staging environment before rolling out to production.
8. Integrating with Revisionary (optional)
If your project already uses the Revisionary plugin, you can link token‑related events to content‑change audits. The audit log already records token actions; Revisionary’s audit entries can be correlated by user ID to provide a full picture of who changed content and which token they used. This synergy improves traceability for both content and security teams.
9. Sample end‑to‑end workflow
- CI pipeline pulls
STRAPI_ENCRYPTION_KEY,API_TOKEN_SALT, andSTRAPI_ADMIN_TOKENfrom the vault. - Nightly job runs
rotation‑script.jsfor each service token. - Script writes the new token back to the vault and updates the service’s environment.
- Audit log automatically records the regeneration event (timestamp, IP, user ID).
- Monthly compliance run exports audit logs, validates that no token exceeds the TTL, and archives the CSV.
Following this workflow keeps your Strapi installation compliant, reduces the attack surface, and provides the visibility required by GDPR and internal security policies.
For further reading on Strapi’s security features, see the official docs and blog posts linked below.
Sources
The Revisionary team
Developers who build Revisionary, a version history plugin for Strapi 5. We write about Strapi, web development, AI and application security.
This article was written with the help of AI.