Taking Snowflake CoWork to Production
Author: Jackson Staub, Senior Solution Engineer at Snowflake
Most agent demos stop at the good bit. You wire a model to some tables, ask it “who are my top customers,” it answers, everyone claps.
Then someone in the room asks the question that actually matters:
“okay, so how do we put this in front of 200 people without it leaking PII, running up a bill nobody approved, or quietly getting worse over time?”
I’ve had that question a few times the clients that I advise, so I built the thing that answers it: a start-to-finish runbook for standing up a governed Snowflake Intelligence (CoWork) agent — from raw tables all the way to a monitored, evaluated, business-user-ready deployment. It’s nine SQL notebooks you run in order against a fictional buy-side firm called Strive Capital. The repo is here:
https://github.com/sfc-gh-jastaub/cowork_enterprise_guide
Want an easy overview guide? I’ve added a html guide into that repo.
This post is the “why it’s shaped the way it is” companion. If you just want the runnable steps, clone the repo.
Why this needs to exist
Standing up a Cortex Agent is genuinely quick — Snowflake makes that part easy. Operating one for an enterprise is a separate discipline, and it comes down to one design decision that’s worth understanding early: the agent runs with the caller’s rights. There’s no service account sitting behind it. Every tool call and every generated SQL statement executes as the invoking user’s role — inheriting their grants, their masking policies, their row-access policies.
That’s an elegant design once it clicks, because it flips the usual mental model. There’s no separate “AI security layer” to build — your existing RBAC and masking flow straight through to the agent’s answers. Get the access model right and the agent is governed by construction. It also means the real controls live in the data layer: a masking policy or a grant is the boundary, while an orchestration instruction like “don’t show PII” is a helpful nudge on top of it rather than the thing doing the enforcing.
So the interesting work in an enterprise agent isn’t the agent — Snowflake hands you that. It’s everything around it: the meaning layer that makes its answers correct, the access model it inherits, the cost controls that keep spend visible and attributed, and the evaluation that tells you whether it’s good enough to ship. That’s the part demos skip, and that’s the part this runbook is about.
Three Important Ideas
1. Caller’s rights means governance is inherited, not configured.
You govern the agent by governing the user. This is why access comes before the agent exists.
2. Govern, then build, then go live.
You establish meaning and access *first*, so the agent is born into an already-governed environment instead of having governance retrofitted around it.
Get Jackson Staub’s stories in your inbox
Join Medium for free to get updates from this writer.
3. Evaluation is the gate.
Nothing gets promoted on vibes. A scored evaluation decides go-live, decides dev-to-prod promotion, and decides every future change. The threshold is the decision-maker, not you.
Walking the build
There are nine notebooks. I’ve lightly aligned them to both a mental framework and the sequential order you’d run them in:
00 — Lab setup
In a real engagement, “phase 0” is confirming the estate the customer already runs. In a demo there’s no estate, so this builds a clean, isolated sandbox: one database, three schemas, one dedicated role, an XS warehouse, and self-contained sample data for Strive Capital — clients, positions, trades, daily metrics, and a set of unstructured research notes. Everything lives under a single `COWORK_ENTERPRISE_DEMO` database so the entire demo is grantable and droppable as a unit. On a shared account that isolation isn’t optional.
01 — The Context Layer
An agent is only as good as the meaning beneath it. Raw tables don’t tell a model that “AUM” is assets under management, or how clients join to trades. A semantic view encodes that — logical tables, relationships, facts, dimensions, business metrics, and a handful of verified example queries — so the agent generates correct SQL instead of guessing. There’s a detail here worth calling out: the Cortex Search service over the high-cardinality client-name column is created *before* the semantic view, because the view’s `CLIENT_NAME` dimension references it. That’s what lets a user type “Acme” and have it resolve to “Acme Capital Partners LLC.” A second search service indexes the research notes for the qualitative questions. And you validate the view by querying it directly — if the numbers are wrong here, the agent will be wrong too, and you want to find that out now.
02 — Govern Access
This is where caller’s rights earns its keep. The consumer role gets built with four independent layers: platform entitlement (Cortex plus warehouse/database usage), the specific agent grant (deferred to notebook 03, since the agent doesn’t exist yet), the tools and resources (search services and the semantic view), and the data itself. Masking goes on here too — an `AI_REDACT` policy on the email column that redacts for non-privileged roles. Note that this happens *before* the agent is built, on purpose: there should never be a window where raw PII could surface. I tested this by granting myself the consumer role and querying — emails came back as `[EMAIL]`. That’s a data-layer control doing its job, not a prompt hoping to.
03 — Build and harden the agent
Now the agent, defined as code from a YAML spec: the model, an orchestration budget, response and routing instructions, and the tools wired to the semantic view and search service. The spec is the artifact you version and promote later, so treat it like source. Tool descriptions are the single biggest lever for correct routing — the agent picks tools by reading them, so keep them sharp and keep the agent narrow. One easy-to-miss gotcha: agents are serverless, so the warehouse has to be named in the spec, not inherited from your session. This is also where the fourth access layer lands — now that the agent exists, the consumer role gets `USAGE ON AGENT`.
04 — Control the cost
AI credits come from two meters — warehouse compute for the SQL, and serverless reasoning for the model — so they’re worth watching deliberately rather than assuming. The nice part is it’s all in the same Account Usage views you already use for warehouse and storage, so there are no hidden meters. The discipline is observe, attribute, control. Tag the agent *and* its warehouse with a cost-centre tag so one budget captures the whole team. Add a warehouse statement timeout, a per-agent budget with a notification threshold, and a per-user quota. On a shared account I keep enforcement in monitoring mode so I’m never capping or emailing other teams — which happens to be exactly the right default discipline for a customer account too.
05 — Evaluate, go live, operate
This is where “evaluation is the gate” gets concrete. First, golden smoke tests across a few question types — including one deliberately out of scope (“what’s the weather in Sydney?”) to confirm the agent refuses gracefully instead of hallucinating. Then a scored evaluation against a curated dataset. Only once it clears the bar does the agent get published to the account’s CoWork object — which is the curation step, because without it users see *every* agent they can access, and with it they see your production shortlist. Users get provisioned here, at go-live, not earlier: a dedicated business user locked to the Snowflake Intelligence interface via `ALLOWED_INTERFACES` — no worksheets, no SQL, no drivers. You don’t hand out keys to a building that isn’t finished.
06 — Dev to prod
You promote the *specification*, not the running agent. Capture the spec, version it with a traceable comment, deploy the identical spec to the prod target, and gate the whole thing on the same evaluation threshold from notebook 05. Then a clean cut-over: add the promoted agent to the CoWork object, remove the dev build, so users see exactly one production agent.
07 — Continuous improvement
Go-live is the start line. A self-improving agent is a governed closed loop with a human in it, not the agent editing itself. You mine real production traces for failures, fold them into the evaluation set, score a baseline, improve the *instructions* — which are the primary lever, not adding more tools — then re-evaluate to prove the change helped without regressions before you promote it. Every change is a versioned, evaluated spec edit.
08 — Cleanup
Deliberately narrow. It removes only the demo’s own footprint and detaches our agents from the shared CoWork object without dropping the object itself, then resets the object’s branding back to defaults. Shared, pre-existing state is never touched.
Runnable vs. reference
I built and verified this in my shared SE account, which forced a rule that turns out to be exactly right for a customer’s account too. Operations that touch only our own objects are runnable. Operations that would change shared state — creating or dropping the singleton CoWork object, revoking `CORTEX_USER` from `PUBLIC`, changing account guardrails, network policy, SSO, MFA — are shown as reference, not executed. The principle is simple: never let a demo change state that belongs to someone else. In a customer’s own account the reference operations become runnable; the boundary just moves.
One concrete example: the CoWork object’s branding (brand name, welcome message, accent colors) is account-global. Setting it changes what every agent tile on the account looks like, not just yours.
How to Run The Playbook
The notebooks are standard Snowflake Workspace SQL notebooks, and the cleanest way to run them is a Git-connected Workspace — Snowsight syncs the repo directly, so you open and run them in place without uploading anything. In Snowsight: Projects → Workspaces → From Git repository, paste the repo URL, and because the repo is public you can pick the “Public repository” auth option and skip the token setup entirely. Then run 00 through 07 in order, and 08 last when you’re done.
If you’d rather regenerate or tweak the notebooks, they’re produced by a single self-contained Python builder (`build_notebooks.py`) that defines all the SQL inline — edit the builder, re-run it, and the notebooks rebuild. That builder is the source of truth; the notebooks are the output.
The takeaway
If there’s one thing to carry out of this, it’s that Snowflake makes the agent itself the easy part — call it 20% of the work. The 80% that decides whether it holds up in front of real users is the meaning layer, the inherited access model, the cost guardrails, and the evaluation gate — in that order, and mostly before the agent exists at all. Build it in that sequence and “put an AI agent in production” stops being a leap of faith and starts being a checklist.
Repo, notebooks, and the narrative overview are all here:
https://github.com/sfc-gh-jastaub/cowork_enterprise_guide
Thanks,
Jackson Staub









