Matchers
As you have seen in PII Redaction, matchers tell the transform engine what to act on. To allow for more precise configuration, matchers are split into two types: common fields and matching fields. There can only be one matching field, but there can be many common fields.Common fields
Common fields are fields that you don’t redact, and are only used for the purpose of finding matching spans. For common fields, you can supply zero or more of the following:direction
: eitherinbound
oroutbound
method
: a list of HTTP methods likeGET
pathPattern
: a regexp to match on the URL pathhost
: a regexp to match on the hostname
Matching fields
Matching fields are fields that you intend to redact. Only one can be present so that what will be modified is clear. For matching fields, you can only supply one of the following:jsonPath
: a JSONPath expression to match on JSON formatted bodies (e.g.$.user.password
)queryParam
: the name of a query parameterheaderName
: the name of a headerurlPath
: if set to true, matches on the entire url pathfullBody
: if set to true, matches on the entire body
The presence of
urlPath
may seem strange given that we have
pathPattern
but you can use this to redact all paths without having
to provide a pathPattern
.Actions
Actions specify how to mutate the matching span. Tusk currently supports these actions:redact
. This replaces the value with a hash. Accepts ahashPrefix
field if you need some form of identifier.mask
. This replaces the value with a repeated charactermashChar
(defaults to ’*’). Use this for fixed length strings where redact won’t work.replace
. Replaces the string withreplaceWith
. This can be used for things like testing tokens, etc.drop
. Deletes all useful data (body, header, etc.) from the span and mark it as dropped. The span isn’t deleted entirely so that tests depending on it can still get mocked.
Examples
1. Inbound Requests
Example: Redact
{"username": "john@example.com", "password": "secretPassword123"}
After: {"username": "john@example.com", "password": "REDACTED_a7b9c1d2e3f4..."}
Example: Mask
/api/user/lookup?ssn=123-45-6789&name=john
After: /api/user/lookup?ssn=XXXXXXXXXXX&name=john
Example: Replace
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...
After: Authorization: Bearer test-token-12345
Example: Drop
/admin/internal/user-data
After: Empty span recorded for /admin/internal/user-data
Example: Redact
{"data": {"name": "John", "creditCard": "4111-1111-1111-1111"}}
After: {"data": {"name": "John", "creditCard": "REDACTED_b8c9d1e2f3g4..."}}
Example: Mask
{"users": [{"name": "John", "phone": "+1-555-123-4567"}]}
After: {"users": [{"name": "John", "phone": "***-***-****"}]}
2. Outbound Request
Example: Redact
Authorization: Bearer sk_live_51234567890abcdef...
After: Authorization: REDACTED_c1d2e3f4a5b6...
Example: Mask
{"customer": {"creditCard": {"number": "4111111111111111"}}}
After: {"customer": {"creditCard": {"number": "****************"}}}
Example: Replace
-
Before:
{"auth": {"username": "dbuser", "password": "prod-secret-123"}}
-
After:
{"auth": {"username": "dbuser", "password": "test-db-password"}}
Example: Redact
{"users": [{"id": 123, "email": "user@example.com"}]}
After: {"users": [{"id": 123, "email": "REDACTED_d1e2f3g4h5i6..."}]}
Example: Mask
{"accounts": [{"type": "checking", "accountNumber": "1234567890123456"}]}
After: {"accounts": [{"type": "checking", "accountNumber": "XXXXXXXXXXXXXXXX"}]}