How to Implement Data Masking or Desensitization for Sensitive Fields via INFINI Gateway
INFINI Gateway provides filter-based transformations and Elasticsearch field-level security integrations to mask, delete, or replace sensitive data in request and response payloads.
INFINI Gateway serves as a high-performance data gateway between clients and Elasticsearch clusters, offering built-in mechanisms to handle data masking or desensitization for sensitive fields via INFINI Gateway configurations. Whether you need to redact credit card numbers from JSON payloads or enforce role-based field masking at the backend, the gateway provides flexible pipeline filters and security mappings to protect sensitive information as it flows through the proxy.
Filter-Based Masking Methods
INFINI Gateway implements data transformation through a series of filters located in the proxy/filters/transform/ package. These filters intercept requests and responses to modify content before it reaches its destination.
JSON Field Replacement with request_body_json_set
The request_body_json_set filter overwrites specific JSON fields with mask values using the jsonparser.Set function. In proxy/filters/transform/request_body_json_set.go (lines 60-73), the filter loads a map of path-to-value pairs from the configuration and applies them to the request body.
pipeline:
- name: request_body_json_set
config:
ignore_missing: true
path:
- "user.password->***"
- "credit_card.number->****-****-****-1234"
This configuration replaces user.password with *** and masks the credit card number while preserving the last four digits.
JSON Field Deletion with request_body_json_del
To completely remove sensitive fields rather than masking them, use the request_body_json_del filter. Located in proxy/filters/transform/request_body_json_del.go (lines 55-68), this filter calls jsonparser.Delete for each configured path, eliminating the field entirely from the payload.
pipeline:
- name: request_body_json_del
config:
ignore_missing: true
path:
- "ssn"
- "api_key"
After processing, the ssn and api_key fields no longer exist in the forwarded request.
Regex-Based Request Masking with request_body_regex_replace
For pattern-based masking that doesn't rely on JSON structure, the request_body_regex_replace filter applies regular expression substitutions. As implemented in proxy/filters/transform/request_body_regex_replace.go (lines 38-45), the filter compiles the pattern and executes filter.p.ReplaceAll on the raw body bytes.
pipeline:
- name: request_body_regex_replace
config:
pattern: "\"(\\d{16})\""
to: "\"************\""
This example masks any 16-digit number (such as a full credit card number) within the request body.
Regex-Based Response Masking with response_body_regex_replace
The gateway can also mask sensitive data in responses before they reach the client. The response_body_regex_replace filter operates identically to its request-side counterpart but processes ctx.Response.GetRawBody() instead. You can find the implementation in proxy/filters/transform/response_body_regex_replace.go (lines 38-45).
pipeline:
- name: response_body_regex_replace
config:
pattern: "\"email\":\"[^\"]+\""
to: "\"email\":\"***@***.com\""
This configuration obscures email addresses in the response payload by replacing them with a generic mask.
Header and Context Manipulation
Additional transform filters such as set_header, response_header_format, and set_context provide capabilities to blank out or replace sensitive information in HTTP headers and internal context values. These filters manipulate metadata without altering the message body, useful for removing authentication tokens or correlation IDs from logs.
Role-Mapping-Based Field Level Security
Beyond request/response transformation, INFINI Gateway supports delegating masking responsibilities to Elasticsearch through field-level security mappings.
FieldPermission with Type Mask
The FieldPermission struct defined in common/role_mapping.go (lines 58-61) includes a Type field that accepts the value "mask". When configured, the gateway forwards these permissions to Elasticsearch, instructing the backend to return masked values (such as "******") for specified fields rather than the raw data.
This integration leverages Elasticsearch's native field-level security, ensuring that sensitive fields remain masked even when accessed directly through the backend.
Configuring Role Mappings
You define masked fields within the gateway.yml configuration by specifying role mappings that include the mask type:
roles:
- name: analyst
indices:
- names: ["sales"]
privileges: ["read"]
field_security:
grant: ["order_id", "date"]
mask: ["customer_name", "customer_email"]
When a user with the analyst role queries the sales index, the gateway passes this role mapping through request headers (such as X-Forwarded-User-Role), causing Elasticsearch to return customer_name and customer_email as masked values while preserving other fields.
Combining Methods for End-to-End Protection
You can chain multiple filters and role mappings to create comprehensive data masking or desensitization for sensitive fields via INFINI Gateway pipelines. For example, delete highly sensitive fields from incoming requests using request_body_json_del, mask partially sensitive response fields with response_body_regex_replace, and enforce backend field-level security through role mappings.
The pipeline execution order follows your configuration sequence, allowing precise control over when each masking operation occurs during the request lifecycle.
Summary
- JSON manipulation: Use
request_body_json_setto overwrite fields with mask values orrequest_body_json_delto remove them entirely, leveragingjsonparser.Setandjsonparser.Deleteinproxy/filters/transform/. - Pattern matching: Apply
request_body_regex_replaceandresponse_body_regex_replacefor regex-based masking on raw body content usingfilter.p.ReplaceAll. - Header security: Utilize
set_headerand related filters to strip sensitive metadata from HTTP headers before logging or forwarding. - Backend integration: Configure
FieldPermissionwithType: "mask"incommon/role_mapping.goto leverage Elasticsearch field-level security. - Pipeline flexibility: Chain multiple filters in
gateway.ymlto implement defense-in-depth for sensitive data protection.
Frequently Asked Questions
How does INFINI Gateway handle JSON field masking without breaking the document structure?
INFINI Gateway uses the jsonparser library to surgically modify JSON documents. The request_body_json_set filter calls jsonparser.Set to replace values while preserving the surrounding JSON structure, and request_body_json_del uses jsonparser.Delete to remove keys without leaving syntax errors. Both filters operate on the parsed JSON tree rather than simple string replacement, ensuring valid JSON output even with nested objects.
Can I mask sensitive data in responses only, leaving the request intact?
Yes. Configure the response_body_regex_replace filter in your pipeline to target outbound traffic specifically. This filter operates on ctx.Response.GetRawBody() after receiving the backend response but before sending it to the client, allowing you to mask sensitive fields in the response while preserving the original data in the request and backend storage.
What is the difference between filter-based masking and role-mapping-based masking?
Filter-based masking occurs at the gateway layer, physically altering or removing data before it reaches Elasticsearch or the client. Role-mapping-based masking delegates the operation to Elasticsearch's field-level security, where the backend returns masked values based on user permissions defined in the FieldPermission struct with Type: "mask". Filter-based approaches offer more flexibility for custom patterns, while role-mapping ensures consistent access control across direct backend queries.
How do I mask only specific portions of a field value, such as the middle digits of a credit card number?
Use the request_body_regex_replace or response_body_regex_replace filters with capture groups. For example, the pattern (\d{4})\d{8}(\d{4}) captures the first and last four digits of a 16-digit number, allowing the replacement string $1********$2 to preserve the identifiable prefix and suffix while masking the middle digits. This regex-based approach in proxy/filters/transform/request_body_regex_replace.go provides granular control over partial field masking.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →