Skip to content

Security

Nick Hamze edited this page Aug 31, 2026 · 6 revisions

Security

Fleet connects sites with WordPress Application Passwords. It never asks for, receives, or stores a person's normal WordPress password.

Credential permissions

An Application Password acts as the WordPress user who approved it. Fleet needs a user who can view, install, and activate plugins. Use a dedicated administrator account when that fits the agency's operating model, and revoke the connection when it is no longer needed.

Application Passwords are individually named, tracked by WordPress, and revocable from Users → Profile on the managed site.

Storage on the hub

Connections belong to the current hub user and are stored in user meta. The record contains:

  • Site name and URL
  • REST API location
  • Remote username
  • Application Password UUID
  • Encrypted Application Password
  • Cached OpenStation status, last check time, and last error

The Application Password is encrypted with sodium secret-box encryption. Fleet derives the encryption key from the hub's WordPress authentication salt, so changing that salt makes existing stored credentials unreadable. Reconnect affected sites after a salt rotation.

Fleet loads WordPress's bundled sodium compatibility layer when the PHP sodium extension is unavailable. It refuses to save a credential if secure encryption cannot be provided.

Request boundary

  • Both hub and managed site must use HTTPS.
  • Target URLs cannot contain embedded credentials, query strings, or fragments.
  • Remote requests use WordPress's safe HTTP functions, including unsafe-URL rejection.
  • Fleet is intentionally limited to publicly reachable sites. It does not weaken WordPress's SSRF protections for private or loopback addresses.
  • Authorization endpoints must be HTTPS and share the target site's origin.
  • The callback includes a short-lived state value and WordPress nonce.
  • Fleet blocks the hub from connecting to itself while allowing path-based multisite siblings on the same host.

Local authorization

Only hub users with manage_options can open Fleet or submit its actions. Every local mutation uses a WordPress nonce. Notice messages are selected from fixed codes rather than displaying arbitrary query-string content.

Remote authorization

The managed site's WordPress capabilities remain authoritative. Its Core REST controllers decide whether the approving user may list, install, activate, or revoke plugins and credentials. Fleet does not bypass those checks.

Disconnect and uninstall

Disconnect revokes the exact remote Application Password before deleting the local record. If revocation fails, Fleet keeps the record and reports the error so the manager can retry.

WordPress plugin uninstall cannot reliably contact every managed site. The uninstall routine removes Fleet metadata from the hub but cannot guarantee remote revocation. Disconnect all sites before uninstalling. If Fleet was removed first, revoke its named Application Password manually from each managed user's profile.

Secrets in logs and support reports

Do not log, paste, or include Application Passwords in issue reports. The WordPress authorization flow returns a new password through a one-time callback URL; Fleet immediately handles that callback and redirects to a clean admin URL.

When reporting a problem, include the hub and managed WordPress versions, PHP versions, HTTP status, and sanitized error message. Remove usernames, domains that must stay private, authorization headers, callback URLs, salts, and credentials.

Clone this wiki locally