---
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"
```
