Lives at /settings/companion (gear menu → White Labeling — renamed from “Companion”). A centralized hub covering every client-facing surface an agency wants rebranded:
- Master Agency Brand Palette — global primary and accent colors that can be defined once and cascaded across all surfaces with a single click.
- Companion (wp-admin) — plugin name/description, author/company, admin menu label and icon, support email, dashboard logo, brand colors, and admin footer text, pushed into every Companion-equipped WordPress site.
- Client Reports — brand colors and footer text for the Client Reports module’s PDF/web output.
- Plugin Notification Email — header/accent colors, sender name, reply-to, and badge text for the CVE/vulnerability alert emails Companion triggers, plus a test-send action.
Master Agency Brand Palette
A quick-action palette bar anchored at the top of the hub allows operators to set agency-wide Primary (#2D2062) and Accent (#7EFF83) colors:
- Operators can adjust colors and click Save Master (
PATCH /settings/companionwithtab: 'master') to persist the master palette inmaster.branding.*. - Clicking Apply to All 3 Hubs immediately syncs the input fields and live previews in the current browser session without saving.
- Clicking Save & Cascade All (
PATCH /settings/companionwithtab: 'master', apply_to_all: 1) persists the master palette and propagates the primary and accent colors across:- Companion (wp-admin):
companion.branding.primary_color&companion.branding.accent_color - Client Reports:
reports.branding.primary_color&reports.branding.accent_color - Plugin Notification Email:
email.branding.header_bg&email.branding.accent_color
- Companion (wp-admin):
- Each individual hub still retains its own color picker inputs for fine-tuning overrides when desired.
Tabs
A client-side segmented control (activeTab Alpine state) switches between the three panels; ?tab=companion|reports|email on the index route (and on every redirect after saving/resetting a given tab) makes sure a link or page reload lands back on the right one.
- Companion (wp-admin) is the original branding surface; configuring company identity, custom colors (with companion header two-tone contrast), logo, and admin menu preferences.
- Client Reports writes to
reports.branding.*settings keys, falling back to tab 1’s shared agency identity (company name, logo, support email/URL) for any field left blank. Colors default to Clockwork Control’s own purple/green (#2D2062/#7EFF83) until customized. This tab is only meaningfully exercised when theclient_reportsmodule is enabled (ModuleStateResolver::isEnabled('client_reports')) — its tab button shows a small “Disabled” badge instead of the enabled/disabled status dot when the module is off, though the form itself doesn’t block saving. - Plugin Notification Email writes to
email.branding.*settings keys with the same shared-defaults fallback, plus a “Send test email” action that fires a realSiteVulnerabilityReportMail— populated with two fabricated demo plugin vulnerabilities, not live site data — to an operator-supplied address, so the styling can be checked in an actual inbox before a client ever sees it.
How it’s stored and pushed
App\Services\Companion\CompanionBrandingManagerpersists tab 1’s configuration toApp\Support\Settings(key prefixcompanion.branding.*), merged with sane Clockwork Control defaults (DEFAULT_COMPANY_NAME,DEFAULT_PLUGIN_NAME, etc.) whenever a field is unset. Tabs 2 and 3 have their own prefixes (reports.branding.*,email.branding.*) viagetReportsBranding()/saveReportsBranding()/resetReports()andgetEmailBranding()/saveEmailBranding()/resetEmail(). Master palette is stored inmaster.branding.*.- Saving tab 1 triggers
ClockworkCompanionClient::pushBranding(), an HMAC-signed REST call to each site’sPOST /wp-json/clockwork/v1/branding— the same signed-request mechanism used by every other Companion write endpoint. The remote plugin stores the payload inwp_options['clockwork_companion_branding']and filters its own plugin header, admin menu, and support links from it on every page load — no outbound requests from the WordPress side. - Only tab 1 (Companion/wp-admin) is pushed to the fleet. Client Reports and Plugin Notification Email branding render entirely inside Clockwork Control (report output, outbound emails) and never reach the remote plugin — there’s no “sync fleet” concept for them. They take effect the next time a Client Report is generated or a vulnerability email is sent.
- Push timing (tab 1 only):
- Checking “Push to all connected sites upon saving” (default on) when saving the form dispatches
PushCompanionBrandingJob(queued, fleet-wide). - The dedicated “Sync Fleet Now” button in the page header launches
clockwork:push-companion-brandingin the background (BackgroundArtisan) and redirects immediately. php artisan clockwork:push-companion-branding [--site=<id-or-domain>]does the same from the CLI, scoped to one site or the whole fleet.- Every Companion install or update (
CompanionInstaller/PressableCompanionInstaller::installOrUpdate()) also pushes the current branding to that one site inline, best-effort — so a freshly-installed or re-installed Companion never briefly shows default Clockwork Control branding before the next fleet sync.
- Checking “Push to all connected sites upon saving” (default on) when saving the form dispatches
- Only sites with
companion_installed = trueand a non-emptycompanion_secretare eligible; everything else is silently skipped (not an error) since there’s no signed channel to reach them yet.
Vulnerability emails use the Plugin Notification Email tab
SiteVulnerabilityReportMail and its Blade view (emails/site-vulnerability-report.blade.php) pull header background, accent color, badge text, sender name, and reply-to from CompanionBrandingManager::getEmailBranding() instead of hardcoded styles — so the CVE alert emails a client receives carry the agency’s own branding once this tab is configured (or its shared-default fallbacks otherwise).
Client Reports branding
ClientReportCompiler and the report view read CompanionBrandingManager::getReportsBranding() for primary/accent colors and footer text on generated Client Reports.
Logo upload & storage management
POST /settings/companion/logoacceptspng,jpg,jpeg, orwebpup to 2MB (SVG files are intentionally rejected to mitigate stored script injection risks). Stored on thepublicdisk underbranding/and referenced by its public URL inlogo_url.- Uploading a replacement logo, entering an external logo URL, or resetting branding cleanly deletes previously uploaded logo files from disk storage.
- The uploaded logo is shared across all three tabs — Client Reports and email branding fall back to it when they don’t specify their own.
Live preview
The right-hand column of the Companion (wp-admin) tab is an Alpine.js mockup of the WordPress sidebar menu, plugins list row, and Companion dashboard header, updating live as the form fields change — nothing here calls out to a real site; it’s local-only, for visualizing the effect before saving. A dedicated preview route (/settings/companion/preview) also renders the full isolated wp-admin chrome mockup in a separate window/tab.
Section 6: Emergency Access & The Unlock Hub (Gatekeeper & LLAR)
When an IP address or technician is locked out of a site due to failed login attempts or false positives, you don’t need SSH access or database credentials to clear it. The Unlock Console (Clockwork → Unlock in wp-admin on your agency hub) fires an authenticated HMAC-SHA256 signed DELETE /wp-json/clockwork/v1/lockouts request directly to the target site’s Companion plugin to immediately flush lockouts.
This endpoint automatically flushes both native Gatekeeper lockouts (wp_clockwork_lockouts) and legacy Limit Login Attempts Reloaded (LLAR) tables/options simultaneously. With the fleet transitioned away from LLAR (eliminating LLAR’s third-party ads, upsell promos, and client-facing scare-tactic widgets) to our native white-labeled Gatekeeper engine, the Unlock Hub provides seamless, identical unlocking across all sites regardless of which engine is active.
How Hub Detection & Client Isolation Works
- Configured Hub Domain (
unlock_hub_domain): Configured on/settings/companion(default:clockworkwd.com), this sets your agency’s designated primary management host. - HMAC Wire Sync: The
unlock_hub_domainvalue is included in the JSON branding payload pushed to all connected sites during fleet sync (ClockworkCompanionClient::pushBranding()) and stored inwp_options['clockwork_companion_branding']. - Subdomain Hub Matching: Subdomain hubs (e.g.,
support.customagency.com) permit staff email addresses from the parent domain (*@customagency.com) as well as the subdomain itself. - Client Isolation & Fail-Closed 403s: Client sites never show the Unlock submenu or navigation tab. Direct URL navigation to
admin.php?page=clockwork-unlockimmediately aborts with an HTTP 403wp_diebefore layout rendering. Unauthorized AJAX calls (clockwork_companion_unlock_target) returnwp_send_json_error(..., 403). - Legacy Fallback: Defining
define('CLOCKWORK_UNLOCK_HUB', true);inwp-config.phpremains supported as an explicit manual override.
Permanent White-Label Lockdown
Local wp-admin branding customization (admin.php?page=clockwork-branding) was permanently removed and returns HTTP 403 Forbidden. All branding is now strictly managed centrally in Clockwork Control at /settings/companion and pushed downstream over HMAC-signed REST. Clients cannot tamper with, override, or revert agency branding locally from their WordPress admin dashboards.
Routes
GET /settings/companion(settings.companion.index) — the settings + preview page; accepts?tab=companion|reports|email.GET /settings/companion/preview(settings.companion.preview) — isolated full-page endpoint rendering the live WordPress admin chrome preview.PATCH|POST /settings/companion(settings.companion.update) — save branding for whichever tab was submitted (tab=companion|reports|email|master), includingunlock_hub_domain, optionally cascading colors or queuing a fleet push.POST /settings/companion/logo(settings.companion.logo) — upload a brand logo (png, jpg, jpeg, webpup to 2MB).POST /settings/companion/sync(settings.companion.sync) — push current Companion (wp-admin) branding to the whole fleet now.POST /settings/companion/reset(settings.companion.reset) — revert Companion (wp-admin) tab fields back to Clockwork Control defaults and purge stored logo.POST /settings/companion/reset-reports(settings.companion.reset-reports) — revert Client Reports branding to shared defaults.POST /settings/companion/reset-email(settings.companion.reset-email) — revert Plugin Notification Email branding to defaults.POST /settings/companion/test-email(settings.companion.test-email) — send a real test vulnerability-alert email (fabricated demo CVE data) to an operator-supplied address, styled with the current Plugin Notification Email branding.
