Skip to content

Security: Snowflake-Labs/schemachange

Security

SECURITY.md

Schemachange Security Best Practices

Overview

This document provides security guidance for configuring schemachange, with a focus on protecting sensitive credentials and following industry best practices.


⚠️ Critical Security Warnings

1. NEVER Store Passwords in YAML Files

❌ DON'T DO THIS:

# BAD - Never store passwords in YAML!
config-version: 2

snowflake:
  account: myaccount.us-east-1
  user: my_user
  password: "my_secret_password"  # ❌ INSECURE!

Why? YAML configuration files are often:

  • Committed to version control (Git, SVN, etc.)
  • Shared across teams
  • Backed up to multiple locations
  • Visible in CI/CD logs

2. NEVER Use CLI Arguments for Secrets

❌ DON'T DO THIS:

# BAD - CLI arguments are visible in process list and shell history!
schemachange deploy --snowflake-password "my_secret_password"  # ❌ INSECURE!

Why?

  • Visible in ps output to all users
  • Stored in shell history (.bash_history, .zsh_history)
  • Logged by monitoring tools
  • Visible to system administrators

Note: schemachange intentionally blocks --snowflake-private-key-passphrase via CLI for this reason.

3. Secure connections.toml File Permissions

βœ… DO THIS:

# Set restrictive permissions on connections.toml
chmod 600 ~/.snowflake/connections.toml

# Verify permissions (should show -rw-------)
ls -l ~/.snowflake/connections.toml

What schemachange checks:

  • Warns if file is readable by group or others
  • Warns if file is writable by group or others
  • Provides actionable remediation commands

πŸ”’ Recommended Authentication Methods

⚠️ SNOWFLAKE AUTHENTICATION REQUIREMENTS (2024-2025):

  • Service users: Password authentication is NOT SUPPORTED. Must use PAT, Key Pair (JWT), OAuth, or WIF.
  • Human users (CLI/CI/CD): PREFERRED to use PAT, Key Pair (JWT), or OAuth. Password+MFA is allowed but not recommended for automation.
  • Human users (Interactive): Password+MFA is acceptable for interactive sessions but use PAT/Key Pair for automation.

Priority Order (Most Secure to Least Secure)

  1. βœ… BEST: JWT/Private Key Authentication (Service Accounts & Automation)

    • REQUIRED for service accounts (password not supported)
    • PREFERRED for all automation (human or service accounts)
    • Most secure - no password exposure
    • Key-based authentication
    export SNOWFLAKE_ACCOUNT="myaccount.us-east-1"
    export SNOWFLAKE_USER="service_account"
    export SNOWFLAKE_AUTHENTICATOR="snowflake_jwt"
    export SNOWFLAKE_PRIVATE_KEY_FILE="~/.ssh/snowflake_key.p8"
    export SNOWFLAKE_PRIVATE_KEY_FILE_PWD="key_passphrase"  # Only if key is encrypted
    export SNOWFLAKE_ROLE="DEPLOYMENT_ROLE"
    export SNOWFLAKE_WAREHOUSE="DEPLOYMENT_WH"
    
    schemachange deploy
  2. βœ… PREFERRED for Automation: Programmatic Access Tokens (PATs)

    • PREFERRED for human users in CLI/CI/CD scenarios
    • Supported for service users (alternative to JWT)
    • Token rotation support
    • Bypasses MFA prompts for automation
    export SNOWFLAKE_ACCOUNT="myaccount.us-east-1"
    export SNOWFLAKE_USER="human_user"
    export SNOWFLAKE_PASSWORD="<your_pat_token>"  # PAT token, NOT your login password
    export SNOWFLAKE_ROLE="DEPLOYMENT_ROLE"
    export SNOWFLAKE_WAREHOUSE="DEPLOYMENT_WH"
    
    schemachange deploy
  3. βœ… GOOD: connections.toml (With Proper Permissions)

    • Centralized credential management
    • Multiple profile support
    • Must have restrictive file permissions (0600)
    • Use PAT tokens for human users, JWT for service accounts
    # ~/.snowflake/connections.toml (chmod 600)
    [production]
    account = "myaccount.us-east-1"
    user = "service_account"
    authenticator = "snowflake_jwt"
    private_key_file = "~/.ssh/snowflake_key.p8"
    # private_key_file_pwd = "passphrase"  # Only if key is encrypted
    role = "DEPLOYMENT_ROLE"
    warehouse = "DEPLOYMENT_WH"
  4. βœ… ACCEPTABLE: OAuth with Token File

    • For SSO integration
    • Token file should have restrictive permissions
    export SNOWFLAKE_AUTHENTICATOR="oauth"
    export SNOWFLAKE_TOKEN_FILE_PATH="~/.snowflake/oauth_token.txt"
    chmod 600 ~/.snowflake/oauth_token.txt
    
    schemachange deploy
  5. ⚠️ NOT RECOMMENDED for Automation: Password + MFA

    • NOT SUPPORTED for service accounts
    • Allowed for human users in interactive sessions
    • NOT RECOMMENDED for CLI/CI/CD automation (requires manual MFA input)
    • Use PAT or Key Pair instead for automation
    # ⚠️ Works for human users but requires MFA prompts (not suitable for automation)
    export SNOWFLAKE_PASSWORD="my_login_password"
    schemachange deploy  # Will prompt for MFA (blocks automation)
  6. ❌ DEPRECATED: Password-Only (No MFA)

    • NOT SUPPORTED - Snowflake requires MFA for password authentication
    • Use PAT, Key Pair, or OAuth instead

πŸ“Š Parameter Source Decision Tree

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Which configuration source should I use?                β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            β–Ό
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚  Is it a      β”‚
                    β”‚  SECRET?      β”‚
                    β”‚  (password,   β”‚
                    β”‚  token, etc.) β”‚
                    β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                β”‚                       β”‚
             YESβ”‚                       β”‚NO
                β”‚                       β”‚
                β–Ό                       β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Use ENVIRONMENT       β”‚   β”‚ What's the use      β”‚
    β”‚ VARIABLE or           β”‚   β”‚ case?               β”‚
    β”‚ connections.toml      β”‚   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
    β”‚ (with chmod 600)      β”‚              β”‚
    β”‚                       β”‚              β”‚
    β”‚ βœ… SNOWFLAKE_PASSWORD β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ βœ… connections.toml   β”‚    β”‚                   β”‚
    β”‚                       β”‚  Same for              Different per
    β”‚ ❌ NEVER CLI          β”‚  all environments      environment
    β”‚ ❌ NEVER YAML         β”‚    β”‚                   β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β–Ό                   β–Ό
                          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                          β”‚ Use YAML     β”‚   β”‚ Use CLI args β”‚
                          β”‚ Config File  β”‚   β”‚ or ENV vars  β”‚
                          β”‚              β”‚   β”‚              β”‚
                          β”‚ Examples:    β”‚   β”‚ Examples:    β”‚
                          β”‚ β€’ root-folderβ”‚   β”‚ CLI:         β”‚
                          β”‚ β€’ log-level  β”‚   β”‚ -d DATABASE  β”‚
                          β”‚ β€’ vars       β”‚   β”‚              β”‚
                          β”‚              β”‚   β”‚ ENV:         β”‚
                          β”‚ Priority:    β”‚   β”‚ SNOWFLAKE_   β”‚
                          β”‚ CLI > ENV >  β”‚   β”‚ DATABASE     β”‚
                          β”‚ YAML         β”‚   β”‚              β”‚
                          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Legend:
βœ… = Recommended
⚠️ = Use with caution
❌ = Never use

🎯 Configuration Priority

Schemachange uses a layered configuration approach:

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  1. CLI Arguments          (Highest Priority)            β”‚
β”‚     --snowflake-account myaccount                        β”‚
β”‚     Wins in conflicts                                    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            ↓ overrides
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  2. Environment Variables                                β”‚
β”‚     SNOWFLAKE_ACCOUNT=myaccount                          β”‚
β”‚     βœ… Best for secrets                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            ↓ overrides
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  3. YAML Configuration File                              β”‚
β”‚     snowflake.account: myaccount                         β”‚
β”‚     βœ… Best for non-secret settings                      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            ↓ overrides
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  4. connections.toml       (Lowest Priority)             β”‚
β”‚     account = "myaccount"                                β”‚
β”‚     βœ… Good for secrets with proper permissions          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ” Secrets Management by Scenario

Scenario 1: Local Development

βœ… Recommended Approach - Human User with MFA:

# Use connections.toml with PAT token
cat > ~/.snowflake/connections.toml << EOF
[dev]
account = "dev-account.us-east-1"
user = "dev_user"
password = "<your_pat_token>"  # PAT token, NOT your login password
role = "DEVELOPER"
warehouse = "DEV_WH"
EOF

chmod 600 ~/.snowflake/connections.toml

# Deploy using connection profile
schemachange deploy -C dev

Why?

  • βœ… Convenient for local development
  • βœ… Credentials don't leak to version control
  • βœ… No MFA prompts during deployment (unlike password+MFA)

How to get a PAT:

  1. Log into Snowflake UI
  2. Go to user preferences
  3. Generate new Programmatic Access Token
  4. Copy and use in place of password

Alternative - Password+MFA (Not Recommended for Automation):

# ⚠️ Acceptable for interactive sessions but will prompt for MFA
export SNOWFLAKE_PASSWORD="my_login_password"
schemachange deploy -C dev  # Will prompt for MFA code each time

Scenario 2: CI/CD Pipeline (GitHub Actions, Jenkins, etc.)

βœ… BEST: JWT with Service Account (Recommended):

# .github/workflows/deploy.yml
- name: Deploy with Schemachange
  env:
    SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
    SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_SERVICE_ACCOUNT }}  # Service account
    SNOWFLAKE_AUTHENTICATOR: "snowflake_jwt"
    SNOWFLAKE_PRIVATE_KEY_FILE: ${{ secrets.SNOWFLAKE_PRIVATE_KEY_FILE }}
    SNOWFLAKE_PRIVATE_KEY_FILE_PWD: ${{ secrets.SNOWFLAKE_KEY_PASSPHRASE }}
    SNOWFLAKE_ROLE: DEPLOYMENT_ROLE
    SNOWFLAKE_WAREHOUSE: DEPLOYMENT_WH
    SNOWFLAKE_DATABASE: ${{ matrix.database }}
  run: |
    # Write private key to temp file
    echo "${{ secrets.SNOWFLAKE_PRIVATE_KEY }}" > /tmp/snowflake_key.p8
    chmod 600 /tmp/snowflake_key.p8

    schemachange deploy --config-folder ./migrations

    # Clean up
    rm -f /tmp/snowflake_key.p8

Alternative - PAT with Human Account (Less Preferred):

- name: Deploy with Schemachange
  env:
    SNOWFLAKE_ACCOUNT: ${{ secrets.SNOWFLAKE_ACCOUNT }}
    SNOWFLAKE_USER: ${{ secrets.SNOWFLAKE_USER }}
    SNOWFLAKE_PASSWORD: ${{ secrets.SNOWFLAKE_PAT }}  # PAT token
    SNOWFLAKE_ROLE: DEPLOYMENT_ROLE
    SNOWFLAKE_WAREHOUSE: DEPLOYMENT_WH
  run: |
    schemachange deploy --config-folder ./migrations

Why JWT or PAT for automation:

  • βœ… Service accounts cannot use passwords - JWT or PAT required
  • βœ… Human accounts (automation) - JWT or PAT preferred (no MFA prompts)
  • βœ… More secure - no password exposure, better audit trail
  • βœ… Key rotation without Snowflake user changes (JWT) or token rotation (PAT)

Scenario 3: Production Deployment (Automated)

βœ… Recommended Approach - JWT with Service Account:

# 1. Generate key pair (one-time setup)
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out snowflake_key.p8 -nocrypt

# 2. Configure Snowflake user with public key
# (Upload public key to Snowflake user)

# 3. Store private key securely
chmod 600 snowflake_key.p8

# 4. Deploy
export SNOWFLAKE_ACCOUNT="prod-account.us-east-1"
export SNOWFLAKE_USER="deployment_service_account"
export SNOWFLAKE_AUTHENTICATOR="snowflake_jwt"
export SNOWFLAKE_PRIVATE_KEY_FILE="./snowflake_key.p8"

schemachange deploy

Why?

  • βœ… No password needed
  • βœ… Key rotation without Snowflake user changes
  • βœ… Better audit trail

Scenario 4: Multi-Environment Deployment

βœ… Recommended Approach - YAML + ENV Override:

Base Configuration (YAML - Checked into Git):

# config/base-config.yml
config-version: 2

schemachange:
  root-folder: ./migrations
  log-level: INFO
  create-change-history-table: true

snowflake:
  # Non-sensitive defaults
  role: DEPLOYMENT_ROLE
  warehouse: DEPLOYMENT_WH

  # DO NOT include:
  # - account (varies by environment)
  # - user (varies by environment)
  # - password (NEVER in YAML!)

Environment-Specific Configuration (Environment Variables):

Option 1 - JWT with Service Account (Recommended):

# Production
export SNOWFLAKE_ACCOUNT="prod-account.us-east-1"
export SNOWFLAKE_USER="prod_service_account"
export SNOWFLAKE_AUTHENTICATOR="snowflake_jwt"
export SNOWFLAKE_PRIVATE_KEY_FILE="~/.ssh/snowflake_prod.p8"
export SNOWFLAKE_DATABASE="PRODUCTION_DB"

schemachange deploy --config-folder ./config

# Staging
export SNOWFLAKE_ACCOUNT="staging-account.us-east-1"
export SNOWFLAKE_USER="staging_service_account"
export SNOWFLAKE_AUTHENTICATOR="snowflake_jwt"
export SNOWFLAKE_PRIVATE_KEY_FILE="~/.ssh/snowflake_staging.p8"
export SNOWFLAKE_DATABASE="STAGING_DB"

schemachange deploy --config-folder ./config

Option 2 - PAT with Human Account:

# Production
export SNOWFLAKE_ACCOUNT="prod-account.us-east-1"
export SNOWFLAKE_USER="prod_deployment"
export SNOWFLAKE_PASSWORD="<prod_pat_token>"  # PAT, not password
export SNOWFLAKE_DATABASE="PRODUCTION_DB"

schemachange deploy --config-folder ./config

πŸ›‘οΈ Security Checklist

Before Deployment

  • No passwords/secrets in YAML files - Check with grep -r password *.yml
  • No passwords/secrets in version control - Use .gitignore for sensitive files
  • connections.toml has 600 permissions - ls -l ~/.snowflake/connections.toml
  • Private keys have 600 permissions - ls -l ~/.ssh/snowflake_key.p8
  • Using JWT or PAT for service accounts - Password auth is not supported
  • Using JWT or PAT for automation - Preferred over password+MFA (no interactive prompts)
  • Test with schemachange verify - Before running deploy

For CI/CD

  • Secrets in secret manager - Not in pipeline YAML
  • Using JWT or PAT - Preferred (passwords not supported for service accounts, not recommended for human users)
  • Minimal permissions - Role has only required privileges
  • Service account preferred - Or use PAT/JWT with human account (avoid password+MFA for automation)
  • Audit logging enabled - Track all deployments
  • Separate environments - Dev/Staging/Prod isolation

Regular Maintenance

  • Rotate credentials quarterly - PATs, passwords, keys
  • Review access logs - Check for unauthorized access
  • Update dependencies - Keep schemachange updated
  • Audit connections.toml - Remove unused profiles

🚨 What to Do If Credentials Are Leaked

If Committed to Version Control:

  1. Immediately rotate the credentials in Snowflake
  2. Remove from Git history using git filter-branch or BFG Repo-Cleaner
  3. Force push after cleaning (coordinate with team)
  4. Notify security team if in production
  5. Review access logs for unauthorized usage
# Remove sensitive file from Git history
git filter-branch --force --index-filter \
  "git rm --cached --ignore-unmatch config-with-secrets.yml" \
  --prune-empty --tag-name-filter cat -- --all

# Force push (after team coordination!)
git push origin --force --all

If Exposed via CLI/Logs:

  1. Rotate credentials immediately
  2. Clear shell history: history -c && history -w
  3. Clear application logs containing the credentials
  4. Review who had access to the system
  5. Implement prevention measures (use environment variables)

πŸ” Verification and Testing

Use schemachange verify Command

# Test your configuration and connectivity
schemachange verify

# What it shows:
# βœ“ Configuration sources used
# βœ“ Masked sensitive parameters (password, tokens)
# βœ“ Connection test results
# βœ“ Session details after successful connection

Example Output:

================================================================================
Schemachange Configuration Verification
================================================================================

Snowflake Connection Configuration:
  Account: myaccount.us-east-1
  User: deployment_user
  Role: DEPLOYMENT_ROLE
  Warehouse: DEPLOYMENT_WH
  Password: ****** (set)

Testing Snowflake Connectivity...
────────────────────────────────────────────────────────────────────────────

βœ“ Connection Successful!

Connection Details:
  Session ID: 123456789
  Snowflake Version: 8.25.0

πŸ“š Additional Resources


πŸ’‘ Quick Reference

Authentication Method by Use Case

Use Case Recommended Method Why
Service Accounts JWT (private key) or PAT βœ… REQUIRED - passwords not supported
CI/CD Automation JWT (private key) or PAT βœ… PREFERRED - no interactive MFA prompts
Human Users (Automation) PAT or JWT βœ… PREFERRED - bypasses MFA prompts
Human Users (Interactive) Password+MFA or PAT ⚠️ Password+MFA allowed but PAT preferred
Local Development PAT via connections.toml βœ… Convenient + no MFA prompts
Legacy (Unsupported) Password-only (no MFA) ❌ BLOCKED by Snowflake

Parameter Source Recommendations

Credential Type CLI ENV YAML connections.toml Recommended
PAT Token ❌ βœ… ❌ βœ… (chmod 600) ENV or connections.toml
Private Key File (private_key_file) ❌ βœ… ❌ βœ… (chmod 600) ENV or connections.toml
Private Key Password (private_key_file_pwd) ❌ βœ… ❌ βœ… (chmod 600) ENV or connections.toml
OAuth Token ❌ ❌ ❌ Use token-file-path Token file
Account βœ… βœ… βœ… βœ… YAML or ENV
User βœ… βœ… βœ… βœ… YAML or ENV
Role βœ… βœ… βœ… βœ… YAML
Warehouse βœ… βœ… βœ… βœ… YAML
Database βœ… βœ… βœ… βœ… ENV or CLI

Remember: Security is not a feature, it's a requirement! πŸ”’

There aren’t any published security advisories