> For the complete documentation index, see [llms.txt](https://docs.slingdata.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.slingdata.io/concepts/secrets.md).

# Secrets

Read connection credentials from 1Password, AWS, Azure, GCP, Vault and other secret managers.

Keep credentials in your secret manager. Put a **secret reference** in place of the value. Sling reads the secret when a run uses it. The secret value does not go to disk, to the logs, or to the Sling Platform.

This is available in **v1.6.5+**.

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+vault://secret/data/postgres#/password     # HashiCorp Vault
    database: analytics

  MY_MD:
    type: motherduck
    database: my_database
    motherduck_token: ref+azurekeyvault://my-vault/motherduck-token     # Azure Key Vault

  MY_RDS:
    type: postgres
    from: ref+awssecrets://prod/rds     # AWS Secrets Manager: all keys from one secret
```

## Reference Forms

A reference has this form:

```
ref+<kind>://<path>[?<params>][#<pointer>]
```

| Part      | Rule                                                                    | Example            |
| --------- | ----------------------------------------------------------------------- | ------------------ |
| `kind`    | The provider kind. See [Providers](#providers).                         | `awssecrets`       |
| `path`    | The secret. Specific to the provider.                                   | `prod/postgres`    |
| `params`  | Options. Specific to the provider, plus the common params below.        | `?provider=aws_eu` |
| `pointer` | A JSON pointer into a JSON or YAML secret. `#key` is short for `#/key`. | `#/password`       |

```yaml
password: ref+awssecrets://prod/postgres#/password
```

<details>

<summary>Common params and rules</summary>

| Param             | Meaning                                                                  |
| ----------------- | ------------------------------------------------------------------------ |
| `provider=<name>` | Use the named instance from [`secret_providers:`](#configure-providers). |
| `trim=false`      | Keep a trailing newline. By default, Sling removes one trailing newline. |

Rules:

* A value can be a whole reference: `password: ref+op://Data/pg/password`.
* A reference can be part of a longer value. End it with `+`:

  ```yaml
  url: postgres://etl:ref+op://Data/pg/password+@db.acme.com:5432/analytics
  ```
* Sling expands `${VAR}` first. Thus `password: ${PG_PASSWORD}` with `PG_PASSWORD=ref+op://Data/pg/password` also works.
* A pointer to an object is valid only in `from:`. A field needs a string.

</details>

<details>

<summary>Native forms (alternatives)</summary>

Sling also accepts some native forms with no `ref+<kind>://` prefix. Each one is the same as the `ref+` form.

| Provider                | Native form                                                                 | Same as                                             |
| ----------------------- | --------------------------------------------------------------------------- | --------------------------------------------------- |
| 1Password               | `op://Data/pg/password`                                                     | `ref+op://Data/pg/password`                         |
| Keeper                  | `keeper://<uid>/field/password`                                             | `ref+keeper://<uid>/field/password`                 |
| Azure Key Vault         | `https://my-vault.vault.azure.net/secrets/pg-password[/<version>]`          | `ref+azurekeyvault://my-vault/pg-password`          |
| AWS Secrets Manager     | `arn:aws:secretsmanager:eu-west-2:123456789012:secret:prod/pg-a1b2c3`       | `ref+awssecrets://arn:aws:secretsmanager:...`       |
| AWS SSM Parameter Store | `arn:aws:ssm:eu-west-2:123456789012:parameter/prod/pg/password`             | `ref+awsssm://arn:aws:ssm:...`                      |
| GCP Secret Manager      | `projects/my-project[/locations/<region>]/secrets/pg-password[/versions/5]` | `ref+gcpsecrets://my-project/pg-password?version=5` |
| CyberArk Conjur         | `myorg:variable:prod/db/password`                                           | `ref+conjur://prod/db/password`                     |

* Use a native form when you copy an identifier from the console of the secret manager.
* A native form must be the whole value. In a longer value, use the `ref+` form.
* Params and a pointer can follow a native form: `arn:aws:secretsmanager:...:secret:prod/pg-a1b2c3#/password`.
* Sling resolves each value that has a native form, also in `env:` values.

</details>

## Where References Work

| Place                                                                     | Example                                | Sling reads the secret    |
| ------------------------------------------------------------------------- | -------------------------------------- | ------------------------- |
| A string value of a connection, also nested values such as API `secrets:` | `password: ref+op://Data/pg/password`  | When the connection opens |
| `from:` of a connection                                                   | `from: ref+awssecrets://prod/postgres` | When the connection opens |
| `env:` of `env.yaml`                                                      | `API_TOKEN: ref+op://Data/acme/token`  | When a connection uses it |
| `env:` of a replication or a pipeline                                     | `API_TOKEN: ref+op://Data/acme/token`  | When Sling loads the file |
| The `secret()` function in hooks and pipeline steps                       | `{secret("ref+op://Data/acme/token")}` | When the step runs        |

<details>

<summary>Examples</summary>

An API connection:

```yaml
connections:
  STRIPE:
    type: api
    spec: stripe
    secrets:
      api_key: ref+awssecrets://prod/stripe#/api_key
```

The `env:` of a replication:

```yaml
source: MY_PG
target: MY_SNOWFLAKE

env:
  WEBHOOK_TOKEN: ref+op://Data/webhook/token

hooks:
  end:
    - type: http
      url: https://hooks.acme.com/sling
      headers:
        Authorization: 'Bearer {env.WEBHOOK_TOKEN}'

streams:
  public.orders:
```

The `secret()` function in a pipeline:

```yaml
steps:
  - type: http
    url: https://api.acme.com/v1/items
    headers:
      Authorization: 'Bearer {secret("ref+op://Data/acme/api_key")}'
```

</details>

## Load a Connection with `from:`

`from:` loads a JSON or YAML object from one secret. Its keys become the keys of the connection.

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+awssecrets://prod/rds/etl
    sslmode: require          # keys written here win over the secret
```

* Keys that you write in the connection win over keys from the secret.
* Sling changes `username` to `user`, and `dbname` to `database`. Thus AWS RDS secrets work as they are.

<details>

<summary>Connections without <code>type</code></summary>

`type` is optional with `from:`. Without it, Sling finds the type when a run uses the connection. It looks in this sequence:

1. The `type` key of the secret.
2. The `engine` key of the secret (AWS RDS secrets).
3. The scheme of the `url` key.

Until a run uses the connection, `sling conns list` shows `Unknown`. We recommend that you write `type`. Then Sling knows the type with no call to the secret manager.

</details>

## Read Values that Sling Has

The `sling` provider reads a field of a connection that Sling knows, or an environment variable.

```
ref+sling://connections/<name>/<field>[/<nested>...]    one field of a connection
ref+sling://connections/<name>                          the whole connection, for from:
ref+sling://env/<KEY>                                   an environment variable
```

```yaml
connections:
  PG_PROD:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+op://Data/pg/password
    database: prod

  PG_ANALYTICS:
    type: postgres
    from: ref+sling://connections/pg_prod     # copy PG_PROD
    database: analytics                       # keys written here win
```

<details>

<summary>Rules</summary>

* Any field is available, a secret or not. `url` is the full connection URL.
* If the field holds a reference, Sling resolves it first.
* The environment includes the `env:` values of `env.yaml`.
* Sling redacts all values that come from a reference, also values that are not secret. Thus log output shows `***` for a `host` from `ref+sling://`.
* If a reference points to itself, directly or through other references, Sling shows a `circular reference` error.

```yaml
steps:
  - type: log
    message: 'host is {secret("ref+sling://connections/pg_prod/host")}'   # logs "host is ***"
```

</details>

## Configure Providers

Most providers need no configuration. They use the default credentials of the host, such as the AWS credential chain or `az login`.

To set credentials, or to use two accounts of one provider, add a `secret_providers:` block to `env.yaml`:

```yaml
secret_providers:
  aws_eu:                         # instance name
    type: awssecrets              # provider kind or alias
    region: eu-west-1
    role_arn: arn:aws:iam::123456789012:role/sling

  aws_us:
    type: awssecrets
    region: us-east-1

connections:
  MY_PG:
    type: postgres
    from: ref+awssecrets://prod/postgres?provider=aws_eu
```

* Config values accept `${VAR}`. They do not accept secret references.
* Each config key has an environment variable as a fallback. See each provider below.

<details>

<summary>How Sling selects the instance</summary>

1. `?provider=<name>` in the reference.
2. The only instance of the provider kind.
3. The instance named `default`, when there are more instances of the kind. Else Sling shows an error.
4. With no instance of the kind, Sling uses the provider with no configuration.

</details>

## Providers

| Provider                                                  | Kind (aliases)                                          | Reference                                     |
| --------------------------------------------------------- | ------------------------------------------------------- | --------------------------------------------- |
| [1Password](#1password)                                   | `op` (`1password`, `onepassword`, `onepasswordconnect`) | `ref+op://Data/pg/password`                   |
| [AWS Secrets Manager](#aws-secrets-manager)               | `awssecrets` (`aws_secrets_manager`)                    | `ref+awssecrets://prod/pg#/password`          |
| [AWS SSM Parameter Store](#aws-ssm-parameter-store)       | `awsssm` (`aws_ssm`)                                    | `ref+awsssm:///prod/pg/password`              |
| [Azure Key Vault](#azure-key-vault)                       | `azurekeyvault` (`azure_key_vault`)                     | `ref+azurekeyvault://my-vault/pg-password`    |
| [GCP Secret Manager](#gcp-secret-manager)                 | `gcpsecrets` (`gcp_secret_manager`)                     | `ref+gcpsecrets://my-project/pg-password`     |
| [HashiCorp Vault](#hashicorp-vault-and-openbao)           | `vault` (`hashicorp_vault`)                             | `ref+vault://secret/data/pg#/password`        |
| [OpenBao](#hashicorp-vault-and-openbao)                   | `openbao` (`bao`)                                       | `ref+openbao://secret/pg#/password`           |
| [Infisical](#infisical)                                   | `infisical`                                             | `ref+infisical://<project>/<env>/<KEY>`       |
| [Doppler](#doppler)                                       | `doppler`                                               | `ref+doppler://<project>/<config>/<NAME>`     |
| [Bitwarden Secrets Manager](#bitwarden-secrets-manager)   | `bws` (`bitwarden_secrets_manager`)                     | `ref+bws://<secret-uuid>`                     |
| [Bitwarden Password Manager](#bitwarden-password-manager) | `bw` (`bitwarden`)                                      | `ref+bw://<item-id>/password`                 |
| [Keeper](#keeper)                                         | `keeper`                                                | `ref+keeper://<uid>/field/password`           |
| [CyberArk Conjur](#cyberark-conjur)                       | `conjur`                                                | `ref+conjur://prod/db/password`               |
| [Delinea Secret Server](#delinea-secret-server)           | `tss` (`delinea`, `thycotic`)                           | `ref+tss://<id>/password`                     |
| [Akeyless](#akeyless)                                     | `akeyless`                                              | `ref+akeyless:///prod/db/password`            |
| [SOPS](#sops)                                             | `sops`                                                  | `ref+sops://secrets.enc.yaml#/pg/password`    |
| [Kubernetes](#kubernetes)                                 | `k8s` (`kubernetes`)                                    | `ref+k8s://v1/Secret/<ns>/<name>/<key>`       |
| [Local file](#local-file)                                 | `file`                                                  | `ref+file://./secrets.yaml#/pg/password`      |
| [Command](#command)                                       | `exec`                                                  | `ref+exec://my-tool?arg=get`                  |
| [HTTP JSON](#http-json)                                   | `httpjson`                                              | `ref+httpjson://config.acme.com/pg#/password` |
| [Sling](#read-values-that-sling-has)                      | `sling`                                                 | `ref+sling://connections/my_pg/password`      |

### 1Password

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: ref+op://Data/postgres/server/host        # <vault>/<item>/<section>/<field>
    user: ref+op://Data/postgres/username           # <vault>/<item>/<field>
    password: ref+op://Data/postgres/password
    database: analytics

secret_providers:        # optional
  op:
    type: 1password
    token: ${OP_SERVICE_ACCOUNT_TOKEN}
```

Reference: `ref+op://<vault>/<item>[/<section>]/<field>`. Vault and item accept names or IDs.

Alternative: the native form `op://<vault>/<item>[/<section>]/<field>`.

Sling uses the first transport that is available:

| Transport                                  | Config                                                    | Environment variable                     |
| ------------------------------------------ | --------------------------------------------------------- | ---------------------------------------- |
| `op` CLI (service account, or `op signin`) | `token`, `account`                                        | `OP_SERVICE_ACCOUNT_TOKEN`, `OP_ACCOUNT` |
| 1Password Connect server                   | `connect_host`, `connect_token`, `ca_cert`, `skip_verify` | `OP_CONNECT_HOST`, `OP_CONNECT_TOKEN`    |

* Set `mode: cli` or `mode: connect` to select one transport.
* With the CLI, Sling reads all 1Password references of a run in one `op inject` call.

</details>

### AWS Secrets Manager

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+awssecrets://prod/rds/etl     # secret name

  MY_SNOWFLAKE:
    type: snowflake
    account: acme-xy12345
    user: SLING
    password: ref+awssecrets://prod/snowflake#/password     # secret name + key
    database: ANALYTICS

secret_providers:        # optional
  aws:
    type: awssecrets
    region: eu-west-2
    profile: data-eng
```

Reference: `ref+awssecrets://<name or ARN>[#/<key>]`.

Alternative: the secret ARN, `arn:aws:secretsmanager:eu-west-2:123456789012:secret:prod/rds/etl-a1b2c3`. Sling reads the region from the ARN.

| Config                    | Environment variable               | Meaning                                   |
| ------------------------- | ---------------------------------- | ----------------------------------------- |
| `region`                  | `AWS_REGION`, `AWS_DEFAULT_REGION` | Region. Sling reads it from an ARN first. |
| `profile`                 | `AWS_PROFILE`                      | Named profile.                            |
| `role_arn`, `external_id` |                                    | Role to assume.                           |
| `endpoint`                |                                    | Custom endpoint, such as a VPC endpoint.  |

* Credentials come from the AWS default chain: environment, profile, SSO, instance or task role.
* Params: `?region=`, `?version_id=`, `?version_stage=` (default `AWSCURRENT`).

</details>

### AWS SSM Parameter Store

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+awsssm:///prod/pg/password     # parameter /prod/pg/password
    database: analytics

  MY_MYSQL:
    type: mysql
    url: ref+awsssm://prod/mysql/url?region=us-east-1      # leading / is optional
```

Reference: `ref+awsssm://<parameter name or ARN>`.

Alternative: the parameter ARN, `arn:aws:ssm:eu-west-2:123456789012:parameter/prod/pg/password`.

* The configuration is the same as [AWS Secrets Manager](#aws-secrets-manager).
* Sling decrypts `SecureString` parameters.

</details>

### Azure Key Vault

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_MD:
    type: motherduck
    database: my_database
    motherduck_token: ref+azurekeyvault://my-vault/motherduck-token     # <vault name>/<secret>

  MY_SQLSERVER:
    type: sqlserver
    host: acme.database.windows.net
    user: etl
    password: ref+azurekeyvault://my-vault/sqlserver-password/ec96f02080254f109c51a1f14cdb1931     # with version
    database: analytics

secret_providers:        # optional
  azure:
    type: azurekeyvault
    tenant_id: ${AZURE_TENANT_ID}
    client_id: ${AZURE_CLIENT_ID}
    client_secret: ${AZURE_CLIENT_SECRET}
```

Reference: `ref+azurekeyvault://<vault>/<name>[/<version>]`. `<vault>` is the vault name, or its full DNS name.

Alternative: the secret identifier from the portal, `https://my-vault.vault.azure.net/secrets/motherduck-token[/<version>]`.

| Config                                    | Environment variable                                        | Meaning                                                         |
| ----------------------------------------- | ----------------------------------------------------------- | --------------------------------------------------------------- |
| `tenant_id`, `client_id`, `client_secret` | `AZURE_TENANT_ID`, `AZURE_CLIENT_ID`, `AZURE_CLIENT_SECRET` | Service principal.                                              |
| `cloud`                                   |                                                             | `public` (default), `usgov` or `china`. Also a `?cloud=` param. |
| `vault_url`                               |                                                             | Full vault URL, for other clouds.                               |

* Without a service principal, Sling uses the Azure default credential: environment, workload identity, managed identity, or `az login`.
* Without a version, Sling reads the latest version.

</details>

### GCP Secret Manager

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_BIGQUERY:
    type: bigquery
    project: my-project
    dataset: analytics
    key_body: ref+gcpsecrets://my-project/bq-service-account     # <project>/<secret>

  MY_PG:
    type: postgres
    host: 10.0.0.5
    user: etl
    password: ref+gcpsecrets://my-project/pg-password?version=3     # a fixed version
    database: analytics

secret_providers:        # optional
  gcp:
    type: gcpsecrets
    impersonate_service_account: sling@my-project.iam.gserviceaccount.com
```

Reference: `ref+gcpsecrets://<project>/<name>[?version=<v>]`. The default version is `latest`.

Alternative: the resource name, `projects/<p>[/locations/<region>]/secrets/<name>[/versions/<v>]`, also with the `//secretmanager.googleapis.com/` prefix. Use it for regional secrets.

| Config                        | Meaning                         |
| ----------------------------- | ------------------------------- |
| `credentials_json`            | Service account key JSON.       |
| `impersonate_service_account` | Service account to impersonate. |
| `endpoint`                    | Custom endpoint.                |

* Without `credentials_json`, Sling uses the application default credentials (`gcloud auth application-default login`, or the attached service account).
* Sling sends a regional secret to its regional endpoint.

</details>

### HashiCorp Vault and OpenBao

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+vault://secret/data/postgres       # KV v2: all keys of the secret
    database: analytics

  MY_MYSQL:
    type: mysql
    host: db.acme.com
    user: ref+vault://database/creds/etl#/username     # dynamic secret
    password: ref+vault://database/creds/etl#/password
    database: analytics

secret_providers:
  vault:
    type: vault
    address: https://vault.acme.com
    auth: approle
    role_id: ${VAULT_ROLE_ID}
    secret_id: ${VAULT_SECRET_ID}
```

Reference: `ref+vault://<path>[#/<key>]`. For OpenBao, use `ref+openbao://`. OpenBao reads `BAO_*` in place of `VAULT_*` variables.

| Config                           | Environment variable                | Meaning                                                                          |
| -------------------------------- | ----------------------------------- | -------------------------------------------------------------------------------- |
| `address`                        | `VAULT_ADDR`                        | Server URL.                                                                      |
| `namespace`                      | `VAULT_NAMESPACE`                   | Enterprise namespace.                                                            |
| `auth`                           | `VAULT_AUTH_METHOD`                 | `token` (default), `approle`, `jwt`, `kubernetes` or `aws`.                      |
| `token`, `token_file`            | `VAULT_TOKEN`, `VAULT_TOKEN_FILE`   | For `auth: token`. Also reads `~/.vault-token` (OpenBao: `~/.bao-token`).        |
| `role_id`, `secret_id`           | `VAULT_ROLE_ID`, `VAULT_SECRET_ID`  | For `auth: approle`.                                                             |
| `role`, `jwt`, `jwt_file`        |                                     | For `auth: jwt`.                                                                 |
| `role`, `token_file`             |                                     | For `auth: kubernetes`. The default token file is the pod service account token. |
| `role`, `region`, `header_value` |                                     | For `auth: aws`. Uses the AWS default chain.                                     |
| `mount`                          |                                     | Auth mount path, when it is not the default.                                     |
| `ca_cert`, `skip_verify`         | `VAULT_CACERT`, `VAULT_SKIP_VERIFY` | TLS.                                                                             |
| `renew_leases`                   |                                     | `false` stops lease renewal.                                                     |

* KV v1 and v2 are both supported. Sling finds the version of the mount. Add `?kv=1` or `?kv=2` to set it.
* `?version=<n>` reads an old version of a KV v2 secret.
* For dynamic secrets, Sling renews the lease during long tasks.

</details>

### Infisical

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+infisical://6512f0a3c9e1/prod/database/PG_PASSWORD     # <project id>/<env>/<folder>/<KEY>
    database: analytics

secret_providers:
  infisical:
    type: infisical
    client_id: ${INFISICAL_CLIENT_ID}
    client_secret: ${INFISICAL_CLIENT_SECRET}
```

References:

* `ref+infisical://<project id>/<env>/<folder path>/<KEY>`.
* `ref+infisical://<KEY>?project=<id>&environment=<env>&path=<folder>`.

| Config                       | Environment variable                                                           | Meaning             |
| ---------------------------- | ------------------------------------------------------------------------------ | ------------------- |
| `client_id`, `client_secret` | `INFISICAL_UNIVERSAL_AUTH_CLIENT_ID`, `INFISICAL_UNIVERSAL_AUTH_CLIENT_SECRET` | Universal auth.     |
| `token`                      | `INFISICAL_TOKEN`                                                              | Access token.       |
| `site_url`                   | `INFISICAL_API_URL`                                                            | Self-hosted server. |

* `?type=personal` reads a personal secret. The default is `shared`.

</details>

### Doppler

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+doppler://data-platform/prd/PG_PASSWORD     # <project>/<config>/<NAME>
    database: analytics

  MY_MYSQL:
    type: mysql
    url: ref+doppler://MYSQL_URL     # project and config from the provider

secret_providers:
  doppler:
    type: doppler
    token: ${DOPPLER_TOKEN}
    project: data-platform
    config: prd
```

| Config              | Environment variable                | Meaning                              |
| ------------------- | ----------------------------------- | ------------------------------------ |
| `token`             | `DOPPLER_TOKEN`                     | Service token or personal token.     |
| `project`, `config` | `DOPPLER_PROJECT`, `DOPPLER_CONFIG` | Defaults for `ref+doppler://<NAME>`. |
| `api_url`           | `DOPPLER_API_ADDR`                  | Custom API URL.                      |

</details>

### Bitwarden Secrets Manager

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+bws://be8e0ad8-d545-4017-a55a-b02f014d4158     # secret ID
    database: analytics

secret_providers:
  bws:
    type: bws
    token: ${BWS_ACCESS_TOKEN}
```

| Config       | Environment variable | Meaning                       |
| ------------ | -------------------- | ----------------------------- |
| `token`      | `BWS_ACCESS_TOKEN`   | Machine account access token. |
| `server_url` | `BWS_SERVER_URL`     | Self-hosted or EU server.     |

* Needs the [`bws` CLI](https://bitwarden.com/help/secrets-manager-cli/).

</details>

### Bitwarden Password Manager

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: ref+bw://4c8e7a3f-1d2b-4e5f-9a8b-c7d6e5f4a3b2/username     # <item id>/<field>
    password: ref+bw://4c8e7a3f-1d2b-4e5f-9a8b-c7d6e5f4a3b2/password
    database: analytics
```

| Config    | Environment variable | Meaning                       |
| --------- | -------------------- | ----------------------------- |
| `session` | `BW_SESSION`         | Session key from `bw unlock`. |

* Needs the [`bw` CLI](https://bitwarden.com/help/cli/). The vault must be unlocked.

</details>

### Keeper

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: ref+keeper://XXXXXXXXXXXXXXXXXXXXXX/field/host      # <record UID>/field/<name>
    user: ref+keeper://XXXXXXXXXXXXXXXXXXXXXX/field/login
    password: ref+keeper://XXXXXXXXXXXXXXXXXXXXXX/field/password
    database: analytics

secret_providers:
  keeper:
    type: keeper
    config: ${KSM_CONFIG}
```

Reference: `ref+keeper://<record UID or title>/field/<name>`. The path uses [Keeper notation](https://docs.keeper.io/en/keeperpam/secrets-manager/about/keeper-notation).

Alternative: the native form `keeper://<record UID or title>/field/<name>`.

| Config   | Environment variable | Meaning                               |
| -------- | -------------------- | ------------------------------------- |
| `config` | `KSM_CONFIG`         | Base64 Secrets Manager configuration. |

</details>

### CyberArk Conjur

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+conjur://prod/db/password      # variable ID
    database: analytics

secret_providers:
  conjur:
    type: conjur
    appliance_url: https://conjur.acme.com
    account: myorg
    login: host/sling
    api_key: ${CONJUR_AUTHN_API_KEY}
```

| Config             | Environment variable                         | Meaning                |
| ------------------ | -------------------------------------------- | ---------------------- |
| `appliance_url`    | `CONJUR_APPLIANCE_URL`                       | Server URL.            |
| `account`          | `CONJUR_ACCOUNT`                             | Account.               |
| `login`, `api_key` | `CONJUR_AUTHN_LOGIN`, `CONJUR_AUTHN_API_KEY` | Host or user identity. |
| `ca_cert`          | `CONJUR_SSL_CERTIFICATE`, `CONJUR_CERT_FILE` | CA certificate.        |
| `skip_verify`      |                                              | Do not verify TLS.     |

Reference: `ref+conjur://<variable ID>`.

Alternative: the resource ID, `myorg:variable:prod/db/password`. Its account must be the configured `account`.

</details>

### Delinea Secret Server

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_SQLSERVER:
    type: sqlserver
    host: sql01.acme.local
    user: ref+tss://1234/username      # <secret id>/<field slug>
    password: ref+tss://1234/password
    database: analytics

  MY_PG:
    type: postgres
    from: ref+tss://5678               # all fields as one object

secret_providers:
  tss:
    type: tss
    server_url: https://acme.secretservercloud.com
    username: ${TSS_USERNAME}
    password: ${TSS_PASSWORD}
```

| Config                           | Environment variable                         | Meaning                                          |
| -------------------------------- | -------------------------------------------- | ------------------------------------------------ |
| `server_url`                     | `TSS_SERVER_URL`                             | Server URL.                                      |
| `username`, `password`, `domain` | `TSS_USERNAME`, `TSS_PASSWORD`, `TSS_DOMAIN` | Application account.                             |
| `token`                          | `TSS_TOKEN`                                  | Access token, in place of username and password. |
| `skip_verify`                    |                                              | TLS.                                             |

</details>

### Akeyless

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+akeyless:///prod/db/password     # static secret path
    database: analytics

secret_providers:
  akeyless:
    type: akeyless
    access_id: ${AKEYLESS_ACCESS_ID}
    access_key: ${AKEYLESS_ACCESS_KEY}
```

| Config                    | Environment variable                        | Meaning                                              |
| ------------------------- | ------------------------------------------- | ---------------------------------------------------- |
| `access_id`, `access_key` | `AKEYLESS_ACCESS_ID`, `AKEYLESS_ACCESS_KEY` | API key auth.                                        |
| `gateway_url`             | `AKEYLESS_GATEWAY_URL`                      | Gateway URL. The default is the Akeyless public API. |

</details>

### SOPS

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+sops://secrets.enc.yaml#/postgres      # an object in the file
    database: analytics

  MY_SNOWFLAKE:
    type: snowflake
    account: acme-xy12345
    user: SLING
    password: ref+sops://secrets.enc.env#/SNOWFLAKE_PASSWORD
```

* Needs the [`sops` CLI](https://github.com/getsops/sops) and its keys (age, PGP, AWS KMS, GCP KMS or Azure Key Vault).
* Files can be YAML, JSON or `.env`.
* A relative path starts at the `env.yaml` folder.
* Sling decrypts each file one time for a run.

</details>

### Kubernetes

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+k8s://v1/Secret/data/postgres/password     # <namespace>/<name>/<key>
    database: analytics

  MY_MYSQL:
    type: mysql
    from: ref+k8s://v1/Secret/data/mysql                      # all keys of the Secret
```

| Config                          | Meaning                                                                |
| ------------------------------- | ---------------------------------------------------------------------- |
| `kubeconfig`, `context`         | Outside a cluster. Also `?kubeConfigPath=` and `?kubeContext=` params. |
| `host`, `token_file`, `ca_file` | In a cluster, to change the defaults.                                  |

* In a pod, Sling calls the API server with the service account token.
* Outside a cluster, Sling uses `kubectl`.

</details>

### Local File

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+file://./secrets/postgres.yaml             # whole file
    database: analytics

  MY_BIGQUERY:
    type: bigquery
    project: my-project
    dataset: analytics
    key_body: ref+file://~/keys/bq.json                  # file content
```

* A relative path starts at the `env.yaml` folder. `~/` is the home folder.
* Use a pointer to read one key of a JSON or YAML file.

</details>

### Command

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    host: db.acme.com
    user: etl
    password: ref+exec://pass?arg=show&arg=prod/postgres     # runs: pass show prod/postgres
    database: analytics
```

* Sling runs the command with no shell and reads its standard output.
* Each `arg` param is one argument.

</details>

### HTTP JSON

<details>

<summary>Example and configuration</summary>

```yaml
connections:
  MY_PG:
    type: postgres
    from: ref+httpjson://config.acme.com/sling/postgres     # GET https://config.acme.com/sling/postgres

secret_providers:
  httpjson:
    type: httpjson
    headers:
      Authorization: Bearer ${CONFIG_API_TOKEN}
```

| Config                   | Meaning                   |
| ------------------------ | ------------------------- |
| `headers`                | Headers for each request. |
| `ca_cert`, `skip_verify` | TLS.                      |

* Sling uses HTTPS. `?insecure=true` uses plain HTTP.

</details>

## When Sling Reads a Secret

* Sling reads a secret only when a run, a test or a query uses the connection. `sling conns list` does not read secrets.
* Each run is a new process. Thus a run gets the latest version of a rotated secret.
* In one run, Sling keeps a value for 5 minutes. Two fields that read keys of one secret share one fetch.
* A fetch stops after 30 seconds.

## Security

* Sling keeps resolved values in memory only.
* Log output and error messages show `***` in place of each value. Sling does not hide values shorter than 4 characters.
* On the Sling Platform, the platform stores only the reference text. The agent reads the secret, so the value stays on the agent host.

## Test the References

`sling conns test` resolves the references of a connection, then connects:

```bash
sling conns test MY_PG
```

If a reference fails, the error names the reference and the provider. It does not show the value:

```
could not resolve secret reference "ref+awssecrets://prod/postgres" (provider awssecrets, awssecrets): ResourceNotFoundException: Secrets Manager can't find the specified secret.
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.slingdata.io/concepts/secrets.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
