Snowflake Object Tagging

Large accounts hold hundreds of warehouses, tables, and users. Questions arise quickly. Which team spent those credits? Which columns hold personal data? Object tagging attaches labels to Snowflake objects so reports and policies can answer such questions in seconds.

Labels in Everyday Life

A shipping warehouse puts colored stickers on boxes: red for fragile, blue for refrigerated, green for express. Workers read a sticker and know the handling rule without opening the box. Snowflake tags work like those stickers. A tag carries a name and a value, and any object can wear one.

TAG ANATOMY
===========

 TAG NAME         TAG VALUE
 cost_center  =   'marketing'
 data_class   =   'confidential'
 owner_team   =   'finance'

 Attached to:  warehouse | database | schema | table | column | user | role

Creating and Applying Tags

-- Create tags with limited allowed values
CREATE TAG governance.tags.cost_center
  ALLOWED_VALUES 'sales', 'marketing', 'finance', 'engineering';

CREATE TAG governance.tags.data_class
  ALLOWED_VALUES 'public', 'internal', 'confidential';

-- Tag a warehouse
ALTER WAREHOUSE marketing_wh
  SET TAG governance.tags.cost_center = 'marketing';

-- Tag a table and a column
ALTER TABLE sales_db.public.customers
  SET TAG governance.tags.data_class = 'confidential';

ALTER TABLE sales_db.public.customers
  MODIFY COLUMN email
  SET TAG governance.tags.data_class = 'confidential';

Allowed values stop typing mistakes such as "Marketing" versus "marketing". A central schema, here governance.tags, keeps every tag in one findable place.

Tag Inheritance

Tags flow downward through the object hierarchy. A tag on a database applies to every schema, table, and column inside it unless a lower level sets its own value.

TAG INHERITANCE
===============

 DATABASE sales_db      data_class = 'internal'
    |
    +-- SCHEMA public           (inherits 'internal')
          |
          +-- TABLE orders       (inherits 'internal')
          |
          +-- TABLE customers    data_class = 'confidential'  (own value)
                |
                +-- COLUMN email (inherits 'confidential')

Cost Allocation by Team

Tagged warehouses make chargeback reports simple. Finance can see credits per department without manual spreadsheets.

SELECT t.tag_value                AS cost_center,
       ROUND(SUM(m.credits_used), 2) AS credits
FROM SNOWFLAKE.ACCOUNT_USAGE.WAREHOUSE_METERING_HISTORY m
JOIN SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES t
  ON  t.object_name = m.warehouse_name
  AND t.domain      = 'WAREHOUSE'
  AND t.tag_name    = 'COST_CENTER'
WHERE m.start_time >= DATEADD('day', -30, CURRENT_TIMESTAMP())
GROUP BY t.tag_value
ORDER BY credits DESC;

Governance With Tag-Based Masking

A masking policy attached to a tag protects every column carrying that tag automatically. A new column tagged confidential gains protection the moment the tag lands, with no extra policy work.

CREATE MASKING POLICY governance.policies.mask_text AS (val STRING)
RETURNS STRING ->
  CASE WHEN CURRENT_ROLE() IN ('PRIVACY_ADMIN') THEN val
       ELSE '*** MASKED ***' END;

ALTER TAG governance.tags.data_class
  SET MASKING POLICY governance.policies.mask_text;

Tag-based masking applies to string columns that carry the tag, subject to data type match between policy and column.

Finding Tagged Objects

-- Value of a tag on one object
SELECT SYSTEM$GET_TAG('governance.tags.cost_center', 'MARKETING_WH', 'WAREHOUSE');

-- Every object that carries a tag
SELECT object_database, object_schema, object_name, domain, tag_value
FROM SNOWFLAKE.ACCOUNT_USAGE.TAG_REFERENCES
WHERE tag_name = 'DATA_CLASS' AND tag_value = 'confidential';

Permissions

GRANT APPLY TAG ON ACCOUNT TO ROLE governance_admin;
GRANT USAGE ON SCHEMA governance.tags TO ROLE data_steward;

Only trusted roles should apply tags, because tags drive billing reports and security rules.

A Starter Tag Plan

TAG NAME       APPLIED TO                    PURPOSE
-------------  ----------------------------  ---------------------------
cost_center    Warehouses, databases         Charge costs to teams
data_class     Tables, columns               Drive masking and audits
owner_team     Databases, schemas            Know who to contact
environment    Databases, warehouses         Separate dev, test, prod

A Practical Scenario

A company shares one Snowflake account among marketing, finance, and engineering. Each team owns several warehouses and databases. A platform engineer creates a cost center tag, applies it to every warehouse, and builds one report that groups credits by tag value. Monthly chargeback meetings now take ten minutes. The same engineer tags every column that holds email addresses with a confidential label, and a tag-based masking policy hides those columns from general roles automatically.

Frequently Asked Questions

Can an object hold several tags?

An object can carry many tags, each with its own value, up to the limit stated in the Snowflake documentation.

Do tags change how queries run?

Tags are metadata and do not change query behavior unless a policy attached to the tag applies.

Tag Hygiene

Tags lose value when naming drifts. Agree on a short list of tag names, assign an owner to the governance schema, and review tag usage every quarter. A report that lists objects without a cost center tag reveals gaps quickly, and the platform team assigns the missing tags before the following billing cycle.

Tags and Audits

Auditors ask where personal data lives. A tag report answers in one query: every table and column labeled confidential, with its owner and schema. The report replaces weeks of manual searching and gives compliance teams a repeatable evidence trail.

Key Points

  • Tags are name and value labels attached to Snowflake objects.
  • Allowed values keep tag data clean and consistent.
  • Tags inherit downward unless a lower object sets its own value.
  • Joining TAG_REFERENCES with metering history builds team cost reports.
  • Tag-based masking protects every column that carries a sensitive tag.
  • Limit the APPLY TAG privilege to trusted governance roles.