[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/ -> secrets.php (summary)

Secrets API

File Size: 805 lines (26 kb)
Included or required:0 times
Referenced: 0 times
Includes or requires: 0 files

Defines 24 functions

  wp_secrets_memzero()
  wp_secrets_validate_name()
  _wp_secrets_get_store()
  _wp_secrets_get_key_manager()
  wp_using_secrets_dropin()
  wp_set_secret()
  wp_import_option_as_secret()
  wp_get_secret()
  wp_delete_secret()
  wp_retire_secret_version()
  wp_list_secrets()
  wp_set_network_secret()
  wp_get_network_secret()
  wp_delete_network_secret()
  wp_retire_network_secret_version()
  wp_list_network_secrets()
  _wp_secrets_get_provider()
  wp_secrets_provider_is_writable()
  wp_secrets_provider_label()
  _wp_secrets_set()
  _wp_secrets_get()
  _wp_secrets_delete()
  _wp_secrets_retire()
  _wp_secrets_list()

Functions
Functions that are not part of a class:

wp_secrets_memzero( &$value )   X-Ref
Best-effort clearing of a plaintext value from memory.

This is hygiene, not a guarantee. PHP strings are reference-counted and often
shared by copy-on-write; sodium_memzero() can only scrub the bytes of a string it
exclusively owns; if another reference to the same value exists elsewhere,
PHP forces a private copy before zeroing rather than corrupting the shared buffer,
and that other reference is left completely untouched. Call this on every plaintext
local as soon as it is no longer needed, and do not keep incidental copies around.

Under sodium_compat, core's documented fallback when the libsodium extension is
unavailable, this scrubs nothing. A userland polyfill cannot reach a PHP string's
underlying memory at all. Overwriting the local binding is the only thing available
in that case, and it removes the live reference from this scope without touching
the memory the string used to occupy.

param: string $value The value to clear, by reference.

wp_secrets_validate_name( string $name )   X-Ref
Validates a secret's name.

Names take the form 'plugin-slug/secret-name': lowercase alphanumerics,
hyphens, and underscores in each segment, exactly one '/' separating them,
and no segment starting or ending with a hyphen or underscore.

Namespacing is a matter of organization, not security. It groups secrets by owner
so that listings and admin screens can be sensible. It confers no isolation: any
plugin that can run PHP can read any secret, namespaced or not.

An unnamespaced name ('secret-name', no '/') is accepted, but reports through
_doing_it_wrong(). It exists for one reason: code written against the earlier
prototype used a flat keyspace, and refusing those names outright would mean
every such call site has to be rewritten before it can be ported at all.
Accepting them keeps that migration incremental. Nothing else should use one.
Two plugins that both choose 'api-key' collide silently, which is a real problem
even though it is not a security one.

return: true|WP_Error True if $name is usable, including the unnamespaced form.
param: string $name Candidate secret name.

_wp_secrets_get_store()   X-Ref
Returns the active secret store.

No filter is applied here, or anywhere on the retrieval path. See
docs/spec/extension-points.md. A secrets.php drop-in overrides the store by setting
$GLOBALS['wp_secrets_store'] to an instance before this is first called, and
that global is checked here directly, not through a hook.

If the global was set but is not a valid WP_Secrets_Store, or if the drop-in
itself failed to load cleanly, this returns WP_Secrets_Broken_Store rather than
silently using the default: the drop-in's presence signals the operator wants
storage other than local options, and falling back to local options anyway would
be the exact silent downgrade this API refuses to make.

return: WP_Secrets_Store

_wp_secrets_get_key_manager()   X-Ref
Returns the active key manager.

A secrets.php drop-in overrides the keyring by setting
$GLOBALS['wp_secrets_keyring'] to an instance before this is first called. See
_wp_secrets_get_store() for why an invalid override or a failed drop-in load
fails closed (WP_Secrets_Broken_Keyring) rather than falling back to the default.

return: WP_Secrets_Key_Manager

wp_using_secrets_dropin()   X-Ref
Whether a secrets.php drop-in is present and was loaded.

True whether or not the drop-in successfully provided a store or keyring
override. It reports presence rather than health; Site Health reports separately
on whether a loaded drop-in is actually working.

return: bool

wp_set_secret( string $name, $value )   X-Ref
Encrypts and stores a secret.

Encryption is unconditional: there is no plaintext mode and no constant to
disable it. No capability check is applied here, because this must be callable from
cron, REST, and front-end requests where no user is logged in. Enforce
capabilities at the operator boundary (CLI, an admin screen) instead.

return: true|WP_Error
param: string $name  The secret's namespaced name ('plugin-slug/secret-name').
param: string $value The plaintext value to store.

wp_import_option_as_secret( string $option, string $name )   X-Ref
Imports an existing option's value as a secret.

For an explicit migration, "on their own explicit upgrade schedule,"
in the proposal's words, because "core cannot reliably tell which options are
credentials, and guessing would break sites." The source option is left
untouched: this reads it, it does not move or delete it.

The imported secret is flagged needs_rotation, unconditionally. A credential that
sat in a plain option has already been through however many backups and
replication paths that option went through; re-encrypting it here does not undo
that, and the flag exists so an operator (or a future admin screen) knows to
actually rotate the value rather than considering the migration finished.

return: true|WP_Error
param: string $option The existing option's name.
param: string $name   The secret's namespaced name to store it under.

wp_get_secret( string $name, string $version = WP_Secret_Version::CURRENT )   X-Ref
Retrieves a secret.

Three states, never collapsed: a WP_Secret if it exists and decrypts, null if it
does not exist, WP_Error if it exists but could not be retrieved. No capability
check is applied here. See wp_set_secret().

return: WP_Secret|null|WP_Error
param: string $name    The secret's namespaced name.
param: string $version A WP_Secret_Version constant. Default WP_Secret_Version::CURRENT.

wp_delete_secret( string $name )   X-Ref
Deletes a secret.

return: true|WP_Error
param: string $name The secret's namespaced name.

wp_retire_secret_version( string $name )   X-Ref
Clears a secret's previous version, retiring it for good.

An explicit operator action, with no timers and no cron. Calling this on a secret
that has never been rotated, or that does not exist, is a successful no-op:
the previous slot is already absent either way.

Beyond the API surface the proposal names.

return: true|WP_Error
param: string $name The secret's namespaced name.

wp_list_secrets( string $namespace = '' )   X-Ref
Lists secrets by name and metadata. Never a value.

Beyond the API surface the proposal names, and justified by its statement that
the hooks and accessors a future admin screen needs are in scope now, even though
the screen itself is not.

return: array|WP_Error Array of associative arrays, each with keys 'name',
param: string $namespace Only secrets whose name starts with "{$namespace}/" are

wp_set_network_secret( string $name, $value )   X-Ref
Encrypts and stores a network-scope secret.

Site secrets and network secrets are separate functions with separate
capabilities and separate storage prefixes, with no implicit fallback from one
scope to the other. The proposal describes network scope but does not name these
functions; these are this implementation's names for them.

return: true|WP_Error
param: string $name  The secret's namespaced name.
param: string $value The plaintext value to store.

wp_get_network_secret( string $name, string $version = WP_Secret_Version::CURRENT )   X-Ref
Retrieves a network-scope secret.

return: WP_Secret|null|WP_Error
param: string $name    The secret's namespaced name.
param: string $version A WP_Secret_Version constant. Default WP_Secret_Version::CURRENT.

wp_delete_network_secret( string $name )   X-Ref
Deletes a network-scope secret.

return: true|WP_Error
param: string $name The secret's namespaced name.

wp_retire_network_secret_version( string $name )   X-Ref
Clears a network-scope secret's previous version.

return: true|WP_Error
param: string $name The secret's namespaced name.

wp_list_network_secrets( string $namespace = '' )   X-Ref
Lists network-scope secrets by name and metadata. Never a value.

return: array|WP_Error
param: string $namespace Only secrets whose name starts with "{$namespace}/" are

_wp_secrets_get_provider()   X-Ref
Returns the active provider.

The provider is whatever is responsible for holding, protecting, and answering for
this site's secrets.

A secrets.php drop-in overrides it by setting $GLOBALS['wp_secrets_provider'] to
an instance before this is first called. Absent that, the provider WordPress
ships is assembled from the active store and keyring, which a drop-in can also
replace individually, so wanting host-managed key custody with default storage needs
no provider at all.

No filter is applied here, or anywhere on the retrieval path. Substitution is by
replacement, never by interception: a filter that can observe which provider
answers is one step from a filter that can answer instead.

Cached for the request. A failed drop-in fails closed, returning WP_Error from
every operation, rather than silently reverting to the default, because a
misconfigured credential backend must never look like a working one that happens
to be empty.

return: WP_Secrets_Provider

wp_secrets_provider_is_writable()   X-Ref
Whether the active provider accepts writes.

Exists so a settings screen can disable its own save control before an operator
types a credential into a field that will only reject it. A provider whose
credentials are managed by host tooling or a control panel reports false.

return: bool

wp_secrets_provider_label()   X-Ref
A human-readable description of what is protecting this site's secrets.

For Site Health and a future admin screen. Never key material, never a value.

return: string

_wp_secrets_set( string $name, $value, bool $network, bool $needs_rotation = false, ?string $action_override = null )   X-Ref
Shared implementation behind wp_set_secret() and wp_set_network_secret().

return: true|WP_Error
param: string      $name            The secret's name.
param: string      $value           The plaintext value.
param: bool        $network         Whether this is a network-scope secret.
param: bool        $needs_rotation  Flag the stored secret as needing rotation.
param: string|null $action_override Overrides the $action reported to

_wp_secrets_get( string $name, string $version, bool $network )   X-Ref
Shared implementation behind wp_get_secret() and wp_get_network_secret().

return: WP_Secret|null|WP_Error
param: string $name    The secret's name.
param: string $version A WP_Secret_Version constant.
param: bool   $network Whether this is a network-scope secret.

_wp_secrets_delete( string $name, bool $network )   X-Ref
Shared implementation behind wp_delete_secret() and wp_delete_network_secret().

return: true|WP_Error
param: string $name    The secret's name.
param: bool   $network Whether this is a network-scope secret.

_wp_secrets_retire( string $name, bool $network )   X-Ref
Shared implementation behind wp_retire_secret_version() and its network twin.

return: true|WP_Error
param: string $name    The secret's name.
param: bool   $network Whether this is a network-scope secret.

_wp_secrets_list( string $name_prefix, bool $network )   X-Ref
Shared implementation behind wp_list_secrets() and wp_list_network_secrets().

return: array|WP_Error
param: string $name_prefix Restrict to names beginning with this prefix.
param: bool   $network     Whether to list network-scope secrets.



Generated : Wed Oct 14 08:20:33 2026 Cross-referenced by PHPXref