Enterprise controls for AI Agents live at the workspace level (Settings) and per agent (Audit tab, Guardrails, Deploy).
Workspace Settings
| Section | API | Purpose |
|---|---|---|
| AI Agent production | GET/PATCH /v1/workspaces/agent-ops | rpm_cap_per_agent (0 = unlimited in playground; public default 60 if unset), eval_pass_threshold (0–1, 0 = off) |
| AI Agent LLM (BYOK) | GET/PATCH /v1/workspaces/agent-llm | Optional per-workspace provider, model, base URL, encrypted API key |
| Workspace secrets | GET/POST /v1/secrets | Fernet-encrypted values for {{secret:NAME}} in tools |
Per-agent rate limits
check_agent_rpm enforces requests per minute per agent ID on public embed and playground. Uses Redis INCR when Redis is available; falls back to in-process counters on single-node dev.
Eval CI gate on publish
When eval_pass_threshold > 0, publish runs every AiAgentEval against the draft config, judges pass/fail, and stores results on the new AiAgentVersion. Publish returns 422 if pass rate is below threshold.
Audit trail
- AiAgentAuditEvent table — dedicated rows for agent admin actions.
- Dual-write to workspace audit_log for compliance search.
- Studio: /app/agents/{slug}/audit — last 100 events.
- API: GET /v1/ai-agents/{slug}/audit-events?limit=50
- Tool handler updates store before_state / after_state on handler_kind and config.
PII, drafts, and RLS
- PII — REDACT guardrails also redact transcript and tool_args at persist (ai_agent_pii.py).
- Drafts — wizard drafts purged after 30 days on API startup.
- RLS — Postgres policies on all ai_agent_* tables; public embed sets app.ai_agent_public_token GUC.
Encryption & KMS
Workspace secrets use Fernet (CONVOSHIP_SECRETS_KEY). Optional CONVOSHIP_KMS_KEY_ID + boto3 extra enables aws: ciphertext via AWS KMS. BYOK API keys use encrypt_at_rest with the same hooks.
# Optional real KMS
pip install -e '.[kms]' # in studio-api
export CONVOSHIP_KMS_KEY_ID=alias/your-keyDefault guardrails at create
New agents receive five seeded guardrails (AUTH, LIMIT, REDACT, ESCALATE, BUDGET) via ai_agent_defaults.py — no GET side effects. Customize on the Guardrails tab.