> ## Documentation Index
> Fetch the complete documentation index at: https://docs.reelevant.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rotate Source Secrets

> Replace the passwords, keys and tokens of a Datasource source without reconfiguring it

## Overview

A source's secrets (passwords, private keys, access keys, authentication headers) can be replaced with a single request, without reconfiguring the source or publishing a new version. Use it when a credential expires, leaks or is rotated by your provider.

The request only changes the secrets you send. The rest of the source configuration is kept, and secrets are never returned in API responses.

## Secrets by source type

Only the fields listed below are accepted. Nested fields use a dotted path.

| Source type | Secret fields |
| - | - |
| [URL](/advanced-guide/datahub/source-types/url) | `options.headers.authorization`, `options.headers.proxy-authorization`, `options.headers.cookie`, `options.headers.x-api-key`, `options.headers.api-key`, `options.headers.x-auth-token`, `pgpPrivateKey`, `pgpPassphrase` |
| [File Upload](/advanced-guide/datahub/source-types/file) | `pgpPrivateKey`, `pgpPassphrase` (rotating them does not lift the [File Upload PGP limitation](/advanced-guide/datahub/source-types/file)) |
| [FTP](/advanced-guide/datahub/source-types/ftp-sftp) | `password`, `pgpPrivateKey`, `pgpPassphrase` |
| [SFTP](/advanced-guide/datahub/source-types/ftp-sftp) | `password`, `privateKey`, `passphrase`, `pgpPrivateKey`, `pgpPassphrase` |
| [BigQuery](/advanced-guide/datahub/source-types/bigquery) | `privateKey` |
| [Snowflake](/advanced-guide/datahub/source-types/snowflake) | `password`, `privateKey` |
| [Google Cloud Storage](/advanced-guide/datahub/source-types/gcs) | `clientEmail`, `privateKey`, `pgpPrivateKey`, `pgpPassphrase` |
| [Amazon S3](/advanced-guide/datahub/source-types/s3) | `accessKey`, `secretKey`, `assumeRole.externalId`, `pgpPrivateKey`, `pgpPassphrase` |
| [Kafka](/advanced-guide/datahub/source-types/kafka) | `password`, `registry.password` |
| [Datasource Reference](/advanced-guide/datahub/source-types/datasource-reference) | None |

<Info>
  URL header names are matched regardless of case: `options.headers.authorization` replaces a stored `Authorization` header instead of adding a second one. Headers that are not listed above cannot be changed with this request.
</Info>

## Rotate secrets

Before you begin, set these values:

| Value | Description |
| - | - |
| `DATASOURCE_ID` | The Datasource identifier. |
| `SOURCE_INDEX` | The position of the source in the Datasource, starting at `0`. A Datasource with a single source uses `0`. |
| `ACCESS_TOKEN` | An OAuth 2.0 access token with permission to update the Datasource. See [Authentication](/developer-docs/api-reference/authentication). |

The `secrets` object maps each secret field to its new value. This example rotates the credentials of an SFTP source:

```bash theme={"theme":{"light":"github-light","dark":"github-dark"}}
DATASOURCE_ID="replace-with-datasource-id"
SOURCE_INDEX=0
ACCESS_TOKEN="replace-with-access-token"

curl --request PUT "https://api.reelevant.com/v2/datasources/${DATASOURCE_ID}/sources/${SOURCE_INDEX}/secrets" \
  --header "Authorization: Bearer ${ACCESS_TOKEN}" \
  --header "Content-Type: application/json" \
  --data '{ "secrets": { "password": "replace-with-new-password", "passphrase": null } }'
```

* A field set to a value replaces the stored secret. A field set to `null` removes it. A field you omit keeps its current value.
* Multi-line values (private keys in PEM or armored format) must keep their line breaks, written as `\n` inside the string.
* Rotate paired secrets in the same request, for example `accessKey` and `secretKey` on S3, or `pgpPrivateKey` and `pgpPassphrase`.
* The new secrets apply to the live version of the Datasource, its draft and any version awaiting verification. The previous secrets cannot come back with a later publication.

A `204` status confirms the change. A field that is not a secret of the source, an empty `secrets` object or an unknown `SOURCE_INDEX` returns `400`, and nothing is saved.

<Info>
  When the result contains a `pgpPrivateKey`, Reelevant checks that the key can be read and unlocked with the passphrase before saving anything. An invalid key or a wrong passphrase returns `400`. See [PGP Decryption](/advanced-guide/datahub/pgp-decryption#rotate-the-private-key). Other secrets are saved as sent and are checked by the next import.
</Info>

## After the rotation

The request does not start an import. A scheduled Datasource uses the new secrets from its next import. To check them immediately, trigger a new run of the Datasource and review its [logs](/advanced-guide/datahub/logs). For a continuous (ingester-mode) Kafka Datasource, there is no next import: review its logs after the rotation.
