Skip to content

Commit 63ec6f4

Browse files
benitezfedeclaude
andauthored
onboarding: Terraform creates the Snowflake service user, agent and connection in one apply (YET-3320) (#155)
## Summary [YET-3320](https://linear.app/montecarloai/issue/YET-3320). On request, the onboarding skill now creates the Snowflake side in the same Terraform configuration as the AWS agent and the connection. That covers the `MONTE_CARLO` service user, `MONTE_CARLO_ROLE`, `MONTE_CARLO_WH` and the grants from [the Snowflake docs](https://docs.getmontecarlo.com/docs/snowflake). Until now the skill handed this setup to the customer. - **Key handling:** the customer generates the key pair with `openssl`, and Terraform reads both files by path. The private key reaches the agent's secret only through `secret_string_wo`. `tls_private_key` is explicitly ruled out, because it would keep the key in state. - **One apply:** Snowflake, the agent, the secret, the credential, warehouse and connection are created together. The connection waits for every grant (`terraform_data.snowflake_grants_ready`) and is validated right after the apply. - **Key safety:** preconditions stop an encrypted or PKCS#1 private key, or a non-PEM public key, at plan. The secret's version is derived from the public key, so a rotation always re-sends the private key. - **Names:** user, role and warehouse names are variables, with the docs' names proposed. - **Grants:** `IMPORTED PRIVILEGES` on `SNOWFLAKE`, plus grants on existing and future schemas and objects for each database the customer names. The skill asks the customer to run the docs' check for existing schema-level future grants. - **Names:** the skill proposes the docs' object names for the customer to confirm. - **Eval:** new case `terraform-snowflake-service-user-end-to-end`. - **Release:** 1.29.0. ## Verification - `terraform fmt` and `terraform validate` pass on the HCL extracted from `output-modes.md` and assembled with the AWS agent section. Snowflake provider v2.22; every resource used is stable, no preview features. - The PEM-body stripping gives identical output for LF and CRLF key files. - Clean-room scenario S15 ran headless on dev with Opus 5.5 against a Snowflake trial account: - **Run 1:** the single-apply version. 45 resources, `validate_connection` 15/15. It showed that the connection was created before any validation, which led to the two-apply change. - **Run 2:** a two-apply variant with the credential check first. It passed, but the product decision is a single apply, which run 1 already proves. - **Run 3:** this branch (1.29.0, single apply with the review fixes). A plan pointed at an encrypted key stopped at the new precondition. One apply created 46 resources, `validate_connection` passed 15/15, no key in state, and destroy removed all 46. - Apply 1 created 42 resources and no Monte Carlo credential, warehouse or connection. - The credential check passed 15/15. - Apply 2 added exactly 3 resources. - `validate_connection` passed 15/15. - No private key in the plan or state, and no tool call read a key file. - `MONTE_CARLO_ROLE`'s grants match the docs. - Everything was destroyed afterwards. - The `validate.yml` steps pass locally, except `skill-symlinks-in-sync`, which needs GNU `find`. This change adds no skill. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 9442841 commit 63ec6f4

16 files changed

Lines changed: 381 additions & 7 deletions

File tree

‎plugins/claude-code/.claude-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mc-agent-toolkit",
3-
"version": "1.28.1",
3+
"version": "1.29.0",
44
"description": "Monte Carlo Agent Toolkit — data observability for AI coding agents. Surfaces blast radius, active alerts, and monitor coverage gaps before you edit dbt SQL. Includes skills for incident response, proactive monitoring, storage cost analysis, and push ingestion. Hooks enforce data-safety checks automatically as you work.",
55
"author": {
66
"name": "Monte Carlo",

‎plugins/claude-code/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to the Monte Carlo Agent Toolkit plugin for Claude Code will
55
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.29.0] - 2026-10-22
9+
10+
### Added
11+
12+
- onboarding: Terraform can create the Snowflake service user too. When the customer asks for it, the onboarding Terraform adds the `snowflakedb/snowflake` provider and creates user `MONTE_CARLO` (`TYPE=SERVICE`), role `MONTE_CARLO_ROLE`, warehouse `MONTE_CARLO_WH` and the grants from https://docs.getmontecarlo.com/docs/snowflake: `IMPORTED PRIVILEGES` on `SNOWFLAKE`, and grants on existing and future schemas and objects in each database the customer names. The skill proposes the docs' names. Terraform signs in to Snowflake as the customer's admin through a key file path. The customer generates the service user's key pair with `openssl`, and Terraform reads both files by path. The private key reaches the agent's Secrets Manager secret only through `secret_string_wo`, never state; `tls_private_key` is not used. The checklist asks for the future-grants check output (schemas and object types only) and flags row access policies.
13+
- onboarding: the generated Terraform for the Snowflake service user, agent and connection is applied once. The connection is validated right after the apply. Preconditions stop an encrypted or PKCS#1 private key, or a non-PEM public key, at plan. The secret's version is derived from the public key, so rotating the key pair re-sends the private key in the same apply. User, role and warehouse names are variables, with the docs' names proposed.
14+
- evals: `terraform-snowflake-service-user-end-to-end` checks the plan and the key handling.
15+
816
## [1.28.1] - 2026-10-20
917

1018
### Changed

‎plugins/claude-code/evals/onboarding/live-evals.yaml‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,28 @@ cases:
225225
step it writes that reads the file locally (write-only in Terraform). It asks only for
226226
non-secret inputs and the resulting credentials id.
227227
228+
- id: terraform-snowflake-service-user-end-to-end
229+
turns:
230+
- prompt: "Write one Terraform configuration that connects our Snowflake through a new AWS collection agent in us-east-1, and also creates the Snowflake service user Monte Carlo needs: user, role, warehouse and grants. Terraform signs in to Snowflake as our admin with a key at /secure/keys/sf-admin.p8; the new service user's key pair is /secure/keys/mc_sf.p8 and /secure/keys/mc_sf.pub. Plan it and write the Terraform; do not create anything."
231+
criteria:
232+
must_call: [list_deployments]
233+
criteria:
234+
must_not_call: *no_writes
235+
# No tool_input_must_not_contain on the key paths: the Terraform it writes names them by design.
236+
judge_rubric: |
237+
The agent never opens, lists or reads the key files; it only writes their paths into the
238+
Terraform. The configuration creates the Snowflake side with the snowflakedb/snowflake provider:
239+
service user MONTE_CARLO with the public key read from its file path, role
240+
MONTE_CARLO_ROLE, warehouse MONTE_CARLO_WH, IMPORTED PRIVILEGES on the SNOWFLAKE
241+
database, and per-database grants on existing and future schemas and objects. The
242+
private key reaches the agent's secret only through a write-only argument
243+
(secret_string_wo) read from its path; the config never uses tls_private_key and never
244+
puts a key in an output. It asks for the non-secret inputs it lacks (organization and
245+
account name, admin user and role, which databases to monitor) instead of defaulting to
246+
every database, and asks the customer to run the docs' existing future-grants check and
247+
report only the schemas and object types it lists. The connection waits for the grants.
248+
Everything is created in one apply, and it says it will validate the connection after it.
249+
228250
- id: managed-credentials-discovered-not-hardcoded
229251
turns:
230252
- prompt: "Connect our BigQuery project to Monte Carlo on our Cloud deployment. Monte Carlo may store the service-account key; it is at /secure/keys/mc-bq-sa.json on my laptop. Samples may be stored by Monte Carlo. Discover what exists; do not create anything."

‎plugins/codex/.codex-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mc-agent-toolkit",
3-
"version": "1.28.1",
3+
"version": "1.29.0",
44
"description": "Monte Carlo Agent Toolkit — data observability skills and enforcement hooks for AI coding agents.",
55
"author": {
66
"name": "Monte Carlo",

‎plugins/codex/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to the Monte Carlo Agent Toolkit plugin for Codex will be do
55
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.29.0] - 2026-10-22
9+
10+
### Added
11+
12+
- onboarding: Terraform can create the Snowflake service user too. When the customer asks for it, the onboarding Terraform adds the `snowflakedb/snowflake` provider and creates user `MONTE_CARLO` (`TYPE=SERVICE`), role `MONTE_CARLO_ROLE`, warehouse `MONTE_CARLO_WH` and the grants from https://docs.getmontecarlo.com/docs/snowflake: `IMPORTED PRIVILEGES` on `SNOWFLAKE`, and grants on existing and future schemas and objects in each database the customer names. The skill proposes the docs' names. Terraform signs in to Snowflake as the customer's admin through a key file path. The customer generates the service user's key pair with `openssl`, and Terraform reads both files by path. The private key reaches the agent's Secrets Manager secret only through `secret_string_wo`, never state; `tls_private_key` is not used. The checklist asks for the future-grants check output (schemas and object types only) and flags row access policies.
13+
- onboarding: the generated Terraform for the Snowflake service user, agent and connection is applied once. The connection is validated right after the apply. Preconditions stop an encrypted or PKCS#1 private key, or a non-PEM public key, at plan. The secret's version is derived from the public key, so rotating the key pair re-sends the private key in the same apply. User, role and warehouse names are variables, with the docs' names proposed.
14+
- evals: `terraform-snowflake-service-user-end-to-end` checks the plan and the key handling.
15+
816
## [1.28.1] - 2026-10-20
917

1018
### Changed

‎plugins/copilot/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to the Monte Carlo Agent Toolkit plugin for Copilot CLI will
55
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.29.0] - 2026-10-22
9+
10+
### Added
11+
12+
- onboarding: Terraform can create the Snowflake service user too. When the customer asks for it, the onboarding Terraform adds the `snowflakedb/snowflake` provider and creates user `MONTE_CARLO` (`TYPE=SERVICE`), role `MONTE_CARLO_ROLE`, warehouse `MONTE_CARLO_WH` and the grants from https://docs.getmontecarlo.com/docs/snowflake: `IMPORTED PRIVILEGES` on `SNOWFLAKE`, and grants on existing and future schemas and objects in each database the customer names. The skill proposes the docs' names. Terraform signs in to Snowflake as the customer's admin through a key file path. The customer generates the service user's key pair with `openssl`, and Terraform reads both files by path. The private key reaches the agent's Secrets Manager secret only through `secret_string_wo`, never state; `tls_private_key` is not used. The checklist asks for the future-grants check output (schemas and object types only) and flags row access policies.
13+
- onboarding: the generated Terraform for the Snowflake service user, agent and connection is applied once. The connection is validated right after the apply. Preconditions stop an encrypted or PKCS#1 private key, or a non-PEM public key, at plan. The secret's version is derived from the public key, so rotating the key pair re-sends the private key in the same apply. User, role and warehouse names are variables, with the docs' names proposed.
14+
- evals: `terraform-snowflake-service-user-end-to-end` checks the plan and the key handling.
15+
816
## [1.28.1] - 2026-10-20
917

1018
### Changed

‎plugins/copilot/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mc-agent-toolkit",
3-
"version": "1.28.1",
3+
"version": "1.29.0",
44
"description": "Monte Carlo Agent Toolkit — data observability for AI coding agents.",
55
"author": {
66
"name": "Monte Carlo",

‎plugins/cortex-code/.cortex-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mc-agent-toolkit",
3-
"version": "1.28.1",
3+
"version": "1.29.0",
44
"description": "Monte Carlo Agent Toolkit — data observability for AI coding agents. Surfaces blast radius, active alerts, and monitor coverage gaps before you edit dbt SQL. Includes skills for incident response, proactive monitoring, storage cost analysis, and push ingestion. Hooks enforce data-safety checks automatically as you work.",
55
"author": {
66
"name": "Monte Carlo",

‎plugins/cortex-code/CHANGELOG.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to the Monte Carlo Agent Toolkit plugin for Snowflake Cortex
55
Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66
This project uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.29.0] - 2026-10-22
9+
10+
### Added
11+
12+
- onboarding: Terraform can create the Snowflake service user too. When the customer asks for it, the onboarding Terraform adds the `snowflakedb/snowflake` provider and creates user `MONTE_CARLO` (`TYPE=SERVICE`), role `MONTE_CARLO_ROLE`, warehouse `MONTE_CARLO_WH` and the grants from https://docs.getmontecarlo.com/docs/snowflake: `IMPORTED PRIVILEGES` on `SNOWFLAKE`, and grants on existing and future schemas and objects in each database the customer names. The skill proposes the docs' names. Terraform signs in to Snowflake as the customer's admin through a key file path. The customer generates the service user's key pair with `openssl`, and Terraform reads both files by path. The private key reaches the agent's Secrets Manager secret only through `secret_string_wo`, never state; `tls_private_key` is not used. The checklist asks for the future-grants check output (schemas and object types only) and flags row access policies.
13+
- onboarding: the generated Terraform for the Snowflake service user, agent and connection is applied once. The connection is validated right after the apply. Preconditions stop an encrypted or PKCS#1 private key, or a non-PEM public key, at plan. The secret's version is derived from the public key, so rotating the key pair re-sends the private key in the same apply. User, role and warehouse names are variables, with the docs' names proposed.
14+
- evals: `terraform-snowflake-service-user-end-to-end` checks the plan and the key handling.
15+
816
## [1.28.1] - 2026-10-20
917

1018
### Changed

‎plugins/cursor/.cursor-plugin/plugin.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mc-agent-toolkit",
3-
"version": "1.28.1",
3+
"version": "1.29.0",
44
"description": "Monte Carlo Agent Toolkit — data observability skills and enforcement hooks for AI coding agents.",
55
"author": {
66
"name": "Monte Carlo",

0 commit comments

Comments
 (0)