Token scopes
A token carries a list of scopes. Every route checks for its scope and for the WordPress capability it needs before it runs, so a token can never do more than the account that created it. Give each token only what its job needs.
On this page
How scopes work
- Two checks, on every route. A request needs the route’s scope and the WordPress capability that route requires, such as
edit_posts,upload_files,install_pluginsormanage_options. A token made by an Editor cannot install plugins, whatever scopes it lists. - Read and write are separate.
content:readnever lets anything change. Writes need the matching…:writescope. - Publishing is its own scope. Without
content:publish, a post or page created or updated with status “publish” is saved as a draft instead. - Dangerous scopes (marked below) are never in the default set, and the Tokens screen warns about each one when you tick it. The most destructive operations also ask for a confirmation step.
- Some scopes are administrator-equivalent.
fs:admin,db:write,cli:exec,system:backup,plugin:write,theme:writeandadmin:loginlet the token holder do what an administrator can. Treat a token that has any of them like an administrator password.
All scopes
Scopes marked default are the plugin’s suggested starting set for a content token. No dangerous scope is in it.
| Scope | Allows | Notes |
|---|---|---|
auth:read | Read who the token belongs to (/whoami). | default |
audit:read | Read the audit log and the debug.log tail. | default · admin only |
dashboard:read | Read the dashboard statistics. | default |
content:read | Read posts, pages, terms, search and multilingual data. | default |
content:write | Create, edit and delete posts and pages (as drafts), create terms, set translations. | default |
content:publish | Publish posts and pages directly. | dangerous |
media:read | Read the media library and list unused media. | default |
media:write | Upload from a URL or base64, edit metadata, optimise and delete media, set media translations. | default |
seo:read | Read SEO meta, analyse posts, audit, sitemap status and broken links. | default |
seo:write | Change SEO titles, descriptions and related meta; apply the safe fixes of an SEO audit. | default |
analytics:read | Read traffic data from the site’s analytics plugin. | default |
theme:read | Read the active theme and its files. | |
theme:write | Write theme files, add custom CSS, switch theme. | dangerous · administrator-equivalent |
plugin:read | List plugins (with available updates) and read plugin files. | |
plugin:write | Write plugin files. | dangerous · administrator-equivalent |
plugin:install | Install from the WordPress.org directory, a URL or an uploaded zip; activate, deactivate, scaffold a new plugin. | dangerous |
site:read | Read settings, menus, widgets, Customizer, performance data and maintenance status; list, read, search and download files. | admin only for files |
site:write | Change settings, menus, widgets and Customizer, toggle maintenance mode, clear debug.log, and change files inside the uploads folder only. | dangerous · admin only for files and maintenance |
fs:admin | With site:write: change any file under the site root, including code, except protected files. | dangerous · admin only · administrator-equivalent |
db:read | Run SELECT queries through the SQL guard. | admin only |
db:write | Run INSERT, UPDATE and DELETE, each with a confirmation step. | dangerous · admin only · administrator-equivalent |
cli:exec | Run allow-listed WP-CLI commands. Off on every site until the operator enables it. | dangerous · admin only · administrator-equivalent |
system:backup | Create, list and restore full backups. | dangerous · admin only · administrator-equivalent |
admin:login | Get a one-time link, valid 60 seconds, that signs the token’s own user in to wp-admin. | dangerous · admin only · administrator-equivalent |
The two file powers
Since plugin 1.7.0, changing files takes one of two levels:
site:write
Changes files strictly inside wp-content/uploads, and only inert types: documents, images, audio, video and archives such as pdf, png, mp4, zip or docx. Anything else is refused with xaflo_fs_outside_uploads.
site:write + fs:admin
Changes any file under the site root, code included, except protected files (wp-config.php, .env, backups, the bridge’s own folder). Each overwrite, rename, delete and each executable or server-config write asks for confirmation first.
Reading files needs site:read and an administrator account. Secrets such as wp-config.php, .env files, backups, SQL dumps and debug.log are refused and hidden from listings at every level.
Sets that work
Reporting, read-only
Audits, analytics, SEO reviews. Cannot change anything.
Content editor
Drafts, SEO fixes and images. Nothing goes live without you.
Publisher
The editor set, plus the right to publish.
Xaflo Desktop, full control
Remote → Files beyond uploads, Deploy and “Open wp-admin” signed in. Administrator-equivalent: keep it on your own computer.
Keep fs:admin, db:write, cli:exec and admin:login out of everyday tokens. If you need one, create a short-lived token for that job and revoke it when you are done.
Rate limits per scope
Every token can make 60 requests per minute by default; administrators signed in to wp-admin are limited the same way. Sensitive scopes have tighter limits of their own, per token:
| Scope | Requests per minute |
|---|---|
cli:exec | 5 |
system:backup | 5 |
db:write | 10 |
plugin:install | 10 |
theme:write | 20 |
plugin:write | 20 |
media:write | 30 |
content:publish | 30 |
Above the limit the API answers 429 with a Retry-After header. Site operators can change the global limit and the per-scope overrides in the plugin settings.
Lifetime and revocation
- A token expires after the number of days you chose (1 to 365, default 30). Expired tokens are cleaned up by a daily job.
- Revoke a token at any time from Xaflo → Tokens. It stops working on the next call.
- A token only works on the site that issued it: its issuer must match the site address. A staging copy with a different address needs its own tokens.
- Rotate secret in Xaflo → Settings invalidates every token at once. After updating to 1.7.0 this is required: see Upgrading to 1.7.0.