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

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

FieldTypeRequiredDefaultDescription
attribute_typeStringConditional"" (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_keyStringConditional"" (all)Restricts the masking rule to a specific attribute key.
textStringYesA Go-flavored regular expression that identifies the data to mask. If the expression is invalid, the log collection pipeline fails to start.
placeholderStringYes""The replacement text used by the replace, partial, and redact_key modes. Ignored when mode is set to hash.
modeStringNoreplaceSpecifies 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
InputOutput
SSN is 123-45-6789SSN 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
InputOutput
card 1234-5678-9012-3456 okcard 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
InputOutput
Auth: Bearer eyJhbGciOi.abc123 okAuth: 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
BeforeAfter
{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_typeattribute_keyScope 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_type is set to resource or record, the log body is never modified, even if attribute_key is left empty. To mask the body, leave attribute_type empty.

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
AreaBeforeAfter
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"}
BodyUser alice@example.com logged in from 10.0.0.1User [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
AreaBeforeAfter
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
AreaBeforeAfter
Record attributes{db_conn: "password=jfbxYMnSt4tuQd"}{db_conn: "password=***"}
BodyConfig: db_password=s3cretVal host=db.localConfig: 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
AreaBeforeAfter
Record attributes{auth_header: "Bearer eyJhbGciOi.abc123"}{auth_header: "8186192c9ac4f3bb"}
BodyAuth: Bearer eyJhbGciOi.abc123 acceptedAuth: 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

ScenarioWhat Happens
text is emptyThat rule is skipped. Any remaining rules continue to be applied.
text contains an invalid regular expressionThe 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 omittedThe default value replace is used.
attribute_type is invalidThe rule is treated as unscoped and is applied to all supported scopes.

Troubleshooting

If you encounter kube events issues, see the Troubleshooting documentation.