Skip to content

Sanitization rules

The collector applies two independent rules to every resource’s planned values. Both run in every mode. secret-scan controls only the extra Gitleaks pass that comes after.

Rule 1: anything Terraform marks sensitive

Section titled “Rule 1: anything Terraform marks sensitive”

Terraform’s plan carries a sensitivity mask (after_sensitive) for every resource. Any value it marks sensitive is removed, whether the provider marked it (a database password, a generated key) or you did (sensitive = true on a variable or output that flows into the resource).

Removal is positional. A sensitive item in a list of nested blocks is replaced with an empty object {}, so ingress[1] still means the second rule and not the third.

Any attribute whose name contains one of these words as a whole segment is removed, with everything nested under it, at any depth:

Segment Catches, for example
password, passwd master_password, admin_passwd
secret, secret_string, client_secret secret_string, oauth_client_secret
token auth_token, token_value
api_key, apikey datadog_api_key
private_key, privatekey tls_private_key_pem
access_key, accesskey access_key_id
authorization authorization_header
cookie session_cookie
user_data, userdata user_data, user_data_base64
connection_string primary_connection_string
certificate_body certificate_body

Matching is case-insensitive. Before matching, names are normalized to snake_case, so masterPassword, master-password and Master.Password are all caught. A segment is bounded by _ or the end of the name: token matches auth_token but not tokenizer.

The exact pattern, from collect/collect.go:

(?i)(^|_)(password|passwd|secret|token|api_?key|private_?key|access_?key|client_?secret|authorization|cookie|user_?data|connection_?string|certificate_?body|secret_?string)($|_)

Everything else in a resource’s planned values, which is what makes a useful diagram: names, tags, CIDR blocks, IP addresses, ports and protocols, regions and zones, instance types and sizes, engine names and versions, and security group rules.

Values Terraform can’t know until apply ((known after apply)) aren’t in the plan, so they aren’t in the bundle either.

The rules above make up the standard profile, the only one today. The bundle records it in sanitization.profile along with two counters, so you can see what was removed in every build:

"sanitization": {
"profile": "standard",
"sensitive_paths_removed": 14,
"denied_keys_removed": 3
}

Stricter profiles, for example ones that drop IP addresses or tags, would come with a new version of the bundle schema.

Infragr.am applies the same credential-name check to every bundle it receives, and refuses the whole bundle if a matching key appears anywhere. A modified or outdated collector can’t upload a field the published collector would have removed.