Getting started with Snowflake App Runtime

This guide walks you through setting up your environment and deploying your first app on Snowflake. Start with the setup section below, then choose your path: use Cortex Code CLI or Cortex Code Desktop to build from a description, or use the Snowflake CLI directly if you already have code.

Set up your environment

Before you can build or deploy, install Cortex Code (CLI or Desktop) and the Snowflake CLI on your machine. Use the install guides below, then confirm the Snowflake Apps command surface in the next section.

Cortex Code

Use Cortex Code CLI or Desktop to scaffold, test, and deploy apps from natural language. Both bundle the snowflake-apps skill and use the Snowflake CLI for deployment.

Cortex Code CLI (macOS, Linux, and Windows):

Cortex Code Desktop (macOS and Windows):

Snowflake CLI

Install the Snowflake CLI using Installing Snowflake CLI.

Use Snowflake CLI 3.19 or later. After install, verify that Snowflake Apps commands are available:

snow --version
snow app setup --help

If snow app setup --help fails, reinstall or upgrade the Snowflake CLI using the installation guide linked above.

Other requirements

  • Snowflake account: Use a paid account (trial accounts don’t support App Runtime).
  • Shared deploy defaults (recommended for team apps): For apps you plan to share, ask an account administrator to complete account administrator setup once, so deploys land in a shared database the whole team can use. Before those defaults are configured, you can deploy to your personal database to build and experiment; you just can’t grant other roles access to apps there.
  • Node.js 22+: Version 22 or later on your machine for local development (npm install, tests, npm run dev). Download Node.js.

Build and deploy with Cortex Code

Cortex Code assistants scaffold, build, test, and deploy Snowflake apps from a natural language description.

Step 1: Describe your app

Use the snowflake-apps skill in your prompt:

> $snowflake-apps Build me a warehouse monitor that shows all my
  warehouses with their current state, credit usage today, and queued
  queries.

The assistant scaffolds a Next.js project with a working UI, Snowflake data access, an app.yml manifest, and a snowflake.yml project definition.

Step 2: Test locally

Ask the assistant to run the dev server and open the app in your browser. In Cortex Code Desktop, the Agent Browser shows a live preview as you go. Describe changes in chat to update the app.

Run the dev server and open it in my browser

Step 3: Deploy

When you’re happy with the app:

Deploy this app

The assistant runs snow app deploy, which uploads your source, builds it remotely, and starts the service. You get a live URL.

Step 4: Open the app

Open the app

Ask the assistant to open the app, or use the URL from deploy output. In Cortex Code Desktop, you can also use the Apps view. The URL uses Snowflake SSO.

Step 5: Share with other roles

To let other roles open your app, ask the assistant to share it. The app must live in a standard database (for example SNOWFLAKE_APPS after account administrator setup), not a personal database.

Share this app with the ANALYST role

In Cortex Code Desktop, you can also use Share on the app in the Apps view.

Behind the scenes, this grants USAGE on the database, schema, and Application Service. To run it yourself (replace MY_APP_NAME and ANALYST with your service name and role):

GRANT USAGE ON DATABASE SNOWFLAKE_APPS TO ROLE ANALYST;
GRANT USAGE ON SCHEMA SNOWFLAKE_APPS.PUBLIC TO ROLE ANALYST;
GRANT USAGE ON APPLICATION SERVICE SNOWFLAKE_APPS.PUBLIC.MY_APP_NAME TO ROLE ANALYST;

For OPERATE, MONITOR, and revoke patterns, see Access control for Snowflake App Runtime.

Step 6: Iterate

Make changes and redeploy. Each deploy produces a new version and upgrades the running service in place. The URL stays the same.

Add a filter for warehouse state and redeploy

Build and deploy with the CLI

If you have an existing application or prefer working directly with code, use the Snowflake CLI. Cortex Code isn’t required for this path.

Step 1: Initialize your project

From your project directory, run snow app setup to generate a snowflake.yml project definition:

snow app setup

Pass --app-name my_app_name when you want an explicit Snowflake identifier instead of the name derived from the current directory.

This creates a snowflake.yml in the current directory with a snowflake-app entity that uses defaults from account administrator setup. After setup, the file typically references the shared SNOWFLAKE_APPS database and uses a code stage for uploaded source, for example:

definition_version: "2"

entities:
  my_app_name:
    type: snowflake-app
    identifier:
      name: MY_APP_NAME
      database: SNOWFLAKE_APPS
      schema: PUBLIC
    artifacts:
      - src: ./*
        dest: ./
        ignore:
          - node_modules
          - .env*
          - .next
          - .git
    query_warehouse: SNOWFLAKE_APPS_QUERY_WH
    code_stage: MY_APP_NAME_CODE

Setup resolves database, schema, and query_warehouse in this order: Snowsight account defaults from administrator setup, then your current connection settings. You normally don’t pick these manually after account setup. During public preview, Snowflake App Runtime uses managed compute pools only, so setup omits compute pool configuration and user-specified pool values aren’t used. The artifacts section controls which files are uploaded, and the ignore list excludes build output and local-only files.

Run with --dry-run to preview the resolved configuration without writing the file.

For snowflake.yml and the snowflake-app entity after setup, use the snow app setup command reference and Specify entities for identifier rules, mixins, and other project-definition patterns the CLI applies to snowflake.yml.

Step 2: Deploy

From your project directory:

snow app deploy

The CLI uploads your source files, triggers a remote build, creates (or upgrades) the Application Service, and prints the live URL. The URL looks like:

https://<id>-<org>-<account>-<region>.snowflakecomputing.app/

This URL is stable across redeploys. It doesn’t change when you upgrade to a new version.

Step 3: Open your app

snow app open

Use snow app open --print-only to print the URL without opening a browser. Use snow app open --settings to open the app in Snowsight instead of the live endpoint.

Step 4: Share with other roles

Grant USAGE on the database, schema, and Application Service so another role can open the app. Use the database and schema from your snowflake.yml identifier (for example SNOWFLAKE_APPS.PUBLIC):

GRANT USAGE ON DATABASE SNOWFLAKE_APPS TO ROLE ANALYST;
GRANT USAGE ON SCHEMA SNOWFLAKE_APPS.PUBLIC TO ROLE ANALYST;
GRANT USAGE ON APPLICATION SERVICE SNOWFLAKE_APPS.PUBLIC.MY_APP_NAME TO ROLE ANALYST;

You can’t share apps deployed to a personal database. For more patterns, see Access control for Snowflake App Runtime.

What happens under the hood

Whether you use Cortex Code or the CLI, snow app deploy automates these steps:

  1. Uploads source files to an internal stage.
  2. Triggers the builder service, which runs install and build commands from your app.yml (or auto-detected from your project layout).
  3. Stores the built output as an immutable package version.
  4. Creates or upgrades the Application Service from that package version.

With account administrator setup complete, snow app setup and snow app deploy use shared destination defaults. You focus on application code; Snowflake handles packaging and service lifecycle.

Connecting to Snowflake data

Your application can query Snowflake directly with no credentials to manage. Snowflake handles authentication automatically at runtime.

Tip

Cortex Code scaffolds a querySnowflake() helper that handles connection pooling, token rotation, and both execution modes described below. You don’t need to implement this yourself.

Owner’s rights vs. caller’s rights

When your app runs a query, it executes in one of two modes:

ModeHow it worksWhen to use it
Owner’s rights

Queries run as the service’s own identity (the owner role). All users see the same data.

Shared dashboards, aggregate views, internal tools where every user sees the same results.

Caller’s rights

Queries run as the end user who opened the app. Snowflake applies that user’s role and privileges.

Apps where different users should see different data, per-user audit trails, row-level security.

With the scaffolded SDK, switching between modes is one parameter:

// Owner's rights (default): queries as the service role
const rows = await querySnowflake("SELECT * FROM sales.summary");

// Caller's rights: queries as the logged-in user
const rows = await querySnowflake("SELECT * FROM sales.detail", {
  callersRights: true,
});

Caller’s rights is enabled for Application Services by default, so you don’t need any app.yml configuration. Each query runs with owner’s rights unless you pass { callersRights: true } to run that query as the signed-in user.

Caller grants

When using caller’s rights, the application operates under restricted caller’s rights. This means both the calling user’s privileges AND the service owner’s caller grants must allow the operation. The service owner must be granted permission to act on behalf of callers:

GRANT CALLER USAGE ON DATABASE my_db TO ROLE service_owner_role;
GRANT CALLER USAGE ON SCHEMA my_db.my_schema TO ROLE service_owner_role;
GRANT CALLER SELECT ON ALL TABLES IN SCHEMA my_db.my_schema TO ROLE service_owner_role;

For the full details on how restricted caller’s rights work, see Configuring caller’s rights.

How authentication works (reference)

For developers building without the scaffolded SDK:

  • Snowflake injects an OAuth token at /snowflake/session/token in each container. The token rotates automatically; read it fresh on each request.
  • For caller’s rights, Snowflake inserts an Sf-Context-Current-User-Token HTTP header on each incoming request. Concatenate the service token and caller token (serviceToken + "." + callerToken) and authenticate with authenticator: "OAUTH".
  • No credentials, connection strings, or manual token management is required.

For a complete walkthrough of the low-level implementation, see Tutorial 7:Create a Snowpark Container Services service that uses caller’s rights.

Other CLI commands

Beyond snow app setup, snow app deploy, and snow app open, the CLI provides additional commands for managing your app lifecycle:

CommandDescription
snow app validate

Check that the target database and schema exist and that the project can be bundled (resolves artifacts from snowflake.yml).

snow app bundle

Copy resolved artifacts into output/bundle so you can inspect what a deploy would upload. No Snowflake connection required.

snow app events

Fetch recent container logs (default: 500 lines). Use --last N for more or fewer lines. Output is capped at 100 KB.

snow app teardown

Drop the Application Service and clean up associated objects (stage or workspace files). Use --force to skip the confirmation prompt.

Retrying a failed deploy

If snow app deploy fails partway through, you can retry just the phase that failed instead of starting over:

  • snow app deploy --upload-only: re-upload source files without rebuilding or redeploying.
  • snow app deploy --build-only: re-trigger the build without re-uploading or redeploying.
  • snow app deploy --deploy-only: create or upgrade the service without re-uploading or rebuilding.

Only one of these flags can be used at a time.