Skip to main content
Adzbyte
SecurityWordPress

I Built a WordPress Monitor Around Capabilities, Not Shared Secrets

Adrian Saycon
Adrian Saycon
October 8, 20264 min read
I Built a WordPress Monitor Around Capabilities, Not Shared Secrets

I recently built a WordPress monitoring plugin for a small network of sites with private feature plugins. The tempting design was a central dashboard with enough credentials to inspect everything remotely. I chose a narrower model: each remote plugin owns a versioned health endpoint, WordPress authenticates the request with an Application Password, and a dedicated capability decides whether that account may run checks. The central monitor sees normalized health results, not form entries, API tokens, or internal response bodies. That boundary made the feature easier to reason about and safer to extend.

The monitor does not own the remote feature

A verification plugin understands its own upstream API, configuration, and failure modes better than a generic dashboard ever will. I kept the actual check beside the feature and made the monitor an orchestrator: identify the site, authenticate, request a check, normalize the result, and display it.

This prevents the central plugin from duplicating business logic or needing every remote secret. It also lets a feature plugin version its endpoint when its internal contract changes.

Authentication and authorization are different

An Application Password proves which WordPress user made the request. It does not automatically mean that user should run monitoring operations. I added a dedicated capability and required it on the remote REST route.

Administrators can receive that capability, but the better operating model is a dedicated low-privilege monitor user. One account per website is sufficient; the capability covers supported feature checks without creating a separate secret for every plugin.

The response contract is intentionally small. I normalized status, a safe summary, version information, timing, and bounded diagnostic details. I explicitly excluded protected health information, form entries, verification response bodies, OAuth tokens, and remote plugin secrets.

A monitoring response should help an operator decide what to inspect next. It does not need to become a remote debug dump. Detailed logs can remain on the system that owns them, under its existing access controls.

Manual checks came before automation. The initial release is view-and-test only. I did not add cron checks, notifications, history, charts, or automatic repair. Manual execution let me validate authentication, error mapping, timeouts, and operator language before creating another background system.

This restraint matters. Alerts built on an unstable check contract create noise, and automatic repair expands the permission and rollback problem dramatically.

I tested the security boundary as behavior

  1. Reject unauthenticated requests.
  2. Reject authenticated users without the monitor capability.
  3. Require HTTPS for configured remote sites.
  4. Never return saved passwords through admin or REST responses.
  5. Normalize remote timeouts and malformed responses.
  6. Keep privileged local changes behind both capability and nonce checks.
  7. Verify a valid check cannot expose protected payloads.

These tests describe the feature more accurately than a screenshot of a green status badge.

The business benefit is bounded visibility

Teams need to know whether critical integrations can respond, but they do not need to centralize every secret and record to get that answer. A narrow health contract reduces the blast radius of the monitor and makes ownership clear.

It also gives support a consistent first step. They can distinguish authentication failure, unavailable endpoint, invalid configuration, and upstream service trouble before escalating to a developer.

Error language became part of the API. A raw exception might reveal a URL, response body, or configuration detail and still fail to tell an operator what to do. I mapped failures into a small vocabulary: authentication rejected, capability denied, endpoint unavailable, check misconfigured, upstream timed out, and response invalid. Each status includes a safe next action without pretending to diagnose beyond the evidence.

This also improved compatibility. The dashboard consumes the normalized contract rather than matching whatever message a remote HTTP library happens to produce. A feature plugin can change its internal client without changing the monitor’s meaning. For developers, bounded diagnostic codes remain available for logs and tests. For administrators, the interface answers the immediate question: is this a credential problem, a site problem, or a provider problem, and who owns the next step? Clear failure categories reduce both secret exposure and support time.

Configuration storage received the same attention. Passwords are accepted through a write-only interface, encrypted or protected according to the installation’s available mechanism, and never returned as form defaults or REST fields. A replacement secret can be saved without proving the old value to the browser. Backup and support procedures must acknowledge that credential separately from ordinary display settings.

Release artifacts are verified separately from source. I record the expected checksum and version, install through the normal plugin path, and confirm the remote route still enforces the capability. Monitoring code deserves the same supply-chain discipline as the features it observes.

Why I am leaving automation for later

I would add scheduling only after the manual checks have a low false-positive rate and a clear owner for each result. The next design question is not how often to poll; it is who receives an alert, what they can safely do, and when silence or repetition should trigger escalation.

Photo by Tima Miroshnichenko on Pexels.

Adrian Saycon

Written by

Adrian Saycon

A developer with a passion for emerging technologies, Adrian Saycon focuses on transforming the latest tech trends into great, functional products.

Discussion (0)

Your email is used only for comment moderation and is never published.

No comments yet. Be the first to share your thoughts.