← Back to docs

WordPress account pairing

WordPress account pairing

Tornevall Tools can authorize a WordPress installation without requiring an administrator to copy service tokens manually.

Flow

  1. WordPress sends POST /api/integrations/wordpress/device with its site name, site URL, callback URL and requested services.
  2. Tools returns a short-lived device code and an authorization URL.
  3. The WordPress administrator signs in to Tools and explicitly approves or denies the request.
  4. For DNSBL/FraudBL, the administrator chooses an active token and decides whether to rotate and reuse that token or create a separate site token.
  5. WordPress exchanges the device code once through POST /api/integrations/wordpress/token.
  6. The encrypted exchange payload is deleted after the successful exchange.

Pairings expire after 10 minutes. The callback URL must use the same host as the submitted WordPress site URL.

The flow is a device-style authorization endpoint for WordPress clients. A separate OAuth client secret is not required: the browser session authenticates the Tools user, approval is explicit, the raw device code is high entropy and stored only by the WordPress client, and the credential bundle is exchanged server-to-server once.

Supported services

DNSBL / FraudBL

If the Tools user owns one or more active DNSBL tokens, the approval screen lists those tokens by name and effective permissions without displaying their raw values.

The default choice is Use this existing token. Tools rotates the selected non-admin token in place, keeps its token id and permissions, invalidates the previous secret immediately, and returns the new secret once through the device-code exchange. This lets a WordPress plugin adopt an already existing DNSBL token without Tools ever reading the old secret back to the browser.

Rotation affects every client that still uses the previous secret. The approval page therefore warns that those clients must be updated.

The alternative choice is Create a separate site token. In that mode the selected token is used only as a permission template and Tools creates a new non-admin DNSBL token for the WordPress site.

Admin DNSBL tokens are never installed directly in WordPress. If an admin token is selected while rotation is requested, Tools creates a non-admin copy of its effective DNSBL permissions instead. Admin bypass behavior is never delegated.

The exchange response includes credential_mode:

  • rotated_existing - the selected non-admin token was rotated in place.
  • created_copy - a separate site token was created from a non-admin token.
  • copied_from_admin - an admin token was selected, so Tools created a non-admin copy instead of rotating the admin credential.

Existing/previous DNSBL token values are never returned. Only the newly generated secret is returned once after approval.

Guestbook

If the Tools user owns at least one active guestbook, Tools creates a dedicated user-bound API key with guestbook.write and guestbook.moderate. Normal guestbook owner checks still apply, so the key cannot access another user's guestbooks.

Device request

POST /api/integrations/wordpress/device
Content-Type: application/json
{
  "site_name": "My WordPress site",
  "site_url": "https://example.test",
  "callback_url": "https://example.test/wp-admin/admin-post.php?action=ttfw_tools_connection_complete",
  "requested_services": ["dnsbl", "guestbook"]
}

A standalone DNSBL plugin can use the same endpoint with only "requested_services": ["dnsbl"] and its own callback on the same WordPress host.

The response contains device_code, user_code, verification_uri_complete, expires_in and interval.

Approval

The approval form accepts the selected DNSBL token id and a DNSBL strategy:

  • rotate - rotate/reuse the selected token. This is the default.
  • clone - leave the selected token unchanged and create a separate site token.

These fields are submitted only by the authenticated Tools approval form. They are not trusted from the original unauthenticated device request.

Exchange

POST /api/integrations/wordpress/token
Content-Type: application/json
{
  "device_code": "the-device-code-returned-by-the-device-endpoint"
}

The successful response contains the approved credential bundle. It can be retrieved once. Later exchanges return already_consumed.

Possible non-success states are authorization_pending, access_denied, expired_token, already_consumed and invalid_device_code.

After approval or denial, Tools appends the generic callback field tools_connection=complete|denied. The older ttfw_connection field is also returned for compatibility with the first Tools-for-WordPress client implementation.

Security properties

  • Raw device codes are not stored; Tools stores a SHA-256 hash.
  • Credentials waiting for exchange are encrypted with the Laravel application encryption key.
  • The exchange payload is cleared immediately after successful retrieval.
  • Existing service token values are not included in the approval page, API response or exchange payload.
  • Rotating a DNSBL token generates a new random secret and invalidates the previous value immediately.
  • Admin DNSBL tokens are never rotated into an external WordPress installation.
  • The browser performs the user approval, while credential exchange is intended to be server-to-server from WordPress.
  • Pairing and DNSBL credential actions are written to the DNSBL API audit log without token values.