Skip to content

fix(security): encrypt missing secret-like plugin fields at rest#13389

Merged
shreemaan-abhishek merged 2 commits into
apache:masterfrom
shreemaan-abhishek:fix/openid-connect-redis-password-encrypt
Jun 2, 2026
Merged

fix(security): encrypt missing secret-like plugin fields at rest#13389
shreemaan-abhishek merged 2 commits into
apache:masterfrom
shreemaan-abhishek:fix/openid-connect-redis-password-encrypt

Conversation

@shreemaan-abhishek

@shreemaan-abhishek shreemaan-abhishek commented May 19, 2026

Copy link
Copy Markdown
Contributor

Description

APISIX's schema-driven data encryption only processes fields explicitly listed in each plugin's encrypt_fields. Several credential-bearing fields were never registered, so even when an operator sets apisix.data_encryption.enable_encrypt_fields: true, those values remain in etcd as plaintext. They also surface in etcd backups, snapshots, and diagnostic exports. This was originally opened for openid-connect.session.redis.password alone, then broadened after the same root cause was found across many plugins.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Changes

Add the following to the corresponding plugin/metadata encrypt_fields:

Plugin / location Field
http-logger auth_header
openfunction authorization.service_token
azure-functions authorization.apikey
azure-functions (plugin metadata) master_apikey
splunk-hec-logging endpoint.token
kafka-logger brokers[].sasl_config.password
loggly customer_token
ai-aws-content-moderation comprehend.secret_access_key
openid-connect session.secret
openid-connect session.redis.password
error-log-logger (plugin metadata) kafka.brokers[].sasl_config.password

For openfunction and azure-functions, which build their schemas via the shared serverless.generic-upstream factory, encrypt_fields is assigned on the returned plugin.schema after the factory call (same pattern as aws-lambda.lua).

Regression tests cover the four distinct schema shapes that exercise the encryption path:

  • top-level string -- t/plugin/loggly.t TEST 21 (customer_token)
  • nested dotted path -- t/plugin/splunk-hec-logging.t TEST 14 (endpoint.token)
  • array of tables -- t/plugin/kafka-logger3.t TEST 2 (brokers[].sasl_config.password)
  • plugin_metadata with array of tables -- t/plugin/error-log-logger-kafka.t TEST 7 (kafka.brokers[].sasl_config.password)
  • existing TEST 21 in t/plugin/openid-connect2.t continues to cover session.redis.password.

Each test PUTs a plaintext value through the Admin API, GETs it back (asserts decrypted round-trip), and reads the raw etcd value (asserts the stored value is encrypted, i.e. non-empty and not equal to the plaintext).

Checklist

  • I have rebased to the latest master.
  • I have added tests to cover my changes.
  • I have updated the documentation (no user-facing doc changes; the affected fields are unchanged from the user's perspective -- only at-rest representation in etcd changes).

The Redis-backed session storage introduced in 3.16.0 added a
`session.redis.password` field. Unlike `client_secret`, this field was
not included in `encrypt_fields`, so the Redis password was persisted
in plaintext in etcd and surfaced through backups, snapshots, and
diagnostic exports.

Add `session.redis.password` to `encrypt_fields` so it follows the same
encryption path that already protects `client_secret` and
`client_rsa_private_key`.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. bug Something isn't working labels May 19, 2026
APISIX's schema-driven encryption only processes fields explicitly
listed in each plugin's `encrypt_fields`. Several credential-bearing
fields were never registered, so even with
`apisix.data_encryption.enable_encrypt_fields: true` they remained in
etcd as plaintext, visible in backups, snapshots, and diagnostic
exports.

Bring the following fields under `encrypt_fields`:

  - http-logger.auth_header
  - openfunction.authorization.service_token
  - azure-functions.authorization.apikey
  - azure-functions metadata: master_apikey
  - splunk-hec-logging.endpoint.token
  - kafka-logger.brokers[].sasl_config.password
  - loggly.customer_token
  - ai-aws-content-moderation.comprehend.secret_access_key
  - openid-connect.session.secret
  - error-log-logger metadata: kafka.brokers[].sasl_config.password

Add regression tests for the four distinct schema shapes -- top-level
string (loggly), nested dotted path (splunk-hec-logging), array of
tables (kafka-logger), and plugin_metadata with an array of tables
(error-log-logger). Each test round-trips a plaintext value through
the Admin API and asserts the value stored in etcd is encrypted.
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels May 28, 2026
@shreemaan-abhishek shreemaan-abhishek changed the title fix(openid-connect): encrypt session.redis.password at rest fix(security): encrypt missing secret-like plugin fields at rest May 28, 2026
@shreemaan-abhishek
shreemaan-abhishek merged commit 473a189 into apache:master Jun 2, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants