WordPress 7.2 gets a Secrets API that stores API keys and OAuth client secrets, that is, confidential credentials, in encrypted form. Eric Mann describes it in a Dev Note dated November 11, 2026 on make.wordpress.org. The release of WordPress 7.2 is planned for December 8, 2026.
For website operators, it comes down to a single step: the encryption only works with a key called WP_SECRETS_KEY in the wp-config.php. If this key is missing, the API stores nothing. The Dev Note does not mention any restrictions by country or language.
How does the Secrets API protect stored credentials?
WordPress encrypts every secret with libsodium (XChaCha20-Poly1305) and stores it in the options tables of the database. WordPress derives the individual keys from a random root key (master key). This is stored encrypted in the database and is protected with WP_SECRETS_KEY, a random, base64-encoded 32-byte key in the wp-config.php.
Secrets API: What it can and cannot do
New in WordPress 7.2, release planned for December 8, 2026
- Encrypts API keys and OAuth client secrets
- Keeps the previous version of each secret for key rotation
- Shows values in output, logs and JSON only as placeholder text
- Stores nothing without WP_SECRETS_KEY in the wp-config.php
- Does not check the permissions of callers
- Does not protect against other code on the website
As of the Dev Note from November 11, 2026, WordPress 7.2 is still in beta.
Sources: Make WordPress Core, WordPress News
According to the Dev Note, Site Health generates a ready-made line for the key that you can copy, and WP-CLI is also supposed to write it with wp config create. Unlike the salts, you must not simply change or remove the key, otherwise all stored secrets become unreadable. An empty value, the example value from the wp-config-sample.php, or a copy of an auth key or salt does not count as a usable key. In these cases, the API reports the error secret_key_unavailable.
In code, plugin authors work with wp_set_secret() and wp_get_secret(). The returned object of the class WP_Secret shows only a placeholder text such as [secret:name] when output, logged, or serialized to JSON. Only the method reveal() returns the value. The previous version of each secret is retained so that keys can be swapped.
Where are the limits of the Secrets API?
The functions do not check permissions. Plugin authors have to control themselves who may enter or manage a value, because otherwise cron and REST would be unprotected. In addition, any code on the website can read any secret. The name portion before the slash, such as plugin-slug/secret-name, only prevents accidental overwriting between plugins and is not access control.
Hosting providers can hand over the protection of the key, the storage location, or the entire management to their own service, such as a key management system, via a drop-in called wp-content/secrets.php. A faulty drop-in does not fall back to the default values; every call then returns an error.
Site Health gets three new tests in the "Security" section. The test for the key source reports the status "recommended" if the key is missing and "critical" if the root key cannot be decrypted. A second test becomes "critical" as soon as stored secrets are unreadable. The third reports "recommended" if credentials are flagged for rotation.
What this means for you
Test the Secrets API first in a test environment with the beta, because the WordPress team writes in the post on Beta 5 that the beta is intended only for testing and development. It is best to set WP_SECRETS_KEY in the wp-config.php there and check in Site Health what the test for the key source reports.
Our assessment: It is best to also keep the key outside the website, for example in a password manager, and include it in the backup. Without it, the secrets can no longer be read from a database backup. However, the encryption only protects the values in the database as long as the key is not passed on together with a database export.
If you develop plugins or client sites with your own credentials, check with wp_is_secrets_api_available() before switching over whether the API is available. Also, do not treat an error from wp_get_secret() as "missing", otherwise your code overwrites a working access. The function wp_import_option_as_secret() copies an existing option into a secret. The option remains in place, and you delete it by hand.
Eric Mann published the Dev Note on November 11, 2026.
Sources