# Connect Doppler

Canonical URL: https://docs.fuse.init.inc/integrations/doppler/setup

Create a Doppler Service or Service Account token and submit it to Init for project/config discovery and single-secret lifecycle.



## Before you start [#before-you-start]

Doppler uses **customer bearer credentials**. Init accepts only **Service Tokens** (`dp.st.*`) and **Service Account Tokens** (`dp.sa.*`). Personal, CLI, SCIM, audit, and service-account-identity tokens are rejected.

There is no Init platform OAuth app and **no generic HTTP proxy** for `api.doppler.com`. Callers use typed actions only. Bulk secret download, dynamic-secret leases, token creation, and arbitrary API paths are intentionally unavailable.

**Connection admin/user** creates a least-privilege token in Doppler and submits it to Init.

You need:

* Permission to create Service Tokens or Service Account Tokens in the Doppler workplace.
* A clear choice between config-scoped Service Tokens and workplace-capable Service Account Tokens.
* An isolated project/config for write validation (no production syncs, references, webhooks, or inheritance).

## Configure the provider [#configure-the-provider]

### Choose a token class (**Connection admin/user**) [#choose-a-token-class-connection-adminuser]

| Token                 | Prefix    | Typical use                                                                                               |
| --------------------- | --------- | --------------------------------------------------------------------------------------------------------- |
| Service Token         | `dp.st.*` | Single config; recommend for narrow read/write of one config.                                             |
| Service Account Token | `dp.sa.*` | Project/config listing plus secret lifecycle across projects; required for the full discovery/live suite. |

1. In Doppler, create a **Service Account** (preferred for discovery) or a **Service Token** scoped to one config.
2. Grant only the roles needed for the Init actions you will run—Doppler permissions are grants/roles, not OAuth scopes. Init actions use empty `requiredScopes`.
3. Copy the token once. Store it securely; Doppler may not show the full value again.
4. Confirm the token can call `https://api.doppler.com/v3/me`.

There is no custom API origin. Init always calls `https://api.doppler.com` under `/v3`.

Secret names must match `^[A-Z_][A-Z0-9_]{0,199}$`. Values are bounded at 50 KiB UTF-8. Visibility must be `masked`, `unmasked`, or `restricted`.

## Connect to Init [#connect-to-init]

**Connection admin/user** starts a Doppler Connect session and submits:

| Field          | Required | Notes                                                                |
| -------------- | -------- | -------------------------------------------------------------------- |
| `access_token` | Yes      | Service Token (`dp.st.*`) or Service Account Token (`dp.sa.*`) only. |

Use `dp.st.example_token_not_valid` only as an inert documentation placeholder. Never paste a live token into docs.

Init probes `GET /v3/me`, stores the token in Vault, and persists only workplace slug/name outside Vault. `auth_config` is empty and `provider_binding` is null. Disconnect deletes Vault custody only—Init does **not** call Doppler `/v3/auth/revoke`.

## Permissions [#permissions]

Doppler access is **role/grant based**. Every Init action has empty `requiredScopes`; the token’s grants decide what succeeds.

| Capability        | Typical Doppler access | Init actions         |
| ----------------- | ---------------------- | -------------------- |
| List projects     | Project list           | `projects.list`      |
| List configs      | Config list            | `configs.list`       |
| List secret names | Secret read (names)    | `secrets.names.list` |
| Read one secret   | Secret read            | `secrets.get`        |
| Write one secret  | Secret write           | `secrets.set`        |
| Delete one secret | Secret write/delete    | `secrets.delete`     |

All six actions are **REST/SDK only** (`mcp: false`) and mark outputs as **sensitive**.

`secrets.names.list` always sends `include_dynamic_secrets=false` so leases are never issued.

`secrets.get` returns only `{ name, computed }`—raw value and note are omitted.

`secrets.set` probes existence, then POSTs a single change request. Init returns `{ project, config, name, saved: true }` only and **discards** Doppler’s config-wide secret-map response without reading it. Do not retry after ambiguous dispatch (`idempotency: unsafe`).

`secrets.delete` maps `204` to `deleted` and `404` to `already_absent`.

## Verify the connection [#verify-the-connection]

1. Complete Connect and confirm the connection is active.
2. Run Init’s connection test (`GET /v3/me`) or a safe read such as `projects.list` / `configs.list`.
3. Success looks like Doppler accepting the bearer token for the workplace without `401`/`403`, with the connection showing workplace slug/name.

Connection testing proves token/workplace identity, not every action grant. Secret writes require write grants and should be validated only against an isolated test config.

## Rotate or revoke access [#rotate-or-revoke-access]

1. Create a new Service or Service Account token with the same least-privilege grants (overlap rotation: keep the old token valid until Connect succeeds with the new one).
2. Reconnect in Init with the new `access_token`.
3. Revoke or roll the previous token in Doppler.

If a token is exposed, revoke it immediately in Doppler, then reconnect. Init disconnect removes Vault custody only—customers own remote revoke/roll.

## Troubleshooting [#troubleshooting]

| Symptom                              | What to check                                                                                            |
| ------------------------------------ | -------------------------------------------------------------------------------------------------------- |
| Connect rejects the token format     | Only `dp.st.*` and `dp.sa.*` are accepted; personal/CLI/SCIM/audit/said tokens fail schema validation.   |
| `401` Unauthorized                   | Token revoked, mistyped, or wrong class for the API.                                                     |
| `403` Forbidden                      | Token lacks the grant for that action (Service Tokens may be limited to one config).                     |
| Cannot list projects                 | Service Tokens are often config-scoped; use a Service Account Token for discovery.                       |
| Secret name rejected                 | Names must match `^[A-Z_][A-Z0-9_]{0,199}$`.                                                             |
| Value too large                      | Secret values must be ≤ 50 KiB UTF-8.                                                                    |
| Visibility rejected                  | Must be `masked`, `unmasked`, or `restricted`.                                                           |
| Proxy / custom host errors           | Doppler has no generic proxy allowlist; use typed actions only.                                          |
| Expecting bulk secret maps           | Bulk download and config-wide responses are intentionally unavailable; use single-secret get/set/delete. |
| Disconnect did not revoke in Doppler | Expected—revoke or roll the token in Doppler yourself.                                                   |

