For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
Data loss prevention (DLP)
Ensure that sensitive data isn’t logged or leaked by masking data in response bodies and access logs.
Solo Enterprise for kgateway includes a built-in Data Loss Prevention (DLP) capability that masks sensitive data in response bodies and access logs. DLP applies regex-based replacements to traffic that passes through the gateway, preventing credit card numbers, social security numbers, and other confidential data from reaching clients or being captured in logs.
For example, consider the following response body:
{
"fakevisa": "4397945340344828",
"ssn": "123-45-6789"
}With DLP enabled, Solo Enterprise for kgateway applies masking transformations so that the client receives a response that is similar to the following.
{
"fakevisa": "XXXXXXXXXXXX4828",
"ssn": "XXX-XX-X789"
}Warning
Performance impact: DLP scans each response body by applying all configured regex patterns in sequence. Latency increases linearly with the response body size and the number of regex actions that are defined in the DLB policy. For routes that return large payloads or apply many regex actions, test DLP overhead against your latency budget before enabling it in production.
Configuration overview
You configure DLP by adding an entDLP section to an EnterpriseKgatewayTrafficPolicy and targeting it at an HTTPRoute. The following example shows the full structure with all supported targets and action types.
entDLP:
targets:
- ResponseBody # mask response bodies
- AccessLogs # mask access log values
actions:
- preset: SSN # built-in preset
- preset: AllCreditCards # built-in preset
- custom: # user-defined regex rule
maskChar: "X"
percent: 100
regexActions:
- regex: '"token":"([^"]*)"'
subgroup: 1
- keyValue: # mask a header in access logs
keyToMask: authorization
askChar: "_"
percent: 100Targets
The targets field controls where masking is applied. You must specify at least one target.
| Target | Description |
|---|---|
ResponseBody | Applies masking to the body of each HTTP response before it is returned to the client. |
AccessLogs | Applies masking to the values that are written to Envoy access logs. |
You can set both targets on the same policy to mask data in both places at once.
Neither target removes a response header. AccessLogs masks a header value in the log entry, and the client still receives the header itself. To keep response headers from reaching clients at all, use response header sanitization, which permits only the headers that you name and removes the rest.
Actions
The actions field is an ordered list of masking operations that are applied in sequence. Each action uses exactly one of the following types.
Preset actions
A preset action selects a built-in masking bundle that targets a well-known sensitive data type. Solo Enterprise for kgateway comes with the following presets:
| Preset | Data type masked |
|---|---|
SSN | US Social Security numbers (9-digit, hyphen, and space formats) |
Mastercard | Mastercard credit card numbers |
Visa | Visa credit card numbers |
Amex | American Express credit card numbers |
Discover | Discover credit card numbers |
JCB | JCB credit card numbers |
DinersClub | Diners Club credit card numbers |
CreditCardTrackers | Credit card track data |
AllCreditCards | All credit card numbers |
Each preset runs a set of predefined regex patterns and masks sensitive data with X characters.
Custom actions
A custom action lets you define your own regex-based masking rule for any data pattern that is not covered by a preset.
| Field | Required | Description |
|---|---|---|
regexActions | Yes | One or more regex patterns to match against the response body. |
regexActions[].regex | Yes | The regex pattern to match. Must not be empty. |
regexActions[].subgroup | No | The capture group to mask. 0 (default) masks the entire match. 1 masks only the first parenthesized group, leaving the surrounding text, such as JSON keys, intact. |
maskChar | No | The character to use for masking. Defaults to X. Must be exactly one character. |
percent | No | The percentage of matched characters to replace, from the start of the match. Defaults to 75. Set to 100 to replace all matched characters. |
Key-value actions
A keyValue action masks the value of a specific header or dynamic metadata key. This action only applies to AccessLogs. You cannot apply this action to response bodies.
| Field | Required | Description |
|---|---|---|
keyToMask | Yes | The header name or dynamic metadata key to mask. |
maskChar | No | The replacement character. Defaults to X. |
percent | No | The percentage of the value to mask. Defaults to 75. |
Before you begin
Follow the Get started guide to install Solo Enterprise for kgateway.
Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESSkubectl port-forward deployment/http -n kgateway-system 8080:8080
Mask response bodies with preset actions
Send a request to the httpbin app that returns a fake social security number and credit card number in the response. Verify that sensitive information is returned unmasked.
curl -vik "http://$INGRESS_GW_ADDRESS:8080/anything?fakevisa=4397945340344828&ssn=123-45-6789" \ -H "host: www.example.com:8080"curl -i "localhost:8080/anything?fakevisa=4397945340344828&ssn=123-45-6789" \ -H "host: www.example.com"Example output:
... { "args": { "fakevisa": [ "4397945340344828" ], "ssn": [ "123-45-6789" ] }, ...Create an
EnterpriseKgatewayTrafficPolicythat targets your HTTPRoute and enables DLP with theSSNandAllCreditCardspresets.kubectl apply -f- <<EOF apiVersion: enterprisekgateway.solo.io/v1alpha1 kind: EnterpriseKgatewayTrafficPolicy metadata: name: dlp namespace: httpbin spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: httpbin entDLP: targets: - ResponseBody actions: - preset: SSN - preset: AllCreditCards EOFSend the same request again. Verify that the sensitive values are now masked.
curl -vik "http://$INGRESS_GW_ADDRESS:8080/anything?fakevisa=4397945340344828&ssn=123-45-6789" \ -H "host: www.example.com:8080"curl -i "localhost:8080/anything?fakevisa=4397945340344828&ssn=123-45-6789" \ -H "host: www.example.com"Example output:
... { "args": { "fakevisa": [ "XXXXXXXXXXXX4828" ], "ssn": [ "XXX-XX-X789" ] }, ...
Mask response bodies with custom actions
Use a custom regex pattern to mask data that is not covered by a preset.
Send a request to the httpbin
/jsonendpoint. This path returns a slideshow with anauthorfield. Verify that the author name is visible in the response.curl -vik http://$INGRESS_GW_ADDRESS:8080/json -H "host: www.example.com:8080"curl -i localhost:8080/json -H "host: www.example.com"Example output:
{ "slideshow": { "author": "Yours Truly", "date": "date of publication", "slides": [...] } }Create an
EnterpriseKgatewayTrafficPolicywith a custom action that captures theauthorvalue in the response body and replaces it with_characters.kubectl apply -f- <<EOF apiVersion: enterprisekgateway.solo.io/v1alpha1 kind: EnterpriseKgatewayTrafficPolicy metadata: name: dlp namespace: httpbin spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: httpbin entDLP: targets: - ResponseBody actions: - custom: maskChar: "_" percent: 100 regexActions: - regex: '"author": [^"]*"([^"]*)"' subgroup: 1 EOFField Description maskCharThe character that is used to replace matched content. Defaults to X.percentThe percentage of matched characters to replace. 100replaces all matched characters;75(the default) replaces the first 75% and leaves the trailing 25% visible.regexActions[].regexA regex pattern that captures the sensitive data. regexActions[].subgroupThe capture group to mask. The regex "author": [^"]*"([^"]*)"matches the full fragment"author": "Yours Truly", but group1(the parenthesized part) isolates only the nameYours Truly. Settingsubgroup: 1replaces just that name, so the JSON key and punctuation are preserved in the output.0(the default) masks the entire regex match, including the key.Send a request to the
/jsonendpoint. Verify that the author is now masked.curl -vik http://$INGRESS_GW_ADDRESS:8080/json -H "host: www.example.com:8080"curl -i localhost:8080/json -H "host: www.example.com"Example output:
{ "slideshow": { "author": "_____ _____", "date": "date of publication", "slides": [...] } }
Mask headers in access logs
Use a keyValue action to mask the value of a specific header or dynamic metadata key in access logs.
In this example, you mask the authorization header value in access logs to prevent credentials from being written to log storage.
Create a
ListenerPolicythat configures access logging for your gateway and logs theauthorizationheader.kubectl apply -f- <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: ListenerPolicy metadata: name: dlp-access-logs namespace: kgateway-system spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: http default: httpSettings: accessLog: - fileSink: path: /dev/stdout jsonFormat: method: "%REQ(X-ENVOY-ORIGINAL-METHOD?:METHOD)%" path: "%REQ(X-ENVOY-ORIGINAL-PATH?:PATH)%" response_code: "%RESPONSE_CODE%" authorization: "%REQ(authorization)%" EOFCreate an
EnterpriseKgatewayTrafficPolicythat masks theauthorizationheader value in access logs.kubectl apply -f- <<EOF apiVersion: enterprisekgateway.solo.io/v1alpha1 kind: EnterpriseKgatewayTrafficPolicy metadata: name: dlp namespace: httpbin spec: targetRefs: - group: gateway.networking.k8s.io kind: HTTPRoute name: httpbin entDLP: targets: - AccessLogs actions: - keyValue: keyToMask: authorization EOFSend a request with an
Authorizationheader.curl -vik http://$INGRESS_GW_ADDRESS:8080/status/200 \ -H "host: www.example.com:8080" \ -H "authorization: Bearer my-secret-token"curl -vik localhost:8080/status/200 \ -H "host: www.example.com" \ -H "authorization: Bearer my-secret-token"Check the gateway proxy logs. Verify that the
authorizationvalue is masked and the original token is not visible.kubectl logs -n kgateway-system deployment/http | grep authorization | tail -5Example output:
{"authorization":"XXXXXXXXXXXXXXX","method":"GET","path":"/status/200","response_code":200}
Cleanup
You can optionally remove the resources that you set up as part of this guide.kubectl delete listenerpolicy -n kgateway-system dlp-access-logs --ignore-not-found
kubectl delete enterprisekgatewaytrafficpolicy -n httpbin dlp