AWS Resource Tagging
After a successful masking run against an AWS target, DataMasque tags the masked resource with a standard set of protection tags. These provide a machine-readable "Protected by DataMasque" governance signal: proof that a resource holds masked data.
When DataMasque is hosted on an EC2 instance, that instance is also tagged, as a DataMasque deployment.
This page covers the tags applied, the IAM permissions required, how to preserve the tags through RDS snapshot and restore, and how to find masked resources with AWS Config.
- The protection tag set
- Tagging the DataMasque host instance
- The
tag_aws_resourcesglobal setting - Required IAM permissions
- Preserving tags through RDS snapshot and restore
- Finding masked resources with AWS Config
The protection tag set
When tagging is enabled and DataMasque is running on AWS, a successful masking run applies the following tags to the masked resource:
| Tag | Example value | Purpose |
|---|---|---|
datamasque:masked |
true |
Customer-facing governance signal: this resource holds masked data. |
datamasque:masked-date |
2026-05-25T10:30:00+00:00 |
The ISO 8601 timestamp the masking run completed. |
datamasque:run-id |
42 |
The DataMasque run ID that produced the masked data. |
aws-apn-id |
pc:<product-code> |
The product code of the DataMasque product that performed the masking, used for auditing with AWS. |
A discovery run (which profiles data without masking it) applies a parallel marker set instead:
| Tag | Example value | Purpose |
|---|---|---|
datamasque:discovered |
true |
Governance signal: this resource has been profiled by a DataMasque discovery run. |
datamasque:discovered-date |
2026-05-25T10:30:00+00:00 |
The ISO 8601 timestamp the discovery run completed. |
datamasque:run-id |
42 |
The DataMasque run ID that profiled the resource. |
A discovery run never applies datamasque:masked or aws-apn-id, since it reads but does not mask data.
The resource tagged depends on the target type:
- RDS instances (matched by an
*.rds.amazonaws.cominstance endpoint) are tagged on the instance, andCopyTagsToSnapshotis enabled so the tags propagate to snapshots automatically. - Aurora clusters (matched by an
*.rds.amazonaws.comcluster endpoint) are tagged on the cluster, andCopyTagsToSnapshotis enabled on the cluster so the tags propagate to snapshots automatically. Aurora custom endpoints, RDS Proxy, Aurora global, and Aurora Limitless endpoints are not tagged. - Redshift clusters are tagged on the cluster.
- DynamoDB tables are tagged on each masked table.
- S3 objects are tagged inline as they are written.
Tagging is best-effort. If a tagging API call fails (for example, because of a missing IAM permission), the masking
run still completes successfully and a WARNING is logged with the underlying error and a remediation message. Tagging
never blocks or fails a masking run.
Unlike the other resource types, which are tagged once on completion, S3 objects are tagged inline as each object is
written. If a run fails partway through, objects already written carry the datamasque:masked tag even though the run
did not complete, and the datamasque:masked-date value reflects the run start rather than its completion.
Tagging the DataMasque host instance
When DataMasque is hosted on an EC2 instance, a successful run that changes data also tags that instance, whatever
the run's target. The instance is tagged as a DataMasque deployment, not as masked data, so it never carries
datamasque:masked.
| Tag | Example value | Purpose |
|---|---|---|
datamasque:deployment |
true |
Governance signal: DataMasque is deployed on this instance. |
datamasque:last-run-date |
2026-08-31T02:14:09+00:00 |
The ISO 8601 timestamp the most recent qualifying run completed. |
aws-apn-id |
pc:<product-code> |
The product code of the DataMasque product running on the instance, used for auditing with AWS. |
datamasque:last-run-date is updated on every qualifying run. Your own tags on the instance are left alone, and
DataMasque never removes the tags it applies.
The instance is not tagged when DataMasque runs from an AWS Marketplace AMI (a Marketplace instance is already attributed through its product code), on Kubernetes (Amazon EKS, ROSA or self-managed), on Amazon ECS or Fargate, or on Snowpark Container Services. Dry runs, discovery runs, failed or cancelled runs, and runs that change no data leave the instance untouched; a run that truncates, subsets or drops tables counts as changing data.
Host tagging is best-effort in the same way as resource tagging and never affects the outcome of a run. If the
instance role does not allow ec2:CreateTags, the run completes as normal and the run log records an informational
message naming the permission; grant the permission or clear the setting to stop it. If DataMasque cannot reach the
instance metadata service from its containers (see IMDS Version), the instance
is not tagged and nothing is recorded in the run log.
The IAM role attached to the instance needs ec2:CreateTags on that instance. This is the
DataMasqueHostInstanceTagging statement in Required IAM permissions; its aws:TagKeys
condition limits it to DataMasque's own tag keys. Omit the statement on installs where the instance is not tagged.
The tag_aws_resources global setting
Tagging is controlled by the Tag AWS resources as masked after a successful run checkbox on the global settings page. It defaults to on and covers both the masked resources and the DataMasque host instance. The setting is only visible when DataMasque is running on AWS; on non-AWS installs no tagging UI or behaviour is present. To opt out, an administrator can clear the checkbox and save.
Required IAM permissions
Grant the DataMasque instance role the following permissions for the resource types you mask. The policy below avoids
Resource: "*"; narrow the Resource ARNs further to the specific regions, accounts, tables, clusters, instances, and
buckets you mask where possible.
Note that s3:PutObjectTagging is required even though S3 tags are supplied inline via the PutObject Tagging
parameter, because IAM evaluates the tagging action independently of s3:PutObject.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "DataMasqueDynamoDbTagging",
"Effect": "Allow",
"Action": [
"dynamodb:DescribeTable",
"dynamodb:TagResource"
],
"Resource": "arn:aws:dynamodb:*:<account-id>:table/*"
},
{
"Sid": "DataMasqueRdsTagging",
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:AddTagsToResource",
"rds:ModifyDBInstance"
],
"Resource": "arn:aws:rds:*:<account-id>:db:*"
},
{
"Sid": "DataMasqueAuroraTagging",
"Effect": "Allow",
"Action": [
"rds:DescribeDBClusters",
"rds:AddTagsToResource",
"rds:ModifyDBCluster"
],
"Resource": "arn:aws:rds:*:<account-id>:cluster:*"
},
{
"Sid": "DataMasqueRedshiftTagging",
"Effect": "Allow",
"Action": [
"redshift:DescribeClusters",
"redshift:CreateTags"
],
"Resource": "arn:aws:redshift:*:<account-id>:cluster:*"
},
{
"Sid": "DataMasqueS3Tagging",
"Effect": "Allow",
"Action": [
"s3:PutObjectTagging"
],
"Resource": "arn:aws:s3:::<bucket-name>/*"
},
{
"Sid": "DataMasqueHostInstanceTagging",
"Effect": "Allow",
"Action": "ec2:CreateTags",
"Resource": "arn:aws:ec2:<region>:<account-id>:instance/<instance-id>",
"Condition": {
"ForAllValues:StringLike": {
"aws:TagKeys": ["datamasque:*", "aws-apn-id"]
}
}
}
]
}
DataMasqueHostInstanceTagging applies to the DataMasque host instance rather than a masked resource; see
Tagging the DataMasque host instance for when it is needed.
rds:ModifyDBInstance (RDS instances) and rds:ModifyDBCluster (Aurora clusters) are used only to enable
CopyTagsToSnapshot on the masked resource, so that the protection tags propagate to snapshots automatically
(see below).
Tagging a resource in another AWS account
The permissions above are granted to the DataMasque instance role, which can only see resources in DataMasque's own
account. If the database you are masking lives in a different account, grant the permissions above to a role in
that account, and set that role's ARN as the IAM Role ARN on the connection. DataMasque then assumes the
role for the tagging calls. The DataMasque instance role still needs sts:AssumeRole on that role, and the role's
trust policy must allow DataMasque's account to assume it.
On a database connection (IBM Db2 LUW, MariaDB, MySQL, Oracle, PostgreSQL, SQL Server or Amazon Redshift), the role is used only for tagging. Masking still reaches the database over its own port with the database credentials on the connection, so a missing or wrong role costs you the tags and nothing else. The role only has any effect when the host is an RDS instance, Aurora cluster or provisioned Redshift cluster endpoint; on a self-managed database, or on the endpoint types listed above as untaggable, it is silently unused.
On a DynamoDB or S3 connection the same field is the role DataMasque assumes to read and write the data itself, so it is required for the masking run, not just for the tags.
For RDS instances, Aurora clusters and Redshift clusters, a cross-account attempt without the ARN typically fails with a message reporting that the resource was not found in the account DataMasque reached, because the resource genuinely does not exist there. A policy that denies the lookup outright reports missing permissions instead. See Cross Account Functionality for AWS for the trust policy and the connection setup.
Preserving tags through RDS snapshot and restore
DataMasque tags the RDS instance (not the snapshot) and sets CopyTagsToSnapshot=true. With this in place, tags
copy automatically from the instance to its snapshots, and from a snapshot to an instance restored from it, as long as
no explicit tags are supplied on the snapshot or restore operation.
Note: Amazon Aurora manages snapshot tag copying at the cluster level, so DataMasque tags the Aurora cluster and sets
CopyTagsToSnapshot=trueon it. The tags then propagate to cluster snapshots automatically, as long as no explicit tags are supplied on the snapshot or restore operation.
Do not pass explicit --tags on snapshot or restore
Supplying explicit --tags on create-db-snapshot or restore-db-instance-from-db-snapshot overrides AWS tag
inheritance and drops the inherited protection tags. When using the AWS CLI, omit --tags so the tags inherit:
# Inherits the instance tags (including the DataMasque protection tags).
aws rds create-db-snapshot \
--db-instance-identifier my-masked-instance \
--db-snapshot-identifier my-masked-snapshot
aws rds restore-db-instance-from-db-snapshot \
--db-instance-identifier my-restored-instance \
--db-snapshot-identifier my-masked-snapshot
CloudFormation and Terraform always send an explicit tag set on the restored resource, so tag inheritance does not
apply to IaC restores. To keep the masked-data signal on resources restored via IaC, include the protection tags in the
restore template, as shown below. If your organisation manages snapshot and restore pipelines entirely through its own
templates, see Tagging AWS resources with your own CloudFormation or Terraform for a
fuller guide. The snippets carry only datamasque:masked and aws-apn-id; datamasque:masked-date
and datamasque:run-id describe the original masking run and are intentionally omitted, so they will not be present on
resources restored this way.
CloudFormation restore snippet
Resources:
RestoredInstance:
Type: AWS::RDS::DBInstance
Properties:
DBSnapshotIdentifier: my-masked-snapshot
DBInstanceClass: db.t3.medium
Tags:
- Key: "datamasque:masked"
Value: "true"
- Key: "aws-apn-id"
# Replace with the value from the masked instance's `aws-apn-id` tag.
Value: "pc:<product-code>"
Terraform restore snippet
resource "aws_db_instance" "restored" {
snapshot_identifier = "my-masked-snapshot"
instance_class = "db.t3.medium"
tags = {
"datamasque:masked" = "true"
# Replace with the value from the masked instance's `aws-apn-id` tag.
"aws-apn-id" = "pc:<product-code>"
}
}
Finding masked resources with AWS Config
If AWS Config is recording resource configurations, you can query for all resources DataMasque has marked as masked using an advanced query:
SELECT
resourceId,
resourceType,
accountId,
awsRegion
WHERE
tags.key = 'datamasque:masked'
AND tags.value = 'true'
Run it from the AWS Config console under Advanced queries, or with the CLI:
aws configservice select-resource-config \
--expression "SELECT resourceId, resourceType, accountId, awsRegion WHERE tags.key = 'datamasque:masked' AND tags.value = 'true'"