{
  "schema_version": 2,
  "id": "develop/ai/featureform/register-providers/snowflake",
  "title": "Register a Snowflake provider",
  "url": "https://redis.io/docs/latest/develop/ai/featureform/register-providers/snowflake/",
  "summary": "Register Snowflake storage and compute with Redis Feature Form.",
  "tags": [],
  "last_updated": "2026-08-25T13:17:04-07:00",
  "page_type": "content",
  "content_hash": "73c9f7eb1ccd2e9838b3763dc21b893fd2d7a2e162bd0a5e4e3096581812da24",
  "sections": [
    {
      "id": "overview",
      "title": "Overview",
      "role": "overview",
      "text": "Register a `snowflake` provider when Redis Feature Form should discover Snowflake tables, run structured query language (SQL) transformations, or materialize training sets and feature-view data in Snowflake.\n\nThe provider fills the `offline-store` and `compute` roles for one account, warehouse, database, and schema. It doesn't provide online serving. A serving feature view also needs a supported `online-store` provider."
    },
    {
      "id": "before-you-begin",
      "title": "Before you begin",
      "role": "content",
      "text": "Make sure you have:\n\n- A Feature Form [workspace](https://redis.io/docs/latest/develop/ai/featureform/manage-workspace).\n- A Snowflake account identifier, warehouse, database, and schema.\n- A Snowflake username with password or key-pair authentication.\n- A [secret provider](https://redis.io/docs/latest/develop/ai/featureform/register-providers#configure-secret-providers) for each password, private key, or passphrase reference.\n- Network access from the Feature Form server and workers to Snowflake.\n\nSet `host` on `SnowflakeConfig`, or use `--snowflake-host` with the CLI, for a PrivateLink or custom hostname. Without it, Feature Form derives the standard hostname from the account identifier.\n\nThe Python examples use this workspace-scoped provider client:\n\n[code example]"
    },
    {
      "id": "choose-authentication",
      "title": "Choose authentication",
      "role": "content",
      "text": "| Authentication | Required values | Support |\n| --- | --- | --- |\n| `password` | Username and password secret reference | Supported |\n| `key-pair` | Username and private-key secret reference; passphrase reference for an encrypted key | Supported |\n| `oauth` | OAuth client and token fields | Not supported by the current Snowflake connector |\n\nDon't use `skip_health_check=True` or `--skip-health-check` to register OAuth. Skipping the check postpones the unsupported-authentication error until the provider is used."
    },
    {
      "id": "register-with-a-password",
      "title": "Register with a password",
      "role": "content",
      "text": "**Python:**\n\n[code example]\n\n**ff CLI:**\n\n[code example]\n\n\n\nThe environment reference is resolved by the Feature Form server. Replace it with a reference to another registered secret backend when appropriate."
    },
    {
      "id": "register-with-a-key-pair",
      "title": "Register with a key pair",
      "role": "content",
      "text": "**Python:**\n\n[code example]\n\n**ff CLI:**\n\n[code example]\n\n\n\nOmit `--snowflake-passphrase-secret` when the private key isn't encrypted. The resolved value must be a Rivest-Shamir-Adleman (RSA) private key."
    },
    {
      "id": "configure-sessions",
      "title": "Configure sessions",
      "role": "configuration",
      "text": "In Python, set `login_timeout`, `request_timeout`, or `session_params` on `SnowflakeConfig`. With the CLI, use these optional flags:\n\n[code example]\n\nRepeat `--snowflake-session-param` for multiple values. Keys and values must be nonempty."
    },
    {
      "id": "grant-health-check-permissions",
      "title": "Grant health-check permissions",
      "role": "content",
      "text": "The default registration health check:\n\n1. Opens a Snowflake session.\n2. Selects the configured warehouse.\n3. Creates a health-check table in the configured database and schema.\n4. Drops the table.\n\nThe Snowflake role therefore needs `USAGE` on the warehouse, database, and schema, plus permission to create and drop a table in that schema. Read-only credentials can't pass the default check.\n\nWorkloads can require additional permissions:\n\n| Workload | Required capability |\n| --- | --- |\n| Discover or read an existing table | `SELECT` on that table |\n| Materialize transformations, training sets, or feature views | Read inputs and create, replace, rename, update, and drop managed tables as needed |\n| Delete a managed output | Drop the managed table |\n\nA successful registration check doesn't test every source table, access policy, masking policy, or warehouse quota."
    },
    {
      "id": "understand-supported-workloads",
      "title": "Understand supported workloads",
      "role": "content",
      "text": "| Capability | Support |\n| --- | --- |\n| Existing Snowflake datasets | Supported |\n| Full SQL transformations | Supported |\n| Incremental transformed datasets | Not supported |\n| Static training-set materialization | Supported |\n| Incremental static training sets | Supported |\n| Feature-view batch computation | Supported with a separate online provider |\n| Direct dataframe reads | Supported |\n| Online serving | Not supported |\n\nKey-pair authentication works for direct Snowflake dataframe reads. A Spark-based Snowflake Java Database Connectivity (JDBC) plan currently requires password authentication."
    },
    {
      "id": "verify-registration",
      "title": "Verify registration",
      "role": "content",
      "text": "[code example]\n\nIn Python, use `providers.get(\"<snowflake-provider-name>\")` or `providers.list()`."
    },
    {
      "id": "update-safely",
      "title": "Update safely",
      "role": "content",
      "text": "| Field | Update behavior |\n| --- | --- |\n| Database and schema | Immutable |\n| Account and custom host | Requires `force=True` or `--force` |\n| Warehouse, role, authentication, timeouts, and session parameters | Mutable |\n\nBefore a forced update or deletion, review datasets, transformations, training sets, feature views, and other references to the provider. The usage check doesn't detect every indirect reference."
    },
    {
      "id": "troubleshoot-registration",
      "title": "Troubleshoot registration",
      "role": "errors",
      "text": "| Symptom | What to check |\n| --- | --- |\n| Secret resolution fails | Confirm the secret-provider name, workspace, and canonical reference syntax |\n| `USE WAREHOUSE` fails | Grant warehouse `USAGE`, or correct the warehouse and role |\n| Health-check table creation fails | Grant create and drop permissions in the configured schema |\n| Key-pair authentication fails | Check that the resolved value is an RSA private key and that an encrypted key has the matching passphrase |\n| Incremental transformation fails | Use a full Snowflake SQL transformation; incremental transformed datasets aren't supported |\n| Direct reads work but a Spark read fails | Use password authentication for the Spark JDBC path |\n| A workload fails after registration | Check grants and policies for the specific table and operation; the health check tests only the configured schema |"
    }
  ],
  "examples": [
    {
      "id": "before-you-begin-ex0",
      "language": "python",
      "code": "import featureform as ff\n\nclient = ff.Client.from_env()\nproviders = client.providers(\"<workspace-id>\")",
      "section_id": "before-you-begin"
    },
    {
      "id": "register-with-a-password-ex0",
      "language": "python",
      "code": "from featureform.types import EnvSecretRef, ProviderType, SnowflakeConfig\n\nproviders.register(\n    name=\"<snowflake-provider-name>\",\n    provider_type=ProviderType.SNOWFLAKE,\n    config=SnowflakeConfig(\n        account=\"<snowflake-account>\",\n        warehouse=\"<warehouse-name>\",\n        database=\"<database-name>\",\n        schema=\"<schema-name>\",\n        role=\"<role-name>\",\n        auth_type=\"password\",\n        username=\"<username>\",\n        password_secret=EnvSecretRef(name=\"SNOWFLAKE_PASSWORD\"),\n    ),\n)",
      "section_id": "register-with-a-password"
    },
    {
      "id": "register-with-a-password-ex1",
      "language": "bash",
      "code": "ff provider register <snowflake-provider-name> \\\n  --workspace <workspace-id> \\\n  --type snowflake \\\n  --snowflake-account <snowflake-account> \\\n  --snowflake-warehouse <warehouse-name> \\\n  --snowflake-database <database-name> \\\n  --snowflake-schema <schema-name> \\\n  --snowflake-role <role-name> \\\n  --snowflake-auth-type password \\\n  --snowflake-username <username> \\\n  --snowflake-password-secret env:SNOWFLAKE_PASSWORD",
      "section_id": "register-with-a-password"
    },
    {
      "id": "register-with-a-key-pair-ex0",
      "language": "python",
      "code": "from featureform.types import K8sSecretRef, ProviderType, SnowflakeConfig\n\nproviders.register(\n    name=\"<snowflake-provider-name>\",\n    provider_type=ProviderType.SNOWFLAKE,\n    config=SnowflakeConfig(\n        account=\"<snowflake-account>\",\n        warehouse=\"<warehouse-name>\",\n        database=\"<database-name>\",\n        schema=\"<schema-name>\",\n        role=\"<role-name>\",\n        auth_type=\"key-pair\",\n        username=\"<username>\",\n        private_key_secret=K8sSecretRef(\n            provider_name=\"<secret-provider-name>\",\n            name=\"<secret-name>\",\n            key=\"private-key\",\n        ),\n        passphrase_secret=K8sSecretRef(\n            provider_name=\"<secret-provider-name>\",\n            name=\"<secret-name>\",\n            key=\"private-key-passphrase\",\n        ),\n    ),\n)",
      "section_id": "register-with-a-key-pair"
    },
    {
      "id": "register-with-a-key-pair-ex1",
      "language": "bash",
      "code": "ff provider register <snowflake-provider-name> \\\n  --workspace <workspace-id> \\\n  --type snowflake \\\n  --snowflake-account <snowflake-account> \\\n  --snowflake-warehouse <warehouse-name> \\\n  --snowflake-database <database-name> \\\n  --snowflake-schema <schema-name> \\\n  --snowflake-role <role-name> \\\n  --snowflake-auth-type key-pair \\\n  --snowflake-username <username> \\\n  --snowflake-private-key-secret k8s@<secret-provider-name>:<secret-name>#private-key \\\n  --snowflake-passphrase-secret k8s@<secret-provider-name>:<secret-name>#private-key-passphrase",
      "section_id": "register-with-a-key-pair"
    },
    {
      "id": "configure-sessions-ex0",
      "language": "text",
      "code": "--snowflake-login-timeout <seconds>\n--snowflake-request-timeout <seconds>\n--snowflake-session-param <key>=<value>",
      "section_id": "configure-sessions"
    },
    {
      "id": "verify-registration-ex0",
      "language": "bash",
      "code": "ff provider get <snowflake-provider-name> --workspace <workspace-id>\nff provider list --workspace <workspace-id>",
      "section_id": "verify-registration"
    }
  ]
}
