Skip to content
You are viewing the latest documentation for Solo Enterprise for kgateway. To access the documentation for older versions, use the version switcher.

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)

Page as Markdown

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: 100

Targets

The targets field controls where masking is applied. You must specify at least one target.

TargetDescription
ResponseBodyApplies masking to the body of each HTTP response before it is returned to the client.
AccessLogsApplies 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:

PresetData type masked
SSNUS Social Security numbers (9-digit, hyphen, and space formats)
MastercardMastercard credit card numbers
VisaVisa credit card numbers
AmexAmerican Express credit card numbers
DiscoverDiscover credit card numbers
JCBJCB credit card numbers
DinersClubDiners Club credit card numbers
CreditCardTrackersCredit card track data
AllCreditCardsAll 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.

FieldRequiredDescription
regexActionsYesOne or more regex patterns to match against the response body.
regexActions[].regexYesThe regex pattern to match. Must not be empty.
regexActions[].subgroupNoThe 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.
maskCharNoThe character to use for masking. Defaults to X. Must be exactly one character.
percentNoThe 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.

FieldRequiredDescription
keyToMaskYesThe header name or dynamic metadata key to mask.
maskCharNoThe replacement character. Defaults to X.
percentNoThe percentage of the value to mask. Defaults to 75.

Before you begin

  1. Follow the Get started guide to install Solo Enterprise for kgateway.

  2. Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.

  3. 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_ADDRESS  
    kubectl port-forward deployment/http -n kgateway-system 8080:8080

Mask response bodies with preset actions

  1. 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"
        ]
      },
    ...
    
  2. Create an EnterpriseKgatewayTrafficPolicy that targets your HTTPRoute and enables DLP with the SSN and AllCreditCards presets.

    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
    EOF
  3. Send 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.

  1. Send a request to the httpbin /json endpoint. This path returns a slideshow with an author field. 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": [...]
      }
    }
    
  2. Create an EnterpriseKgatewayTrafficPolicy with a custom action that captures the author value 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
    EOF
    FieldDescription
    maskCharThe character that is used to replace matched content. Defaults to X.
    percentThe percentage of matched characters to replace. 100 replaces 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 group 1 (the parenthesized part) isolates only the name Yours Truly. Setting subgroup: 1 replaces 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.
  3. Send a request to the /json endpoint. 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.

  1. Create a ListenerPolicy that configures access logging for your gateway and logs the authorization header.

    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)%"
    EOF
  2. Create an EnterpriseKgatewayTrafficPolicy that masks the authorization header 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
    EOF
  3. Send a request with an Authorization header.

    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"
  4. Check the gateway proxy logs. Verify that the authorization value is masked and the original token is not visible.

    kubectl logs -n kgateway-system deployment/http | grep authorization | tail -5

    Example 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
Was this page helpful?