Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d7abced
Secrets API: Require `WP_SECRETS_KEY`.
ericmann Oct 30, 2026
891a722
Secrets API: Report a broken or unreachable secrets backend in Site H…
mpeshev Oct 25, 2026
47bf423
Secrets API: Do not recommend `WP_SECRETS_KEY` when a drop-in replace…
mpeshev Oct 25, 2026
4b1da48
Secrets API: Stop Site Health advice that locks stored secrets.
mpeshev Oct 25, 2026
1b7c9d1
Secrets API: Report a keyring's own error when it cannot unlock the s…
ericmann Oct 30, 2026
67e1330
Merge branch 'trunk' into secrets-require-key
peterwilsoncc Nov 4, 2026
fb1791f
Merge trunk into secrets-require-key.
ericmann Nov 6, 2026
78107b2
Secrets API: Translate the key source, and stop Site Health parsing it.
ericmann Nov 6, 2026
6af3177
Secrets API: Add `wp_is_secrets_api_available()`.
ericmann Nov 6, 2026
684099f
Merge remote-tracking branch 'origin/secrets-require-key' into secret…
ericmann Nov 6, 2026
c5d0e43
Merge secrets-require-key into secrets-site-health-takeover.
ericmann Nov 6, 2026
e754f6b
Merge trunk into secrets-require-key
ericmann Nov 10, 2026
8f2d25a
Secrets API: Reject a whitespace-only key and mark up constants in Si…
ericmann Nov 10, 2026
409a23a
Secrets API: Report the API as unavailable when the key cannot unwrap…
ericmann Nov 10, 2026
6e7aa07
Merge secrets-require-key into secrets-site-health-takeover
ericmann Nov 10, 2026
cbdcfc1
Secrets API: Mark up constants and file names in the Site Health resu…
ericmann Nov 10, 2026
504a0d0
Secrets API: Move the Site Health checks into `WP_Site_Health` and `W…
ericmann Nov 10, 2026
a388a97
Merge trunk into secrets-site-health-integrate
ericmann Nov 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions src/wp-admin/includes/class-wp-debug-data.php
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public static function debug_data() {
'wp-server' => self::get_wp_server(),
'wp-database' => self::get_wp_database(),
'wp-constants' => self::get_wp_constants(),
'wp-secrets-api' => self::get_wp_secrets_api(),
'wp-filesystem' => self::get_wp_filesystem(),
);

Expand Down Expand Up @@ -335,6 +336,80 @@ private static function get_wp_dropins(): array {
);
}

/**
* Gets the Secrets API section of the debug data.
*
* Counts and class names only – no secret values, and no fingerprints. Network
* scope figures are included only for a super admin on a multisite install.
*
* @since 7.2.0
*
* @return array<string, string|array> The Secrets API debug data.
*/
private static function get_wp_secrets_api(): array {
$key_manager = _wp_secrets_get_key_manager();
$provider = _wp_secrets_get_provider();

// A provider from a secrets.php drop-in protects secrets with its own keys, not the keyring.
$uses_keyring = $provider instanceof WP_Secrets_Libsodium_Provider || $provider instanceof WP_Secrets_Broken_Provider;

$fields = array(
'dropin_active' => array(
'label' => __( 'Drop-in active' ),
'value' => wp_using_secrets_dropin() ? __( 'Yes' ) : __( 'No' ),

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe for another issue, but most of the core methods provide an untranslated 'debug' key, which is used inside WP_Debug_Data::format() when copying debug info for support.

Suggested change
'value' => wp_using_secrets_dropin() ? __( 'Yes' ) : __( 'No' ),
'value' => wp_using_secrets_dropin() ? __( 'Yes' ) : __( 'No' ),
'debug' => wp_using_secrets_dropin(),

),
'provider_class' => array(
'label' => __( 'Provider class' ),
'value' => get_class( $provider ),
),
'protected_by' => array(
'label' => __( 'Secrets protected by' ),
'value' => $provider->get_label(),
),
'protection_at' => array(
'label' => __( 'Encryption boundary' ),
'value' => WP_Secrets_Provider::BOUNDARY_WORDPRESS === $provider->get_protection_boundary()
? __( 'WordPress' )
: __( 'The provider (outside WordPress)' ),
),
'writable' => array(
'label' => __( 'Accepts writes' ),
'value' => $provider->is_writable() ? __( 'Yes' ) : __( 'No' ),
),
'keyring_class' => array(
'label' => __( 'Keyring class' ),
'value' => $uses_keyring ? get_class( $key_manager->get_keyring() ) : __( 'Not used by the provider' ),
),
'key_source' => array(
'label' => __( 'Key source' ),
'value' => $uses_keyring ? $key_manager->get_keyring()->get_key_source() : __( 'Not used by the provider' ),
),
'record_version' => array(
'label' => __( 'Record format version' ),
'value' => (string) WP_SECRETS_RECORD_VERSION,
),
);

$site_secrets = wp_list_secrets();
$fields['site_secret_count'] = array(
'label' => __( 'Site secrets' ),
'value' => is_wp_error( $site_secrets ) ? __( 'Unavailable' ) : (string) count( $site_secrets ),
);

if ( is_multisite() && is_super_admin() ) {
$network_secrets = wp_list_network_secrets();
$fields['network_secret_count'] = array(
'label' => __( 'Network secrets' ),
'value' => is_wp_error( $network_secrets ) ? __( 'Unavailable' ) : (string) count( $network_secrets ),
);
}

return array(
'label' => __( 'Secrets API' ),
'fields' => $fields,
);
}

/**
* Gets the WordPress server section of the debug data.
*
Expand Down
Loading
Loading