AlinsRan opened a new pull request, #14162: URL: https://github.com/apache/apisix/pull/14162
### Description Whether a stored plugin value is ciphertext is decided only by the reader's own `encrypt_fields`. After upgrading to a release that adds a field to an existing plugin's `encrypt_fields`, every resource re-saved there stores that field encrypted; rolling back to the previous release then uses the ciphertext as the value (e.g. Redis authentication fails) until each resource is re-saved. Turning off `enable_encrypt_fields` does the same to existing ciphertext. This PR adds a self-describing marker so that every release that recognizes it decrypts the value regardless of its own list. #### Format `$ENC$v1$` followed by the existing ciphertext (same cipher, encoding and `data_encryption.keyring`). #### Reader - `plugin_checker` (routes, services, plugin configs, consumers, credentials, consumer groups, global rules), `check_plugin_metadata` and `stream_plugin_checker` decrypt every string value starting with `$ENC$v1$` before validation, independent of `encrypt_fields` and of `enable_encrypt_fields`. - A marked value that fails to decrypt makes the resource invalid (same handling as any other invalid resource). Decryption of a resource is all-or-nothing, so the "failed to check item data" log never carries plaintexts decrypted before the failing value. - Positions decrypted through the marker skip the `encrypt_fields` logic, so a plaintext that happens to be valid ciphertext is not decrypted twice. Unmarked values keep the current `encrypt_fields` behaviour. - Marked values are decrypted in place even with `enable_encrypt_fields: false`, so the info logs that used to dump a whole conf now print only ids or plugin names: the stream plugin schema check, `merge_service_route`, `merge_service_stream_route`, `merge_consumer_route`, `matched route` (HTTP and stream), `insert uri route`, `filter service`, and the plugin metadata lookup of the logger utilities (plugin name and whether metadata was found). - Outside the checkers, plugin confs are decrypted in the Admin API: read responses (now including the plugin metadata list) return marked values as plaintext, and PATCH decrypts the stored conf before merging; every marked position the PATCH does not modify keeps its stored value byte for byte, whatever `write_marker` is, and only modified positions follow `write_marker`. If a stored marked value cannot be decrypted, the read returns it as stored (and logs an error) and PATCH fails with 400. - The yaml/json config providers use the same checkers, so marked values in a standalone configuration are decrypted with the local keyring too. #### Writer New option `apisix.data_encryption.write_marker` (default `false`, effective only with `enable_encrypt_fields: true`). When on, the Admin API writes every plugin conf and plugin metadata value it encrypts today in marked form. It does not change which fields are encrypted; SSL keys, upstream TLS keys and `/secrets` are unchanged. Enable it only once every node runs a release that recognizes the marker and you will not roll back below that release. #### Input validation The Admin API rejects with 400 any user-supplied string starting with `$ENC$` (the whole reserved prefix, not only `v1`) in plugin confs and plugin metadata, including PATCH bodies written under `plugins/...`, whatever `write_marker` is. Values already stored and merged on PATCH are not user input and are not checked. ### Checklist - [x] I have explained the need for this PR and the problem it solves - [x] I have explained the changes or the new features added to this PR - [x] I have added tests corresponding to this change - [x] I have updated the documentation to reflect this change - [x] I have verified that this change is backward compatible (If not, please discuss on the [APISIX mailing list](https://github.com/apache/apisix/tree/master#community) first) Tests: `t/node/data_encrypt_marker.t` writes resources straight to etcd and covers decryption in routes, services, global rules, consumers, plugin metadata and stream routes, failures, double-decryption avoidance and `enable_encrypt_fields: false`. `t/admin/data_encrypt_marker.t` covers the writer on and off, `write_marker` without `enable_encrypt_fields`, Admin API reads and PATCH, and the rejection. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
