You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/12/19 06:38:06 UTC
[apisix] branch master updated: feat: data encryption support more plugins (#8487)
This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 152ea80e2 feat: data encryption support more plugins (#8487)
152ea80e2 is described below
commit 152ea80e2e5aeafe62bd4358179351e017a0171e
Author: tzssangglass <tz...@gmail.com>
AuthorDate: Mon Dec 19 14:37:57 2022 +0800
feat: data encryption support more plugins (#8487)
Fixes https://github.com/apache/apisix/issues/8407
---
apisix/admin/init.lua | 2 +
apisix/admin/plugin_metadata.lua | 3 +
apisix/admin/utils.lua | 6 ++
apisix/plugin.lua | 97 +++++++++++++----
apisix/plugins/authz-casdoor.lua | 1 +
apisix/plugins/authz-keycloak.lua | 1 +
apisix/plugins/basic-auth.lua | 3 +-
apisix/plugins/clickhouse-logger.lua | 3 +-
apisix/plugins/csrf.lua | 1 +
apisix/plugins/elasticsearch-logger.lua | 1 +
apisix/plugins/error-log-logger.lua | 3 +-
apisix/plugins/google-cloud-logging.lua | 1 +
apisix/plugins/hmac-auth.lua | 1 +
apisix/plugins/jwt-auth.lua | 1 +
apisix/plugins/kafka-proxy.lua | 1 +
apisix/plugins/key-auth.lua | 3 +-
apisix/plugins/openid-connect.lua | 1 +
apisix/plugins/rocketmq-logger.lua | 1 +
apisix/plugins/sls-logger.lua | 1 +
apisix/plugins/tencent-cloud-cls.lua | 1 +
conf/config-default.yaml | 2 +-
docs/en/latest/plugin-develop.md | 21 +++-
docs/en/latest/plugins/authz-casdoor.md | 2 +
docs/en/latest/plugins/authz-keycloak.md | 2 +
docs/en/latest/plugins/basic-auth.md | 2 +-
docs/en/latest/plugins/clickhouse-logger.md | 4 +-
docs/en/latest/plugins/csrf.md | 2 +
docs/en/latest/plugins/elasticsearch-logger.md | 2 +
docs/en/latest/plugins/error-log-logger.md | 2 +
docs/en/latest/plugins/google-cloud-logging.md | 2 +
docs/en/latest/plugins/hmac-auth.md | 2 +
docs/en/latest/plugins/jwt-auth.md | 2 +
docs/en/latest/plugins/kafka-proxy.md | 2 +
docs/en/latest/plugins/key-auth.md | 2 +-
docs/en/latest/plugins/openid-connect.md | 2 +
docs/en/latest/plugins/rocketmq-logger.md | 2 +
docs/en/latest/plugins/sls-logger.md | 2 +
docs/en/latest/plugins/tencent-cloud-cls.md | 2 +
docs/zh/latest/plugin-develop.md | 21 +++-
docs/zh/latest/plugins/authz-casdoor.md | 2 +
docs/zh/latest/plugins/authz-keycloak.md | 2 +
docs/zh/latest/plugins/basic-auth.md | 2 +-
docs/zh/latest/plugins/clickhouse-logger.md | 4 +-
docs/zh/latest/plugins/csrf.md | 2 +
docs/zh/latest/plugins/elasticsearch-logger.md | 2 +
docs/zh/latest/plugins/error-log-logger.md | 2 +
docs/zh/latest/plugins/google-cloud-logging.md | 2 +
docs/zh/latest/plugins/hmac-auth.md | 2 +
docs/zh/latest/plugins/jwt-auth.md | 2 +
docs/zh/latest/plugins/key-auth.md | 2 +-
docs/zh/latest/plugins/openid-connect.md | 2 +
docs/zh/latest/plugins/rocketmq-logger.md | 2 +
docs/zh/latest/plugins/sls-logger.md | 2 +
docs/zh/latest/plugins/tencent-cloud-cls.md | 2 +
t/admin/plugins.t | 2 +-
t/plugin/authz-casdoor.t | 68 ++++++++++++
t/plugin/authz-keycloak3.t | 70 ++++++++++++
t/plugin/csrf.t | 63 +++++++++++
t/plugin/elasticsearch-logger.t | 68 ++++++++++++
t/plugin/error-log-logger-clickhouse.t | 82 ++++++++++++++
t/plugin/google-cloud-logging2.t | 125 ++++++++++++++++++++++
t/plugin/hmac-auth3.t | 73 +++++++++++++
t/plugin/jwt-auth3.t | 142 +++++++++++++++++++++++++
t/plugin/kafka-proxy.t | 65 +++++++++++
t/plugin/openid-connect2.t | 69 ++++++++++++
t/plugin/rocketmq-logger2.t | 65 +++++++++++
t/plugin/sls-logger.t | 83 +++++++++++++++
t/plugin/tencent-cloud-cls.t | 85 +++++++++++++++
68 files changed, 1260 insertions(+), 42 deletions(-)
diff --git a/apisix/admin/init.lua b/apisix/admin/init.lua
index 52df36f1a..3ed8d362e 100644
--- a/apisix/admin/init.lua
+++ b/apisix/admin/init.lua
@@ -204,6 +204,8 @@ local function run()
if method == "get" and plugin.enable_data_encryption then
if seg_res == "consumers" then
utils.decrypt_params(plugin.decrypt_conf, data, core.schema.TYPE_CONSUMER)
+ elseif seg_res == "plugin_metadata" then
+ utils.decrypt_params(plugin.decrypt_conf, data, core.schema.TYPE_METADATA)
else
utils.decrypt_params(plugin.decrypt_conf, data)
end
diff --git a/apisix/admin/plugin_metadata.lua b/apisix/admin/plugin_metadata.lua
index 23859c775..065b60c47 100644
--- a/apisix/admin/plugin_metadata.lua
+++ b/apisix/admin/plugin_metadata.lua
@@ -18,6 +18,7 @@ local pcall = pcall
local require = require
local core = require("apisix.core")
local utils = require("apisix.admin.utils")
+local encrypt_conf = require("apisix.plugin").encrypt_conf
local injected_mark = "injected metadata_schema"
local _M = {
@@ -73,6 +74,8 @@ local function check_conf(plugin_name, conf)
ok, err = plugin_object.check_schema(conf, core.schema.TYPE_METADATA)
end
+ encrypt_conf(plugin_name, conf, core.schema.TYPE_METADATA)
+
if not ok then
return nil, {error_msg = "invalid configuration: " .. err}
end
diff --git a/apisix/admin/utils.lua b/apisix/admin/utils.lua
index ee396d0d3..eee2787f0 100644
--- a/apisix/admin/utils.lua
+++ b/apisix/admin/utils.lua
@@ -102,6 +102,12 @@ function _M.decrypt_params(decrypt_func, body, schema_type)
decrypt_func(name, conf, schema_type)
end
end
+
+ -- metadata
+ if schema_type == core.schema.TYPE_METADATA then
+ local conf = body.node and body.node.value
+ decrypt_func(conf.name, conf, schema_type)
+ end
end
return _M
diff --git a/apisix/plugin.lua b/apisix/plugin.lua
index 35169e8a8..3b5cecac6 100644
--- a/apisix/plugin.lua
+++ b/apisix/plugin.lua
@@ -21,6 +21,7 @@ local enable_debug = require("apisix.debug").enable_debug
local wasm = require("apisix.wasm")
local expr = require("resty.expr.v1")
local apisix_ssl = require("apisix.ssl")
+local re_split = require("ngx.re").split
local ngx = ngx
local crc32 = ngx.crc32_short
local ngx_exit = ngx.exit
@@ -844,12 +845,6 @@ local function check_single_plugin_schema(name, plugin_conf, schema_type, skip_d
end
-check_plugin_metadata = function(item)
- return check_single_plugin_schema(item.id, item,
- core.schema.TYPE_METADATA, true)
-end
-
-
local enable_data_encryption
local function enable_gde()
if enable_data_encryption == nil then
@@ -868,9 +863,15 @@ local function get_plugin_schema_for_gde(name, schema_type)
end
local plugin_schema = local_plugins_hash and local_plugins_hash[name]
+ if not plugin_schema then
+ return nil
+ end
+
local schema
if schema_type == core.schema.TYPE_CONSUMER then
schema = plugin_schema.consumer_schema
+ elseif schema_type == core.schema.TYPE_METADATA then
+ schema = plugin_schema.metadata_schema
else
schema = plugin_schema.schema
end
@@ -882,17 +883,39 @@ end
local function decrypt_conf(name, conf, schema_type)
local schema = get_plugin_schema_for_gde(name, schema_type)
if not schema then
+ core.log.warn("failed to get schema for plugin: ", name)
return
end
- for key, props in pairs(schema.properties) do
- if props.type == "string" and props.encrypted and conf[key] then
- local encrypted, err = apisix_ssl.aes_decrypt_pkey(conf[key], "data_encrypt")
- if not encrypted then
- core.log.warn("failed to decrypt the conf of plugin [", name,
- "] key [", key, "], err: ", err)
- else
- conf[key] = encrypted
+ if schema.encrypt_fields and not core.table.isempty(schema.encrypt_fields) then
+ for _, key in ipairs(schema.encrypt_fields) do
+ if conf[key] then
+ local decrypted, err = apisix_ssl.aes_decrypt_pkey(conf[key], "data_encrypt")
+ if not decrypted then
+ core.log.warn("failed to decrypt the conf of plugin [", name,
+ "] key [", key, "], err: ", err)
+ else
+ conf[key] = decrypted
+ end
+ elseif core.string.find(key, ".") then
+ -- decrypt fields has indents
+ local res, err = re_split(key, "\\.", "jo")
+ if not res then
+ core.log.warn("failed to split key [", key, "], err: ", err)
+ return
+ end
+
+ -- we only support two levels
+ if conf[res[1]] and conf[res[1]][res[2]] then
+ local decrypted, err = apisix_ssl.aes_decrypt_pkey(
+ conf[res[1]][res[2]], "data_encrypt")
+ if not decrypted then
+ core.log.warn("failed to decrypt the conf of plugin [", name,
+ "] key [", key, "], err: ", err)
+ else
+ conf[res[1]][res[2]] = decrypted
+ end
+ end
end
end
end
@@ -903,19 +926,57 @@ _M.decrypt_conf = decrypt_conf
local function encrypt_conf(name, conf, schema_type)
local schema = get_plugin_schema_for_gde(name, schema_type)
if not schema then
+ core.log.warn("failed to get schema for plugin: ", name)
return
end
- for key, props in pairs(schema.properties) do
- if props.type == "string" and props.encrypted and conf[key] then
- local encrypted = apisix_ssl.aes_encrypt_pkey(conf[key], "data_encrypt")
- conf[key] = encrypted
+ if schema.encrypt_fields and not core.table.isempty(schema.encrypt_fields) then
+ for _, key in ipairs(schema.encrypt_fields) do
+ if conf[key] then
+ local encrypted, err = apisix_ssl.aes_encrypt_pkey(conf[key], "data_encrypt")
+ if not encrypted then
+ core.log.warn("failed to encrypt the conf of plugin [", name,
+ "] key [", key, "], err: ", err)
+ else
+ conf[key] = encrypted
+ end
+ elseif core.string.find(key, ".") then
+ -- encrypt fields has indents
+ local res, err = re_split(key, "\\.", "jo")
+ if not res then
+ core.log.warn("failed to split key [", key, "], err: ", err)
+ return
+ end
+
+ -- we only support two levels
+ if conf[res[1]] and conf[res[1]][res[2]] then
+ local encrypted, err = apisix_ssl.aes_encrypt_pkey(
+ conf[res[1]][res[2]], "data_encrypt")
+ if not encrypted then
+ core.log.warn("failed to encrypt the conf of plugin [", name,
+ "] key [", key, "], err: ", err)
+ else
+ conf[res[1]][res[2]] = encrypted
+ end
+ end
+ end
end
end
end
_M.encrypt_conf = encrypt_conf
+check_plugin_metadata = function(item)
+ local ok, err = check_single_plugin_schema(item.id, item,
+ core.schema.TYPE_METADATA, true)
+ if ok and enable_gde() then
+ decrypt_conf(item.name, item, core.schema.TYPE_METADATA)
+ end
+
+ return ok, err
+end
+
+
local function check_schema(plugins_conf, schema_type, skip_disabled_plugin)
for name, plugin_conf in pairs(plugins_conf) do
local ok, err = check_single_plugin_schema(name, plugin_conf,
diff --git a/apisix/plugins/authz-casdoor.lua b/apisix/plugins/authz-casdoor.lua
index 9fd8d8da8..4ed1c92b9 100644
--- a/apisix/plugins/authz-casdoor.lua
+++ b/apisix/plugins/authz-casdoor.lua
@@ -32,6 +32,7 @@ local schema = {
client_secret = {type = "string"},
callback_url = {type = "string", pattern = "^[^%?]+[^/]$"}
},
+ encrypt_fields = {"client_secret"},
required = {
"callback_url", "endpoint_addr", "client_id", "client_secret"
}
diff --git a/apisix/plugins/authz-keycloak.lua b/apisix/plugins/authz-keycloak.lua
index 336fb69b1..f2c02727c 100644
--- a/apisix/plugins/authz-keycloak.lua
+++ b/apisix/plugins/authz-keycloak.lua
@@ -71,6 +71,7 @@ local schema = {
maxLength = 4096
},
},
+ encrypt_fields = {"client_secret"},
required = {"client_id"},
allOf = {
-- Require discovery or token endpoint.
diff --git a/apisix/plugins/basic-auth.lua b/apisix/plugins/basic-auth.lua
index 65d96e5c7..c91ddee77 100644
--- a/apisix/plugins/basic-auth.lua
+++ b/apisix/plugins/basic-auth.lua
@@ -38,8 +38,9 @@ local consumer_schema = {
title = "work with consumer object",
properties = {
username = { type = "string" },
- password = { type = "string", encrypted = true },
+ password = { type = "string" },
},
+ encrypt_fields = {"password"},
required = {"username", "password"},
}
diff --git a/apisix/plugins/clickhouse-logger.lua b/apisix/plugins/clickhouse-logger.lua
index 28404f9ae..70463a752 100644
--- a/apisix/plugins/clickhouse-logger.lua
+++ b/apisix/plugins/clickhouse-logger.lua
@@ -36,7 +36,7 @@ local schema = {
endpoint_addr = core.schema.uri_def,
endpoint_addrs = {items = core.schema.uri_def, type = "array", minItems = 1},
user = {type = "string", default = ""},
- password = {type = "string", default = "", encrypted = true},
+ password = {type = "string", default = ""},
database = {type = "string", default = ""},
logtable = {type = "string", default = ""},
timeout = {type = "integer", minimum = 1, default = 3},
@@ -47,6 +47,7 @@ local schema = {
{required = {"endpoint_addr", "user", "password", "database", "logtable"}},
{required = {"endpoint_addrs", "user", "password", "database", "logtable"}}
},
+ encrypt_fields = {"password"},
}
diff --git a/apisix/plugins/csrf.lua b/apisix/plugins/csrf.lua
index 233fe1d94..4ed2ad624 100644
--- a/apisix/plugins/csrf.lua
+++ b/apisix/plugins/csrf.lua
@@ -44,6 +44,7 @@ local schema = {
default = "apisix-csrf-token"
}
},
+ encrypt_fields = {"key"},
required = {"key"}
}
diff --git a/apisix/plugins/elasticsearch-logger.lua b/apisix/plugins/elasticsearch-logger.lua
index 105cbe4d9..5b7341319 100644
--- a/apisix/plugins/elasticsearch-logger.lua
+++ b/apisix/plugins/elasticsearch-logger.lua
@@ -67,6 +67,7 @@ local schema = {
default = true
}
},
+ encrypt_fields = {"auth.password"},
required = { "endpoint_addr", "field" },
}
diff --git a/apisix/plugins/error-log-logger.lua b/apisix/plugins/error-log-logger.lua
index 5aa7a7418..d847ca1ce 100644
--- a/apisix/plugins/error-log-logger.lua
+++ b/apisix/plugins/error-log-logger.lua
@@ -83,7 +83,8 @@ local metadata_schema = {
{required = {"clickhouse"}},
-- for compatible with old schema
{required = {"host", "port"}}
- }
+ },
+ encrypt_fields = {"clickhouse.password"},
}
diff --git a/apisix/plugins/google-cloud-logging.lua b/apisix/plugins/google-cloud-logging.lua
index 607856759..a07156716 100644
--- a/apisix/plugins/google-cloud-logging.lua
+++ b/apisix/plugins/google-cloud-logging.lua
@@ -92,6 +92,7 @@ local schema = {
{ required = { "auth_config" } },
{ required = { "auth_file" } },
},
+ encrypt_fields = {"auth_config.private_key"},
}
diff --git a/apisix/plugins/hmac-auth.lua b/apisix/plugins/hmac-auth.lua
index c03e5ce82..94916e975 100644
--- a/apisix/plugins/hmac-auth.lua
+++ b/apisix/plugins/hmac-auth.lua
@@ -90,6 +90,7 @@ local consumer_schema = {
default = MAX_REQ_BODY,
},
},
+ encrypt_fields = {"secret_key"},
required = {"access_key", "secret_key"},
}
diff --git a/apisix/plugins/jwt-auth.lua b/apisix/plugins/jwt-auth.lua
index 1215fedb9..96c743e1b 100644
--- a/apisix/plugins/jwt-auth.lua
+++ b/apisix/plugins/jwt-auth.lua
@@ -118,6 +118,7 @@ local consumer_schema = {
}
}
},
+ encrypt_fields = {"secret", "private_key"},
required = {"key"},
}
diff --git a/apisix/plugins/kafka-proxy.lua b/apisix/plugins/kafka-proxy.lua
index b6c666a53..0882692dd 100644
--- a/apisix/plugins/kafka-proxy.lua
+++ b/apisix/plugins/kafka-proxy.lua
@@ -33,6 +33,7 @@ local schema = {
required = {"username", "password"},
},
},
+ encrypt_fields = {"sasl.password"},
}
diff --git a/apisix/plugins/key-auth.lua b/apisix/plugins/key-auth.lua
index 63e41a084..f8cfddae0 100644
--- a/apisix/plugins/key-auth.lua
+++ b/apisix/plugins/key-auth.lua
@@ -40,8 +40,9 @@ local schema = {
local consumer_schema = {
type = "object",
properties = {
- key = { type = "string", encrypted = true },
+ key = { type = "string" },
},
+ encrypt_fields = {"key"},
required = {"key"},
}
diff --git a/apisix/plugins/openid-connect.lua b/apisix/plugins/openid-connect.lua
index d45b4e757..163707f1d 100644
--- a/apisix/plugins/openid-connect.lua
+++ b/apisix/plugins/openid-connect.lua
@@ -124,6 +124,7 @@ local schema = {
default = false
}
},
+ encrypt_fields = {"client_secret"},
required = {"client_id", "client_secret", "discovery"}
}
diff --git a/apisix/plugins/rocketmq-logger.lua b/apisix/plugins/rocketmq-logger.lua
index 447960ba6..7ca61390c 100644
--- a/apisix/plugins/rocketmq-logger.lua
+++ b/apisix/plugins/rocketmq-logger.lua
@@ -69,6 +69,7 @@ local schema = {
}
},
},
+ encrypt_fields = {"secret_key"},
required = {"nameserver_list", "topic"}
}
diff --git a/apisix/plugins/sls-logger.lua b/apisix/plugins/sls-logger.lua
index 290bf1191..89fc952ba 100644
--- a/apisix/plugins/sls-logger.lua
+++ b/apisix/plugins/sls-logger.lua
@@ -42,6 +42,7 @@ local schema = {
access_key_id = {type = "string"},
access_key_secret = {type ="string"}
},
+ encrypt_fields = {"access_key_secret"},
required = {"host", "port", "project", "logstore", "access_key_id", "access_key_secret"}
}
diff --git a/apisix/plugins/tencent-cloud-cls.lua b/apisix/plugins/tencent-cloud-cls.lua
index b0726e607..d9b032b01 100644
--- a/apisix/plugins/tencent-cloud-cls.lua
+++ b/apisix/plugins/tencent-cloud-cls.lua
@@ -44,6 +44,7 @@ local schema = {
include_resp_body = { type = "boolean", default = false },
global_tag = { type = "object" },
},
+ encrypt_fields = {"secret_key"},
required = { "cls_host", "cls_topic", "secret_id", "secret_key" }
}
diff --git a/conf/config-default.yaml b/conf/config-default.yaml
index 33af44564..e1923ec56 100755
--- a/conf/config-default.yaml
+++ b/conf/config-default.yaml
@@ -123,7 +123,7 @@ apisix:
# ip: 127.0.0.1
# port: 9090
disable_sync_configuration_during_start: false # safe exit. Remove this once the feature is stable
- data_encryption: # add `encrypted = true` in plugin schema to enable encryption
+ data_encryption: # add `encrypt_fields = { $field },` in plugin schema to enable encryption
enable: false # if not set, the default value is `false`.
keyring:
- qeddd145sfvddff3 # If not set, will save origin value into etcd.
diff --git a/docs/en/latest/plugin-develop.md b/docs/en/latest/plugin-develop.md
index c55c47bf1..a7aa4c634 100644
--- a/docs/en/latest/plugin-develop.md
+++ b/docs/en/latest/plugin-develop.md
@@ -300,13 +300,24 @@ Specify the parameters to be stored encrypted. (Requires APISIX version >= 3.1.0
Some plugins require parameters to be stored encrypted, such as the `password` parameter of the `basic-auth` plugin. This plugin needs to specify in the `schema` which parameters need to be stored encrypted.
```lua
-password = { type = "string", encrypted = true },
+encrypt_fields = {"password"}
```
-Parameters can be stored encrypted by specifying `encrypted = true` in the `schema`. APISIX will provide the following functionality.
+If it is a nested parameter, such as the `clickhouse.password` parameter of the `error-log-logger` plugin, it needs to be separated by `.`:
-- When adding and updating resources via the `Admin API`, APISIX automatically encrypts parameters with `encrypted = true` and stores them in etcd
-- When fetching resources via the `Admin API` and when running the plugin, APISIX automatically decrypts the `encrypted = true` parameter
+```lua
+encrypt_fields = {"clickhouse.password"}
+```
+
+Currently not supported yet:
+
+1. more than two levels of nesting
+2. fields in arrays
+
+Parameters can be stored encrypted by specifying `encrypt_fields = {"password"}` in the `schema`. APISIX will provide the following functionality.
+
+- When adding and updating resources via the `Admin API`, APISIX automatically encrypts the parameters declared in `encrypt_fields` and stores them in etcd
+- When fetching resources via the `Admin API` and when running the plugin, APISIX automatically decrypts the parameters declared in `encrypt_fields`
How to enable this feature?
@@ -321,7 +332,7 @@ apisix:
- qeddd145sfvddff4
```
-APISIX will try to decrypt the data with keys in the order of the keys in the keyring (only for parameters declared `encrypted = true`). If the decryption fails, the next key will be tried until the decryption succeeds.
+APISIX will try to decrypt the data with keys in the order of the keys in the keyring (only for parameters declared in `encrypt_fields`). If the decryption fails, the next key will be tried until the decryption succeeds.
If none of the keys in `keyring` can decrypt the data, the original data is used.
diff --git a/docs/en/latest/plugins/authz-casdoor.md b/docs/en/latest/plugins/authz-casdoor.md
index fc8c92f09..f1a71be9e 100644
--- a/docs/en/latest/plugins/authz-casdoor.md
+++ b/docs/en/latest/plugins/authz-casdoor.md
@@ -40,6 +40,8 @@ The `authz-casdoor` Plugin can be used to add centralized authentication with [C
| client_secret | string | True | Client secret in Casdoor. |
| callback_url | string | True | Callback URL used to receive state and code. |
+NOTE: `encrypt_fields = {"client_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
:::info IMPORTANT
`endpoint_addr` and `callback_url` should not end with '/'.
diff --git a/docs/en/latest/plugins/authz-keycloak.md b/docs/en/latest/plugins/authz-keycloak.md
index 70a149caf..d04196d06 100644
--- a/docs/en/latest/plugins/authz-keycloak.md
+++ b/docs/en/latest/plugins/authz-keycloak.md
@@ -66,6 +66,8 @@ Refer to [Authorization Services Guide](https://www.keycloak.org/docs/latest/aut
| access_denied_redirect_uri | string | False | | [1, 2048] | URI to redirect the user to instead of returning an error message like `"error_description":"not_authorized"`. |
| password_grant_token_generation_incoming_uri | string | False | | /api/token | Set this to generate token using the password grant type. The Plugin will compare incoming request URI to this value. |
+NOTE: `encrypt_fields = {"client_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
### Discovery and endpoints
It is recommended to use the `discovery` attribute as the `authz-keycloak` Plugin can discover the Keycloak API endpoints from it.
diff --git a/docs/en/latest/plugins/basic-auth.md b/docs/en/latest/plugins/basic-auth.md
index 25c574c9c..8447a4fce 100644
--- a/docs/en/latest/plugins/basic-auth.md
+++ b/docs/en/latest/plugins/basic-auth.md
@@ -42,7 +42,7 @@ For Consumer:
| username | string | True | Unique username for a Consumer. If multiple Consumers use the same `username`, a request matching exception is raised. |
| password | string | True | Password of the user. |
-NOTE: The schema for `password` also defines `encrypted = true`, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+NOTE: `encrypt_fields = {"password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
For Route:
diff --git a/docs/en/latest/plugins/clickhouse-logger.md b/docs/en/latest/plugins/clickhouse-logger.md
index 9de95ccf1..465ebb945 100644
--- a/docs/en/latest/plugins/clickhouse-logger.md
+++ b/docs/en/latest/plugins/clickhouse-logger.md
@@ -45,9 +45,9 @@ The `clickhouse-logger` Plugin is used to push logs to [ClickHouse](https://clic
| name | string | False | "clickhouse logger" | | Unique identifier for the logger. |
| ssl_verify | boolean | False | true | [true,false] | When set to `true`, verifies SSL. |
-This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
+NOTE: `encrypt_fields = {"password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
-NOTE: The schema for `password` also defines `encrypted = true`, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Metadata
diff --git a/docs/en/latest/plugins/csrf.md b/docs/en/latest/plugins/csrf.md
index b3cd5cb7a..a5884a5be 100644
--- a/docs/en/latest/plugins/csrf.md
+++ b/docs/en/latest/plugins/csrf.md
@@ -41,6 +41,8 @@ This Plugin considers the `GET`, `HEAD` and `OPTIONS` methods to be safe operati
| expires | number | False | `7200` | Expiration time in seconds of the CSRF cookie. Set to `0` to skip checking expiration time. |
| key | string | True | | Secret key used to encrypt the cookie. |
+NOTE: `encrypt_fields = {"key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
## Enabling the Plugin
The example below shows how you can enable the Plugin on a specific Route:
diff --git a/docs/en/latest/plugins/elasticsearch-logger.md b/docs/en/latest/plugins/elasticsearch-logger.md
index 51deead86..739641d57 100644
--- a/docs/en/latest/plugins/elasticsearch-logger.md
+++ b/docs/en/latest/plugins/elasticsearch-logger.md
@@ -47,6 +47,8 @@ When the Plugin is enabled, APISIX will serialize the request context informatio
| ssl_verify | boolean | False | true | When set to `true` enables SSL verification as per [OpenResty docs](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake). |
| timeout | integer | False | 10 | Elasticsearch send data timeout in seconds. |
+NOTE: `encrypt_fields = {"auth.password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Enabling the Plugin
diff --git a/docs/en/latest/plugins/error-log-logger.md b/docs/en/latest/plugins/error-log-logger.md
index a37a7a5ff..63b1be1c7 100644
--- a/docs/en/latest/plugins/error-log-logger.md
+++ b/docs/en/latest/plugins/error-log-logger.md
@@ -52,6 +52,8 @@ It might take some time to receive the log data. It will be automatically sent a
| keepalive | integer | False | 30 | [1,...] | Time in seconds to keep the connection alive after sending data. |
| level | string | False | WARN | ["STDERR", "EMERG", "ALERT", "CRIT", "ERR", "ERROR", "WARN", "NOTICE", "INFO", "DEBUG"] | Log level to filter the error logs. `ERR` is same as `ERROR`. |
+NOTE: `encrypt_fields = {"clickhouse.password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Enabling the Plugin
diff --git a/docs/en/latest/plugins/google-cloud-logging.md b/docs/en/latest/plugins/google-cloud-logging.md
index d243aca87..d04d939ca 100644
--- a/docs/en/latest/plugins/google-cloud-logging.md
+++ b/docs/en/latest/plugins/google-cloud-logging.md
@@ -47,6 +47,8 @@ This plugin also allows to push logs as a batch to your Google Cloud Logging Ser
| resource | False | {"type": "global"} | Google monitor resource. See [MonitoredResource](https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource) for more details. |
| log_id | False | apisix.apache.org%2Flogs | Google Cloud logging ID. See [LogEntry](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry) for details. |
+NOTE: `encrypt_fields = {"auth_config.private_key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Enabling the Plugin
diff --git a/docs/en/latest/plugins/hmac-auth.md b/docs/en/latest/plugins/hmac-auth.md
index c43d24a61..5aaef2eb3 100644
--- a/docs/en/latest/plugins/hmac-auth.md
+++ b/docs/en/latest/plugins/hmac-auth.md
@@ -47,6 +47,8 @@ This Plugin works with a [Consumer](../terminology/consumer.md) object and a con
| validate_request_body | boolean | False | false | [ true, false ] | When set to `true`, validates the request body. |
| max_req_body | integer | False | 512 * 1024 | | Max size of the request body to allow. |
+NOTE: `encrypt_fields = {"secret_key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
## Enabling the Plugin
First we enable the Plugin on a Consumer object as shown below:
diff --git a/docs/en/latest/plugins/jwt-auth.md b/docs/en/latest/plugins/jwt-auth.md
index fffb01846..124ae3857 100644
--- a/docs/en/latest/plugins/jwt-auth.md
+++ b/docs/en/latest/plugins/jwt-auth.md
@@ -51,6 +51,8 @@ For Consumer:
| vault | object | False | | | Set to true to use Vault for storing and retrieving secret (secret for HS256/HS512 or public_key and private_key for RS256/ES256). By default, the Vault path is `kv/apisix/consumer/<consumer_name>/jwt-auth`. |
| lifetime_grace_period | integer | False | 0 | [0,...] | Define the leeway in seconds to account for clock skew between the server that generated the jwt and the server validating it. Value should be zero (0) or a positive integer. |
+NOTE: `encrypt_fields = {"secret", "private_key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
:::info IMPORTANT
To enable Vault integration, you have to first update your configuration file (`conf/config.yaml`) with your Vault server configuration, host address and access token.
diff --git a/docs/en/latest/plugins/kafka-proxy.md b/docs/en/latest/plugins/kafka-proxy.md
index d0377cd0f..d7ca53ed7 100644
--- a/docs/en/latest/plugins/kafka-proxy.md
+++ b/docs/en/latest/plugins/kafka-proxy.md
@@ -38,6 +38,8 @@ The `kafka-proxy` plugin can be used to configure advanced parameters for the ka
| sasl.username | string | required | | | SASL/PLAIN authentication username |
| sasl.password | string | required | | | SASL/PLAIN authentication password |
+NOTE: `encrypt_fields = {"sasl.password"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
:::note
If SASL authentication is enabled, the `sasl.username` and `sasl.password` must be set.
The current SASL authentication only supports PLAIN mode, which is the username password login method.
diff --git a/docs/en/latest/plugins/key-auth.md b/docs/en/latest/plugins/key-auth.md
index b188cbc27..ebac702bb 100644
--- a/docs/en/latest/plugins/key-auth.md
+++ b/docs/en/latest/plugins/key-auth.md
@@ -41,7 +41,7 @@ For Consumer:
|------|--------|-------------|----------------------------|
| key | string | required | Unique key for a Consumer. |
-NOTE: The schema for `key` also defines `encrypted = true`, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+NOTE: `encrypt_fields = {"key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
For Route:
diff --git a/docs/en/latest/plugins/openid-connect.md b/docs/en/latest/plugins/openid-connect.md
index 965cf7474..e44e0f622 100644
--- a/docs/en/latest/plugins/openid-connect.md
+++ b/docs/en/latest/plugins/openid-connect.md
@@ -61,6 +61,8 @@ description: OpenID Connect allows the client to obtain user information from th
| session | object | False | | | When bearer_only is set to false, openid-connect will use Authorization Code flow to authenticate on the IDP, so you need to set the session-related configuration. |
| session.secret | string | True | Automatic generation | 16 or more characters | The key used for session encrypt and HMAC operation. |
+NOTE: `encrypt_fields = {"client_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
## Scenarios
:::tip
diff --git a/docs/en/latest/plugins/rocketmq-logger.md b/docs/en/latest/plugins/rocketmq-logger.md
index 557f8ce55..003724b81 100644
--- a/docs/en/latest/plugins/rocketmq-logger.md
+++ b/docs/en/latest/plugins/rocketmq-logger.md
@@ -51,6 +51,8 @@ It might take some time to receive the log data. It will be automatically sent a
| include_resp_body | boolean | False | false | [false, true] | When set to `true` includes the response body in the log. |
| include_resp_body_expr | array | False | | | Filter for when the `include_resp_body` attribute is set to `true`. Response body is only logged when the expression set here evaluates to `true`. See [lua-resty-expr](https://github.com/api7/lua-resty-expr) for more. |
+NOTE: `encrypt_fields = {"secret_key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
:::info IMPORTANT
diff --git a/docs/en/latest/plugins/sls-logger.md b/docs/en/latest/plugins/sls-logger.md
index a823b6097..53ea083ba 100644
--- a/docs/en/latest/plugins/sls-logger.md
+++ b/docs/en/latest/plugins/sls-logger.md
@@ -47,6 +47,8 @@ It might take some time to receive the log data. It will be automatically sent a
| include_req_body | True | When set to `true`, includes the request body in the log. |
| name | False | Unique identifier for the batch processor. |
+NOTE: `encrypt_fields = {"access_key_secret"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Metadata
diff --git a/docs/en/latest/plugins/tencent-cloud-cls.md b/docs/en/latest/plugins/tencent-cloud-cls.md
index fcdc6d0f5..fb3210100 100644
--- a/docs/en/latest/plugins/tencent-cloud-cls.md
+++ b/docs/en/latest/plugins/tencent-cloud-cls.md
@@ -45,6 +45,8 @@ The `tencent-cloud-cls` Plugin uses [TencentCloud CLS](https://cloud.tencent.com
| include_resp_body | boolean | No | false | [false, true] | When set to `true` includes the response body in the log. |
| global_tag | object | No | | | kv pairs in JSON,send with each log. |
+NOTE: `encrypt_fields = {"secret_key"}` is also defined in the schema, which means that the field will be stored encrypted in etcd. See [encrypted storage fields](../plugin-develop.md#encrypted-storage-fields).
+
This Plugin supports using batch processors to aggregate and process entries (logs/data) in a batch. This avoids the need for frequently submitting the data. The batch processor submits data every `5` seconds or when the data in the queue reaches `1000`. See [Batch Processor](../batch-processor.md#configuration) for more information or setting your custom configuration.
## Metadata
diff --git a/docs/zh/latest/plugin-develop.md b/docs/zh/latest/plugin-develop.md
index 6012c323c..f40363002 100644
--- a/docs/zh/latest/plugin-develop.md
+++ b/docs/zh/latest/plugin-develop.md
@@ -280,13 +280,24 @@ end
有些插件需要将参数加密存储,比如 `basic-auth` 插件的 `password` 参数。这个插件需要在 `schema` 中指定哪些参数需要被加密存储。
```lua
-password = { type = "string", encrypted = true },
+encrypt_fields = {"password"}
```
-通过在 `schema` 中指定 `encrypted = true`,可以将参数加密存储。APISIX 将提供以下功能:
+如果是嵌套的参数,比如 `error-log-logger` 插件的 `clickhouse.password` 参数,需要用 `.` 来分隔:
-- 通过 `Admin API` 来新增和更新资源时,对于 `encrypted = true` 的参数,APISIX 会自动加密存储在 etcd 中
-- 通过 `Admin API` 来获取资源时,以及在运行插件时,对于 `encrypted = true` 的参数,APISIX 会自动解密
+```lua
+encrypt_fields = {"clickhouse.password"}
+```
+
+目前还不支持:
+
+1. 两层以上的嵌套
+2. 数组中的字段
+
+通过在 `schema` 中指定 `encrypt_fields = {"password"}`,可以将参数加密存储。APISIX 将提供以下功能:
+
+- 通过 `Admin API` 来新增和更新资源时,对于 `encrypt_fields` 中声明的参数,APISIX 会自动加密存储在 etcd 中
+- 通过 `Admin API` 来获取资源时,以及在运行插件时,对于 `encrypt_fields` 中声明的参数,APISIX 会自动解密
如何开启该功能?
@@ -301,7 +312,7 @@ apisix:
- qeddd145sfvddff4
```
-`keyring` 是一个数组,可以指定多个 key,APISIX 会按照 keyring 中 key 的顺序,依次尝试用 key 来解密数据(只对声明 `encrypted = true` 的参数)。如果解密失败,会尝试下一个 key,直到解密成功。
+`keyring` 是一个数组,可以指定多个 key,APISIX 会按照 keyring 中 key 的顺序,依次尝试用 key 来解密数据(只对在 `encrypt_fields` 声明的参数)。如果解密失败,会尝试下一个 key,直到解密成功。
如果 `keyring` 中的 key 都无法解密数据,则使用原始数据。
diff --git a/docs/zh/latest/plugins/authz-casdoor.md b/docs/zh/latest/plugins/authz-casdoor.md
index a0ed3d9cc..1ad294805 100644
--- a/docs/zh/latest/plugins/authz-casdoor.md
+++ b/docs/zh/latest/plugins/authz-casdoor.md
@@ -40,6 +40,8 @@ description: 本篇文档介绍了 Apache APISIX auth-casdoor 插件的相关信
| client_secret | string | 是 | Casdoor 的客户端密钥。 |
| callback_url | string | 是 | 用于接收 code 与 state 的回调地址。 |
+注意:schema 中还定义了 `encrypt_fields = {"client_secret"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
:::info IMPORTANT
指定 `endpoint_addr` 和 `callback_url` 属性时不要以 “/” 来结尾。
diff --git a/docs/zh/latest/plugins/authz-keycloak.md b/docs/zh/latest/plugins/authz-keycloak.md
index 6bc5c7b96..811baaa3b 100644
--- a/docs/zh/latest/plugins/authz-keycloak.md
+++ b/docs/zh/latest/plugins/authz-keycloak.md
@@ -66,6 +66,8 @@ description: 本文介绍了关于 Apache APISIX `authz-keycloak` 插件的基
| access_denied_redirect_uri | string | 否 | | [1, 2048] | 需要将用户重定向到的 URI,而不是返回类似 `"error_description":"not_authorized"` 这样的错误消息。 |
| password_grant_token_generation_incoming_uri | string | 否 | | /api/token | 将此设置为使用密码授予类型生成令牌。该插件会将传入的请求 URI 与此值进行比较。 |
+注意:schema 中还定义了 `encrypt_fields = {"client_secret"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
除上述释义外,还有以下需要注意的点:
- Discovery and endpoints
diff --git a/docs/zh/latest/plugins/basic-auth.md b/docs/zh/latest/plugins/basic-auth.md
index f19dcab57..ac8035152 100644
--- a/docs/zh/latest/plugins/basic-auth.md
+++ b/docs/zh/latest/plugins/basic-auth.md
@@ -42,7 +42,7 @@ Consumer 端:
| username | string | 是 | Consumer 的用户名并且该用户名是唯一,如果多个 Consumer 使用了相同的 `username`,将会出现请求匹配异常。|
| password | string | 是 | 用户的密码。 |
-注意:`password` 的 schema 中还定义了 `encrypted = true`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+注意:schema 中还定义了 `encrypt_fields = {"password"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
Route 端:
diff --git a/docs/zh/latest/plugins/clickhouse-logger.md b/docs/zh/latest/plugins/clickhouse-logger.md
index dc35db7e9..aed09ca71 100644
--- a/docs/zh/latest/plugins/clickhouse-logger.md
+++ b/docs/zh/latest/plugins/clickhouse-logger.md
@@ -45,9 +45,9 @@ description: 本文介绍了 API 网关 Apache APISIX 如何使用 clickhouse-lo
| name | string | 否 | "clickhouse logger" | | 标识 logger 的唯一标识符。 |
| ssl_verify | boolean | 否 | true | [true,false] | 当设置为 `true` 时,验证证书。 |
-该插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认情况下批处理器每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置)。
+注意:schema 中还定义了 `encrypt_fields = {"password"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
-注意:`password` 的 schema 中还定义了 `encrypted = true`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+该插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认情况下批处理器每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置)。
## 配置插件元数据
diff --git a/docs/zh/latest/plugins/csrf.md b/docs/zh/latest/plugins/csrf.md
index 5db88f8a0..86fb54579 100644
--- a/docs/zh/latest/plugins/csrf.md
+++ b/docs/zh/latest/plugins/csrf.md
@@ -43,6 +43,8 @@ description: CSRF 插件基于 Double Submit Cookie 的方式,帮助用户阻
| expires | number | 否 | `7200` | | CSRF Cookie 的过期时间,单位为秒。当设置为 `0` 时,会忽略 CSRF Cookie 过期时间检查。|
| key | string | 是 | | | 加密 Token 的密钥。 |
+注意:schema 中还定义了 `encrypt_fields = {"key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
## 启用插件
以下示例展示了如何在指定路由上启用并配置 `csrf` 插件:
diff --git a/docs/zh/latest/plugins/elasticsearch-logger.md b/docs/zh/latest/plugins/elasticsearch-logger.md
index 82e035d05..4b25d3077 100644
--- a/docs/zh/latest/plugins/elasticsearch-logger.md
+++ b/docs/zh/latest/plugins/elasticsearch-logger.md
@@ -48,6 +48,8 @@ description: 本文介绍了 API 网关 Apache APISIX 的 elasticsearch-logger
| ssl_verify | boolean | 否 | true | 当设置为 `true` 时则启用 SSL 验证。更多信息请参考 [lua-nginx-module](https://github.com/openresty/lua-nginx-module#tcpsocksslhandshake)。 |
| timeout | integer | 否 | 10 | 发送给 Elasticsearch 请求超时时间。 |
+注意:schema 中还定义了 `encrypt_fields = {"auth.password"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
本插件支持使用批处理器来聚合并批量处理条目(日志和数据)。这样可以避免插件频繁地提交数据,默认设置情况下批处理器会每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解或自定义批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置) 配置部分。
## 启用插件
diff --git a/docs/zh/latest/plugins/error-log-logger.md b/docs/zh/latest/plugins/error-log-logger.md
index 02c717e6f..daee4c521 100644
--- a/docs/zh/latest/plugins/error-log-logger.md
+++ b/docs/zh/latest/plugins/error-log-logger.md
@@ -51,6 +51,8 @@ description: API 网关 Apache APISIX error-log-logger 插件用于将 APISIX
| keepalive | integer | 否 | 30 | [1,...] | 复用连接时,连接保持的时间,以秒为单位。 |
| level | string | 否 | WARN | | 进行错误日志筛选的级别,默认为 `WARN`,取值 ["STDERR", "EMERG", "ALERT", "CRIT", "ERR", "ERROR", "WARN", "NOTICE", "INFO", "DEBUG"],其中 `ERR` 与 `ERROR` 级别一致。 |
+注意:schema 中还定义了 `encrypt_fields = {"clickhouse.password"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
本插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认设置情况下批处理器会每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解或自定义批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置) 配置部分。
## 启用插件
diff --git a/docs/zh/latest/plugins/google-cloud-logging.md b/docs/zh/latest/plugins/google-cloud-logging.md
index 067557c29..7a62b8ac9 100644
--- a/docs/zh/latest/plugins/google-cloud-logging.md
+++ b/docs/zh/latest/plugins/google-cloud-logging.md
@@ -47,6 +47,8 @@ description: API 网关 Apache APISIX 的 google-cloud-logging 插件可用于
| resource | 否 | {"type": "global"} | 谷歌监控资源,请参考 [MonitoredResource](https://cloud.google.com/logging/docs/reference/v2/rest/v2/MonitoredResource)。 |
| log_id | 否 | apisix.apache.org%2Flogs | 谷歌日志 ID,请参考 [LogEntry](https://cloud.google.com/logging/docs/reference/v2/rest/v2/LogEntry)。 |
+注意:schema 中还定义了 `encrypt_fields = {"auth_config.private_key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
该插件支持使用批处理器来聚合并批量处理条目(日志和数据)。这样可以避免该插件频繁地提交数据。默认情况下每 `5` 秒钟或队列中的数据达到 `1000` 条时,批处理器会自动提交数据,如需了解更多信息或自定义配置,请参考 [Batch Processor](../batch-processor.md#配置)。
## 启用插件
diff --git a/docs/zh/latest/plugins/hmac-auth.md b/docs/zh/latest/plugins/hmac-auth.md
index 8621611d9..54c1d0454 100644
--- a/docs/zh/latest/plugins/hmac-auth.md
+++ b/docs/zh/latest/plugins/hmac-auth.md
@@ -47,6 +47,8 @@ description: 本文介绍了关于 Apache APISIX `hmac-auth` 插件的基本信
| validate_request_body | boolean | 否 | false | [ true, false ] | 当设置为 `true` 时,对请求 body 做签名校验。 |
| max_req_body | integer | 否 | 512 * 1024 | | 最大允许的 body 大小。 |
+注意:schema 中还定义了 `encrypt_fields = {"secret_key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
## 启用插件
首先,我们需要在 Consumer 中启用该插件,如下所示:
diff --git a/docs/zh/latest/plugins/jwt-auth.md b/docs/zh/latest/plugins/jwt-auth.md
index b4582f642..0f7196c5b 100644
--- a/docs/zh/latest/plugins/jwt-auth.md
+++ b/docs/zh/latest/plugins/jwt-auth.md
@@ -51,6 +51,8 @@ Consumer 端:
| vault | object | 否 | | | 是否使用 Vault 作为存储和检索密钥(HS256/HS512 的密钥或 RS256/ES256 的公钥和私钥)的方式。该插件默认使用 `kv/apisix/consumer/<consumer name>/jwt-auth` 路径进行密钥检索。 |
| lifetime_grace_period | integer | 否 | 0 | [0,...] | 定义生成 JWT 的服务器和验证 JWT 的服务器之间的时钟偏移。该值应该是零(0)或一个正整数。 |
+注意:schema 中还定义了 `encrypt_fields = {"secret", "private_key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
:::info IMPORTANT
如果你想要启用 Vault 集成,你需要在 [config.yaml](https://github.com/apache/apisix/blob/master/conf/config.yaml) 配置文件中,更新你的 Vault 服务器配置、主机地址和访问令牌。
diff --git a/docs/zh/latest/plugins/key-auth.md b/docs/zh/latest/plugins/key-auth.md
index 8031854e7..23817fea0 100644
--- a/docs/zh/latest/plugins/key-auth.md
+++ b/docs/zh/latest/plugins/key-auth.md
@@ -41,7 +41,7 @@ Consumer 端:
| ---- | ------ | ------ | ------------------------------------------------------------------------------------------------------------- |
| key | string | 是 | 不同的 Consumer 应有不同的 `key`,它应当是唯一的。如果多个 Consumer 使用了相同的 `key`,将会出现请求匹配异常。 |
-注意:`key` 的 schema 中还定义了 `encrypted = true`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+注意:schema 中还定义了 `encrypt_fields = {"key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
Router 端:
diff --git a/docs/zh/latest/plugins/openid-connect.md b/docs/zh/latest/plugins/openid-connect.md
index 5d5a11c30..13a6274ce 100644
--- a/docs/zh/latest/plugins/openid-connect.md
+++ b/docs/zh/latest/plugins/openid-connect.md
@@ -61,6 +61,8 @@ description: OpenID Connect(OIDC)是基于 OAuth 2.0 的身份认证协议
| session | object | 否 | | | 当设置 bearer_only 为 false 时,openid-connect 插件将使用 Authorization Code 在 IDP 上进行认证,因此你必须设置 session 相关设置。 |
| session.secret | string | 是 | 自动生成 | 16 个以上字符 | 用于 session 加密和 HMAC 计算的密钥。 |
+注意:schema 中还定义了 `encrypt_fields = {"client_secret"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
## 使用场景
:::tip
diff --git a/docs/zh/latest/plugins/rocketmq-logger.md b/docs/zh/latest/plugins/rocketmq-logger.md
index 235bc0f1c..5e952837d 100644
--- a/docs/zh/latest/plugins/rocketmq-logger.md
+++ b/docs/zh/latest/plugins/rocketmq-logger.md
@@ -50,6 +50,8 @@ description: API 网关 Apache APISIX 的 rocketmq-logger 插件用于将日志
| include_resp_body | boolean | 否 | false | [false, true] | 当设置为 `true` 时,包含响应体。 |
| include_resp_body_expr | array | 否 | | | 当 `include_resp_body` 属性设置为 `true` 时进行过滤响应体,并且只有当此处设置的表达式计算结果为 `true` 时,才会记录响应体。更多信息,请参考 [lua-resty-expr](https://github.com/api7/lua-resty-expr)。 |
+注意:schema 中还定义了 `encrypt_fields = {"secret_key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
该插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认设置情况下批处理器会每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置)。
:::tip 提示
diff --git a/docs/zh/latest/plugins/sls-logger.md b/docs/zh/latest/plugins/sls-logger.md
index 3b2e737a0..1162426f3 100644
--- a/docs/zh/latest/plugins/sls-logger.md
+++ b/docs/zh/latest/plugins/sls-logger.md
@@ -44,6 +44,8 @@ title: sls-logger
| include_req_body | 可选的 | 是否包含请求体。|
|name| 可选的 | 批处理名字。|
+注意:schema 中还定义了 `encrypt_fields = {"access_key_secret"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
本插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认设置情况下批处理器会每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解或自定义批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置) 配置部分。
## 插件元数据设置
diff --git a/docs/zh/latest/plugins/tencent-cloud-cls.md b/docs/zh/latest/plugins/tencent-cloud-cls.md
index 32a2b9e5c..a94791057 100644
--- a/docs/zh/latest/plugins/tencent-cloud-cls.md
+++ b/docs/zh/latest/plugins/tencent-cloud-cls.md
@@ -45,6 +45,8 @@ description: API 网关 Apache APISIX tencent-cloud-cls 插件可用于将日志
| include_resp_body | boolean | 否 | false | [false, true]| 当设置为 `true` 时,日志中将包含响应体。 |
| global_tag | object | 否 | | | kv 形式的 JSON 数据,可以写入每一条日志,便于在 CLS 中检索。 |
+注意:schema 中还定义了 `encrypt_fields = {"secret_key"}`,这意味着该字段将会被加密存储在 etcd 中。具体参考 [加密存储字段](../plugin-develop.md#加密存储字段)。
+
该插件支持使用批处理器来聚合并批量处理条目(日志/数据)。这样可以避免插件频繁地提交数据,默认情况下批处理器每 `5` 秒钟或队列中的数据达到 `1000` 条时提交数据,如需了解批处理器相关参数设置,请参考 [Batch-Processor](../batch-processor.md#配置)。
## 插件元数据
diff --git a/t/admin/plugins.t b/t/admin/plugins.t
index 5edb3c427..9791278e2 100644
--- a/t/admin/plugins.t
+++ b/t/admin/plugins.t
@@ -339,7 +339,7 @@ qr/\[\{"name":"wolf-rbac","priority":2555\},\{"name":"ldap-auth","priority":2540
}
}
--- response_body eval
-qr/\{"properties":\{"password":\{"encrypted":true,"type":"string"\},"username":\{"type":"string"\}\},"required":\["username","password"\],"title":"work with consumer object","type":"object"\}/
+qr/\{"encrypt_fields":\["password"\],"properties":\{"password":\{"type":"string"\},"username":\{"type":"string"\}\},"required":\["username","password"\],"title":"work with consumer object","type":"object"\}/
diff --git a/t/plugin/authz-casdoor.t b/t/plugin/authz-casdoor.t
index ace2c966b..926d3daef 100644
--- a/t/plugin/authz-casdoor.t
+++ b/t/plugin/authz-casdoor.t
@@ -438,3 +438,71 @@ invalid state
done
--- error_log
failed when accessing token: invalid access_token
+
+
+
+=== TEST 10: data encryption for client_secret
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local callback_url = "http://127.0.0.1:" .. ngx.var.server_port ..
+ "/anything/callback"
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "methods": ["GET"],
+ "uri": "/anything/*",
+ "plugins": {
+ "authz-casdoor": {
+ "callback_url":"]] .. callback_url .. [[",
+ "endpoint_addr": "http://127.0.0.1:10420",
+ "client_id":"7ceb9b7fda4a9061ec1c",
+ "client_secret":"3416238e1edf915eac08b8fe345b2b95cdba7e04"
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "httpbin.org:80": 1
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["authz-casdoor"].client_secret)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["authz-casdoor"].client_secret)
+ }
+ }
+--- response_body
+3416238e1edf915eac08b8fe345b2b95cdba7e04
+YUfqAO0kPXjZIoAbPSuryCkUDksEmwSq08UDTIUWolN6KQwEUrh72TazePueo4/S
diff --git a/t/plugin/authz-keycloak3.t b/t/plugin/authz-keycloak3.t
index a198fb8f8..2671e9039 100644
--- a/t/plugin/authz-keycloak3.t
+++ b/t/plugin/authz-keycloak3.t
@@ -106,3 +106,73 @@ passed
--- error_code: 307
--- response_headers
Location: http://127.0.0.1/test
+
+
+
+=== TEST 3: data encryption for client_secret
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "authz-keycloak": {
+ "token_endpoint": "https://127.0.0.1:8443/auth/realms/University/protocol/openid-connect/token",
+ "permissions": ["course_resource#view"],
+ "client_id": "course_management",
+ "client_secret": "d1ec69e9-55d2-4109-a3ea-befa071579d5",
+ "grant_type": "urn:ietf:params:oauth:grant-type:uma-ticket",
+ "timeout": 3000,
+ "ssl_verify": false,
+ "password_grant_token_generation_incoming_uri": "/api/token"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/api/token"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["authz-keycloak"].client_secret)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["authz-keycloak"].client_secret)
+ }
+ }
+--- response_body
+d1ec69e9-55d2-4109-a3ea-befa071579d5
+Fz1juZEEvh9PPXOmWFdMMJkREt3ZSzEVWcUZPxNP6achk3fosEvn37oN0qH4YgKB
diff --git a/t/plugin/csrf.t b/t/plugin/csrf.t
index 6f76dabb4..1edc30239 100644
--- a/t/plugin/csrf.t
+++ b/t/plugin/csrf.t
@@ -325,3 +325,66 @@ passed
}
--- response_body
hello world
+
+
+
+=== TEST 15: data encryption for key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/hello",
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:1980": 1
+ }
+ },
+ "plugins": {
+ "csrf": {
+ "key": "userkey",
+ "expires": 1000000000
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["csrf"].key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["csrf"].key)
+ }
+ }
+--- response_body
+userkey
+mt39FazQccyMqt4ctoRV7w==
diff --git a/t/plugin/elasticsearch-logger.t b/t/plugin/elasticsearch-logger.t
index b381bf752..11b85e14b 100644
--- a/t/plugin/elasticsearch-logger.t
+++ b/t/plugin/elasticsearch-logger.t
@@ -447,3 +447,71 @@ hello world
--- wait: 2
--- error_log
check elasticsearch custom body success
+
+
+
+=== TEST 12: data encryption for auth.password
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, {
+ uri = "/hello",
+ upstream = {
+ type = "roundrobin",
+ nodes = {
+ ["127.0.0.1:1980"] = 1
+ }
+ },
+ plugins = {
+ ["elasticsearch-logger"] = {
+ endpoint_addr = "http://127.0.0.1:9201",
+ field = {
+ index = "services"
+ },
+ auth = {
+ username = "elastic",
+ password = "123456"
+ },
+ batch_max_size = 1,
+ inactive_timeout = 1
+ }
+ }
+ })
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["elasticsearch-logger"].auth.password)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["elasticsearch-logger"].auth.password)
+ }
+ }
+--- response_body
+123456
+PTQvJEaPcNOXcOHeErC0XQ==
diff --git a/t/plugin/error-log-logger-clickhouse.t b/t/plugin/error-log-logger-clickhouse.t
index f6a328d7f..41dfe15d4 100644
--- a/t/plugin/error-log-logger-clickhouse.t
+++ b/t/plugin/error-log-logger-clickhouse.t
@@ -211,3 +211,85 @@ this is an info message for test6
}
--- response_body
passed
+
+
+
+=== TEST 8: data encryption for clickhouse.password
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/plugin_metadata/error-log-logger',
+ ngx.HTTP_PUT,
+ [[{
+ "clickhouse": {
+ "user": "default",
+ "password": "bar",
+ "database": "default",
+ "logtable": "t",
+ "endpoint_addr": "http://127.0.0.1:1980/clickhouse_logger_server"
+ },
+ "batch_max_size": 15,
+ "inactive_timeout": 1
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/plugin_metadata/error-log-logger',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value["clickhouse"].password)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/plugin_metadata/error-log-logger'))
+
+ ngx.say(res.body.node.value["clickhouse"].password)
+ }
+ }
+--- response_body
+bar
+77+NmbYqNfN+oLm0aX5akg==
+
+
+
+=== TEST 9: verify use the decrypted password to connect to clickhouse
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local core = require("apisix.core")
+ core.log.warn("this is a warning message for test9")
+ }
+ }
+--- response_body
+--- error_log
+this is a warning message for test9
+clickhouse headers: x-clickhouse-key:bar
+--- wait: 5
diff --git a/t/plugin/google-cloud-logging2.t b/t/plugin/google-cloud-logging2.t
index 8efec7942..6fbe6b350 100644
--- a/t/plugin/google-cloud-logging2.t
+++ b/t/plugin/google-cloud-logging2.t
@@ -68,3 +68,128 @@ __DATA__
}
--- response_body
passed
+
+
+
+=== TEST 2: data encryption for auth_config.private_key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local config = {
+ uri = "/hello",
+ upstream = {
+ type = "roundrobin",
+ nodes = {
+ ["127.0.0.1:1980"] = 1
+ }
+ },
+ plugins = {
+ ["google-cloud-logging"] = {
+ auth_config = {
+ private_key = [[
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDDzrFwnA3EvYyR
+aeMgaLD3hBjvxKrz10uox1X8q7YYhf2ViRtLRUMa2bEMYksE5hbhwpNf6mKAnLOC
+UuAT6cPPdUl/agKpJXviBPIR2LuzD17WsLJHp1HxUDssSkgfCaGcOGGNfLUhhIpF
+2JUctLmxiZoAZySlSjcwupSuDJ0aPm0XO8r9H8Qu5kF2Vkz5e5bFivLTmvzrQTe4
+v5V1UI6hThElCSeUmdNF3uG3wopxlvq4zXgLTnuLbrNf/Gc4mlpV+UDgTISj32Ep
+AB2vxKEbvQw4ti8YJnGXWjxLerhfrszFw+V8lpeduiDYA44ZFoVqvzxeIsVZNtcw
+Iu7PvEPNAgMBAAECggEAVpyN9m7A1F631/aLheFpLgMbeKt4puV7zQtnaJ2XrZ9P
+PR7pmNDpTu4uF3k/D8qrIm+L+uhVa+hkquf3wDct6w1JVnfQ93riImbnoKdK13ic
+DcEZCwLjByfjFMNCxZ/gAZca55fbExlqhFy6EHmMjhB8s2LsXcTHRuGxNI/Vyi49
+sxECibe0U53aqdJbVWrphIS67cpwl4TUkN6mrHsNuDYNJ9dgkpapoqp4FTFQsBqC
+afOK5qgJ68dWZ47FBUng+AZjdCncqAIuJxxItGVQP6YPsFs+OXcivIVHJr363TpC
+l85FfdvqWV5OGBbwSKhNwiTNUVvfSQVmtURGWG/HbQKBgQD4gZ1z9+Lx19kT9WTz
+lw93lxso++uhAPDTKviyWSRoEe5aN3LCd4My+/Aj+sk4ON/s2BV3ska5Im93j+vC
+rCv3uPn1n2jUhWuJ3bDqipeTW4n/CQA2m/8vd26TMk22yOkkqw2MIA8sjJ//SD7g
+tdG7up6DgGMP4hgbO89uGU7DAwKBgQDJtkKd0grh3u52Foeh9YaiAgYRwc65IE16
+UyD1OJxIuX/dYQDLlo5KyyngFa1ZhWIs7qC7r3xXH+10kfJY+Q+5YMjmZjlL8SR1
+Ujqd02R9F2//6OeswyReachJZbZdtiEw3lPa4jVFYfhSe0M2ZPxMwvoXb25eyCNI
+1lYjSKq87wKBgHnLTNghjeDp4UKe6rNYPgRm0rDrhziJtX5JeUov1mALKb6dnmkh
+GfRK9g8sQqKDfXwfC6Z2gaMK9YaryujGaWYoCpoPXtmJ6oLPXH4XHuLh4mhUiP46
+xn8FEfSimuQS4/FMxH8A128GHQSI7AhGFFzlwfrBWcvXC+mNDsTvMmLxAoGARc+4
+upppfccETQZ7JsitMgD1TMwA2f2eEwoWTAitvlXFNT9PYSbYVHaAJbga6PLLCbYF
+FzAjHpxEOKYSdEyu7n/ayDL0/Z2V+qzc8KarDsg/0RgwppBbU/nUgeKb/U79qcYo
+y4ai3UKNCS70Ei1dTMvmdpnwXwlxfNIBufB6dy0CgYBMYq9Lc31GkC6PcGEEbx6W
+vjImOadWZbuOVnvEQjb5XCdcOsWsMcg96PtoeuyyHmhnEF1GsMzcIdQv/PHrvYpK
+Yp8D0aqsLEgwGrJQER26FPpKmyIwvcL+nm6q5W31PnU9AOC/WEkB6Zs58hsMzD2S
+kEJQcmfVew5mFXyxuEn3zA==
+-----END PRIVATE KEY-----]],
+ project_id = "apisix",
+ token_uri = "http://127.0.0.1:1980/google/logging/token",
+ scopes = {
+ "https://apisix.apache.org/logs:admin"
+ },
+ entries_uri = "http://127.0.0.1:1980/google/logging/entries",
+ },
+ inactive_timeout = 1,
+ batch_max_size = 1,
+ }
+ }
+ }
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_PUT, config)
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["google-cloud-logging"].auth_config.private_key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["google-cloud-logging"].auth_config.private_key)
+ }
+ }
+--- response_body
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDDzrFwnA3EvYyR
+aeMgaLD3hBjvxKrz10uox1X8q7YYhf2ViRtLRUMa2bEMYksE5hbhwpNf6mKAnLOC
+UuAT6cPPdUl/agKpJXviBPIR2LuzD17WsLJHp1HxUDssSkgfCaGcOGGNfLUhhIpF
+2JUctLmxiZoAZySlSjcwupSuDJ0aPm0XO8r9H8Qu5kF2Vkz5e5bFivLTmvzrQTe4
+v5V1UI6hThElCSeUmdNF3uG3wopxlvq4zXgLTnuLbrNf/Gc4mlpV+UDgTISj32Ep
+AB2vxKEbvQw4ti8YJnGXWjxLerhfrszFw+V8lpeduiDYA44ZFoVqvzxeIsVZNtcw
+Iu7PvEPNAgMBAAECggEAVpyN9m7A1F631/aLheFpLgMbeKt4puV7zQtnaJ2XrZ9P
+PR7pmNDpTu4uF3k/D8qrIm+L+uhVa+hkquf3wDct6w1JVnfQ93riImbnoKdK13ic
+DcEZCwLjByfjFMNCxZ/gAZca55fbExlqhFy6EHmMjhB8s2LsXcTHRuGxNI/Vyi49
+sxECibe0U53aqdJbVWrphIS67cpwl4TUkN6mrHsNuDYNJ9dgkpapoqp4FTFQsBqC
+afOK5qgJ68dWZ47FBUng+AZjdCncqAIuJxxItGVQP6YPsFs+OXcivIVHJr363TpC
+l85FfdvqWV5OGBbwSKhNwiTNUVvfSQVmtURGWG/HbQKBgQD4gZ1z9+Lx19kT9WTz
+lw93lxso++uhAPDTKviyWSRoEe5aN3LCd4My+/Aj+sk4ON/s2BV3ska5Im93j+vC
+rCv3uPn1n2jUhWuJ3bDqipeTW4n/CQA2m/8vd26TMk22yOkkqw2MIA8sjJ//SD7g
+tdG7up6DgGMP4hgbO89uGU7DAwKBgQDJtkKd0grh3u52Foeh9YaiAgYRwc65IE16
+UyD1OJxIuX/dYQDLlo5KyyngFa1ZhWIs7qC7r3xXH+10kfJY+Q+5YMjmZjlL8SR1
+Ujqd02R9F2//6OeswyReachJZbZdtiEw3lPa4jVFYfhSe0M2ZPxMwvoXb25eyCNI
+1lYjSKq87wKBgHnLTNghjeDp4UKe6rNYPgRm0rDrhziJtX5JeUov1mALKb6dnmkh
+GfRK9g8sQqKDfXwfC6Z2gaMK9YaryujGaWYoCpoPXtmJ6oLPXH4XHuLh4mhUiP46
+xn8FEfSimuQS4/FMxH8A128GHQSI7AhGFFzlwfrBWcvXC+mNDsTvMmLxAoGARc+4
+upppfccETQZ7JsitMgD1TMwA2f2eEwoWTAitvlXFNT9PYSbYVHaAJbga6PLLCbYF
+FzAjHpxEOKYSdEyu7n/ayDL0/Z2V+qzc8KarDsg/0RgwppBbU/nUgeKb/U79qcYo
+y4ai3UKNCS70Ei1dTMvmdpnwXwlxfNIBufB6dy0CgYBMYq9Lc31GkC6PcGEEbx6W
+vjImOadWZbuOVnvEQjb5XCdcOsWsMcg96PtoeuyyHmhnEF1GsMzcIdQv/PHrvYpK
+Yp8D0aqsLEgwGrJQER26FPpKmyIwvcL+nm6q5W31PnU9AOC/WEkB6Zs58hsMzD2S
+kEJQcmfVew5mFXyxuEn3zA==
+-----END PRIVATE KEY-----
+YnwwDKc5vNzo0OU4StTRQbwgCnTZ3dmYiBFm8aGnvTxlE86D2nT07Q3BWhUdky6OGIox4MRLbiHz13NZjyUao/Nudh4PeTj5wMldPD5YvNWtbTG4ig/TNSdBncmIQPLPaUqSweE61pnASxodpTlBJ5k9yxfTmwBTOkzZevoKy9D2E4wF9vGCdkcPK/tAkvRoJTj6xD3xVuAbkcap/81oHplUZZ+ghlEnBZgOH8UMa73UfeNbOQVHD2mlU0LxkTXtwFhHWl50adrt890VDHev0+FUUDjv5Ysl8r/nnnlyq3SV4oqJfs/IVRKROe93e8sJ2/49o7kEv2XT1/6DjM/VsSLKfAi5rLNobcSaSzztSSLkrBFKQvvy2rRA7GFWKbIk+rPZhYmTMItDJv23XP6uzaLRPoq2f/AnRTKpWmA8Dk9TfFHsZLupKi1bmjCdtK8lpMCf9Au1rezt7+2BybQrtbbDbwPzC5bKHmKhc0GPTUzL [...]
diff --git a/t/plugin/hmac-auth3.t b/t/plugin/hmac-auth3.t
index 7e89b995d..df41efaa1 100644
--- a/t/plugin/hmac-auth3.t
+++ b/t/plugin/hmac-auth3.t
@@ -682,3 +682,76 @@ location /t {
}
--- response_body
passed
+
+
+
+=== TEST 13: delete exist consumers
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- delete exist consumers
+ local code, body = t('/apisix/admin/consumers/robin', ngx.HTTP_DELETE)
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 14: data encryption for secret_key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack",
+ "plugins": {
+ "hmac-auth": {
+ "access_key": "my-access-key",
+ "secret_key": "my-secret-key",
+ "clock_skew": 10
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/consumers/jack',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["hmac-auth"].secret_key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/consumers/jack'))
+ ngx.say(res.body.node.value.plugins["hmac-auth"].secret_key)
+ }
+ }
+--- response_body
+my-secret-key
+IRWpPjbDq5BCgHyIllnOMA==
diff --git a/t/plugin/jwt-auth3.t b/t/plugin/jwt-auth3.t
index 6a9777132..3e431232f 100755
--- a/t/plugin/jwt-auth3.t
+++ b/t/plugin/jwt-auth3.t
@@ -300,3 +300,145 @@ GET /get
Cookie: hello=world; jwt-cookie=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJrZXkiOiJ1c2VyLWtleSIsImV4cCI6MTg3OTMxODU0MX0.fNtFJnNmJgzbiYmGB0Yjvm-l6A6M4jRV1l4mnVFSYjs; foo=bar
--- response_body eval
qr/hello=world; foo=bar/
+
+
+
+=== TEST 13: delete exist consumers
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- delete exist consumers
+ local code, body = t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE)
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 14: data encryption for secret
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack",
+ "plugins": {
+ "jwt-auth": {
+ "key": "user-key",
+ "secret": "my-secret-key"
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/consumers/jack',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+ ngx.say(res.value.plugins["jwt-auth"].secret)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/consumers/jack'))
+ ngx.say(res.body.node.value.plugins["jwt-auth"].secret)
+ }
+ }
+--- response_body
+my-secret-key
+IRWpPjbDq5BCgHyIllnOMA==
+
+
+
+=== TEST 15: data encryption for private_key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+
+ -- dletet exist consumers
+ t('/apisix/admin/consumers/jack', ngx.HTTP_DELETE)
+
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack",
+ "plugins": {
+ "jwt-auth": {
+ "key": "user-key-rs256",
+ "algorithm": "RS256",
+ "public_key": "-----BEGIN PUBLIC KEY-----\nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr\n7noq/0ukiZqVQLSJPMOv0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQ==\n-----END PUBLIC KEY-----",
+ "private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr7noq/0ukiZqVQLSJPMOv\n0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQJAYPWh6YvjwWobVYC45Hz7\n+pqlt1DWeVQMlN407HSWKjdH548ady46xiQuZ5Cfx3YyCcnsfVWaQNbC+jFbY4YL\nwQIhANfASwz8+2sKg1xtvzyaChX5S5XaQTB+azFImBJumixZAiEAxt93Td6JH1RF\nIeQmD/K+DClZMqSrliUzUqJnCPCzy6kCIAekDsRh/UF4ONjAJkKuLedDUfL3rNFb\n2M4BBSm58wnZAiEAwYLMOg8h6kQ7iMDRcI9I8diCHM8yz0SfbfbsvzxIFxECICXs\nYvIufaZvBa8f+E/9CAN [...]
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/consumers/jack',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["jwt-auth"].private_key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/consumers/jack'))
+ ngx.say(res.body.node.value.plugins["jwt-auth"].private_key)
+ }
+ }
+--- response_body
+-----BEGIN RSA PRIVATE KEY-----
+MIIBOgIBAAJBAKebDxlvQMGyEesAL1r1nIJBkSdqu3Hr7noq/0ukiZqVQLSJPMOv
+0oxQSutvvK3hoibwGakDOza+xRITB7cs2cECAwEAAQJAYPWh6YvjwWobVYC45Hz7
++pqlt1DWeVQMlN407HSWKjdH548ady46xiQuZ5Cfx3YyCcnsfVWaQNbC+jFbY4YL
+wQIhANfASwz8+2sKg1xtvzyaChX5S5XaQTB+azFImBJumixZAiEAxt93Td6JH1RF
+IeQmD/K+DClZMqSrliUzUqJnCPCzy6kCIAekDsRh/UF4ONjAJkKuLedDUfL3rNFb
+2M4BBSm58wnZAiEAwYLMOg8h6kQ7iMDRcI9I8diCHM8yz0SfbfbsvzxIFxECICXs
+YvIufaZvBa8f+E/9CANlVhm5wKAyM8N8GJsiCyEG
+-----END RSA PRIVATE KEY-----
+HrMHUvE9Esvn7GnZ+vAynaIg/8wlB3r0zm0htmnwofYPZeBpLnpW3iN9UtQG4ZIBYRZih6EBuRK8W3Kychw/SgjIFuzVeTFowBCUfd1wZ4Q+frUOLZ0Xmkh8j3yHUprnh+d9PA8EHCEapdkWY3psJj6rTgrREzjDEVf/TV3EjjfgG16ih5/c3TChApLXwfEwfBp5APSf7kzMccCRbA4bXvMDsQSQAwVsRD8cjJkSdHTvuzfg1g8xoCy4I05DsMM8CybJAd+BDZnJxhrGIQaItu5/0XQJy+uy/niOpzYYN+NDX+8fl65VUxdUtqXF82ChRlmGP3+zKN7epufAsL/36pHOnS73Q7WBKRxyyA16BEBk0wK7rI+KemBfG5YFXjcBnPkxYssSudqhmlcr6e5Tl0LhVj/BIj94fVE3/EJ+NO3BJMrlhjorilrQKAsiCWujWSqAK7gtAp3YEO//yOygh/p8gh22NdIV0ykGAx4QNKIN [...]
diff --git a/t/plugin/kafka-proxy.t b/t/plugin/kafka-proxy.t
index a6ada516f..52ba9d874 100644
--- a/t/plugin/kafka-proxy.t
+++ b/t/plugin/kafka-proxy.t
@@ -55,3 +55,68 @@ done
done
property "sasl" validation failed: property "password" is required
property "sasl" validation failed: property "password" validation failed: wrong type: expected string, got number
+
+
+
+=== TEST 2: data encryption for sasl.password
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "kafka-proxy": {
+ "sasl": {
+ "username": "admin",
+ "password": "admin-secret"
+ }
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/opentracing"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["kafka-proxy"].sasl.password)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["kafka-proxy"].sasl.password)
+ }
+ }
+--- response_body
+admin-secret
+y4Z3aqo51xrt3f9UziNUrg==
diff --git a/t/plugin/openid-connect2.t b/t/plugin/openid-connect2.t
index 810df9775..c9c963319 100644
--- a/t/plugin/openid-connect2.t
+++ b/t/plugin/openid-connect2.t
@@ -78,3 +78,72 @@ __DATA__
end
}
}
+
+
+
+=== TEST 2: data encryption for client_secret
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "openid-connect": {
+ "client_id": "kbyuFDidLLm280LIwVFiazOqjO3ty8KH",
+ "client_secret": "60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa",
+ "discovery": "http://127.0.0.1:1980/.well-known/openid-configuration",
+ "redirect_uri": "https://iresty.com",
+ "ssl_verify": false,
+ "timeout": 10,
+ "scope": "apisix",
+ "use_pkce": false
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["openid-connect"].client_secret)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["openid-connect"].client_secret)
+ }
+ }
+--- response_body
+60Op4HFM0I8ajz0WdiStAbziZ-VFQttXuxixHHs2R7r7-CW8GR79l-mmLqMhc-Sa
+xMlerg8pE2lPSDlQdPi+MsAwBnzqpyLRar3lUhP2Tdc2oXnWmit92p8cannhDYkBPc6P/Hlx0wSA0T2wle9QyHaW2oqw3bXDQSWWk8Vqq0o=
diff --git a/t/plugin/rocketmq-logger2.t b/t/plugin/rocketmq-logger2.t
index ae33d1f5c..af84ecf28 100644
--- a/t/plugin/rocketmq-logger2.t
+++ b/t/plugin/rocketmq-logger2.t
@@ -440,3 +440,68 @@ qr/send data to rocketmq: \{.*"body":"hello world\\n"/
}
--- response_body
done
+
+
+
+=== TEST 14: data encryption for secret_key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "rocketmq-logger": {
+ "nameserver_list" : [ "127.0.0.1:9876" ],
+ "topic" : "test2",
+ "access_key": "foo",
+ "secret_key": "bar"
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["rocketmq-logger"].secret_key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["rocketmq-logger"].secret_key)
+ }
+ }
+--- response_body
+bar
+77+NmbYqNfN+oLm0aX5akg==
diff --git a/t/plugin/sls-logger.t b/t/plugin/sls-logger.t
index c8aaf9c4f..c1bce8107 100644
--- a/t/plugin/sls-logger.t
+++ b/t/plugin/sls-logger.t
@@ -240,3 +240,86 @@ passed
GET /hello
--- response_body
hello world
+
+
+
+=== TEST 10: delete exist routes
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- delete exist consumers
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_DELETE)
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 11: data encryption for access_key_secret
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "sls-logger": {
+ "host": "100.100.99.135",
+ "port": 10009,
+ "project": "your_project",
+ "logstore": "your_logstore",
+ "access_key_id": "your_access_key_id",
+ "access_key_secret": "your_access_key_secret",
+ "timeout": 30000
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1980": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/hello"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["sls-logger"].access_key_secret)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["sls-logger"].access_key_secret)
+ }
+ }
+--- response_body
+your_access_key_secret
+1T6nR0fz4yhz/zTuRTvt7Xu3c9ASelDXG2//e/A5OiA=
diff --git a/t/plugin/tencent-cloud-cls.t b/t/plugin/tencent-cloud-cls.t
index e5736fa0f..b16e5c124 100644
--- a/t/plugin/tencent-cloud-cls.t
+++ b/t/plugin/tencent-cloud-cls.t
@@ -324,3 +324,88 @@ GET /opentracing
--- response_body
opentracing
--- wait: 0.5
+
+
+
+=== TEST 11: delete exist routes
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ -- delete exist consumers
+ local code, body = t('/apisix/admin/routes/1', ngx.HTTP_DELETE)
+ ngx.say(body)
+ }
+ }
+--- response_body
+passed
+
+
+
+=== TEST 12: data encryption for secret_key
+--- yaml_config
+apisix:
+ data_encryption:
+ enable: true
+ keyring:
+ - edd1c9f0985e76a2
+--- config
+ location /t {
+ content_by_lua_block {
+ local json = require("toolkit.json")
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {
+ "tencent-cloud-cls": {
+ "cls_host": "127.0.0.1:10421",
+ "cls_topic": "143b5d70-139b-4aec-b54e-bb97756916de",
+ "secret_id": "secret_id",
+ "secret_key": "secret_key",
+ "batch_max_size": 1,
+ "max_retry_count": 1,
+ "retry_delay": 2,
+ "buffer_duration": 2,
+ "inactive_timeout": 2
+ }
+ },
+ "upstream": {
+ "nodes": {
+ "127.0.0.1:1982": 1
+ },
+ "type": "roundrobin"
+ },
+ "uri": "/opentracing"
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(body)
+ return
+ end
+ ngx.sleep(0.1)
+
+ -- get plugin conf from admin api, password is decrypted
+ local code, message, res = t('/apisix/admin/routes/1',
+ ngx.HTTP_GET
+ )
+ res = json.decode(res)
+ if code >= 300 then
+ ngx.status = code
+ ngx.say(message)
+ return
+ end
+
+ ngx.say(res.value.plugins["tencent-cloud-cls"].secret_key)
+
+ -- get plugin conf from etcd, password is encrypted
+ local etcd = require("apisix.core.etcd")
+ local res = assert(etcd.get('/routes/1'))
+ ngx.say(res.body.node.value.plugins["tencent-cloud-cls"].secret_key)
+ }
+ }
+--- response_body
+secret_key
+oshn8tcqE8cJArmEILVNPQ==