Data Loss Prevention

Ensure that sensitive data isn't logged or leaked with Data Loss Prevention (DLP). You can apply DLP masking to data in response bodies and headers, and in response data recorded access logs.

If you import or export resources across workspaces, your policies might not apply. For more information, see Import and export policies.

DLP for response bodies and headers

When you apply a Gloo DLP policy, Gloo Gateway completes a series of regex replacements on the body of each response that it processes. For example, consider the following response body that is returned to Gloo Gateway.

{
   "fakevisa": "4397945340344828",
   "ssn": "123-45-6789"
}

With DLP enabled, Gloo Gateway applies a transformation to the response that masks sensitive data.

{
   "fakevisa": "XXXXXXXXXXXX4828",
   "ssn": "XXX-XX-X789"
}

Additionally, you can mask header information included in the response. For example, the x-my-header-01: my-value-01 response header might be passed with the response to Gloo Gateway. With DLP enabled, Gloo Gateway applies a transformation to the header value that masks sensitive data, such as x-my-header-01: _________.

DLP for access logs

You can also apply DLP transformations on content that is logged by Envoy, such as the headers and dynamic metadata that is logged by the configured access loggers. To apply DLP to logging only, set sanitize to ACCESS_LOGS in your DLP policy. To apply DLP to response bodies and logging, set sanitize to ALL.

WAF access logs are masked only when they are logged to Dynamic metadata. WAF logs written to Filter State are not masked.

Before you begin

This guide assumes that you use the same names for components like clusters, workspaces, and namespaces as in the getting started, and that your Kubernetes context is set to the cluster you store your Gloo config in (typically the management cluster). If you have different names, make sure to update the sample configuration files in this guide.

Follow the getting started instructions to:

  1. Set up Gloo Gateway in a single cluster.
  2. Deploy sample apps.
  3. Configure an HTTP listener on your gateway and set up basic routing for the sample apps.

Configure DLP policies

You can apply a DLP policy at the route level. For more information, see the following resources.

DLP predefined actions for response bodies

In this example, you mask data in responses by using some of the predefined DLP actions. For the current list of available predefined actions, see the Gloo Gateway API documentation.

  1. Send a request to the httpbin app through the ingress gateway that the route table is attached to.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/anything?fakeamex=349191317465935&ssn=123-45-6789" -H "Host: www.example.com" -H "X-httpbin: true"
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/anything?fakeamex=349191317465935&ssn=123-45-6789" -H "Host: www.example.com" -H "X-httpbin: true"
    

    The credit card and social security numbers in the reponse are unmasked:

    ...
      "form": {
        "fakeamex": "349191317465935", 
        "ssn": "123-45-6789"
      }, 
    ...
    
  2. Create the following DLP policy in the cluster with the Bookinfo workspace in your example setup. This policy uses DLP predefined actions to mask the credit card and social security numbers.

    kubectl apply -f - << EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: DLPPolicy
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: dlp-policy-predefined-actions
      namespace: bookinfo
    spec:
      applyToRoutes:
      - route:
          labels:
            route: httpbin
      config:
        actions:
        - predefinedAction: AMEX
        - predefinedAction: SSN
    EOF
    
  3. Send another request to the httpbin app through the ingress gateway.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/anything?fakeamex=349191317465935&ssn=123-45-6789" -H "Host: www.example.com" -H "X-httpbin: true"
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/anything?fakeamex=349191317465935&ssn=123-45-6789" -H "Host: www.example.com" -H "X-httpbin: true"
    

    This time, the credit card and social security numbers in the reponse are masked:

    ...
      "form": {
        "fakeamex": "XXXXXXXXXXXX5935", 
        "ssn": "XXX-XX-X789"
      }, 
    ...
    
  4. Optional: Clean up the resource that you created.

    kubectl -n bookinfo delete dlppolicy dlp-policy-predefined-actions
    

DLP custom actions for response bodies

In this example, you mask data in responses by using a custom DLP action. For more information about how to write custom actions, see the Gloo Gateway API documentation.

  1. Send a request to the reviews app through the ingress gateway that the route table is attached to.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/reviews/1" -H "Host: www.example.com" | jq ''
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/reviews/1" -H "Host: www.example.com" | jq ''
    

    Example output:

    {
      "id": "1",
      "podname": "reviews-v2-cdd8fb88b-8r82x",
      "clustername": "null",
      "reviews": [
        {
          "reviewer": "Reviewer1",
          "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!",
          "rating": {
            "stars": 5,
            "color": "black"
          }
        },
        {
          "reviewer": "Reviewer2",
          "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare.",
          "rating": {
            "stars": 4,
            "color": "black"
          }
        }
      ]
    }
    
  2. Create the following DLP policy in the cluster with the Bookinfo workspace in your example setup. This policy uses a DLP custom action to mask the reviewer, in the case that the reviewer ID might be personally identifying information (PII). The regex in the custom action replaces the reviewer ID characters with underscores (_).

    kubectl apply -f - << EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: DLPPolicy
    metadata:
      name: dlp-policy-custom-actions
      namespace: bookinfo
    spec:
      applyToRoutes:
      - route:
          labels:
            route: reviews
      config:
        actions:
        - customAction:
            maskChar: _
            name: test # only used for logging
            percent: 100
            regexActions:
            - regex: '"reviewer": [^"]*"([^"]*)"'
              subgroup: 1
    EOF
    
  3. Send another request to the reviews app through the ingress gateway.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/reviews/1" -H "Host: www.example.com" | jq ''
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/reviews/1" -H "Host: www.example.com" | jq ''
    

    This time, the reviewer data in the response is masked:

    {
      "id": "1",
      "podname": "reviews-v2-cdd8fb88b-8r82x",
      "clustername": "null",
      "reviews": [
        {
          "reviewer": "_________",
          "text": "An extremely entertaining play by Shakespeare. The slapstick humour is refreshing!",
          "rating": {
            "stars": 5,
            "color": "black"
          }
        },
        {
          "reviewer": "_________",
          "text": "Absolutely fun and entertaining. The play lacks thematic depth when compared to other plays by Shakespeare.",
          "rating": {
            "stars": 4,
            "color": "black"
          }
        }
      ]
    }
    
  4. Optional: Clean up the resource that you created.

    kubectl -n bookinfo delete dlppolicy dlp-policy-custom-actions
    

DLP key-value actions for headers in access logs

In this example, you define a key-value DLP action, which you can use to mask the value associated with a specified request header. For more information about how to write key-value actions, see the Gloo Gateway API documentation.

Note the following on key-value actions:

To apply a key-value DLP policy:

  1. Apply the following Envoy filter, which configures the ingress gateway to log the value of the x-my-header-01 request header.

    kubectl apply -f - << EOF
    apiVersion: networking.istio.io/v1alpha3
    kind: EnvoyFilter
    metadata:
      name: dlp-logging-test-filter
      namespace: gloo-mesh-gateways
    spec:
      configPatches:
      - applyTo: NETWORK_FILTER
        match:
          listener:
            filterChain:
              filter:
                name: envoy.filters.network.http_connection_manager
        patch:
          operation: MERGE
          value:
            typedConfig:
              '@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
              accessLog:
              - name: envoy.access_loggers.file2
                typedConfig:
                  '@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLog
                  path: "/dev/stdout"
                  log_format:
                    text_format_source:
                      inline_string: "x-my-header-01: %REQ(x-my-header-01)%\n"
      workloadSelector:
        labels:
          app: istio-ingressgateway
          istio: ingressgateway
    EOF
    
  2. Send a request to the reviews app through the ingress gateway that the route table is attached to. The kv-action-1 value is specified for the x-my-header-01 request header.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/reviews/1" -H "Host: www.example.com" -H "x-my-header-01: kv-action-1"
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/reviews/1" -H "Host: www.example.com" -H "x-my-header-01: kv-action-1"
    

  3. Get the access logs from the ingress gateway deployment.

    kubectl -n gloo-mesh-gateways logs deployment/istio-ingressgateway
    

    Verify that you see the following log entry:

    x-my-header-01: kv-action-1
    
  4. To mask the value of the x-my-header-01 request header, apply the following DLP policy.

    kubectl apply -f - << EOF
    apiVersion: security.policy.gloo.solo.io/v2
    kind: DLPPolicy
    metadata:
      annotations:
        cluster.solo.io/cluster: ""
      name: dlp-key-value-actions
      namespace: bookinfo
    spec:
      applyToRoutes:
      - route:
          labels:
            route: httpbin
      config:
        actions:
        - keyValueAction:
            keysToMask:
            - x-my-header-01
            maskChar: _
            name: kv-action-1
            percent: 100
    EOF
    
  5. Send another request to the reviews service.

    curl -k -s --connect-timeout 5 --resolve www.example.com:80:${INGRESS_GW_IP} "http://www.example.com:80/reviews/1" -H "Host: www.example.com" -H "x-my-header-01: kv-action-1"
    
    curl -k -s --connect-timeout 5 --resolve www.example.com:443:${INGRESS_GW_IP} "https://www.example.com:443/reviews/1" -H "Host: www.example.com" -H "x-my-header-01: kv-action-1"
    

  6. Check the ingress gateway access logs again.

    kubectl -n gloo-mesh-gateways logs deployment/istio-ingressgateway
    

    Verify that you see the following log entry, in which the value is masked:

    x-my-header-01: ___________
    
  7. Optional: Clean up the resources that you created.

    kubectl -n gloo-mesh-gateways envoyfilter dlp-logging-test-filter
    kubectl -n bookinfo delete dlppolicy dlp-key-value-actions