Skip to main content

Connect Third-Party LLMs

This tutorial connects SOAT to hosted LLM providers such as xAI, OpenAI, Anthropic, and Amazon Bedrock, showing how Secrets, AI Providers, Agents, and Sessions work together for externally hosted models.

Prerequisites

  • SOAT running locally. Follow Quick Start if needed.
  • CLI installed and configured, or SDK set up. See CLI or SDK.
  • Server is at http://localhost:5047.
  • Valid credentials for at least one third-party provider.
export SOAT_BASE_URL=http://localhost:5047

Step 1 — Log in as admin

Admin is the built-in superuser role. It bypasses policy evaluation entirely. See Users for full authentication and user management details.

ADMIN_TOKEN=$(soat login-user --username admin --password Admin1234! | jq -r '.token')
export SOAT_TOKEN=$ADMIN_TOKEN

Step 2 — Create a project

Every resource in SOAT lives inside a project. Create one to hold the provider and agent.

PROJECT_ID=$(soat create-project --name "Hosted LLM Demo" | jq -r '.id')
echo "PROJECT_ID: $PROJECT_ID"

Step 3 — Store provider credentials as secrets

Secrets store sensitive values encrypted; providers reference them by ID. Create one secret per provider credential set.

OPENAI_SECRET_ID=$(soat create-secret \
--project-id "$PROJECT_ID" \
--name "openai-api-key" \
--value "sk-<your-openai-key>" | jq -r '.id')

ANTHROPIC_SECRET_ID=$(soat create-secret \
--project-id "$PROJECT_ID" \
--name "anthropic-api-key" \
--value "sk-ant-<your-anthropic-key>" | jq -r '.id')

XAI_SECRET_ID=$(soat create-secret \
--project-id "$PROJECT_ID" \
--name "xai-api-key" \
--value "xai-<your-xai-key>" | jq -r '.id')

BEDROCK_SECRET_ID=$(soat create-secret \
--project-id "$PROJECT_ID" \
--name "bedrock-credentials" \
--value '{"accessKeyId":"<aws-access-key-id>","secretAccessKey":"<aws-secret-access-key>","sessionToken":"<optional-session-token>"}' | jq -r '.id')

Step 4 — Create provider records

Each provider points to a hosted model endpoint. See AI Providers for the full list of supported providers and configuration options. Choose the provider that matches your hosted model:

# OpenAI
OPENAI_PROVIDER_ID=$(soat create-ai-provider \
--project-id "$PROJECT_ID" \
--name "OpenAI" \
--provider "openai" \
--default-model "gpt-4.1-mini" \
--secret-id "$OPENAI_SECRET_ID" | jq -r '.id')

# Anthropic
ANTHROPIC_PROVIDER_ID=$(soat create-ai-provider \
--project-id "$PROJECT_ID" \
--name "Anthropic" \
--provider "anthropic" \
--default-model "claude-3-5-sonnet-latest" \
--secret-id "$ANTHROPIC_SECRET_ID" | jq -r '.id')

# xAI
XAI_PROVIDER_ID=$(soat create-ai-provider \
--project-id "$PROJECT_ID" \
--name "xAI" \
--provider "xai" \
--default-model "grok-3-mini" \
--secret-id "$XAI_SECRET_ID" | jq -r '.id')

# Bedrock (secret value can be JSON credentials, region can live in config)
BEDROCK_PROVIDER_ID=$(soat create-ai-provider \
--project-id "$PROJECT_ID" \
--name "Bedrock" \
--provider "bedrock" \
--default-model "anthropic.claude-3-5-sonnet-20240620-v1:0" \
--secret-id "$BEDROCK_SECRET_ID" \
--config '{"region":"us-east-1"}' | jq -r '.id')

Step 5 — Create an agent

Once the provider exists, create an agent that points at it.

AGENT_ID=$(soat create-agent \
--project-id "$PROJECT_ID" \
--ai-provider-id "$OPENAI_PROVIDER_ID" \
--name "Hosted Assistant" \
--instructions "You are a helpful assistant using a hosted LLM." \
| jq -r '.id')

Step 6 — Start a conversation

Create a session and send a message through the provider-backed agent.

SESSION_ID=$(soat create-session --agent-id "$AGENT_ID" | jq -r '.id')

soat add-session-message \
--session-id "$SESSION_ID" \
--message "Summarize why model routing matters in one paragraph."

What's next

  • Provider rotation: Create multiple provider records in the same project and switch agents between them.
  • Custom gateways: Use the gateway or custom provider types when you have an OpenAI-compatible upstream.
  • Production secrets: Rotate provider secrets by creating a new secret and updating the provider's secret_id.