Docs / Staging Guard

Staging Guard

Stops staging copies from emailing real people or getting indexed.

Hooks

Every default, limit and message has a filter, and every change fires an action.

axle_staging_guard_environmentFilter
( array $environment )

Change the detected environment, see below

axle_staging_guard_production_hostsFilter
( string[] $hosts )

The live site’s domains. Default from AXLE_STAGING_GUARD_PRODUCTION_HOSTS

axle_staging_guard_mail_policyFilter
( array $policy, string $environment )

The final email handling: mode, redirect_to, allowlist. For example redirect on staging but block on development. A redirect without a valid address still blocks

axle_staging_guard_allow_emailFilter
( bool $allow, array $atts )

Let one email out untouched and unlogged, such as monitoring alerts to your own team

axle_staging_guard_allowlistFilter
( string[] $allowlist )

Addresses and @domains that still get email

axle_staging_guard_redirect_subjectFilter
( string $subject, string[] $stopped, array $atts )

Subject of a redirected email. Default [STAGING → original recipients] Subject

axle_staging_guard_noindexFilter
( bool $noindex )

Whether staging copies are hidden from search engines

axle_staging_guard_robots_txtFilter
( string $output )

The robots.txt a staging copy serves

axle_staging_guard_coloursFilter
( array $colours )

Admin bar colour per environment type. Anything but a hex colour falls back to the default

axle_staging_guard_environment_labelFilter
( string $label, string $type )

The environment name in the admin bar and on the screens, such as "UAT"

axle_staging_guard_log_sizeFilter
( int $size )

Stopped emails the log keeps at most. Default 1000

axle_staging_guard_http_modeFilter
( string $mode, string $environment )

allow, log or block. An unknown value blocks

axle_staging_guard_http_allowed_hostsFilter
( string[] $hosts )

Hosts that always go through. *.example.com covers subdomains

axle_staging_guard_http_blocked_hostsFilter
( string[] $hosts )

Hosts that are always blocked, even in allow all and log only

axle_staging_guard_http_default_hostsFilter
( string[] $hosts )

The built-in always-allowed hosts: WordPress.org and this site. Removing WordPress.org stops core updates on this copy

axle_staging_guard_http_decisionFilter
( array $decision, string $url, array $args )

The decision for one request: action (allow, log, block), reason, host, path, method. Never runs on the live site. Do not store $url, it may hold a key

axle_staging_guard_http_error_messageFilter
( string $message, array $entry )

The message of the axle_staging_guard_http_blocked error

axle_staging_guard_http_log_sizeFilter
( int $size )

Requests the list keeps at most. Default 1000

axle_staging_guard_log_daysFilter
( int $days )

Days a stopped email stays in the log

axle_staging_guard_capabilityFilter
( string $capability )

Who may see and change Axle Staging Guard. Default manage_options, or manage_network_options on multisite

axle_staging_guard_mail_stoppedAction
( array $entry, array $atts )

Fires when an email is blocked or redirected. $entry has id, to, subject, action, delivered and body

axle_staging_guard_http_blockedAction
( array $entry )

A request was blocked. $entry has id, method, host, path, action, reason and caller

axle_staging_guard_http_loggedAction
( array $entry )

A request went through in log only mode and was recorded

axle_staging_guard_production_lockedAction
( string $domain )

The production lock was set on this domain

axle_staging_guard_production_unlockedAction

The production lock was removed

WP-CLI

wp axle-staging-guard status [--format=json]       # environment, how it was detected, what is guarded
wp axle-staging-guard lock-production              # mark the current domain as the live site
wp axle-staging-guard unlock-production
wp axle-staging-guard log [--format=table|csv|json|count]
wp axle-staging-guard test-email <to>              # prints blocked, redirected, partly_blocked or sent
wp axle-staging-guard http-log [--format=table|csv|json|count]
wp axle-staging-guard test-url <url> [--method=GET] [--format=json]   # prints allowed, logged or blocked, and why

Abilities

What AI agents can do through the WordPress Abilities API and MCP, with the same permissions as the screen.

axle-staging-guard/get-environment

Read-only. Production, staging, development or local, how that was decided, and what happens to email, outgoing requests and search engines. An agent should ask this before sending email, calling an outside service, importing data or changing settings

Who can run it: edit_posts. Where redirected email goes is only shown with the Axle Staging Guard capability

axle-staging-guard/get-mail-log

Read-only. Stopped email, newest first. Input: limit

Who can run it: the Axle Staging Guard capability

axle-staging-guard/get-http-log

Read-only. Stopped and recorded outgoing requests, most recent first: method, host, path, caller and count. Input: limit

Who can run it: the Axle Staging Guard capability

axle-staging-guard/test-url

Read-only. Says what would happen to a request to url: allowed, logged or blocked, and why. Sends and records nothing

Who can run it: the Axle Staging Guard capability

axle-staging-guard/send-test-email

Sends a test email to to and says what happened to it. On the live site it really sends

Who can run it: the Axle Staging Guard capability

Constants

Set these in wp-config.php.

AXLE_STAGING_GUARD_MAIL_MODE

block, redirect, allow | Overrides the email setting. A redirect without a valid address falls back to block

AXLE_STAGING_GUARD_REDIRECT_TO

an email address | Where redirected email goes

AXLE_STAGING_GUARD_ALLOWLIST

addresses and @domains, comma separated | Recipients who always get email

AXLE_STAGING_GUARD_HTTP_MODE

allow, log, block | Overrides the outgoing request setting. An unknown value falls back to block

AXLE_STAGING_GUARD_HTTP_ALLOWED_HOSTS

hosts, comma or space separated, *.example.com for subdomains | Hosts that always go through, on top of the built-in ones

AXLE_STAGING_GUARD_HTTP_BLOCKED_HOSTS

hosts, same format | Hosts that are always blocked, in every mode

AXLE_STAGING_GUARD_PRODUCTION_HOSTS

domains, comma separated, with a port if they need one | The live site’s domains. Decides production or staging before the lock

AXLE_STAGING_GUARD_KEEP_BODIES

true, false | Whether the log keeps message bodies

AXLE_STAGING_GUARD_NOINDEX

true, false | Whether staging copies are hidden from search engines

AXLE_STAGING_GUARD_LOG_DAYS

a number | Days a stopped email or request stays in its list. Default 7

The full reference, with the PHP API and examples, is in REFERENCE.md for version 2.1.0