Library Filters
This page documents the filters that register library sources and authorize pulls from a shared library.
The library's two permission gates live with the other editor gates: unblock/library/can_use and unblock/library/can_manage.
| Filter | Description |
|---|---|
unblock/library/sources | Register a library source in code |
unblock/library/share_access | Authorize one pull from a shared library |
library/sources
Register, modify or remove library sources. Runs once per request, after the core seed and the stored site registry.
| Parameter | Type | Description |
|---|---|---|
$sources | array | Unblock\Library\Source[] keyed by source id |
Returns: the same shape. The array is re-keyed from each entry's own id. A plain array entry is accepted too and built into a site-scoped Source; anything that fails to build is dropped without an error.
Example: Register a Vendor Library
add_filter( 'unblock/library/sources', function( array $sources ): array {
$sources['acme'] = new \Unblock\Library\Source(
id: 'acme',
origin: \Unblock\Library\Origin::Vendor,
scope: \Unblock\Library\Scope::Site,
label: 'Acme Blocks',
url: 'https://patterns.acme.com/library',
interval: 'day',
);
return $sources;
} );
Example: Pin a Trusted Signing Key
This is the only place a vendor origin can be granted the trusted tier. Without a pinned key, its payloads are sanitized before they are cached.
add_filter( 'unblock/library/sources', function( array $sources ): array {
if ( isset( $sources['acme'] ) ) {
$sources['acme'] = $sources['acme']->with_public_key( 'paste-the-vendor-public-key' );
}
return $sources;
} );
Use with_public_keys( array $keys ) to accept an old and a new key during a rotation.
Example: Hide the Official Catalog
add_filter( 'unblock/library/sources', function( array $sources ): array {
unset( $sources['unblock'] );
return $sources;
} );
Trying to pin trust from stored data. A source saved in the unbk_library_sources option is forced site-scoped and has its public_keys stripped on read, and no stored entry can claim the core origin. Pinning works only through this filter or the UNBK_LIBRARY_TRUSTED_KEYS constant. Anywhere else it is ignored without an error, and the source stays in the sanitized tier.
Trust tiers
A library is either trusted or sanitized. Pinning a public key, either through unblock/library/sources above or the UNBK_LIBRARY_TRUSTED_KEYS constant, is what moves one to the trusted tier.
A catalog is trusted only when all four hold. Anything else fails closed to sanitized:
- Its index carries an integer
versionat or above the last one seen (anti-rollback) - Its
expirestimestamp is in the future (anti-freeze) X-Unblock-Signatureis a valid detached Ed25519 signature over the raw index bytes, against a pinned key- Every fetched document matches the
sha256recorded for it
What the tier changes:
| Trusted | Sanitized | |
|---|---|---|
| Payload cached | Raw | Passed through Library\Sanitizer first |
| Executable JS in patterns | Kept, gated on unfiltered_html, never auto-executed | Stripped |
| Previews | Sandboxed iframe | Sandboxed iframe |
Sanitizing happens before the write to cache, not on read. When a library's trust flips to true, the documents cached at the sanitized tier are dropped, so the next read pulls them raw.
The official catalog ships with its key already pinned, so it is trusted out of the box. Everything else is sanitized until you pin it.
library/share_access
Authorize one pull from a library this site shares. Runs on every request to the sharing routes, after the token has been matched.
Return false to refuse, true to allow. This is where a paid or metered library plugs its own entitlement check.
| Parameter | Type | Description |
|---|---|---|
$verdict | bool | The built-in verdict: an enabled key holds the token and that key opens the library |
$context | array | Request context |
$context keys:
| Key | Type | Description |
|---|---|---|
library | string | Id of the requested library |
key | string | Id of the matched access key, empty when no key matched |
token | string | The presented access token |
site | string | The consumer's site URL, from X-Unblock-Site |
method | string | HTTP method of the request |
file | string | Requested file, for single-file pulls |
files | array | Requested files, for batch pulls |
Example: Refuse Sites Whose Subscription Lapsed
add_filter( 'unblock/library/share_access', function( $verdict, $context ) {
if ( ! $verdict ) {
return $verdict;
}
return acme_subscription_is_active( $context['site'] );
}, 10, 2 );
Example: Open One Library to Everyone
add_filter( 'unblock/library/share_access', function( $verdict, $context ) {
if ( 'free-starters' === $context['library'] ) {
return true;
}
return $verdict;
}, 10, 2 );
This filter is the last word on access. Returning true unconditionally serves every library on the site to anyone who finds the share URL. The token match is already done by the time it runs.
A refused pull answers exactly like an unknown library, so library ids cannot be probed. The precise 401 / 403 is only returned on the discovery route the consumer reconnects through.
Next steps
- System filters — the library's
can_useandcan_managegates - Share libraries — the UI side of the same machinery
- Constants — pin a connected library from
wp-config.php