Any user in your Snowflake account can now schedule an AI agent that runs unattended — and it runs with the combined privileges of every role that user holds. Not the role they were using when they created it. Not a service account you provisioned. The union of their default role and their default secondary roles, which for most users on most accounts is every role they have ever been granted.
The privilege that permits this is EXECUTE AGENT TASK, and Snowflake's own documentation states that it "is granted to the PUBLIC role by default, so every user in the account has it unless an administrator changes the grant." Nobody had to enable anything. No admin was asked. If your account is on the release, the capability is live right now.
This is not a vulnerability. It is documented behaviour, written down plainly, and it follows from two design decisions that were each defensible on their own. The problem is that almost nobody governs DEFAULT_ROLE as a security control. It has been a login convenience for a decade. It just became the execution identity for an autonomous process that runs while you are asleep.
What Snowflake Actually Shipped on August 21
Snowflake put scheduled, unattended agent runs into preview, on by default. The release notes entry reads "Aug 21, 2026 - CoCo automations in CLI and Snowsight (Preview)" in Snowflake's server release notes, and the feature documentation describes it in one sentence: "CoCo automations turn a prompt into a recurring, unattended CoCo run. Each automation runs on a schedule in a Snowflake-managed sandbox, even when your terminal or browser is closed." The same page scopes availability: "Available in all commercial regions on AWS, Azure, and Google Cloud. Not available in government, FedRAMP, DoD, VPS, or China deployments."
You create one with cortex automation create --name --prompt --schedule from the CLI, or through an Automations panel in Snowsight. The supported minimum scheduling frequency is once per hour. Threads and run history are kept for two months. Each automation is stored as an AGENT TASK whose internal name is prefixed COCO_ROUTINE_, and the docs say "task history is the authoritative source for run state and error information."
It costs money without a warehouse in the loop. Per the same page, "an automation does not require a warehouse," and "during public preview, user-created automations incur standard Snowflake task billing in addition to CoCo token consumption for each run." A scheduled agent is therefore a line item that does not appear in your warehouse credit review.
This is the third agent-execution surface Snowflake has shipped in three weeks. Snowflake CoWork got its own recurring-report automations in public preview on August 6, and the release notes index also lists a Cortex Agent code execution tool going to preview on August 20. The direction is not ambiguous.
The Run Identity Is Not the Role You Were Using
An automation does not inherit the role you had active when you created it — it inherits your account defaults. The documentation is explicit: "A run does not use the role that was active in your CoCo session when you created the automation. That role is not recorded on the agent task. Each run starts a task session whose primary role is your user's default role, with your user's default secondary roles activated."
Then it states the blast radius outright: "If the user's default secondary roles include every role granted to them, a run can reach any object that the user can reach through any of their roles."
That conditional is doing a lot of work, and for most accounts it is already satisfied. Behavior change bundle 2024_08 changed the default value of DEFAULT_SECONDARY_ROLES from NULL to ('ALL') for every user whose property was unset — the change only skipped users an administrator had explicitly configured. Snowflake's CREATE USER reference confirms the current default is ALL, meaning all roles granted to the user activate at session start.
Secondary roles are not decorative. Per Snowflake's access control overview, "a user can perform SQL actions on objects in a session using the aggregate privileges granted to the primary and secondary roles," and "for any other SQL action, any permission granted to any active primary or secondary role can be used to authorize the action." Only CREATE statements are restricted to the primary role.
So the practical translation for a senior data engineer who has accumulated eleven roles across four business units over three years: an automation they create at 4pm on a Friday runs every hour, forever, against the union of all eleven.
Snowflake's remedy is the honest part, and it is also the uncomfortable part. The docs recommend: "To apply least privilege, narrow the default role and default secondary roles of the user that owns the automation rather than switching roles before you create it." There is no run-as override. To constrain the agent, you constrain the human — you degrade a person's interactive access to shrink the footprint of their scheduled job.
Compare that to how the neighbouring platform handles the same problem. Databricks documents that the job creator is set as the Run as identity by default too, but it then recommends "changing the Run as user to a service principal, so that privileges can be controlled separately from the owner's privileges, and so that jobs do not break when the owner leaves or has changed privileges." Same default, an exit from it. Databricks Mosaic AI and Snowflake Cortex AI are converging on nearly identical agent capabilities; they have not converged on identity.
The Approval Model Is the Thing That Gets Turned Off
Interactive CoCo has a careful, well-designed permission system, and unattended runs disable all of it. The CoCo CLI security documentation describes a three-tier approval system — Confirm, Plan, Bypass — and classifies every operation by risk. ls, cat, echo and grep are SAFE and auto-approved. File editing is MEDIUM and prompts. rm, curl, wget and sudo are HIGH and "always prompt." Destructive operations like rm -rf are CRITICAL and need extra confirmation. On the SQL side, SELECT, SHOW and DESCRIBE are read-only and auto-approved, while INSERT, UPDATE, DELETE and CREATE prompt — and so does switching roles or warehouses. The Desktop permission modes page recommends Default Approvals for everyday use and warns that Bypass Approvals "disables every approval check."
Then the automations page: "Automation runs are unattended, so interactive tool permission prompts are disabled. Tools that are available to the run can execute without waiting for approval."
Every tier collapses at once. The classification survives; the enforcement does not, because there is no human on the other end of the prompt. This is the same lesson enterprises learned when Claude Code moved to auto-mode by default — a confirmation dialog is a user-experience feature, not a policy control, and it evaporates the moment the workflow goes headless. The only boundary left standing in an unattended CoCo run is RBAC, which is exactly the boundary set by DEFAULT_ROLE plus every secondary role.
Two further details compound it. Hooks — bash commands the sandbox runs before or after the agent — carry the same warning: "hooks run with the same access as the rest of the automation and without an interactive approval prompt." And "a failing hook does not fail the run. Task history reports the run as succeeded in both of the following cases, so a broken hook can go unnoticed until you open the run's thread." Your audit trail can read SUCCESS while the guardrail you wrote never executed.
The CoCo sandbox is real, and it is host-level. It "can run shell commands inside a sandbox to restrict filesystem access, network access, and process capabilities." It governs the shell. It does not govern your Snowflake privileges, which are the assets an attacker or a confused model would actually want. Neither does permissions.json, the local CLI file holding onlyAllow, defaultMode and dangerouslyAllowAll — it lives on a developer's machine, and the automation runs in Snowflake's sandbox.
Snowflake's Own Task Model Is Narrower Than This
The ordinary Snowflake task — a long-established primitive — has a tighter identity model than the new agent task. Per Snowflake's task documentation, "by default, tasks run as a system service that is decoupled from a user. The system service runs the task using the same privileges as the task owner." One role. No secondary roles. The wide behaviour is opt-in, reserved for tasks explicitly configured with EXECUTE AS USER, where "the primary role of the task session will be the owner role of the task, and the user's default secondary roles will be activated."
An agent task is the second shape by default. The most autonomous thing Snowflake has ever let a non-admin schedule is the one that runs widest.
The relevant privileges for ordinary tasks were also never on PUBLIC. EXECUTE TASK "grants the ability to run tasks owned by the role," and EXECUTE MANAGED TASK "grants the ability to create tasks that rely on serverless compute resources" — both are account-level grants an administrator makes deliberately. EXECUTE AGENT TASK arrives pre-granted to a pseudo-role that, per the access control overview, is "automatically granted to every user and every role in your account."
The Case for Doing It This Way
The strongest argument for Snowflake's design is that running as the user is more auditable than the alternative, and the alternative is genuinely worse. The February 2026 NIST NCCoE concept paper, "Accelerating the Adoption of Software and Artificial Intelligence Agent Identity and Authorization," names both failure modes — and as Biometric Update reported, the proposal is that agents "should be treated as identifiable entities within enterprise identity systems" rather than running anonymously under shared credentials.
A shared service principal is the classic way to lose attribution. Ten engineers, one SVC_AUTOMATION account, and no way to answer who caused the 3am delete. Snowflake's model never loses that thread: every run is attributable to a named human, and the SNOWFLAKE_COCO_USAGE_HISTORY view, which reached general availability on August 17, records USER_ID, USER_NAME, REQUEST_ID, TOKEN_CREDITS and a metadata object carrying role_name, with up to one hour of latency and a year of retention.
That is a real advantage and it should not be waved away. But attribution and authorization are different problems, and this design solves the first by making the second worse. NIST's framing wants both — a distinct identity and scoped authority. Snowflake has given the agent the human's name and the human's whole keyring.
There is also history here. The 2024 campaign against Snowflake customers was not a breach of Snowflake. Mandiant's investigation into UNC5537 "has not found any evidence to suggest that unauthorized access to Snowflake customer accounts stemmed from a breach of Snowflake's enterprise environment," and traced every incident to compromised customer credentials — roughly 165 organizations notified, with impacted accounts lacking MFA, running credentials that "were still valid, in some cases years after they were stolen," and having no network allow lists. The failure mode was customer-side identity configuration. That is precisely the layer this feature now depends on.
What to Do About It
This Week:
- Find out whether the grant is live. Run
SHOW GRANTS TO ROLE PUBLIC;asSECURITYADMINand look forEXECUTE AGENT TASKon the account. - If it is there and you have not made a decision about it, take it back. The documentation gives the exact statement:
REVOKE EXECUTE AGENT TASK ON ACCOUNT FROM ROLE PUBLIC;Re-grant it to a named role for the teams that need it. This is reversible in one line, which is a good reason to do it before the debate rather than after. - Look for automations that already exist. Query
TASK_HISTORYfor names beginningCOCO_ROUTINE_. Note the window: the TASK_HISTORY table function "can return all executions run in the past seven days or the next scheduled execution within the next eight days," so a weekly check misses nothing and a monthly one misses plenty.
This Month:
- Inventory your default roles.
SELECT NAME, DEFAULT_ROLE, DEFAULT_SECONDARY_ROLE FROM SNOWFLAKE.ACCOUNT_USAGE.USERS;— the ACCOUNT_USAGE.USERS view carries both columns, withDEFAULT_SECONDARY_ROLEholding "ALL" orNULL, and up to two hours of latency. Sort by how many roles each user holds. The engineers at the top of that list are your largest agent identities, whether or not they have created one. - Set
DEFAULT_SECONDARY_ROLES = ()for the accounts that do not need the union. The behavior change note documents the empty list as the way to restore pre-2024 behaviour. Do it for service-shaped human accounts and contractor accounts first — those get the least UX pain and remove the most reach. - Write the policy sentence you are missing: a scheduled agent may not run under a human's default role. Then decide what it does run under. Snowflake does not offer you a service principal here, so your options are a dedicated, narrowly-granted user per automation, or not scheduling it in production yet.
Before You Enable It in Production:
- Treat an automation the same way you treat a production job: an owner, a review, a documented scope, and a kill path.
cortex automation listandcortex automation doctorexist; put them in a runbook, not in one engineer's shell history. - Test the hook-failure case deliberately. Make a pre-run hook exit non-zero and confirm for yourself that task history still reports success. Anyone building alerting on run status needs to have seen that with their own eyes.
The Bottom Line
Every platform shipping agents right now is quietly answering the same question — what identity does the agent get? — and most are answering it by reaching for whatever identity was already sitting there. AWS reached for the long-lived runtime session. Cloud IAM reached for standing permissions the agent inherited. Snowflake reached for DEFAULT_ROLE, a field that has meant "which role should this person see first at login" since long before anything autonomous existed on the platform.
Snowflake bought Natoma's MCP gateway to solve agent identity, and shipped scheduled agents that route around it. The vendor consolidation happening across agent identity tooling is not going to reach inside your DEFAULT_ROLE column either. The same conversation is already running in your Cortex account, where agents hold admin access that no one scoped, and it is one of the real differences to weigh when choosing between Cortex and Mosaic AI. It is the same failure the Antigravity allowlist showed this week: the admin control exists somewhere, and the agent is not routed through it.
Snowflake wrote all of this down. The behaviour is documented, the risk sentence is in the docs, and the fix is a single REVOKE. That is more transparency than most vendors have offered.
Read the release note. Then read your own SHOW GRANTS TO ROLE PUBLIC. One of those tells you what the product does. The other tells you what your company already agreed to.
Continue Reading
- AWS Agents Run 14 Days. The Session Is the Only Wall.
- One Agent Escalated Another. Every Call Was Authorized.
- Claude Code Stops Asking Aug 14. Prompts Aren't Policy.
- Snowflake Cortex vs Databricks Mosaic AI: Pick on Exit Cost
- AI Agents Have Admin Access. 57% of Firms Aren't Ready.
- 9,400 MCP Servers, 18% Trust: Why Snowflake Bought Natoma
- Okta Bought Permiso. Your Leverage Expires Oct 31.
- Antigravity's Allowlist Isn't Honored. Use Your Proxy.
