# Account Resources YAML Reference


This guide serves as a detailed reference for the CLI project YAML files that contain definitions of your Reverse ETL warehouse account resources.

## Overview

An **account** holds the credentials and connection settings for a data warehouse. A [Reverse ETL SQL model]({{< ref "dev-tools/rudder-cli/yaml-sql-models.md" >}}) does not carry its own credentials — it points at an account through its `account_id`. Defining accounts in YAML keeps warehouse credentials under the same Git-based workflow as your other CLI resources.

You define accounts by setting `kind` to `account`. As with every other resource type, you can store the YAML files anywhere within the project's root directory or subdirectories.

{{< warning >}}
**Account support is experimental**. 

Enable the `accountSupport` flag in your CLI configuration (or set `RUDDERSTACK_X_ACCOUNT_SUPPORT=true`) before applying account resources — without it the `account` kind is not registered and your specs will fail validation.

Because account specs reference secrets as variables, you also need to enable the `enableVarSubstitution` flag (`RUDDERSTACK_X_ENABLE_VAR_SUBSTITUTION=true`) in your CLI configuration.
{{< /warning >}}

## Account resources

The `spec` parameter of the YAML file has the following structure:

| Property | Type | Description |
| :----| :-----| :------|
| `id` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Unique identifier for the account resource within the project. This parameter must be unique across all account resources, and identifies the account on subsequent applies. |
| `name` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Display name for the account as shown in the RudderStack dashboard. |
| `account_definition_name` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | The warehouse type this account connects to. <br /><br />See [Supported account definitions](#supported-account-definitions) for the values you can use. |
| `config` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | Object | Flat map of connection settings and credentials for the warehouse. The available keys depend on `account_definition_name`. |

{{< warning >}}
`account_definition_name` is **immutable**. Changing it on an existing account fails the apply rather than silently recreating the resource — a warehouse account is a credential, and recreating one would break every Reverse ETL source pointing at it. To move to a different warehouse type, define a new account.
{{< /warning >}}

### Supported account definitions

| Warehouse | `account_definition_name` value |
| :------| :-------|
| Google BigQuery | `SOURCE_BIGQUERY` |
| PostgreSQL | `SOURCE_POSTGRES` |
| Snowflake | `SOURCE_SNOWFLAKE` |

### BigQuery configuration

The `config` object for `SOURCE_BIGQUERY` accepts the following keys:

| Key | Type | Description |
| :----| :-----| :------|
| `project` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | The Google Cloud project ID that owns the BigQuery dataset. |
| `location` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | The BigQuery dataset location, for example `US` or `EU`. |
| `credentials` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | The service account key JSON. This is a **secret** — supply it as a variable reference, never as a literal. See [Secret handling](#secret-handling). |

Although `config` is a single flat map in YAML, it is split on the way to the API — the secret keys are sent as a write-only credential payload and everything else as plain options. You do not need to model that split yourself.

### Example definition

```yaml
version: "rudder/v1"
kind: "account"
metadata:
  name: "prod-bq"
spec:
  id: "prod-bq"
  name: "Production BigQuery"
  account_definition_name: "SOURCE_BIGQUERY"
  config:
    project: "acme-analytics-prod"
    location: "US"
    credentials: "{{ .BQ_CREDENTIALS }}"
```

With a var file (`credentials.vars.yaml`) alongside it:

```yaml
BQ_CREDENTIALS: '{"type":"service_account","project_id":"acme-analytics-prod","private_key":"..."}'
```

Apply the two together:

```bash
rudder-cli apply --location ./project --var-file ./credentials.vars.yaml
```

### PostgreSQL configuration

The `config` object for `SOURCE_POSTGRES` accepts the following keys:

| Key | Type | Description |
| :----| :-----| :------|
| `host` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database host |
| `dbname` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database name |
| `user` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database username — this is a plain option, not a secret |
| `port` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database port — this is a **string**, not a number, matching the PostgreSQL source form |
| `sslMode` | String | One of `disable` or `require`. Defaults to `disable`. |
| `password` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database password — this is a **secret**; supply it as a variable reference |

```yaml
version: "rudder/v1"
kind: "account"
metadata:
  name: "prod-postgres"
spec:
  id: "prod-postgres"
  name: "Production Postgres"
  account_definition_name: "SOURCE_POSTGRES"
  config:
    host: "warehouse.acme.internal"
    dbname: "analytics"
    user: "rudderstack"
    port: "5432"
    sslMode: "require"
    password: "{{ .PG_PASSWORD }}"
```

### Snowflake configuration

The `config` object for `SOURCE_SNOWFLAKE` accepts the following keys:

| Key | Type | Description |
| :----| :-----| :------|
| `account` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Snowflake account identifier. |
| `dbname` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Database name. |
| `warehouse` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Virtual warehouse to run against. |
| `user` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | Login name. This is a plain option, not a secret. |
| `role` | String | Snowflake role to assume. |
| `authenticationType` <br/> <span style="color: #4D4DFF;font-size:12px;">Required</span> | String | One of `keyPair` or `password`. Determines which secret key you must supply — see below. |
| `privateKey` | String | PEM private key. **Secret**, required when `authenticationType` is `keyPair`. |
| `privateKeyPassphrase` | String | Passphrase for the private key. **Secret**, optional, only valid with `keyPair`. |
| `password` | String | Account password. **Secret**, required when `authenticationType` is `password`. |

{{< warning >}}
`authenticationType` decides which secret keys are legal. The combination is validated rather than ignoring surplus keys:

- `keyPair` accepts **only** `privateKey` and `privateKeyPassphrase`.
- `password` accepts **only** `password`.

Supplying a secret that does not belong to the selected authentication type — for example, a `password` alongside `authenticationType: keyPair` — is rejected, not silently dropped.
{{< /warning >}}

{{< tabs tabTotal="2" >}}
{{% tab tabName="Key pair authentication" %}}
```yaml
version: "rudder/v1"
kind: "account"
metadata:
  name: "prod-snowflake"
spec:
  id: "prod-snowflake"
  name: "Production Snowflake"
  account_definition_name: "SOURCE_SNOWFLAKE"
  config:
    account: "acme-prod.us-east-1"
    dbname: "ANALYTICS"
    warehouse: "TRANSFORMING"
    user: "RUDDERSTACK"
    role: "RUDDERSTACK_ROLE"
    authenticationType: "keyPair"
    privateKey: "{{ .SF_PRIVATE_KEY }}"
    privateKeyPassphrase: "{{ .SF_PRIVATE_KEY_PASSPHRASE }}"
```
{{% /tab %}}
{{% tab tabName="Password authentication" %}}
```yaml
version: "rudder/v1"
kind: "account"
metadata:
  name: "prod-snowflake"
spec:
  id: "prod-snowflake"
  name: "Production Snowflake"
  account_definition_name: "SOURCE_SNOWFLAKE"
  config:
    account: "acme-prod.us-east-1"
    dbname: "ANALYTICS"
    warehouse: "TRANSFORMING"
    user: "RUDDERSTACK"
    role: "RUDDERSTACK_ROLE"
    authenticationType: "password"
    password: "{{ .SF_PASSWORD }}"
```
{{% /tab %}}
{{< /tabs >}}

## Secret handling

Secret fields must be written as `{{ .VARIABLE_NAME }}` references and resolved at apply time from a var file. This keeps the credential out of the spec file you commit.

- **Secrets are never read back.** The RudderStack API does not return credential values, so the CLI cannot compare the remote secret against your local one. It therefore re-sends the secret on every apply. A re-apply that reports a change to a secret field is expected behavior, not drift.
- **Secrets never appear in exported specs.** When you import an existing account, the credential is written out as a `{{ .VAR }}` placeholder rather than a value.
- **Keep the var file out of version control.** It holds real credentials. Add it to `.gitignore`.

## Import existing accounts

You can bring warehouse accounts created through the dashboard under Git control:

```bash
rudder-cli import workspace --location ./project
```

This scaffolds two things under `./project/imported`:

- `accounts/<id>.yaml` — one spec per importable account, with every secret field masked to a `{{ .VAR }}` reference.
- `secrets.vars.yaml` — a fill-in-the-blanks var file with one placeholder line per variable the generated specs reference.

Fill in each placeholder with the real credential, then run `apply` with `--var-file` to adopt the accounts. Import scaffolds the files; the accounts are claimed on apply, after which they are managed resources and are no longer offered for import.

{{< tip >}}
An unfilled (null) placeholder makes the apply fail loudly rather than silently sending an empty credential. To deliberately send an empty value, set the key to `""`.
{{< /tip >}}

You can list the accounts in your workspace, managed or not, with:

```bash
rudder-cli workspace accounts list
```

## See more

- [SQL Model Resources YAML Reference]({{< ref "dev-tools/rudder-cli/yaml-sql-models.md" >}}) — SQL models reference accounts through `account_id`
- [How to Import Workspace Resources into Your Rudder CLI Project]({{< ref "dev-tools/rudder-cli/import-resources/" >}}) — general import workflow
