mirror of
https://github.com/opentffoundation/opentf.git
synced 2025-12-21 10:47:34 -05:00
124 lines
4.2 KiB
Plaintext
124 lines
4.2 KiB
Plaintext
---
|
|
sidebar_label: nonsensitive
|
|
description: >-
|
|
The nonsensitive function removes the sensitive marking from a value that
|
|
OpenTofu considers to be sensitive.
|
|
---
|
|
|
|
# `nonsensitive` Function
|
|
|
|
`nonsensitive` takes a sensitive value and returns a copy of that value with
|
|
the sensitive marking removed, thereby exposing the sensitive value.
|
|
|
|
:::warning
|
|
Using this function indiscriminately will cause values that
|
|
OpenTofu would normally have considered as sensitive to be treated as normal
|
|
values and shown clearly in OpenTofu's output. Use this function only when
|
|
you've derived a new value from a sensitive value in a way that eliminates the
|
|
sensitive portions of the value.
|
|
:::
|
|
|
|
Normally OpenTofu tracks when you use expressions to derive a new value from
|
|
a value that is marked as sensitive, so that the result can also be marked
|
|
as sensitive.
|
|
|
|
However, you may wish to write expressions that derive non-sensitive results
|
|
from sensitive values. For example, if you know based on details of your
|
|
particular system and its threat model that a SHA256 hash of a particular
|
|
sensitive value is safe to include clearly in OpenTofu output, you could use
|
|
the `nonsensitive` function to indicate that, overriding OpenTofu's normal
|
|
conservative behavior:
|
|
|
|
```hcl
|
|
output "sensitive_example_hash" {
|
|
value = nonsensitive(sha256(var.sensitive_example))
|
|
}
|
|
```
|
|
|
|
Another example might be if the original value is only partially sensitive and
|
|
you've written expressions to separate the sensitive and non-sensitive parts:
|
|
|
|
```hcl
|
|
variable "mixed_content_json" {
|
|
description = "A JSON string containing a mixture of sensitive and non-sensitive values."
|
|
type = string
|
|
sensitive = true
|
|
}
|
|
|
|
locals {
|
|
# mixed_content is derived from var.mixed_content_json, so it
|
|
# is also considered to be sensitive.
|
|
mixed_content = jsondecode(var.mixed_content_json)
|
|
|
|
# password_from_json is derived from mixed_content, so it's
|
|
# also considered to be sensitive.
|
|
password_from_json = local.mixed_content["password"]
|
|
|
|
# username_from_json would normally be considered to be
|
|
# sensitive too, but system-specific knowledge tells us
|
|
# that the username is a non-sensitive fragment of the
|
|
# original document, and so we can override OpenTofu's
|
|
# determination.
|
|
username_from_json = nonsensitive(local.mixed_content["username"])
|
|
}
|
|
```
|
|
|
|
When you use this function, it's your responsibility to ensure that the
|
|
expression passed as its argument will remove all sensitive content from
|
|
the sensitive value it depends on. By passing a value to `nonsensitive` you are
|
|
declaring to OpenTofu that you have done all that is necessary to ensure that
|
|
the resulting value has no sensitive content, even though it was derived
|
|
from sensitive content. If a sensitive value appears in OpenTofu's output
|
|
due to an inappropriate call to `nonsensitive` in your module, that's a bug in
|
|
your module and not a bug in OpenTofu itself.
|
|
**Use this function sparingly and only with due care.**
|
|
|
|
`nonsensitive` allows passing a value that isn't marked as sensitive,
|
|
even though such a call may be redundant and potentially confusing
|
|
or misleading to a future maintainer of your module.
|
|
|
|
Consider including a comment adjacent to your call to explain to future
|
|
maintainers what makes the usage safe and thus what invariants they must take
|
|
care to preserve under future modifications.
|
|
|
|
## Examples
|
|
|
|
The following examples are from `tofu console` when running in the
|
|
context of the example above with `variable "mixed_content_json"` and
|
|
the local value `mixed_content`, with a valid JSON string assigned to
|
|
`var.mixed_content_json`.
|
|
|
|
```
|
|
> var.mixed_content_json
|
|
(sensitive value)
|
|
> local.mixed_content
|
|
(sensitive value)
|
|
> local.mixed_content["password"]
|
|
(sensitive value)
|
|
> nonsensitive(local.mixed_content["username"])
|
|
"zqb"
|
|
> nonsensitive("clear")
|
|
"clear"
|
|
```
|
|
|
|
Note though that it's always your responsibility to use `nonsensitive` only
|
|
when it's safe to do so. If you use `nonsensitive` with content that
|
|
_ought to be_ considered sensitive then that content will be disclosed:
|
|
|
|
```
|
|
> nonsensitive(var.mixed_content_json)
|
|
<<EOT
|
|
{
|
|
"username": "zqb",
|
|
"password": "p4ssw0rd"
|
|
}
|
|
EOT
|
|
> nonsensitive(local.mixed_content)
|
|
{
|
|
"password" = "p4ssw0rd"
|
|
"username" = "zqb"
|
|
}
|
|
> nonsensitive(local.mixed_content["password"])
|
|
"p4ssw0rd"
|
|
```
|