Mask Sensitive Data in Logs
Data masking is a data protection technology aimed at preventing the exposure of sensitive information in various environments, thus supporting secure application testing and data analysis without compromising privacy.
The built-in data-mask
plugin provided by API7 Enterprise can help remove or replace sensitive information in request headers, request bodies, and URL queries.
This guide will walk you through masking sensitive information in the URL-encoded request bodies using API7 Enterprise. The file-logger
plugin used for logging in the example is only to show that information has been successfully masked. Adjust accordingly per your use case.
Below is an interactive demo providing a hands-on introduction to masking sensitive data in logs.
Prerequisite(s)
Enable data-mask
and file-logger
Plugins
- Dashboard
- ADC
- Ingress Controller
-
Select Published Services of your gateway group from the side navigation bar, then click the service you want to modify, for example, a no-version
httpbin
service. -
Under the published service, select Routes from the side navigation bar.
-
Select your target route, for example,
/anything
. -
Click + Add Plugin.
-
Search for the
data-mask
plugin. -
Click Add.
-
In the dialog box, do the following:
- Add the following configuration to the JSON Editor:
{
"request": [
{
"action": "remove",
"body_format": "urlencoded",
"name": "password",
"type": "body"
},
{
"action": "replace",
"body_format": "urlencoded",
"name": "token",
"type": "body",
"value": "*****"
},
{
"action": "regex",
"body_format": "urlencoded",
"name": "card",
"regex": "(\\d+)\\-\\d+\\-\\d+\\-(\\d+)",
"type": "body",
"value": "$1-****-****-$2"
}
]
}- Click Add.
-
Under the same route, click + Add Plugin.
-
Search for the
file-logger
plugin. -
Click Add.
-
In the dialog box, do the following:
- Add the following configuration to the JSON Editor:
{
"include_req_body": true,
"path": "/tmp/mask-urlencoded-body.log"
}- Click Add.
Update the ADC configuration file with the data-mask
and file-logger
plugins:
services:
- name: httpbin
upstream:
name: default
scheme: http
nodes:
- host: httpbin.org
port: 80
weight: 100
routes:
- uris:
- /anything
name: getting-started-anything
methods:
- GET
plugins:
data-mask:
request:
- action: remove
body_format: urlencoded
name: password
type: body
- action: replace
body_format: urlencoded
name: token
type: body
value: "*****"
- action: regex
body_format: urlencoded
name: card
regex: "(\\d+)\\-\\d+\\-\\d+\\-(\\d+)"
type: body
value: "$1-****-****-$2"
file-logger:
include_req_body: true
path: /tmp/mask-urlencoded-body.log
Synchronize the configuration to API7 Enterprise:
adc sync -f adc.yaml
Update the Kubernetes manifest file of the selected route with data-mask
and file-logger
plugins:
- Gateway API
- APISIX CRD
apiVersion: apisix.apache.org/v1alpha1
kind: PluginConfig
metadata:
namespace: api7
name: mask-data-plugin-config
spec:
plugins:
- name: data-mask
config:
request:
- action: remove
body_format: urlencoded
name: password
type: body
- action: replace
body_format: urlencoded
name: token
type: body
value: "*****"
- action: regex
body_format: urlencoded
name: card
regex: "(\\d+)\\-\\d+\\-\\d+\\-(\\d+)"
type: body
value: "$1-****-****-$2"
- name: file-logger
config:
include_req_body: true
path: /tmp/mask-urlencoded-body.log
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
namespace: api7
name: httpbin-route
spec:
parentRefs:
- name: apisix
rules:
- matches:
- path:
type: Exact
value: /anything
filters:
- type: ExtensionRef
extensionRef:
group: apisix.apache.org
kind: PluginConfig
name: mask-data-plugin-config
backendRefs:
- name: httpbin
port: 80
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
namespace: api7
name: httpbin
spec:
ingressClassName: apisix
http:
- name: httpbin-route
match:
paths:
- /anything
backends:
- serviceName: httpbin
servicePort: 80
plugins:
- name: data-mask
enable: true
config:
request:
- action: remove
body_format: urlencoded
name: password
type: body
- action: replace
body_format: urlencoded
name: token
type: body
value: "*****"
- action: regex
body_format: urlencoded
name: card
regex: "(\\d+)\\-\\d+\\-\\d+\\-(\\d+)"
type: body
value: "$1-****-****-$2"
- name: file-logger
enable: true
config:
include_req_body: true
path: /tmp/mask-urlencoded-body.log
Apply the configuration to your cluster:
kubectl apply -f httpbin-route.yaml
Validate
Send a request to the route:
curl -i "http://127.0.0.1:9080/anything" \
--data-urlencode "password=abc" \
--data-urlencode "token=xyz" \
--data-urlencode "card=1234-1234-1234-1234"
You should receive an HTTP/1.1 200 OK
response.
View the file content of /tmp/mask-urlencoded-body.log
in your gateway Docker container or Kubernetes pod. You should see a log entry similar to the following:
{
"request": {
"uri": "/anything",
"body": "token=*****&card=1234-****-****-1234",
"method": "POST",
"url": "http://127.0.0.1:9080/anything"
}
}
Additional Resource(s)
- Getting Started
- Plugin Hub