---
title: Use pre-shared tokens
description: Supply your own token value when creating an API token so the same credential authenticates with multiple Telegraf Controller instances.
url: https://docs.influxdata.com/telegraf/controller/tokens/preshared/
estimated_tokens: 1677
publisher: InfluxData
canonical: https://docs.influxdata.com/telegraf/controller/tokens/preshared/
date: '2026-10-21T11:44:12-06:00'
lastmod: '2026-10-21T11:44:12-06:00'
---

By default, Telegraf Controller generates a random value when you create an
API token. A pre-shared token is a token whose raw value you supply yourself.
Because Telegraf Controller stores a deterministic hash of the value,
installing the same value on several instances gives you one credential for
your whole fleet. Use pre-shared tokens for API clients, CI pipelines, and
infrastructure-as-code modules that interact with more than one
Telegraf Controller instance.

Each instance keeps its own description, permissions, expiration, and owner
for the shared value. There is no synchronization between instances.
This lets you grant different permissions per instance, for example, read-only
access on production and read-write access on development. It also means the
token metadata can drift between instances.

> [!Important]
> #### One value, one blast radius
>
> If a pre-shared value is compromised, every instance that holds it is
> compromised. Revoking the token on one instance does not revoke it anywhere
> else. To revoke it everywhere, issue a revoke request against every instance
> that holds it. Collapsing many secrets into one is a trade-off you opt into
> deliberately.

## Provide a token value

Use either of the following as the token value:

* **A value generated by another Telegraf Controller instance**: create a
  token without supplying a value, copy the generated value, and then supply
  that value when creating tokens on your other instances.
* **A value you generate yourself**: see[Generate a token value](#generate-a-token-value).

The value must meet the [token requirements](#token-requirements).

### Use the UI

1. Navigate to the **API Tokens** page.
2. Click  **Create API Token**.
3. Enter a **Description** for the token.
4. Expand **Provide your own token string** and enter the value in the**Token String** field.
5. *(Optional)* Set an **Expiration** date and **Custom permissions** as
   described in [Create an API token](/telegraf/controller/tokens/create/).
6. Click **Create**.

<img src="/img/telegraf/controller-tokens-preshared-field.png" alt="Telegraf Controller create token form with a user-supplied token value" width="928">

### Use the API

Include the optional `rawToken` field in a `POST /api/tokens` request:

```bash
curl -X POST https://telegraf-controller.example.com/api/tokens \
  -H "Authorization: Bearer ADMIN_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
        "name": "ci-pipeline",
        "permissions": "configs:read",
        "rawToken": "SHARED_TOKEN_VALUE"
      }'
```

Replace the following:

* `ADMIN_API_TOKEN`:
  an API token with permission to create tokens on the instance
* `SHARED_TOKEN_VALUE`:
  the token value to install, matching the[token requirements](#token-requirements)

To install the same credential across a fleet, run the same request against
each instance and vary the description, permissions, and expiration as needed.

## Token requirements

A supplied token value must be the prefix `tc-apiv1_` followed by exactly
64 lowercase hexadecimal characters (32 random bytes):

```
tc-apiv1_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
```

Values that don’t match this format are rejected with `400 Bad Request`.

The format requirement protects the stored hash. Telegraf Controller stores
only a SHA-256 hash of the value, and a 256-bit random value cannot be
brute-forced or looked up in a rainbow table, while a short or human-chosen
string could be.

## Generate a token value

Use any of the following commands to generate a value that meets the[token requirements](#token-requirements):

[Linux and macOS](#linux-and-macos)[PowerShell](#powershell)[Python](#python)

```bash
printf 'tc-apiv1_%s\n' "$(openssl rand -hex 32)"
```

```powershell
$bytes = [byte[]]::new(32)
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($bytes)
"tc-apiv1_" + (($bytes | ForEach-Object { $_.ToString('x2') }) -join '')
```

```bash
python3 -c "import secrets; print('tc-apiv1_' + secrets.token_hex(32))"
```

## Uniqueness and conflicts

A raw value maps to exactly one token per instance. You cannot register the
same value twice under two descriptions. It is one credential, and two
descriptions require two distinct values.

`POST /api/tokens` returns `409 Conflict` with a machine-readable error code
when a conflict occurs:

|      Error code      |                      Meaning                      |
|----------------------|---------------------------------------------------|
|`token_value_conflict`|The supplied value already exists on this instance.|
|`token_name_conflict` | The description already exists on this instance.  |

## Correct a token’s permissions

Token permissions are fixed at creation. There is no endpoint that edits them.
To correct a mistake, delete or revoke the token, and then create it again
with the same value and the correct permissions. For a pre-shared token this
is inexpensive because you still hold the value. Anything already using the
value keeps working.

## Disable pre-shared tokens

Pre-shared tokens are enabled by default. To make an instance refuse
client-supplied token values, set the[`disable-preshared-tokens`](/telegraf/controller/reference/config-options/#disable-preshared-tokens)option at startup:

```bash
DISABLE_PRESHARED_TOKENS=true ./telegraf_controller
```

Or use the command flag:

```bash
./telegraf_controller --disable-preshared-tokens
```

When disabled:

* `POST /api/tokens` requests that include a `rawToken` field return`403 Forbidden` with the error code `preshared_tokens_disabled`.
  Requests without the field keep working as before.
* The UI hides the **Provide your own token string** field.
  The UI learns the instance’s state from `GET /api/tokens/capabilities`,
  which returns `{ "preSharedTokensEnabled": boolean }`.

> [!Note]
> This option does not restrict the[`owner-token`](/telegraf/controller/reference/config-options/#owner-token)startup option.[Bootstrap provisioning](/telegraf/controller/tokens/bootstrap/) is a
> separate feature with its own provisioning path, and it keeps working on an
> instance where pre-shared tokens are disabled.

#### Related

* [Create an API token](/telegraf/controller/tokens/create/)
* [Revoke a token](/telegraf/controller/tokens/revoke/)
* [Bootstrap an owner token](/telegraf/controller/tokens/bootstrap/)
* [Telegraf Controller configuration options](/telegraf/controller/reference/config-options/)
| Error code | Meaning |
| --- | --- |
| Error code | Meaning |
| token_value_conflict | The supplied value already exists on this instance. |
| token_name_conflict | The description already exists on this instance. |
