Snowflake-Labs/sfutils-pat
Python
Captured source
source ↗Snowflake-Labs/sfutils-pat
Language: Python
Stars: 0
Forks: 0
Open issues: 0
Created: 2026-03-31T12:31:49Z
Pushed: 2026-05-08T04:05:18Z
Default branch: main
Fork: no
Archived: no
README:
Snowflake PAT (Programmatic Access Token) Manager
Create and manage Snowflake Programmatic Access Tokens (PATs) for service users. Handles the full lifecycle: service user creation, authentication policies, network policies, PAT generation, rotation, and local configuration.
PAT secrets are stored only in the OS keychain (via Python `keyring`), using a service string aligned with snowflake-connector-python conventions. The tool does not write PAT material to `.env` or other files. It may update .env with `SA_USER` and `SA_ROLE` only.
8+ manual steps → single command.
Prerequisites
- Snowflake CLI (
snow) installed and configured - Python 3.12+
- Task (optional, for task-based workflow)
Install
uv sync # or: pip install .
For running tests: uv sync --extra dev
Quick Start
# Create PAT with local IP network policy (most secure) sfutils-pat create --user my_sa --role demo_role --db my_db # Allow GitHub Actions (hybrid policy: custom CIDRs + Snowflake-managed rule; see Network Policy) sfutils-pat create --user ci_sa --role ci_role --db my_db --allow-gh # Skip network setup (if managed separately by sfutils-networks) sfutils-pat create --user my_sa --role demo_role --db my_db --skip-network # Preview all SQL without executing sfutils-pat create --user my_sa --role demo_role --db my_db --dry-run # Rotate an existing PAT (keeps all policies) sfutils-pat rotate --user my_sa --role demo_role # Verify PAT works (loads token from keyring only) sfutils-pat verify --user my_sa --role demo_role # Print PAT to stdout once (insecure; appears in logs) — optional sfutils-pat create --user my_sa --role demo_role --db my_db --print # Remove PAT and all associated objects (per-step prompts; use --yes to skip) sfutils-pat remove --user my_sa --db my_db sfutils-pat remove --user my_sa --db my_db --yes
Keyring layout
The PAT is stored with:
- `keyring` service (first argument):
{HOST}:{ACCOUNT}:{SA_USER}:SFUTILS-PAT:{PAT_NAME} All segments are uppercased. HOST comes from snow connection test --format json when present; otherwise the first segment is NA. ACCOUNT is the connection account identifier from the same JSON. Legacy installs may still have secrets under SNOW-UTILS-PAT; the CLI reads that label as a fallback and deletes both on remove.
- `keyring` username (second argument):
SA_USERuppercased (same pattern as the Snowflake Python connector for cached tokens).
The same tuple is used for create, rotate, verify, show-pat, and keyring cleanup on remove.
What create Does
1. Creates a service user (if not exists) 2. Creates a network rule and policy with your allowed CIDRs (unless --skip-network). With --allow-gh, the policy also references Snowflake’s managed GitHub Actions rule (Snowflake-managed network rules); GitHub IPs are no longer copied from the GitHub meta API into your rule. 3. Assigns the network policy to the user 4. Creates an authentication policy (PAT-only, with network policy enforcement). Default expiry profile is 7 days default / 30 days max (hardened baseline). For Snowflake’s platform-style limits, pass --default-expiry-days 15 --max-expiry-days 365. 5. Generates or rotates the PAT in Snowflake 6. Stores the PAT in the OS keyring (not on disk) 7. Updates .env with `SA_USER` and `SA_ROLE` only (strips obsolete raw-PAT lines from older layouts) 8. Verifies the connection by loading the PAT from the keyring and running a test query (unless --skip-verify)
JSON output (-o json) never includes the raw token; it includes redaction and keyring metadata (e.g. keyring_service, account, host).
--print may print the PAT to stdout after storage (default: off). It cannot be combined with -o json.
verify and show-pat
- `verify` reads the PAT only from the keyring. It does not accept
--password, PAT-in-env, or.envsecrets for the token. - `show-pat` asks for confirmation (with a warning) before printing the PAT to stdout; use
--yesonly when you must script it and accept log exposure.
Task Workflow
task create SA_USER=my_sa SA_ROLE=demo_role SF_UTILS_DB=my_db task create SA_USER=ci_sa SA_ROLE=ci_role SF_UTILS_DB=my_db -- --allow-gh task no-rotate SA_USER=my_sa SA_ROLE=demo_role SF_UTILS_DB=my_db task remove SA_USER=my_sa SF_UTILS_DB=my_db
Integration testing
Opt-in checks against a real Snowflake account and the OS keychain are documented in [docs/it/README.md](docs/it/README.md). task it runs unit tests (pytest) then shell smoke (scripts/it/smoke.sh). For manual full lifecycle IT, use the same `.env` keys as daily CLI use (SA_USER, SA_ROLE, SF_UTILS_DB; legacy SNOW_UTILS_DB is still accepted); see the runbook.
CLI Commands
| Command | Description | |---------|-------------| | create | Create/rotate PAT for a service user (full setup) | | rotate | Rotate an existing PAT (keeps policies intact) | | verify | Test PAT connection; PAT loaded from keyring only | | show-pat | Print PAT from keyring to stdout after confirm (or --yes; insecure) | | remove | Remove PAT and associated objects (your account network policy and {db}.NETWORKS.{user} rule; auth policy); does not drop SNOWFLAKE.NETWORK_SECURITY managed rules; per-step confirmation unless --yes; non-interactive runs require --yes; clears keyring entry when connection metadata is available |
Environment Variables
| Variable | Description | |----------|-------------| | SA_USER | Service account username | | SA_ROLE | Role restriction for the PAT | | SA_ADMIN_ROLE | Admin role for creating policies (default: ACCOUNTADMIN) | | SF_UTILS_DB | Database for PAT objects (network rules, auth policies); legacy SNOW_UTILS_DB still read by CLI and check-setup | | PAT_NAME | Snowflake PAT object name (default: {USER}_PAT) | | DOT_ENV_FILE | Used by Taskfile examples; CLI uses…
Excerpt shown — open the source for the full document.
Notability
notability 3.0/10Routine new utility repo by Snowflake.