Masking protects sensitive data in your Kubernetes log pipeline by applying regex-based transformations to log records before they leave your cluster. Use it to hide, hash, partially redact, or completely remove sensitive information such as personally identifiable information (PII), credentials, API tokens, and secrets.
Applies to: Pod logs collected by the Worker Agent
Prerequisites
- Log Management is enabled for your client.
- Pod log collection is enabled, see Configuring Pod Log Collection.
- Agent version 22.0.0 or later.
How masking works
Masking rules live in the masking array under pods in the opsramp-logs-user-config ConfigMap. Each rule defines:
- What to match - a regex pattern
- What to do with matches - replace, partially hide, hash, or delete the key entirely
- Where to apply it - everywhere, or scoped to a specific attribute
To add or edit masking rules:
kubectl edit configmap opsramp-logs-user-config -n <agent-namespace>
pods:
enable: true
masking:
- attribute_type: "<scope>"
attribute_key: "<key-name>"
text: '<regex-pattern>'
placeholder: '<replacement>'
mode: "<masking-mode>"
Changes are detected automatically if the agent restarts the log collector within a few minutes to apply them.
Field reference
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
attribute_type | String | Conditional | "" (all) | Defines the masking scope. Supported values are resource, record, or an empty value to apply masking to all scopes, including the log body. |
attribute_key | String | Conditional | "" (all) | Restricts the masking rule to a specific attribute key. |
text | String | Yes | — | A Go-flavored regular expression that identifies the data to mask. If the expression is invalid, the log collection pipeline fails to start. |
placeholder | String | Yes | "" | The replacement text used by the replace, partial, and redact_key modes. Ignored when mode is set to hash. |
mode | String | No | replace | Specifies the masking mode. Supported values are replace, partial, hash, and redact_key. |
Masking modes
1. replace (default)
Replaces every regex match with the placeholder text. This is the default mode, if mode is omitted, replace is used.
masking:
- text: '\d{3}-\d{2}-\d{4}'
placeholder: '***-**-****'
mode: replace
| Input | Output |
|---|---|
SSN is 123-45-6789 | SSN is ***-**-**** |
2. partial
Replaces only the first capture group in the regex, leaving surrounding text intact. Useful when you want to keep a label visible (like password=) but hide the value.
masking:
- text: '\d{4}(-\d{4}-\d{4}-)\d{4}'
placeholder: '-****-****-'
mode: partial
| Input | Output |
|---|---|
card 1234-5678-9012-3456 ok | card 1234-****-****-3456 ok |
Requirements:
- The regex must contain at least one capture group
(...). - Only the first capture group is replaced.
- If there’s no capture group, or no match, the value is left unchanged.
3. hash
Replaces each match with a truncated SHA-256 hash (16 hex characters). The same input always produces the same hash, allowing you to correlate log records containing the same sensitive value without exposing the original data. The placeholder field is ignored in this mode.
masking:
- text: 'Bearer [A-Za-z0-9._\-]+'
placeholder: ""
mode: hash
| Input | Output |
|---|---|
Auth: Bearer eyJhbGciOi.abc123 ok | Auth: 8186192c9ac4f3bb ok |
4. redact_key
Removes the entire key-value pair from structured data when its value matches the regex, rather than just masking the value in place.
masking:
- text: '.*'
placeholder: ""
mode: redact_key
attribute_type: resource
attribute_key: k8s.pod.ip
| Before | After |
|---|---|
{k8s.pod.ip: "10.244.0.15", hostname: "node-1"} | {hostname: "node-1"} |
Scoping: controlling where a rule applies
By default, a masking rule applies to all resource attributes, record attributes, and the log body. Use attribute_type and attribute_key to limit the rule to a specific scope or attribute.
attribute_type | attribute_key | Scope Applied |
|---|---|---|
"" (empty) | "" (empty) | All resource attributes, all record attributes, and the log body. |
"" (empty) | "hostname" | The hostname attribute wherever it appears (resource, record, or body map). |
"resource" | "" (empty) | All resource attributes only. |
"resource" | "k8s.pod.ip" | Only the k8s.pod.ip resource attribute. |
"record" | "" (empty) | All record attributes only. |
"record" | "user_id" | Only the user_id record attribute. |
Important: When
attribute_typeis set toresourceorrecord, the log body is never modified, even ifattribute_keyis left empty. To mask the body, leaveattribute_typeempty.
Examples
Example 1: Mask email addresses everywhere
Scope: attribute_type: "" + attribute_key: "" → applies to all resource attributes, all record attributes, and the body.
masking:
- attribute_type: ""
attribute_key: ""
text: '[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}'
placeholder: '[EMAIL REDACTED]'
mode: replace
| Area | Before | After |
|---|---|---|
| Resource attributes | {hostname: "node-1", k8s.namespace.name: "prod"} | Unchanged — no emails present. |
| Record attributes | {owner: "admin@opsramp.com", level: "info"} | {owner: "[EMAIL REDACTED]", level: "info"} |
| Body | User alice@example.com logged in from 10.0.0.1 | User [EMAIL REDACTED] logged in from 10.0.0.1 |
Example 2: Remove pod IP from resource attributes
Deletes the k8s.pod.ip key entirely from resource attributes.
masking:
- attribute_type: resource
attribute_key: k8s.pod.ip
text: '.*'
placeholder: ""
mode: redact_key
| Area | Before | After |
|---|---|---|
| Resource attributes | {k8s.pod.ip: "10.244.0.15", hostname: "node-1", k8s.namespace.name: "prod"} | {hostname: "node-1", k8s.namespace.name: "prod"} |
Example 3: Partially mask passwords, keep the label visible
Applies everywhere. Only the captured password value is replaced; the password= label stays visible for debugging.
masking:
- attribute_type: ""
attribute_key: ""
text: '(?i)password[=:\s]+["\x27]?(\S+)["\x27]?'
placeholder: '***'
mode: partial
| Area | Before | After |
|---|---|---|
| Record attributes | {db_conn: "password=jfbxYMnSt4tuQd"} | {db_conn: "password=***"} |
| Body | Config: db_password=s3cretVal host=db.local | Config: db_password=*** host=db.local |
Example 4: Hash Bearer tokens for correlation
Applies everywhere. The same token always produces the same hash, so you can trace which log records share a token without exposing the value itself.
masking:
- attribute_type: ""
attribute_key: ""
text: 'Bearer [A-Za-z0-9._\-]+'
placeholder: ""
mode: hash
| Area | Before | After |
|---|---|---|
| Record attributes | {auth_header: "Bearer eyJhbGciOi.abc123"} | {auth_header: "8186192c9ac4f3bb"} |
| Body | Auth: Bearer eyJhbGciOi.abc123 accepted | Auth: 8186192c9ac4f3bb accepted |
Example 5: Combining multiple rules
Rules run in order, and each applies independently to every log record. A value already modified by one rule can be modified again by a later rule.
masking:
# Rule 1: Replace SSNs everywhere
- attribute_type: ""
attribute_key: ""
text: '\d{3}-\d{2}-\d{4}'
placeholder: '***-**-****'
mode: replace
# Rule 2: Hash API secrets everywhere
- attribute_type: ""
attribute_key: ""
text: 'secret-[a-z0-9]+'
placeholder: ""
mode: hash
# Rule 3: Remove pod IPs from resource attributes only
- attribute_type: resource
attribute_key: k8s.pod.ip
text: '.*'
placeholder: ""
mode: redact_key
Full ConfigMap example
apiVersion: v1
kind: ConfigMap
metadata:
name: opsramp-logs-user-config
data:
logsConfig.yaml: |
pods:
enable: true
namespaces:
include:
is_include_regex: false
exclude:
is_exclude_regex: false
log_level: "Unspecified"
masking:
- attribute_type: ""
attribute_key: ""
text: '[a-z0-9._%+\-]+@[a-z0-9.\-]+\.[a-z]{2,4}'
placeholder: '[REDACTED]'
mode: replace
- attribute_type: resource
attribute_key: k8s.pod.ip
text: '.*'
placeholder: ""
mode: redact_key
Behavior
| Scenario | What Happens |
|---|---|
text is empty | That rule is skipped. Any remaining rules continue to be applied. |
text contains an invalid regular expression | The log collection pipeline fails to start, and an error is logged with the invalid pattern. |
mode is invalid (not replace, partial, hash, or redact_key) | That rule is skipped and a warning is logged. Any remaining rules continue to be applied. |
mode is empty or omitted | The default value replace is used. |
attribute_type is invalid | The rule is treated as unscoped and is applied to all supported scopes. |
Troubleshooting
If you encounter kube events issues, see the Troubleshooting documentation.