> ## Documentation Index
> Fetch the complete documentation index at: https://tyk-tt17611-iam-auth.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Secrets Management

> Store secrets outside your API definitions and Tyk component configuration, and reference them safely using Tyk's Secrets Management system.

## Introduction

Secrets Management lets you keep sensitive values, such as passwords, API keys and certificates, out of your API definitions and the configuration of Tyk Gateway and other components. Instead of writing a secret value directly into a config field, you register a *secret store* and write a *reference* to a key within that store. The component resolves the reference to the real value.

This keeps sensitive values in one place you control access to, lets the same API definition move between environments (development, staging, production) unchanged, and means the people editing API definitions don't need to see the secrets those definitions use.

**Available from Tyk Gateway and Tyk Dashboard 5.15.0, Tyk Portal 1.19.0, Tyk MDCB 2.13.0, and Tyk Pump 1.17.0.** Earlier versions only support the [legacy syntax](/tyk-configuration-reference/kv-store-legacy), which continues to work unchanged alongside this on all newer versions too.

## Supported Secret Stores

Each store is registered under a name you choose, with a `type` that selects which backend it talks to:

| Store Type            | Availability       | Reads From                                                                  |
| :-------------------- | :----------------- | :-------------------------------------------------------------------------- |
| `env`                 | All users          | Environment variables                                                       |
| `inline`              | All users          | A literal key/value map written directly into the component's configuration |
| `file`                | All users          | Local files, including Kubernetes Secrets mounted as files                  |
| `hashicorp_vault`     | All users          | A HashiCorp Vault instance                                                  |
| `hashicorp_consul`    | All users          | A HashiCorp Consul instance                                                 |
| `aws_secrets_manager` | Enterprise Edition | AWS Secrets Manager                                                         |
| `azure_key_vault`     | Enterprise Edition | Azure Key Vault                                                             |
| `gcp_secret_manager`  | Enterprise Edition | GCP Secret Manager                                                          |

See [Secret Store Providers](/tyk-configuration-reference/kv-store-providers) for how to configure each type.

## How It Works

There are three parts to using Secrets Management:

1. **Register a store.** Add an entry under the `kv.stores` section of the component's configuration, naming the store and giving it a `type` from the table above and whatever connection details that type needs. A store can also be marked `required`. See [Error Handling](#error-handling) below for what that changes. Stores are not shared between components: each component only sees the stores registered in its own configuration, so a Vault instance you want both Tyk Gateway and Tyk Dashboard to read from needs registering separately in each.

2. **Write a reference to it.** Anywhere a config value would normally be written, use one of two equivalent notations instead:

   | Notation              | Form                  | Use when                                                                     |
   | :-------------------- | :-------------------- | :--------------------------------------------------------------------------- |
   | Whole-value reference | `kv://<store>/<path>` | The entire field is the secret.                                              |
   | Inline token          | `$kv{<store>:<path>}` | The secret is part of a larger string, such as a hostname embedded in a URL. |

3. **The component resolves it.** Exactly when this happens depends on the component and where the reference sits. See [When References Are Resolved](#when-references-are-resolved) for details. What happens if a reference can't be resolved is explained in [Error Handling](#error-handling).

## Getting Started

This example registers an inline store, a literal key/value map written directly into the config, and references it from a component's configuration field.

`tyk.conf`:

```json theme={null}
{
  "kv": {
    "stores": {
      "myvals": {
        "type": "inline",
        "config": {
          "data": {
            "token": "xyz"
          }
        }
      }
    }
  }
}
```

Any API definition string field, and the supported fields in a component's configuration file, can now reference it. For example, a token used to authenticate with the upstream:

```json theme={null}
{
  "api_token": "kv://myvals/token"
}
```

`api_token` resolves to the value registered under the `token` key in the `myvals` store, so it ends up with the value `xyz`:

```json theme={null}
{
  "api_token": "xyz"
}
```

The inline-token form resolves the same store but only replaces part of the value, for example a token embedded in a URL:

```json theme={null}
{
  "upstream_url": "https://api.example.com/v1?token=$kv{myvals:token}"
}
```

which resolves to:

```json theme={null}
{
  "upstream_url": "https://api.example.com/v1?token=xyz"
}
```

## When References Are Resolved

Exactly when a reference is resolved, and what happens if it can't be, depends on the component, and on where in that component's configuration the reference sits:

| Location                                  | Scope                             | When Resolved                                            |
| :---------------------------------------- | :-------------------------------- | :------------------------------------------------------- |
| API definition fields                     | Any string field                  | On load, and on every reload                             |
| Tyk Gateway's configuration file          | A fixed set of fields (see below) | Mostly at startup; three fields also on every hot reload |
| Other Tyk components' configuration files | Any string field                  | At startup                                               |

**Tyk Gateway**

Two things are different about `tyk.conf` compared to the other components above.

First, it only supports a reference on a fixed, named set of fields. A reference written into any other field is never resolved:

| Field                                          | When Resolved                             |
| :--------------------------------------------- | :---------------------------------------- |
| `secret`                                       | At startup                                |
| `node_secret`                                  | At startup                                |
| `storage.password`                             | At startup                                |
| `cache_storage.password`                       | At startup                                |
| `security.private_certificate_encoding_secret` | At startup                                |
| `db_app_conf_options.connection_string`        | At startup                                |
| `policies.policy_connection_string`            | At startup                                |
| `slave_options.api_key`                        | At startup                                |
| `external_services.oauth.mtls.cert_file`       | At startup, and again on every hot reload |
| `external_services.oauth.mtls.key_file`        | At startup, and again on every hot reload |
| `external_services.oauth.mtls.ca_file`         | At startup, and again on every hot reload |

Second, the three `external_services.oauth.mtls` file paths are re-resolved on every subsequent Gateway hot reload to support certificate rotation.

## Multiple Store Instances

You can register more than one store of the same type, for example separate Vault instances for different environments or teams. Each gets its own name, and references disambiguate by store name:

```json theme={null}
{
  "kv": {
    "stores": {
      "vault-prod": {
        "type": "hashicorp_vault",
        "config": { "address": "https://vault-prod.internal:8200" }
      },
      "vault-staging": {
        "type": "hashicorp_vault",
        "config": { "address": "https://vault-staging.internal:8200" }
      }
    }
  }
}
```

`kv://vault-prod/secret/db/password` and `kv://vault-staging/secret/db/password` will read the value stored as `password` from two independent Vault instances.

## Referencing Fields From JSON Secrets

If a secret's value is a JSON document, append `#<pointer>` to the path to extract one field from it instead of resolving the whole document. The pointer follows [JSON Pointer](https://www.rfc-editor.org/rfc/rfc6901) notation: segments separated by `/`, with `~1` and `~0` used to escape a literal `/` or `~` within a key.

For example, suppose a store named `myvault` holds the following JSON value at the path `secrets/db`:

```json theme={null}
{
  "user": "admin",
  "credentials": { "pass": "s3cret" },
  "replicas": ["db-a", "db-b"]
}
```

The path (`secrets/db`) selects which secret to fetch from the store; the `#fragment` then addresses a field within that secret's own JSON value, including array elements by index:

| Reference                                  | Resolves To |
| :----------------------------------------- | :---------- |
| `kv://myvault/secrets/db#user`             | `admin`     |
| `kv://myvault/secrets/db#credentials/pass` | `s3cret`    |
| `kv://myvault/secrets/db#replicas/0`       | `db-a`      |

Multiple `#field` extractions from the same underlying secret only fetch that secret from the store once.

## Error Handling

There are two independent things that can go wrong with a secret store, and Tyk treats them differently: the store itself can fail to initialize, before any reference is ever resolved against it, or a specific reference can fail to resolve against a store that initialized fine. The rest of this section covers each in turn.

### Failed Store Initialization

Marking a store `required` controls what happens if the *store itself* fails to initialize (unreachable, bad credentials, an unsupported type). This is a different failure to a single reference not resolving, covered next.

* `required` left unset, or `false` (the default): a failed store logs a warning and is skipped. The component keeps starting; any reference to that store then fails when something tries to resolve it, following whichever behavior applies to that location (see below).
* `required: true`: a failed store is reported as an error, and the component refuses to start.

Set `required: true` on any store that provides secrets essential to secure operation, such as authentication credentials or TLS material. With the default `false`, a component can start and keep serving traffic even though a security-critical secret silently failed to load.

### Failed References

An unresolvable reference (an unknown store, a missing key, a malformed reference) in a component's **configuration file** is treated as a fatal configuration error at startup: the component logs the failure and refuses to start. The three `external_services.oauth.mtls` fields on Tyk Gateway are the one exception, since they're also re-resolved on every hot reload rather than only at startup. If one of these references fails to resolve during a hot reload, an error is logged and the previous value is used.

An unresolvable reference in an **API definition** field is different: it is logged as an error but does not stop the API loading. What this means in practice depends on the field: an unresolved reference in `target_url`, for example, still parses as a syntactically valid URL, so the API loads and only fails when a request tries to reach that upstream, returning a `500`. A reference left unresolved in a header added by transformation middleware is not an error at all: the literal reference string is just sent as the header's value.

<Warning>
  An unresolved reference string sent as a header or body value (for example `kv://my-store/db/password`) can reveal your store names and secret paths to whatever receives it: an upstream service, or the client, if the field is echoed back in a response. Treat an unresolved reference found in a live environment as a configuration bug to fix immediately, not a benign fallback.
</Warning>

## Legacy Key-Value Syntax

If you have existing API definitions or Tyk Gateway configuration using the older `vault://`, `consul://`, `env://`, `secrets://`, `file://` or `$secret_*` notation, they continue to work unchanged alongside this. See [Legacy Key-Value Syntax](/tyk-configuration-reference/kv-store-legacy) for details.
