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

# Snowflake Integration: Export Credentials Setup

> Register Snowflake as a DualEntry export destination - validate connectivity, store credentials in AWS Secrets Manager, and link an export integration.

In DualEntry, Snowflake isn't a general-ledger sync like Stripe or Brex - it's an **export destination**. You provide Snowflake account connectivity so downstream AWS-based export jobs (for example, AWS Glue pipelines configured for your organization) can read credentials from AWS Secrets Manager and write data into your warehouse. DualEntry validates the connection, then stores the full credential payload in AWS Secrets Manager. Passwords and secrets are never persisted in the DualEntry database - only non-sensitive metadata such as the account identifier, warehouse, and database names.

## Prerequisites

Confirm the following before connecting:

* A Snowflake account identifier (for example `xy12345.us-east-1`), warehouse, database, username, and password for a user that's allowed to connect from DualEntry's network. If your Snowflake account uses network policies, your platform team may need to allow DualEntry's egress IPs (the connection log records the egress IP that was attempted, so you can confirm the value with your platform team during failed attempts).
* Optionally, a Snowflake role. If you omit it, DualEntry doesn't send a `role` parameter to the Snowflake connector - an empty string is treated as unset.
* Permission in DualEntry to create export destinations.
* Awareness that one active Snowflake export integration is allowed per organization. The same single-active rule applies to other export types (Qlik, Power BI, PostgreSQL).

## How to connect

The connect flow is the same for every export destination: provide credentials, DualEntry validates them in the background, and on success the credentials land in AWS Secrets Manager and the integration shows as **Connected**.

1. In DualEntry, navigate to **Settings → Integrations → Snowflake**.
2. Provide a display name for the destination, the integration type (`snowflake`), and the credential fields from Prerequisites.
3. Choose **Save**. DualEntry returns immediately with the destination in **Pending** status - credential validation runs in the background.
4. Wait for the destination to move from **Pending** to **Testing** to **Validated**. While testing, DualEntry opens a connection to Snowflake using your credentials with a 10-second login timeout, then closes it. A successful open/close counts as validation.
5. On success, the destination shows **Validated**, the linked integration shows **Connected**, and the credentials are written to AWS Secrets Manager. On failure, the destination shows **Failed** with an error message and the linked integration is set to **Error**.

If validation fails, fix the underlying cause (see [Troubleshoot connection errors](#troubleshoot-connection-errors)) and create a new destination - the failed row is kept for audit but does not retry automatically.

## Credential schema

DualEntry validates the credential payload against a fixed schema before attempting to connect. Every field except `role` is required.

| Field       | Required | Notes                                                                           |
| ----------- | -------- | ------------------------------------------------------------------------------- |
| `type`      | Yes      | Must be the literal `"snowflake"`.                                              |
| `account`   | Yes      | Snowflake account locator (region-aware form, for example `xy12345.us-east-1`). |
| `warehouse` | Yes      | Non-empty warehouse name.                                                       |
| `database`  | Yes      | Non-empty database name.                                                        |
| `username`  | Yes      | Non-empty user.                                                                 |
| `password`  | Yes      | Non-empty password.                                                             |
| `role`      | No       | If provided, passed to the Snowflake connector as `role`.                       |

The current schema doesn't collect a Snowflake schema name; the connector uses Snowflake defaults for the given database and user.

<Warning>
  DualEntry stores only `account`, `warehouse`, and `database` in its relational database. Username and password live exclusively in AWS Secrets Manager and are never returned by DualEntry's APIs after creation. Treat any rotation or reset as a full re-create flow - there's no in-place credential edit.
</Warning>

## Disconnect

Disconnecting a Snowflake destination archives the export-secret row, marks the integration as **Disconnected**, and schedules deletion of the AWS Secrets Manager entry (subject to AWS's secret recovery window). One blocking condition: you can't disconnect while an AWS Glue export job tied to the integration is in a **Running** state - the disconnect call returns an error with the active job ID. Wait for the job to complete (or cancel it if appropriate), then retry the disconnect.

## Troubleshoot connection errors

Validation runs in the background, so symptoms surface in the destination's status field and the linked integration's error message.

| Symptom                                                 | Likely cause                                                                                                                           | Resolution                                                                                                                                                                                                                       |
| ------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` "integration already exists" on create            | Another Snowflake export integration is already active for this organization.                                                          | List existing destinations, archive or disconnect the old one, then re-create. The single-active rule is enforced at the API level.                                                                                              |
| Destination stuck in **Failed** with a credential error | Wrong account locator, wrong username or password, suspended warehouse, or a Snowflake network policy blocking DualEntry's egress IP.  | Confirm the account locator format with Snowflake's docs; reset the password in Snowflake; resume the warehouse if it was auto-suspended; ask your platform team to allow DualEntry's egress IP in the Snowflake network policy. |
| Login timeout                                           | The Snowflake account is unreachable from DualEntry's worker network, or the 10-second timeout is too aggressive for a cold warehouse. | Check Snowflake service status; confirm the network path; resume or scale up the Snowflake warehouse so the first connection doesn't cold-start.                                                                                 |
| `500` on create                                         | AWS Secrets Manager error or an internal failure.                                                                                      | Surface the error message to platform engineering - the `export_secret_provisioning_error` log key in the maintainer block below names the diagnostic.                                                                           |
| Cannot disconnect                                       | An AWS Glue export job tied to the integration is currently running.                                                                   | Wait for the Glue job to finish (or cancel it), then retry the disconnect call.                                                                                                                                                  |

## FAQ

### Does DualEntry sync data into Snowflake automatically as part of this flow?

No. The connect flow registers and tests credentials, then stores them so that downstream export infrastructure (typically AWS Glue jobs) can write data into your warehouse. The table layout, job cadence, and SQL for specific datasets are owned by your deployment's export configuration, not by this integration.

### Where are passwords stored?

In AWS Secrets Manager, under a secret name that's keyed to your organization and the destination's identifier. The password never lands in DualEntry's relational database.

### What other export destinations work the same way?

Qlik, Power BI, and PostgreSQL export destinations all share this connect flow, the same single-active-per-organization rule, and the same AWS Secrets Manager storage pattern. Only the credential schema differs per destination type.

## For maintainers

The details below describe the connect-flow plumbing, not user-facing features.

* API endpoints (internal admin):
  * `POST /api/integrations/exports/secrets/` to create a destination.
  * `GET /api/integrations/exports/secrets/{secret_id}/` to poll status.
  * `POST /api/integrations/exports/secrets/{secret_id}/disconnect/` to disconnect.
* Credential schema class: `ExportSnowflakeCredentialsSchema`. The schema's `metadata` property exposes `account`, `warehouse`, and `database` as the non-sensitive fields stored on the export-secret row's `destination_metadata`.
* Background validation: the `provision_export_secret` Celery task parses credentials, calls `snowflake.connector.connect` with `account`, `user`, `password`, `warehouse`, `database`, `login_timeout=10`, and optional `role`, then opens and closes the connection. A clean open/close counts as validation.
* AWS Secrets Manager naming: secrets are stored at `dualentry/exports/org_{organization_id}/{name}_{secret_id}` (built by `ExportSecret.build_secret_qual_name`). If AWS reports the secret already exists, the task reuses the existing ARN and continues.
* Disconnect uses AWS Secrets Manager's scheduled deletion with the standard recovery window; reusing the same name within the recovery window will collide.
* Diagnostic log keys: `export_secret_provisioning_error` (creation/validation failures), `export_secret_ip_check` (the egress IP DualEntry attempted from). Confirm with your platform team whether the IP-check path applies to your deployment.
* Other export integration types (`qlik`, `power_bi`, `postgresql`) follow the same lifecycle and share the single-active-per-organization rule.

## Result

After a successful connect, your organization has a validated Snowflake export destination and a linked Snowflake integration that shows as **Connected** in the integrations list. Downstream AWS export jobs (for example, AWS Glue pipelines) can now read the Snowflake credentials from AWS Secrets Manager and write data into your warehouse. To compare with a product-to-product GL sync (rather than export plumbing), see [Brex](./brex). To connect additional systems, return to [Integrations](./index). For Snowflake's own connector documentation, see the [Snowflake Python connector docs](https://docs.snowflake.com/en/developer-guide/python-connector/python-connector).
