Masking Email Addresses in Logs with Zsh

The error log bled raw email addresses into plain text, visible to anyone with access. You knew it was a problem the moment you saw it. Compliance risk. Privacy breach. Attack surface. It had to be fixed—and fast.

Masking email addresses in logs with Zsh is straightforward if you keep it simple and script with precision. The goal: replace sensitive data before it ever gets written. No regex over-complication, no bloated dependencies.

Start by leveraging Zsh’s built-in pattern matching. Most email formats follow *@*.*, so you can define a filter to catch and transform them into a safe placeholder. For example:

log_mask() {
 while IFS= read -r line; do
 masked="${line//[[:alnum:]._%+-]@[[:alnum:].-]+\.[[:alpha:].]{2,}/[EMAIL_MASKED]}"
 printf '%s\n' "$masked"
 done
}

Pipe your log-generating command through this function:

your_command | log_mask >> /var/log/secure.log

This ensures any email address is stripped before reaching disk. Customize the regex for your application’s exact patterns. Test on a variety of addresses, including subdomains and uncommon TLDs, to avoid gaps.

For higher performance, integrate the masking step into your command pipeline rather than running post-process jobs. This reduces exposure windows and keeps unmasked data out of rotation entirely.

Review permissions on your log storage. Even masked data can leak if logs are accessible beyond trusted systems. Combine the masking with strict access control, encryption at rest, and log rotation policies to stay aligned with governance frameworks like GDPR or HIPAA.

The key is discipline: make masking part of your logging architecture, not an afterthought.

If you want to see email masking in logs up and running without writing everything from scratch, test it live at hoop.dev. In minutes, you can secure your pipeline and stop leaking sensitive data.