lfx-snowflake-access/SKILL.md
Guide users through requesting Snowflake access at the Linux Foundation. Handles two request types: (1) individual user access — adding or modifying an entry in users.tf in the lfx-snowflake-terraform repo, and (2) service account creation — adding an entry in service_accounts.tf. For each, the skill collects the necessary details, generates the exact Terraform HCL block to add, explains where to place it, and guides the user through the PR process. Use this skill any time someone asks about Snowflake access, permissions, user provisioning, service accounts, or making changes to the lfx-snowflake-terraform repo — including phrases like "get access to Snowflake", "add me to Snowflake", "need a service account", "request Snowflake permissions", "I need to query Snowflake", or "how do I get Snowflake access".
npx skillsauth add linuxfoundation/lfx-skills lfx-snowflake-accessInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Snowflake access at the Linux Foundation is controlled through a configuration file that the platform engineering team manages. Requesting access means submitting a small change to that file for review — once approved, access is automatically applied within minutes.
For the AI: The underlying mechanism is Terraform in the lfx-snowflake-terraform repo, provisioned via pull request. Use technical terms freely with engineers. With everyone else, say "access configuration", "change request", and "submit for review" — avoid "Terraform", "HCL", "PR", "commit", and "branch" unless the user introduces those terms first.
There are two types of access requests:
| Who needs access | What gets updated |
| --- | --- |
| A person logging into the Snowflake web UI or tools | The user access list (users.tf) |
| An automated system, script, or integration | The service account list (service_accounts.tf) |
Your job is to:
⚠️ Scope of changes: Users should only ever edit
users.tforservice_accounts.tf. Do not assist with changes to warehouses, role definitions, network rules (beyond IP lists for service accounts), providers, or any other Terraform files. If someone asks about those, let them know that infrastructure changes require a CloudOps engineer and they should open a GitHub issue or reach out in the#lfx-devopsSlack channel.
users.tf)Ask the user for:
@linuxfoundation.org or @contractor.linuxfoundation.orgUse the team/function to recommend an appropriate role set. These map to existing patterns in users.tf:
| Team / Function | Recommended roles |
| --- | --- |
| Platform Engineering / Platform Admin | ACCOUNTADMIN (CloudOps approval required) |
| Datalake Core Team | DATA_ADMIN, DBT_TRANSFORM_DEV, CENSUS_ROLE, AIRFLOW_ROLE, FORMATION_TEAM_ROLE, TRAINING_TEAM_ROLE |
| Core Services / Backend Dev | DATA_DEV, DBT_TRANSFORM_DEV |
| Community Management Dev | PRODUCT_DEV, DATA_DEV, DBT_TRANSFORM_DEV, COMMUNITY_MANAGEMENT_USER |
| Product Dev | PRODUCT_DEV, DBT_TRANSFORM_DEV, LF_DEVELOPER_R_ROLE |
| Product Support | VIEWER, PRODUCT_DEV, FORMATION_TEAM_ROLE, TRAINING_TEAM_ROLE, DBT_TRANSFORM_DEV, CENSUS_ROLE, AIRFLOW_ROLE |
| Architecture Team | DATA_DEV, DBT_TRANSFORM_DEV (+ additional as needed) |
| BizOps | VIEWER, PRODUCT_DEV, DBT_TRANSFORM_DEV |
| Marketing | VIEWER, HUBSPOT_INTEGRATION_ROLE, LF_DEVELOPER_R_ROLE, DB_HUBSPOT_INGEST_RO |
| Sales | VIEWER, LF_DEVELOPER_R_ROLE |
| Finance | VIEWER, LF_DEVELOPER_R_ROLE |
| Mentorship | VIEWER, LF_DEVELOPER_R_ROLE |
| Events | DBT_TRANSFORM_DEV |
| Formation Team | VIEWER, FORMATION_TEAM_ROLE |
| Training / Education | VIEWER, TRAINING_TEAM_ROLE |
| Data Privacy | DBT_TRANSFORM_DEV |
| Project / Community Management | VIEWER, PRODUCT_DEV, DBT_TRANSFORM_DEV |
| Read-only / general business | VIEWER, LF_DEVELOPER_R_ROLE |
Role descriptions (for explaining to users what they're getting):
| Role | What it grants |
| --- | --- |
| VIEWER | Read-only access to analytics data in Snowflake |
| DATA_ADMIN | Full administrative access to data pipelines and schemas |
| DATA_DEV | Data production access — read/write to data schemas |
| DBT_TRANSFORM_DEV | Access to run and develop dbt transformations in the ANALYTICS_DEV database |
| PRODUCT_DEV | Product engineering data access |
| LF_DEVELOPER_R_ROLE | Read access to LFX developer-facing data |
| CENSUS_ROLE | Integration access for the Census reverse ETL tool |
| AIRFLOW_ROLE | Access for Airflow-orchestrated pipelines |
| FORMATION_TEAM_ROLE | Access for Formation team workflows |
| TRAINING_TEAM_ROLE | Access for the training/certification team datasets |
| COMMUNITY_MANAGEMENT_USER | Community management platform data access |
| HUBSPOT_INTEGRATION_ROLE | HubSpot marketing tool integration access |
| ACCOUNTADMIN | Full Snowflake account administration — CloudOps only |
Generate a block like this and instruct the user to add it inside the users = { ... } map in
users.tf, under the appropriate team comment section:
"[email protected]" = {
roles = ["ROLE_ONE", "ROLE_TWO"]
full_name = "Full Name"
},
If CLI access was requested, add cli = "started":
"[email protected]" = {
roles = ["ROLE_ONE", "ROLE_TWO"]
cli = "started"
full_name = "Full Name"
},
The users map is organized by team sections with # comments. Tell the user:
Add your block under the comment that matches your team (e.g.,
# Product Dev,# Marketing Team, etc.). If your team doesn't have a section yet, add a new comment and your entry at the end of theusers = { ... }block, before the closing}.
service_accounts.tf)Service accounts are for applications, automation scripts, CI/CD pipelines, or integrations — not for humans logging in. They are given an IP allowlist and specific role grants.
Ask the user for:
MY_SERVICE
(this becomes the Snowflake username)local.ip_list_api_gwlocal.ip_list_k8s_clusters| Access pattern | Roles to include |
| --- | --- |
| Read analytics data | DB_ANALYTICS_RO (or DB_ANALYTICS_PLATINUM_RO, DB_ANALYTICS_GOLD_RO for tiered access) |
| Read all ingested data | DB_INGEST_ALL_RO |
| Write ingested data | A specific DB_*_INGEST_RW role (coordinate with CloudOps) |
| Use a dedicated warehouse | WH_<NAME>_USAGE (CloudOps creates warehouses — see note below) |
| Read raw data | DB_RAW_RO or DB_RAW_RW |
Warehouse note: If the service needs its own warehouse (e.g.,
WH_MY_SERVICE_USAGE), that warehouse must be created separately by CloudOps. Note this in the PR description so reviewers know to provision it. For existing shared warehouses, use the appropriateWH_*_USAGErole.
Add inside the legacy_service_accounts = { ... } map:
"MY_SERVICE" = {
roles = ["WH_MY_SERVICE_USAGE", "DB_ANALYTICS_RO"],
default_warehouse = "MY_SERVICE_WH", # omit if no dedicated warehouse
default_role = "MY_SERVICE", # omit if using default behavior
ip_list = ["1.2.3.4"], # or: local.ip_list_api_gw
},
Minimal example (no dedicated warehouse, no default role override):
"MY_SERVICE" = {
roles = ["DB_ANALYTICS_RO", "DB_INGEST_ALL_RO"],
ip_list = ["1.2.3.4", "5.6.7.8"],
},
A network policy will be automatically created from the ip_list — no additional changes needed.
Add the block inside the
legacy_service_accounts = { ... }local inservice_accounts.tf, before the closing}. Add a comment above it explaining what the service is.
After generating the configuration, walk the user through submitting it for review.
<!-- -->Not comfortable with git? That's completely fine. Share the configuration block above with a technical teammate (an engineer on your team, or post in the
#lfx-devopsSlack channel), and ask them to open a pull request on your behalf. The steps below are for people who will submit the change themselves via git.
For the AI: "PR" and "pull request" are the correct technical terms. When talking to non-engineers, say "change request" or "submit the change for review" instead. Explain that the review process exists so CloudOps can verify access is appropriate before it takes effect.
Create a working branch: Start from main with a descriptive name, e.g.,
add-user-jane-smith or add-sa-my-service
Make the edit: Add the generated configuration block to users.tf or
service_accounts.tf at the location described in the placement instruction above.
Save and sign the change: The Linux Foundation requires all commits to be DCO-signed (certifying the change is yours to contribute) and GPG-signed (a cryptographic identity check). Run:
git commit -S --signoff -m "Add Snowflake access for Jane Smith (Product Dev team)"
-S applies a GPG signature (cryptographic proof the commit came from you)--signoff appends a Signed-off-by: trailer, satisfying the Developer Certificate of Origin (DCO)Title your change request with a clear description, e.g.:
Add Snowflake access for Jane Smith (Product Dev team)Add MY_SERVICE service account for [purpose]Write a short description explaining:
Submit the change request to:
https://github.com/linuxfoundation/lfx-snowflake-terraform
Reviewers: The CloudOps team is automatically notified — no need to manually assign anyone
Once the change is approved and merged, access is applied automatically within a few minutes. New users will receive an activation email from Snowflake. Anyone who also needs command-line or programmatic access (dbt, SnowSQL) must complete the key setup described below.
Once the PR is merged and Terraform applies (usually within minutes):
If your account isn't active yet, wait a few minutes for CI/CD to complete and try again. If it still doesn't work after 15 minutes, reach out in the
#lfx-devopsSlack channel.
If the user's users.tf entry includes cli = "started" (meaning they need dbt build,
SnowSQL, or other programmatic access), they must set up RSA keypair authentication.
This replaces password/MFA for CLI connections and is required for dbt build to work
without repeated Duo push prompts.
Full instructions: lf-dbt README — SnowSQL Keypair Authentication Setup
Summary of steps:
Generate the private key:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8 -nocrypt
Generate the public key:
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
Store keys securely:
mkdir ~/.sf/ && chmod go-rwx ~/.sf/
cp rsa_key.p8 rsa_key.pub ~/.sf/
chmod go-rwx ~/.sf/rsa_key.*
Copy the public key contents (cat ~/.sf/rsa_key.pub, strip the header/footer lines,
remove line breaks) and send it to CloudOps — they will run:
ALTER USER DEV_YOUR_USERNAME SET RSA_PUBLIC_KEY='<your public key>';
The CLI username format is DEV_ + your email prefix in uppercase, e.g.,
DEV_JSMITH for [email protected].
Verify the key was registered by comparing fingerprints — see the full README for the verification commands.
Connect via SnowSQL using your private key:
snowsql -a <account> -u DEV_YOUR_USERNAME --private-key-path "${HOME}/.sf/rsa_key.p8"
For dbt-specific key/pair setup (profiles.yml configuration), see the dbt Snowflake setup guide.
Many people requesting Snowflake access — in marketing, sales, finance, leadership, and product — will not be familiar with git, Terraform, or pull requests. Adjust your language to match:
users.tf and commit it" — Do say: "Open the file, paste
this entry in, then save and submit the change."#lfx-devops, and they can submit it on your behalf."roles = [...] line with the new roles appended, and tell them to find their existing
entry and update that line.#lfx-devops Slack channel.development
LFX cross-repo topology and ownership router. Use when the task spans more than one LFX repo, asks "which repo owns X", "where does Y live", "what repos does this touch", "what consumes Z", or needs a peer-repo file path from inside a single repo. Loads per-repo configs when invoked from the LFX workspace root with a full task prompt; gives targeted cross-repo guidance when invoked from inside a single repo. Also answers LFX glossary and topology questions, and performs read-only discovery when the user asks whether a contract, API, event, field, workflow, or repo capability exists. Do not fire for single-repo implementation tasks where the active repo's own CLAUDE.md already governs (those belong to the repo's local skills). Do not fire for V2 platform composition, service classes, or cross-service handoffs (use `/lfx-skills:lfx-platform-architecture`), ITX wrapper plumbing (`/lfx-skills:lfx-itx-integration`), or Intercom app/Fin workflows (`/lfx-skills:lfx-intercom`).
tools
Create a new ticket in the LFXV2 Jira project (linuxfoundation.atlassian.net). Guides the user through picking an issue type (Bug, Story, Task, Epic), writing a concise summary, and capturing the requirement, feature, or bug context, collecting reproduction steps for bugs. Optionally attaches a parent epic, labels, or priority if the user provides them. Submits the ticket via Atlassian MCP and returns the URL. Use this skill any time someone asks to "create a Jira ticket", "open an LFXV2 ticket", "file a bug", "log a story", "write up a feature request", "draft a ticket", or any variation of submitting work into LFXV2.
testing
Combine multiple feature branches across repos into worktrees for end-to-end journey testing. Create, refresh, and teardown integration environments that merge branches from multiple repos.
devops
Guide users through requesting Snowflake access at the Linux Foundation. Handles two request types: (1) individual user access, adding or modifying an entry in users.tf in the lfx-snowflake-terraform repo, and (2) service account creation, adding an entry in service_accounts.tf. For each, the skill collects the necessary details, generates the exact Terraform HCL block to add, explains where to place it, and guides the user through the PR process. Use this skill any time someone asks about Snowflake access, permissions, user provisioning, service accounts, or making changes to the lfx-snowflake-terraform repo, including phrases like "get access to Snowflake", "add me to Snowflake", "need a service account", "request Snowflake permissions", "I need to query Snowflake", or "how do I get Snowflake access".