> ## Documentation Index
> Fetch the complete documentation index at: https://gateway.forceaisecurity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Snowflake Cortex Agent (A2A)

> Register a Snowflake Cortex Agent in the ForceAI Gateway over A2A, with PAT or key-pair JWT auth.

The gateway bridges a Snowflake Cortex Agent to the A2A protocol. You register the agent once, and ForceAI signs each call (PAT or key-pair JWT), invokes the Cortex `agents/{name}:run` REST API, and returns the reply. This guide covers the Snowflake-side setup, the two auth modes, and the registration payload

## Prerequisites (Snowflake side)

<Steps>
  <Step title="A deployed Cortex Agent">
    Create the agent in Snowsight or with `CREATE AGENT`. Find its fully-qualified name with `SHOW AGENTS IN ACCOUNT`; you need the `database`, `schema`, and agent `name`
  </Step>

  <Step title="The account URL">
    Run `SELECT SYSTEM$ALLOWLIST();` and take the `host` of type `SNOWFLAKE_DEPLOYMENT_REGIONLESS` (or `SNOWFLAKE_DEPLOYMENT`), then prefix `https://`. Do not use the bare account-locator host; it returns an HTML "File not found" and the call will fail
  </Step>

  <Step title="Grant the calling role access">
    Grant the role behind your PAT or key-pair user: `USAGE` on the database, schema, and agent; `USAGE` and `READ` on the semantic-model stage; `USAGE` on the warehouse; and `SELECT` on the tables the agent queries
  </Step>

  <Step title="Put the warehouse in the agent spec">
    The Analyst tool runs SQL using the warehouse named in the agent spec's `tool_resources.<analyst_tool>.execution_environment`, not the user's default warehouse. Set it there or Analyst queries fail
  </Step>
</Steps>

<Note>
  PAT auth also requires a **network policy** on the user or account that allows the gateway's egress IP, or Snowflake rejects the token with error `390432`. Key-pair JWT auth does not need a network policy, which is why it is the better choice for a hosted gateway
</Note>

## Auth modes

<Tabs>
  <Tab title="PAT (simplest)">
    Create a Programmatic Access Token for the calling user. The gateway sends it as `Authorization: Bearer <pat>` with `X-Snowflake-Authorization-Token-Type: PROGRAMMATIC_ACCESS_TOKEN`. Requires a network policy covering the gateway IP
  </Tab>

  <Tab title="Key-pair JWT (recommended for hosting)">
    Generate an RSA key pair and register the public key: `ALTER USER <user> SET RSA_PUBLIC_KEY='<base64 pubkey>'`. The gateway mints a short-lived RS256 JWT per call. No network policy needed. Supply the unencrypted PKCS8 private key PEM at registration
  </Tab>
</Tabs>

## Register the agent

<CodeGroup>
  ```bash PAT mode theme={null}
  curl -X POST https://YOUR_GATEWAY_DOMAIN/v1/agents \
    -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" \
    -d '{
      "agent_name": "sales-analyst",
      "agent_card_params": {
        "protocolVersion": "0.3", "name": "Sales Analyst",
        "description": "Snowflake Cortex sales analyst agent",
        "url": "https://myorg-myaccount.snowflakecomputing.com/",
        "capabilities": { "streaming": false },
        "defaultInputModes": ["text"], "defaultOutputModes": ["text"],
        "skills": [{ "id": "analyze", "name": "Analyze", "description": "sales analytics", "tags": ["snowflake"] }]
      },
      "forceai_params": {
        "model": "snowflake_cortex_agents/SALES_ANALYST_AGENT",
        "custom_llm_provider": "snowflake_cortex_agents",
        "snowflake_account_url": "https://myorg-myaccount.snowflakecomputing.com",
        "snowflake_database": "SALES_DB",
        "snowflake_schema": "PUBLIC",
        "snowflake_agent_name": "SALES_ANALYST_AGENT",
        "snowflake_auth_mode": "pat",
        "snowflake_pat": "<PAT>"
      }
    }'
  ```

  ```bash Key-pair JWT mode theme={null}
  "forceai_params": {
    "model": "snowflake_cortex_agents/SALES_ANALYST_AGENT",
    "custom_llm_provider": "snowflake_cortex_agents",
    "snowflake_account_url": "https://myorg-myaccount.snowflakecomputing.com",
    "snowflake_database": "SALES_DB",
    "snowflake_schema": "PUBLIC",
    "snowflake_agent_name": "SALES_ANALYST_AGENT",
    "snowflake_auth_mode": "keypair_jwt",
    "snowflake_account_locator": "MYORG-MYACCOUNT",
    "snowflake_user": "FORCEAI_SVC",
    "snowflake_private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----"
  }
  ```
</CodeGroup>

Or use the dashboard: **Agentic -> Agents -> Add New Agent**, pick **Snowflake Cortex Agents**, and fill the same fields

### Fields

<ParamField path="snowflake_account_url" type="string" required>
  The regionless deployment host from `SYSTEM$ALLOWLIST()`, with `https://`
</ParamField>

<ParamField path="snowflake_database / snowflake_schema / snowflake_agent_name" type="string" required>
  The fully-qualified Cortex agent. `snowflake_agent_name` also fills the model template `snowflake_cortex_agents/{name}`
</ParamField>

<ParamField path="snowflake_auth_mode" type="string" default="pat">
  `pat` or `keypair_jwt`
</ParamField>

<ParamField path="snowflake_pat" type="string">
  Required in PAT mode
</ParamField>

<ParamField path="snowflake_account_locator / snowflake_user / snowflake_private_key" type="string">
  Required in key-pair mode. Private key is an unencrypted PKCS8 PEM
</ParamField>

## Approve and invoke

```bash theme={null}
# Approve
curl -X POST https://YOUR_GATEWAY_DOMAIN/v1/agents/{agent_id}/approve \
  -H "Authorization: Bearer $ADMIN_KEY" -H "Content-Type: application/json" -d '{"reason":"onboard"}'

# Invoke (reload the gateway first on docker-compose)
curl -X POST https://YOUR_GATEWAY_DOMAIN/v1/a2a/{agent_id}/message/send \
  -H "Authorization: Bearer $AGENT_KEY" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":"1","method":"message/send",
       "params":{"message":{"role":"user","parts":[{"kind":"text","text":"Top 5 customers by revenue?"}]}}}'
```

## Troubleshooting

| Snowflake error       | Cause                                                                           |
| --------------------- | ------------------------------------------------------------------------------- |
| `390432`              | PAT rejected; add a network policy covering the gateway IP, or use key-pair JWT |
| `399513`              | Missing `USAGE` grants on the database / schema / agent                         |
| `399504`              | Missing stage grants (`USAGE` + `READ`) on the semantic-model stage             |
| HTML "File not found" | Wrong host; use the regionless deployment host from `SYSTEM$ALLOWLIST()`        |
