Partial Redaction
Partial redaction allows you to keep a portion of a PII field visible after crypto-shredding. Instead of replacing the entire value with an empty string or a static replacement, Tayra can preserve a prefix, suffix, or email local part while masking the rest with * characters.
When to Use Partial Redaction
Partial redaction is useful when you need to:
- Identify records after shredding — e.g., showing
"Jo**********"so support staff can confirm which customer record was erased - Preserve analytics — e.g., keeping the last 4 digits of a phone number for regional analysis
- Maintain UX — e.g., showing
"user@*******.***"so the user recognizes their email pattern
Use partial redaction instead of full replacement when the masked portion alone does not constitute personal data and the visible portion serves a legitimate operational need.
Configuration
Partial redaction is configured on the [PersonalData] attribute using the Masking and MaskingParameter properties. The redacted value is computed at encryption time and embedded in the ciphertext, so it is available after the key is shredded.
Mask After
Preserves the first N characters and masks the rest:
[PersonalData(Masking = MaskingStrategies.MaskAfter, MaskingParameter = 2)]
public string FullName { get; set; } = "";With FullName = "Eleanor Rigby" and MaskingParameter = 2:
- Redacted value:
"El***********"
Mask Before
Preserves the last N characters and masks the rest:
[PersonalData(Masking = MaskingStrategies.MaskBefore, MaskingParameter = 4)]
public string PhoneNumber { get; set; } = "";With PhoneNumber = "+1-555-0600" and MaskingParameter = 4:
- Redacted value:
"*******0600"
Mask Email Domain
Preserves the local part (before @) and masks the domain, keeping the structure (dots and @):
[PersonalData(Masking = MaskingStrategies.MaskEmailDomain)]
public string Email { get; set; } = "";With Email = "eleanor@example.com":
- Redacted value:
"eleanor@*******.***"
Masking Strategy Reference
| Strategy | Parameter | Description | Example Input | Example Output |
|---|---|---|---|---|
MaskingStrategies.MaskAfter | Number of leading chars to keep | Masks everything after the first N characters | "Jane Doe" | "Ja******" |
MaskingStrategies.MaskBefore | Number of trailing chars to keep | Masks everything before the last N characters | "+1-555-1234" | "*******1234" |
MaskingStrategies.MaskEmailDomain | N/A | Keeps local part, masks domain (preserving dots) | "jane@corp.co" | "jane@****.**" |
Fluent API
Use named methods on PersonalDataBuilder for built-in strategies:
e.PersonalData(c => c.Name).WithMaskAfter(2);
e.PersonalData(c => c.Phone).WithMaskBefore(4);
e.PersonalData(c => c.Email).WithMaskEmailDomain();Custom Masking
Use WithMask() to define custom masking logic inline:
// Keep last 4 characters of a tax ID
e.PersonalData(c => c.TaxId)
.WithMask(value => new string('*', value.Length - 4) + value[^4..]);
// Show only the first initial
e.PersonalData(c => c.Name)
.WithMask(value => value[0] + new string('*', value.Length - 1));Custom masking is fluent API only — the lambda is captured directly, no registration needed.
How It Works
When a field with a masking strategy is encrypted:
- The strategy's
Maskmethod computes the partially masked value. - The redacted value is stored alongside the ciphertext in the wire format with a
TAYRA_M:prefix. - On decryption, if the key is available, the original plaintext is returned.
- If the key has been shredded, the stored redacted value (after the
TAYRA_M:prefix) is returned instead of the standard replacement.
INFO
The TAYRA_M: prefix in the stored value distinguishes redacted ciphertext from regular ciphertext. This is an internal implementation detail; you do not need to handle it directly.
Edge Cases
- If
MaskingParameteris 0 or negative withMaskAfter/MaskBefore, the entire value is masked. - If
MaskingParameterexceeds the string length, the entire value is preserved (no masking). - If
MaskEmailDomainis used on a value without@, the entire value is masked. - Empty or null values produce an empty string regardless of the strategy.
Redaction vs. Full Replacement
| Concern | Full Replacement | Partial Redaction |
|---|---|---|
| Data minimization | Maximum — no original data visible | Partial — some characters visible |
| Record identification | Not possible | Possible with prefix/suffix |
| Analytics | Not possible | Limited analytics on visible portion |
| Re-identification risk | None | Low (depends on visible portion) |
| GDPR compliance | Strongest erasure guarantee | Acceptable when visible portion is non-identifying |
WARNING
Carefully consider whether the visible portion of a redacted value could be used to re-identify a data subject, especially in combination with other data. When in doubt, use full replacement (no Masking configured).
See Also
- Crypto-Shredding — Full erasure through key deletion
- Data Subject Access — Export data including redaction status
- GDPR Overview — Complete compliance feature map
