Skip to main content

Version: 3.10.0

Data Encryption with Keyring

Data encryption is a key consideration of APISIX. Sensitive information, such as user passwords and private keys, is often present in gateway configurations when implementing authentication or integrating with another system. To prevent these information from being intercepted and exploited by malicious actors, APISIX encrypts these information and transform them into unintelligible ciphertext for storage. The ciphertexts are then transformed back to plaintexts with the correct keys, whenever needed.

In APISIX, when the data encryption is enabled, the following data will be encrypted before being saved to etcd:

This guide will help you understand why you should enable data encryption for sensitive data and how you can enable data encryption to harden security.

Enable Data Encryption

By default, APISIX has data encryption enabled with two default keys:

apisix/cli/config.lua
apisix ={
...,
data_encryption = {
enable_encrypt_fields = true,
keyring = { "qeddd145sfvddff3", "edd1c9f0985e76a2" }
},
...
}

To see data encryption in effect, create a consumer JohnDoe with key-auth enabled:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "JohnDoe",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'

In this configuration, the user key is a sensitive information that should not be stored in plaintext.

You should see a response when the consumer is created, showing an encrypted key:

{
"key":"/apisix/consumers/JohnDoe",
"value":
{
"update_time":1718103993,
"create_time":1718102143,
"plugins":{
"key-auth":{
"key":"a/TGSySA4i1LGn4ZXlYuew=="
}
},
"username":"JohnDoe"
}
}

To further verify that the key is encrypted, you can also examine the item saved to etcd:

etcdctl get /apisix/consumers/JohnDoe

You should see the key has been encrypted:

{
"update_time":1718103993,
"create_time":1718102143,
"plugins":{
"key-auth":{
"key":"a/TGSySA4i1LGn4ZXlYuew=="
}
},
"username":"JohnDoe"
}

Similarly, APISIX will also encrypt the TLS certificate private key before saving it to etcd. To verify, you can follow steps in Configure HTTPS Between Client and APISIX and observe that server_key is encrypted.

Verify Decryption

To verify the consumer key-auth key will be decrypted and used as intended in authentication, create a route with key-auth enabled:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "auth-route",
"uri": "/get",
"plugins": {
"key-auth": {},
},
"upstream" : {
"nodes": {
"httpbin.org":1
}
}
}'

Send a request to the route with the consumer credential:

curl -i "http://127.0.0.1:9080/get" -H 'apikey: john-key'

You should receive an HTTP/1.1 200 OK response, verifying the key has been successfully decrypted and used in authentication.

Update Keyring

The encrypted data can be reversed to plaintext with the correct keyring. Therefore, it is strongly recommended that you use customized keyring in production.

The keys should be hexadecimal strings of length 16 to accompany the underlying cipher AES-128-CBC. To update the keyring, you can add the new keys as such:

config.yaml
apisix:
data_encryption:
enable_encrypt_fields: true
keyring:
- aa2b3c4d1e6f7g9h
- xiy8z7a2b522dke
- qeddd145sfvddff3
- edd1c9f0985e76a2

❶ Enable the encryption for sensitive plugin fields.

❷ Add the first and second new keys.

❸ Add the first and second old keys.

caution

If your APISIX is already running and has data encrypted, do not remove the old keys. Add the new keys at the top of the array, such as the above, so that the encrypted data can be correctly decrypted. Removing the old keys directly can render the encrypted data irreversible.

If no data has been encrypted, you may directly configure the section with your custom keys.

If your APISIX is already running, reload APISIX for configuration changes to take effect.

Disable Data Encryption

To disable data encryption, simply update the enable_encrypt_fields to false:

config.yaml
apisix:
data_encryption:
enable_encrypt_fields: false

If your APISIX is already running, reload APISIX for configuration changes to take effect.

Now if you configure the consumer with key-auth again:

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "JohnDoe",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'

You should see a response where the key is saved in plaintext:

{
"key":"/apisix/consumers/JohnDoe",
"value":
{
"update_time":1718103527,
"create_time":1718102143,
"plugins":{
"key-auth":{
"key":"john-key"}
},
"username":"JohnDoe"
}
}

Understand Plugin Encrypt Fields

Encrypt plugin fields are defined in the encrypt_fields attribute of each plugin schema. For example:

apisix/plugins/basic-auth.lua
local consumer_schema = {
type = "object",
title = "work with consumer object",
properties = {
username = { type = "string" },
password = { type = "string" },
},
encrypt_fields = {"password"},
required = {"username", "password"},
}

Once defined, these fields will be encrypted when data encryption is enabled.

The table below summarizes encrypt plugin fields of all plugins:

PluginField(s)
authz-casdoorclient_secret
authz-keycloakclient_secret
basic-authpassword
clickhouse-loggerpassword
elasticsearch-loggerauth.password
rocketmq-loggersecret_key
sls-loggeraccess_key_secret
error-log-loggerclickhouse.password
google-cloud-loggingauth_config.private_key
csrfkey
hmac-authsecret_key
jwt-authsecret, private_key
key-authkey
openwhiskservice_token
tencent-cloud-clssecret_key
openid-connectclient_secret, client_rsa_private_key
kafka-proxysasl.password
jwt-decryptkey, secret

API7.ai Logo

API Management for Modern Architectures with Edge, API Gateway, Kubernetes, and Service Mesh.

Product

API7 Cloud

SOC2 Type IRed Herring

Copyright © APISEVEN Ltd. 2019 – 2024. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the

Apache Software Foundation