What you will be able to do
- Explain which account privilege and database role a user needs before they can call any Cortex AI function
- Restrict the whole account to specific models with CORTEX_MODELS_ALLOWLIST
- Grant per-model access using the application roles that represent model objects in SNOWFLAKE.MODELS
- Predict whether a model call succeeds when both the allowlist and RBAC apply, and plan a migration away from the default all-models grant
Key concept
Two independent model-access checks — When a call names a model, Cortex checks two things: whether the calling role has RBAC access to that model's object, and whether the model is on the account allowlist. If either one permits the model, the call goes through. It is blocked only when both say no.
1.Before model choice: the AI function privilege gate
Before you think about which model a user may call, check whether they can call Cortex AI functions at all. Two things are needed, and they come from different places. The first is an account-level privilege: either the blanket USE AI FUNCTIONS or a per-function USE AI FUNCTION <name>. The second is a database role in the SNOWFLAKE database: either CORTEX_USER or AI_FUNCTIONS_USER. A user who is missing either one cannot use the functions.
The defaults are permissive. USE AI FUNCTIONS and CORTEX_USER are both granted to PUBLIC, and every user and role inherits PUBLIC. So in a new account, everyone can call AI functions. To lock this down, an ACCOUNTADMIN revokes the grants from PUBLIC and then grants access to chosen roles instead.
USE ROLE ACCOUNTADMIN;
-- Remove blanket access from PUBLIC
REVOKE USE AI FUNCTIONS ON ACCOUNT FROM ROLE PUBLIC;
-- Create a role with access to only AI_COMPLETE
CREATE ROLE ai_complete_user_role;
GRANT USE AI FUNCTION AI_COMPLETE ON ACCOUNT TO ROLE ai_complete_user_role;
GRANT DATABASE ROLE SNOWFLAKE.CORTEX_USER TO ROLE ai_complete_user_role;
GRANT ROLE ai_complete_user_role TO USER example_user;The blanket privilege and the per-function privileges combine with OR. A role that holds USE AI FUNCTIONS can call every function, so revoking one of its per-function grants changes nothing. The two database roles also differ in scope. AI_FUNCTIONS_USER covers the scalar AI functions only. It does not cover the aggregate functions AI_AGG and AI_SUMMARIZE_AGG, and it gives no access to Cortex services such as Agents, Analyst, Fine-tuning or Search. It is also not granted to PUBLIC by default. Neither database role can be granted directly to a user. You grant it to an account role and then grant that role to users.
One gap to remember: USE AI FUNCTIONS currently does not apply to AI function queries that run inside Snowflake native applications.
| Database role | Granted to PUBLIC by default? | What it covers |
|---|---|---|
| SNOWFLAKE.CORTEX_USER | Yes | Cortex AI functions, including the aggregates |
| SNOWFLAKE.AI_FUNCTIONS_USER | No | Scalar AI functions only; no Cortex Agent, Analyst, Fine-tuning or Search |
Checkpoint 1 of 6· Check yourself
A role holds USE AI FUNCTIONS and also a per-function grant for AI_COMPLETE. An admin revokes USE AI FUNCTION AI_COMPLETE from the role. What happens?
The blanket and per-function privileges combine with OR, so the blanket privilege alone is enough to call AI_COMPLETE.
“If a role has USE AI FUNCTIONS, it can call all Cortex AI functions, regardless of any per-function grants or revocations.”Source: docs.snowflake.com
2.The account-level allowlist: one list for the whole account
After a user is allowed to call AI functions, the next question is which models they may use. The older and coarser control is the CORTEX_MODELS_ALLOWLIST parameter. You can set it to 'All', to 'None', or to a comma-separated list of model names. Model names are case-sensitive and must be written in lowercase.
The parameter applies to the whole account. You cannot set it for a single user or session, and only ACCOUNTADMIN can change it with ALTER ACCOUNT. That makes it all-or-nothing: if a model is on the list, every user who can call AI functions can use it.
ALTER ACCOUNT SET CORTEX_MODELS_ALLOWLIST = 'mistral-large2,llama3.1-70b';Setting the allowlist to 'None' does not stop every model call. It only removes access that comes from the allowlist. Roles that have RBAC grants on a model can still use that model. Snowflake recommends moving to RBAC rather than relying on the allowlist.
Checkpoint 2 of 6· Check yourself
A data science team wants claude-sonnet-4-6 available only to their own role, not to the rest of the account. Why is CORTEX_MODELS_ALLOWLIST the wrong tool?
The allowlist is account-wide. To give one role access to a model, you need per-model RBAC.
“This parameter can only be set at the account level, not at the user or session levels.”Source: docs.snowflake.com
3.RBAC on model objects and their application roles
Cortex models are not Snowflake objects by themselves. Snowflake represents each one as a model object in the SNOWFLAKE.MODELS schema, and you control access to those objects with RBAC like any other object. Every day, a Snowflake-managed task (CORTEX_BASE_MODELS_REFRESH_TASK) refreshes the schema. The refresh also creates one application role per model and a catch-all role, CORTEX-MODEL-ROLE-ALL. If you need a newly released model before the next daily run, an ACCOUNTADMIN can call SNOWFLAKE.MODELS.CORTEX_BASE_MODELS_REFRESH(). Calling it again is safe and does not create duplicates.
To restrict a role to specific models, grant it those models' application roles. These are application roles in the SNOWFLAKE application. They are not account roles and not database roles.
SHOW APPLICATION ROLES LIKE 'CORTEX-MODEL%' IN APPLICATION SNOWFLAKE;Checkpoint 3 of 6· Fill the gap
Complete the grant so MY_ROLE gets access to all current and future Cortex models.
GRANT APPLICATION ROLE SNOWFLAKE." ? " TO ROLE MY_ROLE;CORTEX-MODEL-ROLE-ALL covers all models, including models added later. CORTEX_USER and AI_FUNCTIONS_USER are database roles that control function access, not model access.
Source: docs.snowflake.comIn a call such as AI_COMPLETE, you can name the model with a fully-qualified identifier like 'SNOWFLAKE.MODELS."LLAMA3.1-70B"', or with a plain name like 'llama3.1-70b'. Cortex resolves a plain name to the matching object in SNOWFLAKE.MODELS. If you want RBAC to be the only control, set the allowlist to 'None'.
Checkpoint 4 of 6· Exam question
A financial services company wants only its ACCOUNTADMIN and a small group of approved analyst roles to be able to invoke SNOWFLAKE.CORTEX.COMPLETE against any large language model, while every other role in the account should be blocked from calling any Cortex LLM function entirely. Which mechanism should the security team configure first to enforce this account-wide restriction?
Correct answer: A — Set the CORTEX_MODELS_ALLOWLIST account parameter to 'None' and grant model access only through RBAC
- A. Setting the account-level allowlist to 'None' blocks all model access by default, after which access can be selectively restored to specific roles using role-based access control on individual model objects, exactly matching the described requirement.
- B. Revoking IMPORTED PRIVILEGES on the SNOWFLAKE database would break far more than Cortex model access, since many system views and shared objects depend on that grant, making it too blunt and disruptive a tool.
- C. Cortex functions execute inside Snowflake's own infrastructure rather than calling an external endpoint reachable over the network, so a network policy has no effect on which roles can invoke a model.
- D. There is no Snowsight admin toggle that disables the CORTEX schema outright; model access is governed through account parameters and role grants, not a schema-level on/off switch.
4.How the two checks combine, and removing the default grant
-- set up access
USE SECONDARY ROLES NONE;
USE ROLE ACCOUNTADMIN;
ALTER ACCOUNT SET CORTEX_MODELS_ALLOWLIST = 'MISTRAL-LARGE2';
CALL SNOWFLAKE.MODELS.CORTEX_BASE_MODELS_REFRESH();
GRANT APPLICATION ROLE SNOWFLAKE."CORTEX-MODEL-ROLE-LLAMA3.1-70B" TO ROLE PUBLIC;
-- test access
USE ROLE PUBLIC;
-- this succeeds because mistral-large2 is in the allowlist
SELECT AI_COMPLETE('MISTRAL-LARGE2', 'Hello');
-- this succeeds because the role has access to the model object
SELECT AI_COMPLETE('SNOWFLAKE.MODELS."LLAMA3.1-70B"', 'Hello');Cortex first looks for the model object, then applies the two checks together. A call fails only when both refuse.
Migration has one more catch. As part of deprecating the allowlist, Snowflake grants CORTEX-MODEL-ROLE-ALL to the SNOWFLAKE.PUBLIC application role. This happens in accounts where the allowlist is 'All', which includes new accounts. SNOWFLAKE.PUBLIC is inherited by the account-level PUBLIC role, so every user gets every model by default. SNOWFLAKE.PUBLIC and account PUBLIC are different objects, which means SHOW GRANTS TO ROLE PUBLIC might not show this grant. A plain REVOKE APPLICATION ROLE ... FROM ROLE PUBLIC also does not remove it. Use the stored procedure instead.
CALL SNOWFLAKE.LOCAL.REVOKE_FROM_PUBLIC_APPLICATION_ROLE(
'APP_ROLE',
'CORTEX-MODEL-ROLE-ALL'
);Checkpoint 5 of 6· Put it in order
Put the steps for removing default all-models access in order
- 1.Call SNOWFLAKE.LOCAL.REVOKE_FROM_PUBLIC_APPLICATION_ROLE for CORTEX-MODEL-ROLE-ALL
- 2.Grant specific model application roles to the roles that need them
- 3.Re-run SHOW GRANTS TO APPLICATION ROLE SNOWFLAKE.PUBLIC and confirm CORTEX-MODEL-ROLE-ALL is gone
Revoke the bootstrap grant with the procedure, check that it is gone, and only then grant narrower per-model roles.
“After the revoke, re-run SHOW GRANTS TO APPLICATION ROLE SNOWFLAKE.PUBLIC and confirm that CORTEX-MODEL-ROLE-ALL is no longer listed.”Source: docs.snowflake.com
Checkpoint 6 of 6· Exam question
A platform engineer needs to grant the ML_ENGINEERING role permission to call llama3.1-70b specifically, without granting access to any other model in the account. Which approach achieves this fine-grained, per-model restriction?
Correct answer: A — Grant the SNOWFLAKE."CORTEX-MODEL-ROLE-LLAMA3.1-70B" application role to ML_ENGINEERING
- A. Snowflake exposes a per-model application role named after each model, and granting that specific role to a role gives it usage on only that one model object, which is the correct fine-grained approach.
- B. Adding a model to the allowlist parameter changes what is permitted for the whole account rather than for a single role, so it cannot be used to scope access to just one role.
- C. Granting SELECT on a metadata view would at most let a role read information about models; it does not grant usage rights to invoke a model through Cortex functions.
- D. The CORTEX_USER role grants broad usage of Cortex AI functions themselves but does not control which individual models a role may target, so it cannot restrict access to a single model.
Sources1
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Running REVOKE APPLICATION ROLE SNOWFLAKE."CORTEX-MODEL-ROLE-ALL" FROM ROLE PUBLIC removes default access to all models.Why is that wrong?
The default grant goes through the SNOWFLAKE.PUBLIC application role, and a plain REVOKE does not remove it. Use SNOWFLAKE.LOCAL.REVOKE_FROM_PUBLIC_APPLICATION_ROLE.
Covered in How the two checks combine, and removing the default grant
2.Setting CORTEX_MODELS_ALLOWLIST = 'None' blocks every model for every role.Why is that wrong?
'None' removes only access that comes from the allowlist. Roles with RBAC grants on a model can still use it.
Covered in The account-level allowlist: one list for the whole account
3.You can grant SNOWFLAKE.CORTEX_USER straight to a user.Why is that wrong?
The database role must be granted to an account role, and that account role is then granted to the user.
Covered in Before model choice: the AI function privilege gate
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“and one of the CORTEX_USER or AI_FUNCTIONS_USER database roles to use Snowflake Cortex AI Functions.”
↩︎ Before model choice: the AI function privilege gate“By default, the USE AI FUNCTIONS privilege is granted to the PUBLIC role.”
↩︎ Before model choice: the AI function privilege gate“without granting access to Cortex services such as Cortex Agent, Cortex Analyst, Cortex Fine-tuning, or Cortex Search.”
↩︎ Before model choice: the AI function privilege gate“AI_FUNCTIONS_USER role is not granted to the PUBLIC role by default.”
↩︎ Before model choice: the AI function privilege gate“Currently, USE AI FUNCTIONS does not apply to AI Function queries that are run inside Snowflake native applications.”
↩︎ Before model choice: the AI function privilege gate“Model names are case-sensitive and must be specified in lowercase”
↩︎ The account-level allowlist: one list for the whole account“Snowflake recommends migrating to RBAC instead, as described in the following section.”
↩︎ The account-level allowlist: one list for the whole account“Snowflake lets you create model objects in the SNOWFLAKE.MODELS schema that represent the Cortex models.”
↩︎ RBAC on model objects and their application roles“The refresh also creates corresponding application roles and CORTEX-MODEL-ROLE-ALL, a role that covers all models.”
↩︎ RBAC on model objects and their application roles“To use RBAC exclusively, set CORTEX_MODELS_ALLOWLIST to 'None'.”
↩︎ RBAC on model objects and their application roles“users inherit access to all current and future Cortex models by default (subject to Cortex LLM privileges)”
↩︎ How the two checks combine, and removing the default grant“SNOWFLAKE.PUBLIC is an application role on the SNOWFLAKE database. It is not the same object as the account-level PUBLIC role.”
↩︎ How the two checks combine, and removing the default grant“Access is denied only if both checks fail.”
↩︎ Key concept“Always use SNOWFLAKE.LOCAL.REVOKE_FROM_PUBLIC_APPLICATION_ROLE to revoke the bootstrap grant.”
↩︎ Exam trap 1“To block allowlist access to all models (roles with RBAC grants can still use those models):”
↩︎ Exam trap 2“The SNOWFLAKE.CORTEX_USER database role cannot be granted directly to a user.”
↩︎ Exam trap 3“If a role has USE AI FUNCTIONS, it can call all Cortex AI functions, regardless of any per-function grants or revocations.”
↩︎ Checkpoint“This parameter can only be set at the account level, not at the user or session levels.”
↩︎ Checkpoint“Access is granted if either of the following is true:”
↩︎ Prediction“After the revoke, re-run SHOW GRANTS TO APPLICATION ROLE SNOWFLAKE.PUBLIC and confirm that CORTEX-MODEL-ROLE-ALL is no longer listed.”
↩︎ Checkpoint - 2.
“Revoking the SNOWFLAKE.CORTEX_USER and SNOWFLAKE.COPILOT_USER roles from PUBLIC does not prevent ACCOUNTADMIN from using these features.”
↩︎ Before model choice: the AI function privilege gate“you can limit access to specific LLMs via an account-level allowlist, by role-based access control, or by a combination of both.”
↩︎ RBAC on model objects and their application roles - 3.
“Use this parameter to allowlist models for all users in the account.”
↩︎ The account-level allowlist: one list for the whole account