Authentication
User login and API key management.
User Authentication
Web Application Login
URL: app.twig.so
Methods:
Email/Password: Standard authentication, JWT session token (7-day expiry)
SSO: SAML 2.0 or OAuth 2.0 redirect to IdP
OAuth: Google, Microsoft (redirect flow)
Flow:
Enter credentials or click OAuth provider button
Server validates, issues JWT
JWT stored in httpOnly cookie
All requests include cookie automatically
Session Details
Storage: httpOnly secure cookie (name:
twig_session)Expiry: 7 days (refreshed on each request)
Refresh: Automatic (silent refresh 1 hour before expiry)
Logout: DELETE
/api/auth/logout, cookie cleared
Observable behavior: Logged out after 7 days of inactivity. Login again to restore session.
API Authentication
API keys authenticate programmatic requests.
Generate API Key
Log in to app.twig.so
Settings → API Keys
Click Generate New Key
Fill form:
Name: e.g., "Production API" (required)
Scopes: Check boxes for Read, Write, Execute, Admin
Environment: Live or Test
Click Generate
Result: Key displayed once (format: twigsk_live_a1b2c3... or twigsk_test_x1y2z3...). Copy immediately.
Storage: Store in environment variable:
Use API Key
Include in Authorization header:
Response (success):
Response (auth failure):
API Key Best Practices
Storage:
✅ Environment variables (
TWIG_API_KEY=...)✅ Secrets manager (AWS Secrets Manager, HashiCorp Vault)
❌ Hardcoded in source code
❌ Committed to git repos
❌ Shared in Slack/email
Key Management:
Use separate keys for dev/staging/prod environments
Rotate every 90 days (generate new, update apps, delete old)
Delete unused keys immediately
Monitor usage: Settings → API Keys → [Key Name] → Usage tab
Permissions:
Grant minimum required scopes
Production keys: Execute only (no Write/Admin)
CI/CD keys: Read only for testing
API Key Scopes
Read
GET /agents, /data-sources, /interactions
Analytics, monitoring dashboards
Write
POST/PUT/DELETE agents, data sources
Admin tools, setup automation
Execute
POST /query, /chat
Production apps, user-facing features
Admin
All endpoints including org settings
Full admin access, avoid for apps
Observable behavior: API returns 403 Forbidden if scope insufficient:
External API Keys
Store third-party service credentials for custom model usage.
Supported Providers
OpenAI: For bring-your-own-key (BYOK) usage, avoids Twig's shared pool
Anthropic: For Claude models
Custom LLM: Any OpenAI-compatible API endpoint
Add External Key
Settings → External API Keys
Click Add Key
Fill form:
Provider: Dropdown (OpenAI, Anthropic, Custom)
API Key: Paste key
Endpoint (Custom only): e.g.,
https://your-llm.com/v1
Click Save
Security: Keys encrypted at rest (AES-256), never logged
Usage: Agent Configuration → Model → Select "Use my OpenAI key" (dropdown)
Observable behavior: Queries use your key instead of Twig's. Billing goes to your OpenAI/Anthropic account, not Twig.
SSO Integration
SAML/OAuth for enterprise user authentication.
Supported Protocols
SAML 2.0: Okta, Azure AD, Google Workspace, OneLogin, Auth0
OAuth 2.0: Google Workspace, Microsoft 365
OIDC: OpenID Connect providers
Setup Process
Prerequisites: Enterprise plan, domain verified
Steps:
Email [email protected] with:
IdP type (Okta, Azure AD, etc.)
SSO metadata URL or XML file
Attribute mapping (email → NameID)
Twig configures SSO (1-2 business days)
Test with 1-2 pilot users
Enable for org: Settings → Authentication → Enforce SSO (toggle)
Post-setup:
Users go to app.twig.so → "Sign in with SSO"
Enter email → redirected to IdP → authenticated → redirected back
Session managed as normal (7-day expiry)
Failure scenarios:
Invalid SAML assertion → "Authentication failed" error page
Email not in allowed domains → "Unauthorized domain" error
See SSO Setup Guide for IdP-specific instructions.
OAuth for Data Connectors
Third-party service authentication (Google Drive, Slack, etc.).
OAuth Flow
Data → Add Data Source → Select connector (e.g., Google Drive)
Click Connect
Redirected to Google OAuth consent screen
Grant permissions (read files)
Redirected to app.twig.so
Access token stored, data source status: "Connected"
Tokens:
Access token: Short-lived (1 hour), used for API requests
Refresh token: Long-lived (no expiry), auto-refreshes access token
Storage: Encrypted in PostgreSQL
oauth_tokenstable
Revoke access: Data → [Source] → Settings → Disconnect (deletes tokens from Twig and revokes at provider)
Observable failure: If refresh token invalid (user revoked in Google), data source status: "Connection failed". Reconnect required.
Security
Token Security
Encryption:
API keys: Hashed with bcrypt (cost factor: 12) before storage
OAuth tokens: AES-256-GCM encryption at rest
Session JWTs: HMAC-SHA256 signed, verified on each request
Transport:
TLS 1.3 required (TLS 1.2 minimum)
HTTPS only (HTTP redirects to HTTPS)
HSTS header enabled (max-age: 31536000)
Verification: All API keys checked against PostgreSQL api_keys table on each request (cached in Redis for 5 minutes)
Rate Limiting
Limits by scope:
Execute: 100 requests/minute
Write: 10 requests/minute
Read: 200 requests/minute
Admin: 50 requests/minute
Implementation: Token bucket algorithm, enforced at API gateway (Cloudflare Workers)
Response when exceeded:
HTTP status: 429 Too Many Requests
Headers:
Custom limits: Enterprise plan can request increases. Contact support with use case.
IP Allowlisting
Available on: Enterprise plan only
Setup: Settings → Security → IP Allowlist → Add range
Format: CIDR notation (e.g., 192.168.1.0/24, 10.0.0.5/32)
Enforcement: API gateway blocks requests from IPs not in list (returns 403 Forbidden)
Audit: All blocked attempts logged: Settings → Security → Access Logs
Troubleshooting
Error: Invalid API Key
Symptom: API returns 401 with:
Diagnostic steps:
Verify key format: Must start with
twigsk_live_ortwigsk_test_Check header:
Authorization: Bearer twigsk_live_...(note "Bearer" prefix)Settings → API Keys → verify key not deleted
Common mistakes:
Missing "Bearer" prefix in Authorization header
Using test key (
twigsk_test_) against production APIExtra whitespace in key
Fix: Regenerate key if lost, update header format.
Error: Token Expired
Symptom: Web UI redirects to login after period of inactivity
Cause: Session JWT expired (7-day TTL)
Fix: Log in again. Session auto-refreshes if you use UI within 7 days.
API users: This doesn't apply to API keys (no expiry).
Error: Insufficient Permissions
Symptom: API returns 403 with:
Diagnostic steps:
Settings → API Keys → [Your Key] → check Scopes section
Verify required scope in error message
Check if key belongs to correct organization
Fix:
Delete key, generate new one with correct scopes
Or: Contact org admin to regenerate with proper scopes
Error: Rate Limit Exceeded
Symptom: 429 response after burst of requests
Diagnostic steps:
Check response headers:
X-RateLimit-Limit: Your limit (e.g., 100)X-RateLimit-Reset: Unix timestamp when reset occurs
Calculate wait time:
reset_timestamp - current_timestamp
Fix:
Implement exponential backoff in your client
Reduce request frequency
Enterprise: Request limit increase from support
SSO Login Fails
Symptom: Redirected to error page after IdP authentication
Diagnostic steps:
Check error message (e.g., "Invalid SAML assertion", "Email domain not allowed")
Settings → Authentication → SSO Config → verify IdP metadata URL still valid
Test SAML response with browser dev tools (Network tab)
Common issues:
Email attribute not mapped correctly (NameID must contain email)
SAML certificate expired at IdP
User's email domain not in allowed list
Fix: Contact [email protected] with SAML response XML for diagnosis.
Next Steps
Quick Start Guide - Create your first agent
REST API Reference - API endpoint documentation
Security Best Practices - Secure your deployment
Last updated

