Field masking
If you don’t want to remove fields from a document using field-level security, you can mask their values. Currently, field masking is only available for string-based fields and replaces the field’s value with a cryptographic hash.
Field masking works alongside field-level security on the same per-role, per-index basis. You can allow certain roles to see sensitive fields in plain text and mask them for others.
Important limitation: Search functionality
Fields with masking applied cannot be searched. When you apply field masking to a field, you will not be able to search for terms within that field, even if the terms are not masked by your pattern. This occurs because field masking is applied after indexing, while search operations rely on the inverted index created during the indexing process.
For example, if you have a field message with the value "User john.doe@example.com accessed the system" and apply pattern-based masking to hide email addresses, the displayed result might show "User ***@***.*** accessed the system". However, you will not be able to search for "User", "accessed", or "system" in this field, even though these terms are not masked.
Workarounds
If you need to maintain search functionality on partially masked fields, consider these alternatives:
- Use separate fields: Split your data into separate fields—one for searchable content and another for sensitive data that needs masking.
- Index transformation: Create a separate index with pre-applied masking transformations rather than using dynamic field masking.
- Field-level security: Instead of masking, use field-level security to completely hide sensitive fields from unauthorized users.
A search result with a masked field might appear similar to the following:
{
"_index": "movies",
"_source": {
"year": 2013,
"directors": [
"Ron Howard"
],
"title": "ca998e768dd2e6cdd84c77015feb29975f9f498a472743f159bec6f1f1db109e"
}
}
Set the salt setting
You can set the salt (a random string used to hash your data) in opensearch.yml using the optional plugins.security.compliance.salt setting. The salt value must fulfill the following requirements:
- Must be at least 16 characters.
- Use only ASCII characters.
The following example shows a salt value:
plugins.security.compliance.salt: abcdefghijklmnop
Although setting the salt is optional, it is highly recommended.
Configure field masking
You configure field masking using OpenSearch Dashboards, roles.yml, or the REST API.
OpenSearch Dashboards
- Choose a role.
- Choose an index permission.
- For Anonymization, specify one or more fields and press Enter.
roles.yml
someonerole:
index_permissions:
- index_patterns:
- 'movies'
allowed_actions:
- read
masked_fields:
- "title"
- "genres"
REST API
See Create role.
(Advanced) Use an alternative hash algorithm
By default, the Security plugin uses the BLAKE2b algorithm, but you can use any hashing algorithm that your JVM provides. This list typically includes MD5, SHA-1, SHA-384, and SHA-512.
BLAKE2b and several other commonly available algorithms, such as MD5 and SHA-1, are not approved for use in FIPS 140-3-compliant environments. If your deployment requires FIPS compliance, configure the plugin to use a FIPS-approved algorithm, such as SHA-256 or SHA-512, and make sure that the underlying cryptographic provider (for example, Bouncy Castle FIPS or another FIPS-validated JCE provider) is installed and configured correctly.
You can override the default algorithm in opensearch.yml using the optional default masking algorithm setting plugins.security.masked_fields.algorithm.default, as shown in the following example:
plugins.security.masked_fields.algorithm.default: SHA-256
OpenSearch 3.x contains a bug fix to apply the default BLAKE2b algorithm correctly. You can override the default algorithm in OpenSearch 3.x to continue to produce the same masked values as OpenSearch 1.x and 2.x in opensearch.yml using the optional default masking algorithm setting plugins.security.masked_fields.algorithm.default, as shown in the following example:
plugins.security.masked_fields.algorithm.default: BLAKE2B_LEGACY_DEFAULT
To specify a different algorithm, add it after the masked field in roles.yml, as shown in the following:
someonerole:
index_permissions:
- index_patterns:
- 'movies'
allowed_actions:
- read
masked_fields:
- "title::SHA-512"
- "genres"
(Advanced) Pattern-based field masking
Rather than creating a hash, you can use one or more regular expressions and replacement strings to mask a field. The syntax is <field>::/<regular-expression>/::<replacement-string>. If you use multiple regular expressions, the results are passed from left to right, like piping in a shell, as shown in the following example:
hr_employee:
index_permissions:
- index_patterns:
- 'humanresources'
allowed_actions:
- read
masked_fields:
- 'lastname::/.*/::*'
- '*ip_source::/[0-9]{1,3}$/::XXX::/^[0-9]{1,3}/::***'
someonerole:
index_permissions:
- index_patterns:
- 'movies'
allowed_actions:
- read
masked_fields:
- "title::/./::*"
- "genres::/^[a-zA-Z]{1,3}/::XXX::/[a-zA-Z]{1,3}$/::YYY"
The title statement changes each character in the field to *, so you can still discern the length of the masked string. The genres statement changes the first three characters of the string to XXX and the last three characters to YYY.
Effect on audit logging
The read history feature lets you track read access to sensitive fields in your documents. For example, you might track access to the email field of your customer records. Access to masked fields are excluded from read history, because the user only saw the hash value, not the clear text value of the field.