Security model

SnowClaw is designed to be safe to run in your Snowflake account by default. Every security decision below is on by default — you don't have to opt in.

Network egress control

All outbound traffic is deny-by-default. Only explicitly approved hosts (managed via snowclaw network) get Snowflake network rules and external access integrations. The container cannot reach the internet unless you allow it.

Setup auto-detects required hosts from your provider, channel, and tool selections, shows you the diff, and prompts before applying.

SPCS ingress control

Snowflake handles TLS termination and authentication on the single public endpoint (port 18789). There are no open ports or exposed services beyond what SPCS declares — the ingress surface is managed entirely by Snowflake's infrastructure.

The Cortex proxy sidecar is internal only. It does not bind to any public port.

File permissions at runtime

The Docker entrypoint runs as root, locks down config files, and drops to the node user (UID 1000) before starting OpenClaw:

  • openclaw.jsonroot:node 440 (read-only for gateway, no write for agent)
  • credentials/root:node 440
  • secrets.jsonroot:node 440
  • workspace/ and skills/node:node (writable)
  • .snowflake/connections.toml → owned by node so Cortex can read/write connection state

The agent process cannot modify its own config or credentials. Two independent layers enforce this: OS permissions and the tools.fs.workspaceOnly: true policy in the generated openclaw.json, which restricts agent file tools to the workspace directory.

Role separation

  • Admin role (default: SYSADMIN) — used by the CLI for infrastructure operations: create database, secrets, compute pool, network rules, external access integrations, service.
  • Service role (default: SNOWCLAW_SERVICE_ROLE) — used by the container at runtime, with only the privileges required to read secrets and write to the stage. Must already exist in your Snowflake account before setup.

The container never runs under your admin role.

Secret masking

The Cortex proxy sidecar scans all outbound LLM messages and replaces known secret values with [REDACTED:VAR_NAME]. Credentials never reach the model, even if the agent tries to include them in a prompt.

Variables listed in SNOWCLAW_MASK_VARS (auto-generated from your .env) are added to the masking set. By default, all token and API key variables are masked. You can extend this list manually.

The masker uses two shape-specific walkers — one for OpenAI-style messages[].content + tool calls, and one for Anthropic-style messages[].content blocks + top-level system. Both preserve cache_control markers and other block metadata.

User-managed secrets

Every KEY=value in .env becomes an individual Snowflake SECRET object at deploy time — never baked into the Docker image. CUSTOM_-prefixed variables are auto-registered with no extra config. Secrets are mounted into the container as env vars at runtime.

Secrets are never retrievable — Snowflake stores them as encrypted blobs. .env is your source of truth.