{"slug": "building-an-ai-first-dashboard-with-snowflake-dashboards-2-0", "title": "Building an AI-First Dashboard with Snowflake Dashboards 2.0", "summary": "A developer named Sagara built a walkthrough of Snowflake's Dashboards 2.0, an AI-first BI feature in public preview that lets analysts create SQL-based, multi-tile dashboards as .dash files in Snowsight Workspaces by chatting with Cortex Code (CoCo). The walkthrough defines a Semantic View over TPC-H sample data, explains the .dash file structure, and covers role-based sharing, noting that tile queries run with the viewer's privileges and require SELECT only on the Semantic View rather than the underlying tables. The developer also flags that 2.0 is not a drop-in replacement for the legacy version, since the old :filter_name syntax must be replaced with {{ filter('name') }}.", "body_md": "**Note:** This is the English translation of the following article.\n\n[https://dev.classmethod.jp/articles/snowflake-try-dashboards-2/](https://dev.classmethod.jp/articles/snowflake-try-dashboards-2/)\n\nHi, I'm Sagara.\n\nSnowflake has a new feature called **Dashboards 2.0**. It's an AI-first BI artifact. You build a dashboard as a `.dash` file in Snowsight Workspaces, share it with roles, and viewers open it in CoWork or Snowsight.\n\n[https://docs.snowflake.com/en/user-guide/snowflake-dashboards](https://docs.snowflake.com/en/user-guide/snowflake-dashboards)\n\nThe official docs below cover the sharing details.\n\n[https://docs.snowflake.com/user-guide/snowflake-artifacts-create-share](https://docs.snowflake.com/user-guide/snowflake-artifacts-create-share)\n\nIn this article, I'll define a Semantic View on the TPC-H sample data and then visualize it with Dashboards 2.0. I'll also briefly explain what's inside the generated `.dash` file and try granting privileges through roles.\n\n**Note:** As of November 13, 2026, the official docs list this feature as \"Preview Feature — Open.\" The specs may change before GA, so please keep that in mind.\n\nDashboards 2.0 is a SQL-based, multi-tile dashboard that you create in Snowsight Workspaces. Analysts build it by chatting with Cortex Code (CoCo) and then share it with roles. Viewers open it in CoWork or Snowsight and can explore by clicking on charts. In CoWork, viewers can also ask follow-up questions about a tile.\n\nA dashboard is mainly made up of these components:\n\n| Component | Description | \n|---|---|\n| Dashboard | The main body, containing the layout, filters, and tiles (the `.dash` file) | \n| Tile | A single display unit with SQL and a visualization type (chart / table / markdown). Placed on a 12-column grid | \n| Tab | A group of tiles. Up to 20 per dashboard. Filters apply across all tabs | \n| Filter | Defined per dashboard. Connected to tile SQL with `{{ filter('name') }}` | \n| Hierarchy | A hierarchy definition used for drill-down | \n| Chart action | Clicking or dragging on a chart filters or highlights other tiles | \n| Artifact | A read-only copy of the `.dash` file. This is the unit you share with roles | \n\nTile queries run with **the viewer's own privileges (caller's rights)**, and no data is extracted.\n\nEven though queries run with the viewer's privileges, a tile that references a Semantic View only needs the viewer to have SELECT on that Semantic View. **You don't need to grant privileges on the underlying tables.** The privileges required to query a Semantic View are listed on this page of the official docs:\n\n[https://docs.snowflake.com/en/user-guide/views-semantic/querying](https://docs.snowflake.com/en/user-guide/views-semantic/querying)\n\nThe official docs state clearly that Dashboards 2.0 is not a drop-in replacement for the legacy version. The main differences are:\n\n| Item | Legacy | Dashboards 2.0 | \n|---|---|---|\n| Follow-up questions | Not supported | Conversational in CoWork | \n| How to create | Worksheet UI | CoCo + manual | \n| Access control | UBAC | RBAC | \n| Filter scope | Account-wide | Per dashboard | \n| Query cache | Shared within a role | Per user (results reused per viewer) | \n\nVersion 2.0 doesn't recognize the legacy `:filter_name` syntax. You have to replace it with `{{ filter('name') }}`. An upgrade tool can also do this conversion automatically.\n\nPei-san, a Snowflake Data Superhero, wrote a great article (in Japanese) titled \"Why Snowflake Dashboards 2.0 Is the Best, and What BI Will Need Going Forward.\" It covers the feature's characteristics and where BI is heading. It was a big help when I wrote the overview section of this article.\n\nPlease check it out as well.\n\n[https://zenn.dev/dataheroes/articles/snowflake-dashboards-2-and-future-of-bi](https://zenn.dev/dataheroes/articles/snowflake-dashboards-2-and-future-of-bi)\n\nHere are the items from the \"Limitations (public preview)\" section of the official docs that seem relevant to this walkthrough:\n\n`.dash` file in Workspaces. Users granted `Can edit` (the `WRITE` privilege) can publish changes to the artifact. Note that having `Open source file` will point to a path that no longer exists. Renaming or moving the file may make its link to the artifact outdated or break it. If you then create the artifact again, it may become a separate artifact with a different link.`{{ hierarchy_key(...) }}` must also use `{{ hierarchy_rows(...) }}`.` SHOW ARTIFACTS`, `DESCRIBE ARTIFACT`, etc.) is listed as \"Coming soon\" as of November 13, 2026.\nFor this walkthrough, I'll set up an author role and a viewer role.\n\n```\nUSE ROLE ACCOUNTADMIN;\n\n-- Author role and viewer role\nCREATE ROLE IF NOT EXISTS DASH_AUTHOR;\nCREATE ROLE IF NOT EXISTS DASH_VIEWER;\n\n-- Database, schema, and warehouse for testing\nCREATE DATABASE IF NOT EXISTS DASH_TEST_DB;\nCREATE SCHEMA IF NOT EXISTS DASH_TEST_DB.SV;\nCREATE WAREHOUSE IF NOT EXISTS DASH_TEST_WH WAREHOUSE_SIZE = XSMALL AUTO_SUSPEND = 60;\n\n-- Create the sample database (run only if SNOWFLAKE_SAMPLE_DATA does not exist in your account)\nCREATE DATABASE SNOWFLAKE_SAMPLE_DATA FROM SHARE SFC_SAMPLES.SAMPLE_DATA;\n```\n\nNext, grant the required privileges to the author role `DASH_AUTHOR`.\n\n```\n-- Privileges on the sample data (shared DB) - author only; not granted to the viewer\nGRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE_SAMPLE_DATA TO ROLE DASH_AUTHOR;\n\n-- Author role privileges (limited to what's needed)\nGRANT USAGE ON DATABASE DASH_TEST_DB TO ROLE DASH_AUTHOR;\nGRANT USAGE ON SCHEMA DASH_TEST_DB.SV TO ROLE DASH_AUTHOR;\nGRANT CREATE SEMANTIC VIEW ON SCHEMA DASH_TEST_DB.SV TO ROLE DASH_AUTHOR;\nGRANT USAGE ON WAREHOUSE DASH_TEST_WH TO ROLE DASH_AUTHOR;\n\n-- Privilege to share artifacts (don't rely on the default grant to PUBLIC)\nGRANT MANAGE ACCESS ON DASHBOARD ARTIFACTS\n  ON ACCOUNT TO ROLE DASH_AUTHOR;\n\n-- Grant the author role to your own user\nGRANT ROLE DASH_AUTHOR TO USER <your_user>;\n```\n\nI'll define a Semantic View using the TPC-H `ORDERS`, `CUSTOMER`, and `LINEITEM` tables.\n\n```\nUSE ROLE DASH_AUTHOR;\nUSE WAREHOUSE DASH_TEST_WH;\nUSE SCHEMA DASH_TEST_DB.SV;\n\nCREATE OR REPLACE SEMANTIC VIEW TPCH_SALES_SV\n  TABLES (\n    customers AS SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.CUSTOMER\n      PRIMARY KEY (c_custkey)\n      COMMENT = 'Customers',\n    orders AS SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS\n      PRIMARY KEY (o_orderkey)\n      COMMENT = 'Orders',\n    line_items AS SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.LINEITEM\n      PRIMARY KEY (l_orderkey, l_linenumber)\n      COMMENT = 'Order line items'\n  )\n  RELATIONSHIPS (\n    orders_to_customers AS orders (o_custkey) REFERENCES customers,\n    line_items_to_orders AS line_items (l_orderkey) REFERENCES orders\n  )\n  FACTS (\n    line_items.net_price AS l_extendedprice * (1 - l_discount)\n  )\n  DIMENSIONS (\n    customers.customer_name AS c_name,\n    customers.market_segment AS c_mktsegment,\n    orders.order_date AS o_orderdate,\n    orders.order_year AS YEAR(o_orderdate),\n    orders.order_priority AS o_orderpriority\n  )\n  METRICS (\n    orders.order_count AS COUNT(o_orderkey),\n    line_items.total_net_sales AS SUM(line_items.net_price)\n  )\n  COMMENT = 'Semantic View for TPC-H sales analysis';\n```\n\nI based the DDL syntax on this page of the official docs:\n\n[https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view](https://docs.snowflake.com/en/sql-reference/sql/create-semantic-view)\n\nTo confirm the Semantic View was created, query it directly (run these as the `DASH_AUTHOR` role).\n\n```\n-- Total sales by year\nSELECT *\nFROM SEMANTIC_VIEW(\n  DASH_TEST_DB.SV.TPCH_SALES_SV\n  DIMENSIONS orders.order_year\n  METRICS line_items.total_net_sales\n)\nORDER BY order_year;\n-- Order count by order priority\nSELECT *\nFROM SEMANTIC_VIEW(\n  DASH_TEST_DB.SV.TPCH_SALES_SV\n  DIMENSIONS orders.order_priority\n  METRICS orders.order_count\n)\nORDER BY order_priority;\n```\n\nIf you get one row per year and one row per priority, you're good. I based the `SEMANTIC_VIEW` clause syntax on this page of the official docs:\n\nNote that the sales metric `total_net_sales` is the sum of each line item's extended price (`l_extendedprice`) minus its discount. It won't match amounts that include tax or the sum of `ORDERS.O_TOTALPRICE`.\n\nOpen `Workspaces` in Snowsight and switch the role to `DASH_AUTHOR` and the warehouse to `DASH_TEST_WH` in the Workspace.\n\nThen select `Add new` → `Dashboard`.\n\nThe CoCo chat panel opens on the right side of the Workspace. In the prompt, I specify which Semantic View to use. If you don't specify one, CoCo searches for a relevant Semantic View, but this time I named it explicitly. I also told CoCo not to query the underlying tables directly and not to redefine the metrics on its own. This keeps the dashboard consistent with the setup, where the viewer has no privileges on the underlying tables.\n\n```\n/dashboard Using DASH_TEST_DB.SV.TPCH_SALES_SV, please create a TPC-H sales dashboard.\n- Total sales trend by year (line chart)\n- Total sales by market segment (bar chart)\n- Order count by order priority (table)\n- Filter: order year\n\nAll tile SQL, and any SQL used to fetch the options for the order year filter, must reference DASH_TEST_DB.SV.TPCH_SALES_SV.\nDo not reference the underlying tables in SNOWFLAKE_SAMPLE_DATA directly.\nUse line_items.total_net_sales for sales and orders.order_count for order count, and do not redefine the metrics on your own.\n```\n\n(The prompt in the screenshot is the original Japanese version.)\n\nCoCo shows this as in the screenshot below and starts by drafting an implementation plan. For some reason it wrote the plan in English, so I asked it to reply in Japanese.\n\nThe implementation plan then appeared in Japanese. It looked fine, so I asked CoCo to build it.\n\nAfter a short wait, a `.dash` file was created in Workspaces and opened, with charts showing in the tiles.\n\nNext, I asked CoCo to add a chart action. Chart actions can't be added from the tile editor; they can only be added through CoCo.\n\nI sent CoCo the following request:\n\n```\nWhen a bar in the sales by market segment chart is clicked,\nadd a chart action that filters the sales by year and\nthe order count by order priority to the selected market segment.\n```\n\nAs a result, a chart action was added: clicking a bar in \"Total Sales by Market Segment\" now updates the other tiles, as shown below.\n\nBy the way, here's what the definition of the added filter looked like.\n\n(You can also add filters manually through the GUI. However, the GUI didn't let me pick a Semantic View dimension, so the filter uses a SELECT statement that extracts a single dimension from the Semantic View.)\n\nLet's open the generated `.dash` file and look at its contents.\n\nYou can view it by clicking `View JSON` in the top-right corner of the dashboard.\n\nThe file is in JSON format. The file generated this time is made up of the following main blocks. (The full file is included in a collapsible section at the end of this step.)\n\n| Key | Contents | \n|---|---|\n| `version` /`spec_version` /`spec_revision` | Format version information ( `2` /`2` /`17` in this case) | \n| `title` | Dashboard title | \n| `filters` | Filter definitions ( `order_year` ,`market_segment` ) | \n| `datasources` | SQL definitions used by tiles and filter options | \n| `tabs` | Tabs and the tiles (charts and tables) inside them | \n| `layout` | Position and size of each tile on the 12-column grid | \n| `scopes` | Definitions of how far chart actions reach | \n\n`filters`)\nOrder year is defined as `single_select`, and market segment as `multi_select`. The options use `\"source\": \"query\"` and reference a datasource that fetches them (such as `ds-order_year-options`).\n\nThe official docs write filter modes with hyphens, like `multi-select`, but the actual file uses underscores, like `multi_select`.\n\n`datasources`)\nEach datasource is `\"type\": \"sql\"`, with the SQL embedded as a string. For example, the SQL for sales by year looked like this:\n\n```\nSELECT\n    order_year,\n    AGG(total_net_sales) AS TOTAL_NET_SALES\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\nWHERE\n    {{ filter('order_year') }}\n    AND {{ filter('market_segment') }}\nGROUP BY\n    order_year\nORDER BY\n    order_year\n```\n\nKey points:\n\n`FROM` and aggregates metrics with `AGG()`.` TPCH_SALES_SV` and none touched the underlying tables in `SNOWFLAKE_SAMPLE_DATA` directly. Sales used `total_net_sales`, order count used `order_count`, and neither metric was redefined. So the instructions from Step 1 were followed.`{{ filter('order_year') }}` in the SQL and the `filter_id` in `filter_bindings`.` ds-sales-by-segment`) is bound only to `order_year`; the `market_segment` filter isn't connected. My guess is that this is because this tile is the source of the chart action.`ds-order_year-options`) use SQL that extracts a single dimension from the Semantic View with `GROUP BY`, as mentioned in Step 2.` tabs`)\nThere are two tile types, `chart` and `table`. A `chart` tile's `spec` uses `mark` (`line` / `bar`) and `encoding` (`field`, `type`, and `title` for `x` / `y`). The official docs say chart tiles are rendered with Vega-Lite, and this format is indeed close to Vega-Lite syntax.\n\nThe chart action added in Step 2 is defined as `interactions` on the sales by market segment tile.\n\n```\n\"interactions\": [\n  {\n    \"trigger\": \"select\",\n    \"operator\": \"set_filter\",\n    \"fields\": [\"MARKET_SEGMENT\"],\n    \"targets\": [\n      {\n        \"scope\": \"segment_action\",\n        \"fields\": [\"MARKET_SEGMENT\"],\n        \"filter\": \"market_segment\"\n      }\n    ]\n  }\n]\n```\n\nWhen a bar is selected (`select`), this sets the `market_segment` filter (`set_filter`). The target tiles (sales by year and order count by order priority) have `\"scope\": \"segment_action\"`, and `segment_action` is defined in `scopes` at the end of the file.\n\n`layout`)\n`layout` specifies `x` / `y` / `w` / `h` for each tile, per tab. Sales by year has a width of 12 (full width). Sales by market segment and order count by order priority have a width of 6 each and sit side by side in the bottom row. This matches the \"12-column grid\" described in the official docs.\n\n```\n{\n  \"version\": 2,\n  \"title\": \"TPC-H 売上ダッシュボード\",\n  \"filters\": {\n    \"order_year\": {\n      \"label\": \"注文年\",\n      \"mode\": \"single_select\",\n      \"valueType\": \"STRING\",\n      \"options\": {\n        \"source\": \"query\",\n        \"datasources\": [\n          \"ds-order_year-options\"\n        ]\n      },\n      \"default_values\": []\n    },\n    \"market_segment\": {\n      \"label\": \"市場セグメント\",\n      \"mode\": \"multi_select\",\n      \"valueType\": \"STRING\",\n      \"options\": {\n        \"source\": \"query\",\n        \"datasources\": [\n          \"ds-market_segment-options\"\n        ]\n      },\n      \"default_values\": []\n    }\n  },\n  \"datasources\": {\n    \"ds-order_year-options\": {\n      \"type\": \"sql\",\n      \"sql\": \"SELECT\\n    order_year\\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\\nGROUP BY\\n    order_year\\nORDER BY\\n    order_year\"\n    },\n    \"ds-sales-by-year\": {\n      \"type\": \"sql\",\n      \"columns\": [\n        {\n          \"name\": \"ORDER_YEAR\",\n          \"type\": \"NUMBER\"\n        },\n        {\n          \"name\": \"TOTAL_NET_SALES\",\n          \"type\": \"NUMBER\"\n        }\n      ],\n      \"sql\": \"SELECT\\n    order_year,\\n    AGG(total_net_sales) AS TOTAL_NET_SALES\\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\\nWHERE\\n    {{ filter('order_year') }}\\n    AND {{ filter('market_segment') }}\\nGROUP BY\\n    order_year\\nORDER BY\\n    order_year\",\n      \"filter_bindings\": [\n        {\n          \"filter_id\": \"order_year\"\n        },\n        {\n          \"filter_id\": \"market_segment\"\n        }\n      ]\n    },\n    \"ds-sales-by-segment\": {\n      \"type\": \"sql\",\n      \"columns\": [\n        {\n          \"name\": \"MARKET_SEGMENT\",\n          \"type\": \"VARCHAR\"\n        },\n        {\n          \"name\": \"TOTAL_NET_SALES\",\n          \"type\": \"NUMBER\"\n        }\n      ],\n      \"sql\": \"SELECT\\n    market_segment,\\n    AGG(total_net_sales) AS TOTAL_NET_SALES\\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\\nWHERE\\n    {{ filter('order_year') }}\\nGROUP BY\\n    market_segment\\nORDER BY\\n    TOTAL_NET_SALES DESC\",\n      \"filter_bindings\": [\n        {\n          \"filter_id\": \"order_year\"\n        }\n      ]\n    },\n    \"ds-orders-by-priority\": {\n      \"type\": \"sql\",\n      \"columns\": [\n        {\n          \"name\": \"ORDER_PRIORITY\",\n          \"type\": \"VARCHAR\"\n        },\n        {\n          \"name\": \"ORDER_COUNT\",\n          \"type\": \"NUMBER\"\n        }\n      ],\n      \"sql\": \"SELECT\\n    order_priority,\\n    AGG(order_count) AS ORDER_COUNT\\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\\nWHERE\\n    {{ filter('order_year') }}\\n    AND {{ filter('market_segment') }}\\nGROUP BY\\n    order_priority\\nORDER BY\\n    order_priority\",\n      \"filter_bindings\": [\n        {\n          \"filter_id\": \"order_year\"\n        },\n        {\n          \"filter_id\": \"market_segment\"\n        }\n      ]\n    },\n    \"ds-market_segment-options\": {\n      \"type\": \"sql\",\n      \"sql\": \"SELECT\\n    market_segment\\nFROM DASH_TEST_DB.SV.TPCH_SALES_SV\\nGROUP BY\\n    market_segment\\nORDER BY\\n    market_segment\"\n    }\n  },\n  \"tabs\": [\n    {\n      \"tab_id\": \"tab-0\",\n      \"title\": \"概要\",\n      \"tiles\": [\n        {\n          \"tile_id\": \"sales-by-year\",\n          \"type\": \"chart\",\n          \"title\": \"年別 売上合計の推移\",\n          \"datasources\": [\n            \"ds-sales-by-year\"\n          ],\n          \"spec\": {\n            \"mark\": \"line\",\n            \"encoding\": {\n              \"x\": {\n                \"field\": \"ORDER_YEAR\",\n                \"type\": \"ordinal\",\n                \"title\": \"注文年\"\n              },\n              \"y\": {\n                \"field\": \"TOTAL_NET_SALES\",\n                \"type\": \"quantitative\",\n                \"title\": \"売上合計\"\n              }\n            }\n          },\n          \"scope\": \"segment_action\"\n        },\n        {\n          \"tile_id\": \"sales-by-segment\",\n          \"type\": \"chart\",\n          \"title\": \"市場セグメント別 売上合計\",\n          \"datasources\": [\n            \"ds-sales-by-segment\"\n          ],\n          \"spec\": {\n            \"mark\": \"bar\",\n            \"encoding\": {\n              \"x\": {\n                \"field\": \"MARKET_SEGMENT\",\n                \"type\": \"nominal\",\n                \"title\": \"市場セグメント\",\n                \"sort\": \"-y\"\n              },\n              \"y\": {\n                \"field\": \"TOTAL_NET_SALES\",\n                \"type\": \"quantitative\",\n                \"title\": \"売上合計\"\n              }\n            }\n          },\n          \"interactions\": [\n            {\n              \"trigger\": \"select\",\n              \"operator\": \"set_filter\",\n              \"fields\": [\n                \"MARKET_SEGMENT\"\n              ],\n              \"targets\": [\n                {\n                  \"scope\": \"segment_action\",\n                  \"fields\": [\n                    \"MARKET_SEGMENT\"\n                  ],\n                  \"filter\": \"market_segment\"\n                }\n              ]\n            }\n          ]\n        },\n        {\n          \"tile_id\": \"orders-by-priority\",\n          \"type\": \"table\",\n          \"title\": \"注文優先度別 注文件数\",\n          \"datasources\": [\n            \"ds-orders-by-priority\"\n          ],\n          \"spec\": {\n            \"columns\": [\n              {\n                \"field\": \"ORDER_PRIORITY\"\n              },\n              {\n                \"field\": \"ORDER_COUNT\"\n              }\n            ]\n          },\n          \"scope\": \"segment_action\"\n        }\n      ]\n    }\n  ],\n  \"layout\": {\n    \"tab-0\": {\n      \"meta\": {\n        \"default\": true\n      },\n      \"positions\": {\n        \"sales-by-year\": {\n          \"x\": 0,\n          \"y\": 0,\n          \"w\": 12,\n          \"h\": 4\n        },\n        \"sales-by-segment\": {\n          \"x\": 0,\n          \"y\": 4,\n          \"w\": 6,\n          \"h\": 4\n        },\n        \"orders-by-priority\": {\n          \"x\": 6,\n          \"y\": 4,\n          \"w\": 6,\n          \"h\": 4\n        }\n      }\n    }\n  },\n  \"spec_version\": 2,\n  \"spec_revision\": 17,\n  \"scopes\": {\n    \"segment_action\": {}\n  }\n}\n```\n\nTo show the dashboard to other users, you share it as an artifact.\n\nFirst, as an administrator, set up the privileges for the viewer role. Viewer queries run with the viewer's own privileges, but when they reference a Semantic View, only SELECT on the Semantic View is needed. We don't grant any privileges on the underlying tables (`SNOWFLAKE_SAMPLE_DATA`).\n\n```\nUSE ROLE ACCOUNTADMIN;\n\n-- Privileges required for the viewer role (no privileges on the underlying tables)\nGRANT USAGE ON WAREHOUSE DASH_TEST_WH TO ROLE DASH_VIEWER;\nGRANT USAGE ON DATABASE DASH_TEST_DB TO ROLE DASH_VIEWER;\nGRANT USAGE ON SCHEMA DASH_TEST_DB.SV TO ROLE DASH_VIEWER;\nGRANT SELECT ON SEMANTIC VIEW DASH_TEST_DB.SV.TPCH_SALES_SV TO ROLE DASH_VIEWER;\n```\n\nNext, in Snowsight, with the role set to `DASH_AUTHOR` and the warehouse set to `DASH_TEST_WH`, open the `.dash` file in Workspaces and select `Publish artifact`.\n\nIn the dialog that opens, do the following:\n\n`Who has access`, add the `DASH_VIEWER` role.`Can view`.` Publish`.\nWhen you click `Publish`, the artifact link is copied to your clipboard.\n\nYou can find published dashboards under `Workspaces` → `Artifacts` in Snowsight.\n\n**How the artifact relates to the original `.dash` file, and how updates work**\n\nA shared artifact is stored separately from the original `.dash` file.\n\n[https://docs.snowflake.com/en/user-guide/snowflake-artifacts-create-share](https://docs.snowflake.com/en/user-guide/snowflake-artifacts-create-share)\n\nAn artifact is a securable object identified by a UUID. The UUID appears after `/artifacts/` in the artifact's URL.\n\nYou can grant three types of privileges:\n\n| Privilege | Description | \n|---|---|\n| `OWNERSHIP` | Delete and transfer ownership | \n| `READ` | View the contents | \n| `WRITE` | View and modify (including publishing changes to the artifact) | \n\nIf you already granted `Can view` to `DASH_VIEWER` through the UI earlier, the SQL below isn't a required step. I'm including it as **an example of how to grant privileges with SQL**, run by an administrator (`ACCOUNTADMIN`).\n\n```\nUSE ROLE ACCOUNTADMIN;\n\n-- Example: grant READ to the viewer role\nGRANT READ\n  ON ARTIFACT \"<artifact UUID>\"\n  TO ROLE DASH_VIEWER;\n```\n\nSQL for checking artifacts, such as `SHOW ARTIFACTS` and `DESCRIBE ARTIFACT`, is listed as \"Coming soon\" as of November 13, 2026. So this article doesn't check privileges with SQL.\n\nThe user who created the dashboard owns the artifact, so I checked viewer access with a different user. As an administrator, grant the viewer role to an existing test user.\n\n```\nUSE ROLE ACCOUNTADMIN;\nGRANT ROLE DASH_VIEWER TO USER <viewer_user>;\n```\n\nThis assumes the test user doesn't have `DASH_AUTHOR` or any administrator role.\n\nI logged in to Snowsight as this user and opened `Workspaces` → `Artifacts`. The dashboard was viewable, as shown below.\n\nI tried Snowflake Dashboards 2.0 together with a Semantic View and confirmed that sharing through roles works.\n\nIt's an AI-first, code-based dashboard, and I found it very easy to use. Give it a try!", "url": "https://wpnews.pro/news/building-an-ai-first-dashboard-with-snowflake-dashboards-2-0", "canonical_source": "https://dev.to/sagara/building-an-ai-first-dashboard-with-snowflake-dashboards-20-1pii", "published_at": "2026-11-13 08:11:10+00:00", "updated_at": "2026-11-13 08:21:07.941854+00:00", "lang": "en", "topics": ["ai-products", "ai-tools", "artificial-intelligence"], "entities": ["Snowflake", "Snowsight Workspaces", "Cortex Code", "CoWork", "TPC-H", "Pei"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/building-an-ai-first-dashboard-with-snowflake-dashboards-2-0", "markdown": "https://wpnews.pro/news/building-an-ai-first-dashboard-with-snowflake-dashboards-2-0.md", "text": "https://wpnews.pro/news/building-an-ai-first-dashboard-with-snowflake-dashboards-2-0.txt", "jsonld": "https://wpnews.pro/news/building-an-ai-first-dashboard-with-snowflake-dashboards-2-0.jsonld"}}