Skip to main content

data-mask

data-mask

Masks sensitive fields in the request: query parameters, headers, and JSON body fields can be removed, replaced with a fixed value, or partially rewritten with a regex substitution. Place it before the logging and/or upstream nodes that must not see the raw values.

Configuration

KeyTypeDefaultDescription
requestarray of rules[]Masking rules, applied in order.
max_body_sizeinteger > 01048576 (1 MiB)Bodies larger than this skip body rules (query/header rules still apply).

Each rule object:

KeyTypeRequiredDescription
typestringyesquery, header, or body.
namestringyesQuery parameter / header name (case-insensitive for headers), or a dotted path into the JSON body — user.cards.0.number. Numeric segments index arrays; a leading $. is tolerated.
actionstringyesremove, replace, or regex.
valuestringfor replace/regexReplacement value. For regex it may use $1-style capture references.
regexstringfor regexPattern (Rust regex syntax), compiled at config load.
body_formatstringfor body rulesOnly json is accepted.
type: data-mask
config:
request:
- { type: header, name: authorization, action: replace, value: "***" }
- { type: query, name: token, action: remove }
- type: body
body_format: json
name: user.card_number
action: regex
regex: "^(\\d{4})\\d+(\\d{4})$"
value: "$1********$2"

Rejected at config load: unknown type/action values, regex rules without regex+value, replace rules without value, invalid regex patterns, body rules without body_format, body_format values other than json, and dotted paths with empty segments.

Behavior

Masking is best-effort and never fails at execution time — the node always exits through the success port and emits no error codes.

  • Query rules operate on context.request.query_params: remove deletes the parameter, replace collapses it to the single configured value, regex rewrites the first match in every value of the parameter (only the first occurrence is substituted).
  • Header rules operate the same way on context.request.headers (names lowercased).
  • Body rules share one lazily parsed JSON document. Rules whose dotted path does not resolve (missing key, out-of-range index, type mismatch) are skipped, as are regex actions on non-string values. remove on an array index deletes the element (shifting the rest left). If any body rule changed the document it is re-serialized into context.request.body and the stale content-length header is removed.

Bodies that are absent, larger than max_body_size, or not valid JSON silently skip all body rules — the body passes through untouched.

The plugin only touches context.request; it never writes context.message or context.errors.

Behavior notes

  • Dotted paths, not JSONPath — body field names are exact dotted paths only; there is no JSONPath engine, no recursive descent, no wildcards, and each rule addresses one location.
  • body_format: urlencoded is not supported and is rejected at config load; only JSON bodies can be masked.
  • Phase — masking applies at the node's position in the graph, so it also masks what the upstream receives if placed before upstream, not only what downstream loggers see.

Errors

This node never fails at execution time: it always returns through success, so its error port is never taken.