BACK TO DIRECTORY

Bulwarden

by jgloeckl.de

0.0
(0 ratings)

Bulwarden is the site agent, installed on each managed WordPress site. It
exposes a signed REST API (jgm/v1) that a Bulwarden hub calls to read
health and security data, run checks and trigger updates. The hub is a separate
application — it is not part of this plugin — and this plugin talks to no hub
at all until you pair it with one
. On its own it sends nothing anywhere.

It is built for the person who is responsible for a site they did not build:
an agency looking after forty of them, or an owner who wants one place that
answers “is this thing all right?” without logging into it.

What it reports

  • Site health — WordPress, PHP and plugin versions, pending updates, disk
    usage, and WordPress’ own Site Health tests, collected in one snapshot.
  • A full plugin and theme inventory, with each item’s version, whether it
    is active, whether an update is waiting, and whether it came from
    WordPress.org at all — which is what lets a hub match it against a CVE feed.
  • Must-use plugins, which WordPress runs on every single request with
    nothing activating them and no way to switch one off from the admin. Nothing
    else in wp-admin lists them properly, and dropping a file there is the tidiest
    way to install a backdoor.
  • Configuration-level security checks with a posture score — file editing,
    directory listing, XML-RPC, debug output, and the rest of the settings that
    quietly decide how exposed a site is.
  • Unfinished updates. An update that already replaced a site’s files can
    still fail to finish, and neither state clears itself: a pending database
    schema upgrade that every administrator is sent to and the public site hides
    completely, or a leftover .maintenance lock from an updater that died
    mid-copy. Both are reported, and both can be finished from the hub by running
    exactly what WordPress itself would have run.
  • Email delivery. WordPress keeps no record of the mail a site sends: when
    a contact form stops delivering or an order confirmation never arrives, the
    error is raised and thrown away. This counts what was attempted, what failed
    and why, and reports which transport is doing it — PHP’s mail(), an SMTP
    server, or the plugin that configured one. No part of any message is stored:
    not the recipient, not the subject, not the body.

What it finds

  • A malware scan in three layers. Every core and WordPress.org file is
    verified against its published checksums, so a modified file is found
    whether or not anybody has written a signature for what was put in it; then
    every file is read for the code patterns webshells and injected backdoors
    actually use. Findings carry the file, the line and a short excerpt.
  • Backdoors that arrive dressed as an ordinary plugin — a forged
    administrator login, a privileged action gated on a key baked into the file,
    an account created from hard-coded credentials, users hidden from the users
    list. A plugin absent from WordPress.org has no published files to check it
    against, so without this a hostile one surfaced only as unverifiable.
  • A plugin hiding itself. Malware that conceals a plugin does it by
    answering the question before WordPress can — and the hidden plugin is then
    also the one plugin whose files are never checked. The scan counts what is on
    disk itself and compares.
  • Server-configuration files. .htaccess, php.ini and .user.ini are
    the one part of a WordPress install that changes what the server does
    rather than what WordPress does, and nothing in wp-admin shows them. A file
    set to run before every request, a rule that makes uploaded images execute as
    PHP, a redirect that only fires for search engines: all reported, with the
    line. Nothing is ever changed for you — a good share of those directives are
    written deliberately by a host or a security plugin, and the point is that
    you get to decide which.
  • Leftover files. An interrupted backup, a finished restore and a migration
    plugin all leave things behind and none of them clean up: a
    wp-config.php.bak the web server hands out as plain text, a database.sql
    in the web root, an installer that overwrites the site with no login. Found,
    measured, and removable from the hub — and the site decides what may be
    deleted, so a stale list can only ever be refused.
  • Signatures that keep up. The scan’s pattern list can be updated by your
    provider without updating this plugin, so a new detection reaches the site in
    hours rather than waiting for a release to travel a whole fleet. A site that
    has never been paired scans with the list this plugin ships.

What it does

  • Remote core, plugin and theme updates, wrapped in maintenance mode so
    visitors never see a half-updated site — and taken off the host’s PHP time
    limit, so a core update on shared hosting finishes instead of being killed
    part-way.
  • Zero-knowledge encrypted backups. The archive is built and encrypted on
    this server
    , under a passphrase that is never transmitted anywhere;
    only the ciphertext is uploaded. Nobody — including whoever runs the hub —
    can read a backup without that passphrase. Restores work the same way in
    reverse, and can put back the database alone if that is all that broke.
  • Page tracing. Your provider can ask this site to render one of its own
    public pages and report which file produced each line of the HTML — core, a
    plugin, the theme, a must-use plugin. It answers the question nothing in
    WordPress answers: which plugin adds the Google Fonts tag, or the tracking
    script, or the markup nobody can find a setting for. The page is never
    altered to do it.
  • WP-Cron on a schedule that actually runs. A site with no visitors runs no
    cron, which is how scheduled posts, order emails and licence checks quietly
    stop.
  • A support card on the dashboard naming whoever maintains the site, how to
    reach them, and a Request help button that files a ticket with them
    directly — attached to the right site, without the owner having to explain
    which one.

Pairing

On activation the plugin provisions an API key + secret. Copy the connect
string
from the Bulwarden entry in the WordPress admin menu and paste
it into the hub’s “Connect a site” form. Your provider’s support details are
then pushed to the site automatically by the hub and appear on the dashboard.

Security

Hub client requests are authenticated with the per-site API key and an
HMAC-SHA256 signature over the method, route, timestamp, and body. Timestamps
outside a 5-minute window are rejected to limit replay. The secret never
travels on the wire — it lives only in this plugin and in the hub webapp.

Privacy

Bulwarden is a client agent: on its own it sends data nowhere. Pairing this
site with a hub (yours, or your maintenance provider’s) is an explicit,
opt-in action — you choose when to copy the connect string from the Bulwarden
screen in the WordPress admin menu and hand it to that hub. Nothing is
transmitted before that.

Once paired, data only moves in these cases:

  • Health, inventory, and security checks. The paired hub reads these from
    this site’s signed REST API when it polls or when a check is requested —
    WordPress/plugin/theme versions and update status, a full plugin & theme
    inventory, disk usage, and the configuration-level security posture score.
  • Backups, only when triggered (the Settings screen’s “Back up now”
    button, or a request from the paired hub): the full site is archived and
    encrypted on this server with a passphrase that is never transmitted
    anywhere, then the ciphertext is uploaded to the hub. Only someone who has
    the passphrase can decrypt a backup — the hub operator cannot read its
    contents.
  • Malware scan results, only when a scan is triggered (admin- or
    hub-initiated): findings (type, severity, file path, line, and a short
    excerpt) are sent to the hub that requested the scan.
  • Finishing an interrupted update, when the paired hub asks. Nothing is
    sent in that exchange; the site runs WordPress’ own database upgrade, or
    deletes an expired .maintenance lock file, and reports the outcome.
  • Server-configuration files, when the paired hub asks: the contents of
    this site’s .htaccess, php.ini and .user.ini files, so the hub can show
    what is in them and when they last changed. These are configuration, not
    content — no post, page, media file or user data is read.
  • Email counters, as part of the health snapshot: how many messages this
    site attempted and how many failed over the last seven days, the error text
    the mail server returned, and which transport is sending. No part of any
    message is recorded
    — not the recipient, not the subject, not the body.
  • A traced page, only when the hub asks for one: the HTML of a single
    public page of this site, exactly as an anonymous visitor would receive it,
    plus the file paths and line numbers that produced it. No file contents are
    read and no logged-in view is ever rendered.

Independently of any hub pairing, this plugin verifies WordPress core and
wordpress.org-hosted plugin files by comparing local file hashes against the
public checksum APIs at api.wordpress.org and downloads.wordpress.org.
Those requests carry only what identifies the release to look up — the
WordPress version and locale, and each plugin’s slug and version. No file
contents, hashes, URLs or user data are sent: the reference checksums come
back and the comparison happens here, on this server.

Bulwarden does not call home on activation, does not collect analytics, and
stores data on no server this site hasn’t been explicitly connected to. The
hub itself is a separate service outside this plugin’s control; consult your
provider for how it handles the data described above.

External services

This plugin connects to the services below. Nothing here runs on activation.

Your Bulwarden hub

Bulwarden is the site-side agent for a hub — the management application an
agency or site owner runs to watch and maintain a fleet of WordPress sites. The
hub is a separate product and is not part of this plugin.

The default hosted hub is operated by Bulwarden at https://bulwarden.net/ —
terms of use: https://bulwarden.net/terms/ , privacy policy:
https://bulwarden.net/privacy/ . A hub can also be self-hosted, or run by the
maintenance provider you buy from, in which case this plugin talks to that
provider’s server instead and their terms and privacy policy apply.

No connection to any hub exists until you make one. You pair a site by
copying the connect string from the Bulwarden screen in the WordPress admin
menu and pasting it into the hub; before that the plugin contacts no hub at
all, and it never discovers or chooses one on its own. Once paired, data moves only in these cases:

  • When the hub asks for status. It reads this site’s signed REST API and
    receives WordPress/plugin/theme versions and update status, the full plugin
    and theme inventory, disk usage, the results of WordPress’ own Site Health
    tests, and the configuration-level security posture score.
  • When a backup runs (you press “Back up now”, or the hub requests one).
    The site is archived and encrypted here, with a passphrase that is never
    transmitted, and only the ciphertext is uploaded. The hub operator cannot
    read a backup’s contents without that passphrase.
  • When a malware scan runs (started by you or by the hub). The findings —
    type, severity, file path, line number and a short excerpt — are sent to the
    hub that asked for the scan.
  • When the hub pushes your provider’s support details — their name, logo,
    support address and accent colour — on connect and whenever they change
    them. Nothing is sent from the site in that exchange.

Every one of those requests is authenticated with this site’s own API key and
an HMAC-SHA256 signature; the shared secret never travels over the wire.

api.wordpress.org and downloads.wordpress.org

The malware scan verifies WordPress core and wordpress.org-hosted plugins
against their published checksums, using WordPress.org’s own public APIs at
https://api.wordpress.org/core/checksums/1.0/ and
https://downloads.wordpress.org/plugin-checksums/. This happens whenever a
scan runs, whether or not the site is paired with a hub.

These requests identify only the release being looked up: the WordPress version
and locale, and each installed plugin’s slug and version. No file contents,
hashes, site URL or user data are sent — the reference checksums are returned
and compared locally.

These are WordPress.org services, covered by the WordPress.org privacy policy:
https://wordpress.org/about/privacy/

Screenshots

The Bulwarden screen at a glance: whether the site is connected, whether
backups are encrypted, and when the last backup and scan ran.

The Bulwarden screen at a glance: whether the site is connected, whether backups are encrypted, and when the last backup and scan ran.

Connecting the site: the connect string you paste into your hub, and the
API credentials behind it.

Connecting the site: the connect string you paste into your hub, and the API credentials behind it.

Backups: a run in progress showing the phase it has reached and its log,
above the encryption passphrase and the folders left out of the archive.

Backups: a run in progress showing the phase it has reached and its log, above the encryption passphrase and the folders left out of the archive.

The malware scan: what the last one found, grouped by kind, and how much of
the site could be checked against the files WordPress.org published.

The malware scan: what the last one found, grouped by kind, and how much of the site could be checked against the files WordPress.org published.

The activity log: an append-only record of credential changes, backups,
restores, scans and repairs, including the ones the hub triggered.

The activity log: an append-only record of credential changes, backups, restores, scans and repairs, including the ones the hub triggered.

The dashboard support card — who maintains this site and how to reach
them, pushed by the hub.

The dashboard support card — who maintains this site and how to reach them, pushed by the hub.

Plugin Details

Active Installs
10
Total Downloads
283
Version
1.19.0
Requires WP
6.0
Requires PHP
7.4
Tested Up To
7.1
Added
2026-08-23
Last Updated
2026-09-01 6:49pm GMT

Ratings

5
0
4
0
3
0
2
0
1
0