#64819 closed defect (bug) (fixed)
Revisit AI provider API key masking & validation
| Reported by: |
|
Owned by: |
|
|---|---|---|---|
| Milestone: | 7.0 | Priority: | normal |
| Severity: | normal | Version: | trunk |
| Component: | AI | Keywords: | has-patch |
| Focuses: | Cc: |
Description
_wp_connectors_is_ai_api_key_valid in the sanitize_callback is a bit annoying because it means I can't just do wp option update connectors_ai_openai_api_key 1234 in WP-CLI, because it won't pass validation
It's also not typical for a command like wp option get connectors_ai_google_api_key to not return the actual raw value.
I also can't do wp option update connectors_ai_google_api_key "" to set the option to an empty value, because, again, the validation fails. I have to delete the option, which is not great for caching / db queries.
Soo... can we do this masking and validation somewhere else? And not in a weird way like that _wp_connectors_validate_keys_in_rest hack btw
Change History (9)
#2
@
3 weeks ago
Also as an FYI:
wp option list uses a direct db query to get the full list of options, so you will always get the unmasked API key there.
#3
@
3 weeks ago
- Keywords needs-patch added
- Version set to trunk
It also doesn't help that none of the AI client HTTP requests go through the WP HTTP API, so I cannot hook into those and filter them to short-circuit validation.
There's no filter in _wp_connectors_is_ai_api_key_valid either.
This ticket was mentioned in Slack in #core-ai by swissspidy. View the logs.
3 weeks ago
#5
@
3 weeks ago
It also doesn't help that none of the AI client HTTP requests go through the WP HTTP API, so I cannot hook into those and filter them to short-circuit validation.
@swissspidy How do you mean? What do they go through instead? The adapter for WP exists exactly so that they should go through the WP HTTP API.
#6
@
3 weeks ago
@jorgefilipecosta, do the changes you applied in the Gutenberg plugin cover all the requirements? We still need to sync these changes to WordPress trunk.
This ticket was mentioned in PR #11228 on WordPress/wordpress-develop by @jorgefilipecosta.
2 weeks ago
#7
- Keywords has-patch added; needs-patch removed
## Summary
Trac ticket: https://core.trac.wordpress.org/ticket/64819
Backports two Gutenberg PRs into WordPress core:
- Gutenberg #76266 — Adds
_wp_connectors_get_api_key_source()to detect whether an API key is configured via environment variable, PHP constant, or database. The UI uses this to show the key source and hide "Remove and replace" for externally configured keys.
- Gutenberg #76327 — Refactors API key validation and masking from
sanitize_callback+option_filters into a singlerest_post_dispatchhandler (_wp_connectors_rest_settings_dispatch), ensuring raw keys are never exposed via REST API responses.
### Changes
- New function:
_wp_connectors_get_api_key_source()— checks env var → PHP constant → database for API key origin - New function:
_wp_connectors_rest_settings_dispatch()— masks keys in all/wp/v2/settingsresponses and validates on POST/PUT, reverting invalid keys - Removed function:
_wp_connectors_get_real_api_key()— no longer needed since masking moved out of option filters - Removed function:
_wp_connectors_validate_keys_in_rest()— replaced by the new dispatch handler - Modified:
_wp_connectors_get_connector_settings()— added static memoization and pluginis_installed/is_activatedstatus enrichment - Modified:
_wp_register_default_connector_settings()— simplifiedsanitize_callbacktosanitize_text_field, removed option mask filter - Modified:
_wp_connectors_pass_default_keys_to_ai_client()— skips keys from env/constant sources, usesget_option()directly - Modified:
_wp_connectors_get_connector_script_module_data()— exposeskeySource,isConnected,logoUrl, and plugin status (isInstalled,isActivated)
## Test plan
- [ ] Verify connectors admin screen loads and displays connector data correctly
- [ ] Test saving a valid API key via the settings REST endpoint — key should be masked in the response
- [ ] Test saving an invalid API key — key should be reverted to empty
- [ ] Verify env var and constant-sourced keys are detected and shown with correct source
- [ ] Run
phpunit --group connectorsto verify existing tests pass
#8
@
2 weeks ago
- Owner set to jorgefilipecosta
- Resolution set to fixed
- Status changed from new to closed
In 61985:
#9
@
2 weeks ago
Thank you for raising this @swissspidy. The issues you noticed should be addressed.
Now masking happens at the REST API level instead of get_option level, so WP CLI returns full keys.
Validation happens when updating a key in REST, and on the data structure passed to the client (in case a key gets revoked). I removed the validation during setting retrieval. WP CLI should be able to set any key now.
Posting what I shared on Slack already, this is what happens due to all this custom logic in place: