---
layout: docs
page_title: Secure Variables
description: Learn about Nomad's secure variables feature
---

# Secure Variables

Most Nomad workloads need access to config values or secrets. Nomad has a
`template` block to provide such configuration to tasks, but has left the role
of storing that configuration to external services such as [HashiCorp Consul]
and [HashiCorp Vault].

Nomad's Secure Variables feature provides the option to securely store
configuration at file-like paths directly in Nomad's state store. The contents
of these secrets are encrypted and replicated between servers via raft. Access
to secrets is controlled by ACL policies, and tasks have implicit ACL policies
that allow them to access their own secrets. You can create, read, update, or
delete secrets via the command line, the Nomad API, or in the Nomad web UI.

Note that the Secure Variables feature is intended for small pieces of
configuration data needed by workloads. Because writing to the Nomad state store
uses resources needed by Nomad, it is not well-suited for large or fast-changing
data. For example, do not store batch job results as Secure Variables - these
should be stored in an external database. Secure Variables are also not intended
to be a full replacement for HashiCorp Vault. If you need powerful options like
dynamic secrets or transit encryption, continue using Vault.

## ACL for Secure Variables

Every Secure Variable belongs to a specific Nomad namespace. ACL policies can
restrict access to Secure Variables within a namespace on a per-path basis,
using a list of `path` blocks, located under `namespace.secure_variables`. See
the [ACL policy specification] docs for details about the syntax and structure
of an ACL policy.

Path definitions may also include wildcard symbols, also called globs, allowing
a single path policy definition to apply to a set of paths within that
namespace. For example, the policy below allows full access to secure variables
at all paths in the "dev" namespace that are prefixed with "project/" (including
child paths) but only read access to paths prefixed with "system/". Note that
the glob can match an empty string and all other characters. This policy grants
read access to paths prefixed with "system/" but not a path named "system"
(without a trailing slash).

```hcl
namespace "dev" {
  policy       = "write"
  capabilities = ["alloc-node-exec"]

  secure_variables {

    # full access to secrets in all "project" paths
    path "project/*" {
      capabilities = ["write", "read", "destroy", "list"]
    }

    # read/list access within a "system/" path belonging to administrators
    path "system/*" {
      capabilities = ["read"]
    }
  }
}
```

The available capabilities for Secure Variables are as follows:

| Capability | Notes                                                                                                                        |
|------------|------------------------------------------------------------------------------------------------------------------------------|
| write      | Create or update Secure Variables at this path. Includes the "list" capability but not the "read" or "destroy" capabilities. |
| read       | Read the decrypted contents of Secure Variables at this path. Also includes the "list" capability                            |
| list       | List the metadata but not contents of Secure Variables at this path.                                                         |
| destroy    | Delete Secure Variables at this path.                                                                                        |

## Task Access to Secure Variables

In Nomad 1.4.0 tasks can only access Secure Variables with the [`template`]
block. The [workload identity] for each task grants it automatic read and list
access to Secure Variables found at Nomad-owned paths with the prefix
`nomad/jobs/`, followed by the job ID, task group name, and task name. This is
equivalent to the following policy:

```hcl
namespace "$namespace" {
  secure_variables {

    path "nomad/jobs" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/$job_id" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/$job_id/$task_group" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/$job_id/$task_group/$task_name" {
      capabilities = ["read", "list"]
    }
  }
}
```

For example, a task named "redis", in a group named "cache", in a job named
"example", will automatically have access to Secure Variables as if it had the
following policy:

```hcl
namespace "default" {
  secure_variables {

    path "nomad/jobs" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/example" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/example/cache" {
      capabilities = ["read", "list"]
    }

    path "nomad/jobs/example/cache/redis" {
      capabilities = ["read", "list"]
    }
  }
}
```

You can provide access to additional secrets by creating policies associated
with the task's [workload identity]. For example, to give the task above access to
set of shared secrets, you can create the following policy file:

```hcl
namespace "shared" {
  secure_variables {
    path "*" {
      capabilities = ["read"]
    }
  }
}
```

Then create the policy with to give the task read access to
all paths in the "shared" namespace:

```shell-session
nomad acl policy apply "_:/default/example/cache/redis" ./policy.hcl
```

See [Implicit Access to ACL Policies] for more details.

[HashiCorp Consul]: https://consul.io
[HashiCorp Vault]: https://vaultproject.io
[ACL policy specification]: docs/other-specifications/acl-policy
[`template`]: /docs/job-specification/template
[workload identity]: /docs/concepts/workload-identity
[Implicit Access to ACL Policies]: /docs/concepts/workload-identity#implicit-access-to-acl-policies
