EN · ORIGINAL REPOSITORY DOCUMENT
WordPress administration adapter
Original English text. Commands and evidence apply to the revision and environment stated in the document.
product/licensing/wordpress-admin/README.md
On this page
Original WordPress entitlement admin prototype
This standalone original plugin binds the existing entitlement client and fixed HTTP transport to explicit WordPress administrator actions. It is separate from the inherited paid cache, the original free cache and upstream licensing APIs. An original premium entitlement does not grant upstream software rights. There is no checkout, payment verification, customer account, license recovery, automatic installer or frontend/cache integration.
Operator configuration
Keep this directory alongside the original client.php and transport.php, for
example beneath an installed original-entitlement/ plugin directory. Activate
wordpress-admin/plugin.php. The operator must define a trusted configuration in
wp-config.php or an equivalent private deployment configuration:
define('ORIGINAL_ENTITLEMENT_ADMIN_CONFIG', [
'service_origin' => 'https://licenses.operator.example',
'public_keys' => ['fixture-v1' => $operatorPublicVerificationPem],
'cache_directory' => '/private/operator/entitlement-cache',
]);
The service address and verification keys never come from a posted field. The public PEM must come from the trusted operator, not the licensing HTTP response. The cache directory must already exist, be writable, and resolve outside both WordPress’s installation and content roots. Use a genuinely private filesystem location: the plugin cannot detect every additional directory a server publishes. The existing entitlement client locks and verifies local files, with bounded signed deadlines and denial handling. No private signing keys belong in WordPress.
The installed origin is derived from network_home_url() for multisite and
home_url() for single-site and normalized to an HTTPS
origin. Domain/subdomain/port changes fail closed against the saved identity.
Paths are not independent activations; network installations share one network
identity and require manage_network_options. Single-site installations require
manage_options. Domain ownership must first be independently verified and
approved on the backend by an operator. There is no automatic site migration.
Explicit workflow
- Open Settings → Original entitlement (network Settings for multisite). GET renders only locally verified status and key fingerprints. No HTTP occurs.
- Paste an original license and Save license. Only this action stores the credential and a randomly generated 256-bit installation key. Re-saving the same license preserves the installation key. Credentials are held in a single WordPress option (autoload disabled) or network site option and read back to confirm persistence. They are not rendered in HTML or sent as URL parameters. This is database credential storage, not an encrypted secret vault; protect database backups and any object-cache copies under normal operator controls.
- Activate installation explicitly posts to
/activate, then verifies and persists/entitlement. Backend origin approvals, ownership and site limits remain authoritative. Refresh verified status calls/entitlementonly. - Deactivate installation posts
/deactivate, then obtains a signed inactive denial. Backend ownership remains bound. A server outage cannot create or extend a grant. If refresh fails after a state change, existing client deadlines remain bounded; retry explicitly to observe the signed denial. - Check original update metadata validates the existing client’s server response. Only version and SHA-256 are stored/displayed; the bearer download token is discarded. Nothing downloads, installs, or hooks a WordPress updater.
Every mutation checks POST, capability and a WordPress nonce before constructing
configuration, storage or transport. The binding repeats this gate for direct
callers. No init, frontend, cron, REST, cache read/write or automatic refresh hook
is registered. A failed action redirects with a generic result; posted keys and
raw transport errors are not placed in the redirect or notice.
Changing the license generates another installation identity. Deactivate the old license first when freeing its slot is intended. Operator key replacement, installation recovery, checkout/customer support, uninstall cleanup and an actual premium product installer remain deliberate future work, not claimed workflows.
Focused tests and fixture-only HTTP
php -n product/licensing/wordpress-admin/test.php
The test uses WordPress API doubles and a real ephemeral RSA signer. It covers permission, nonce and GET rejection before effects, failed option writes, installation persistence, redacted/local-only status, explicit activate and signed refresh, sanitized update metadata, signed deactivation, installed-origin changes, multisite capability and rejection of an HTTP service/web-root cache. Boot checks allow only the admin menu and admin-post hooks and verify zero transport calls. No keys or fixture credentials are committed.
For a separate CLI integration fixture only, ORIGINAL_ENTITLEMENT_ADMIN_FIXTURE
must be exactly true and WP_CLI must be true. A trusted config may then set
fixture_loopback => true, an exact http://127.0.0.1:PORT service origin, and a
fixture_site HTTPS origin preapproved on the synthetic backend. This exception
is unavailable to web/admin requests. It allows the parent integration runner to
exercise the actual local backend without modifying TLS or network settings.
Use only an ephemeral original ZIP and temporary credentials. The Python service
is a reference fixture; the API-compatible Go backend is the runnable service documented in ../go/README.md.
Real WordPress ↔ Go fixture validation
real-wordpress-go.php is a bounded WP-CLI test against an actual local Go service.
It requires ORIGINAL_ADMIN_DISPOSABLE_FIXTURE=1, the fixture-admin superadmin,
and ORIGINAL_ADMIN_FIXTURE_CONFIG pointing to a private
/dev/shm/original-admin-fixture/config.json. The operator handoff contains only
synthetic license_key, trusted public_pem, and exact numeric-loopback
service_origin. The backend must already approve
https://original-admin.fixture.test for that license and expose a synthetic
original ZIP. Prepare the sibling client.php, transport.php, binding and
cache/ directory readable/writable by the WordPress fixture UID. Do not execute
on a real site: this stores the two original-admin network option keys.
Run the flow, then read its persisted denial in a separate WordPress process:
wp eval-file /dev/shm/original-admin-fixture/wordpress-admin/real-wordpress-go.php --user=fixture-admin --allow-root
wp eval-file /dev/shm/original-admin-fixture/wordpress-admin/real-wordpress-go.php verify-denial --user=fixture-admin --allow-root
The actual disposable multisite run passed on WordPress 6.8.3 / PHP 8.3.28
using UID 33 and the Go service on shared-container loopback. It verified real
WordPress capability and nonce rejection before effects, GET mutation rejection,
identity save/stable resave, activation, RSA entitlement refresh, local GET-mode
status with zero HTTP and redacted keys, explicit check, verified update metadata
without bearer persistence, and deactivation. Exactly six explicit backend calls
occurred: /activate, /entitlement, /entitlement, /updates, /deactivate,
/entitlement. A second WP process verified the persisted signed inactive denial
with zero backend calls. No inherited/free cache configuration, plugin, drop-in,
SQL schema or paid license API changed. Root integration owns fixture cleanup.
This is real WordPress API/Go HTTP evidence, not a browser-admin-page or payment
checkout test. Fixture credentials and private keys are excluded from the repository.
For the actual paid-plugin adapter and explicit bounded download/updater/optional refresh interfaces, see README.paid.md.