# Agent Filesystem Source: https://docs.cotool.ai/agents/agent-filesystem Keep an agent's files and workspace between runs By default, an agent starts each run from a clean slate. **Agent Filesystem** changes that: when it's enabled, the agent's workspace **persists between runs**, so files, notes, and tool state carry forward instead of resetting every time. ## Viewing Files The files in an agent's workspace are viewable directly in the UI, where you can browse the workspace, preview files, and download them. ## Persisting Files Across Runs Turning on **Agent Filesystem** keeps an agent's workspace between runs. This is useful when an agent should: * Build on prior work instead of starting over each run * Reuse reference files, lookup tables, or templates you upload once * Keep packages or scripts it installed available for later runs ### Enabling It **1. Open the agent** Go to **Agents** and open the agent you want to update. **2. Turn on Agent Filesystem** Find the **Agent Filesystem** card and flip the toggle to **On**. On the agents and detections list pages, you can also use **Learn more** on the Agent Filesystem banner to enable it for several agents at once. **3. Manage the files** Once enabled, the agent gets a persistent workspace panel where you can browse, upload, download, and delete files. ### Managing the Persistent Workspace From the workspace panel you can: * **Upload** files with the Upload button or by dragging them onto the panel * **Download** any file, or a whole folder as a zip * **Delete** files and folders you no longer need * **Preview** text, markdown, and image files without downloading Files you upload and files the agent creates share the same workspace, so the agent can pick up where it left off. > [!NOTE] > > Use the persistent workspace for files that should stick around, like > reference data or reusable scripts. Keep large, run-specific scratch output > (such as raw logs) out of it so the workspace stays tidy. ## Agent Filesystem vs File Attachments These are related but separate: | Use this for... | Agent Filesystem | File Attachments | | - | - | - | | Files the agent creates during a run | Yes | No | | Files that carry across runs | Yes (when enabled) | No | | Files you upload to a single chat message | No | Yes | See [File Attachments](/chat/file-attachments) for uploading files directly to a chat message. ## Passing result files to a parent agent Built-in subagents share their parent's sandbox. A separately configured agent called through `agentTools` has its own sandbox and persistent workspace. Both named agents and dynamic subagents can publish a result file with `sandbox_publishOutput`. This tool is available only during named-child executions and dynamic subagents (including those delegated by a user chat), not top-level runs or user chats: ```json theme={null} { "path": "/workspace/inventory.json", "name": "inventory.json" } ``` This snapshots the file's exact bytes into durable storage. The child should check that publication succeeded and keep its final response short. It does not need to print, copy, or base64-encode the file into its response. Changes to the source file after publication do not change the snapshot; publishing the same name again replaces it. When the child completes successfully, Cotool copies its published files into `/workspace/.cotool/agent-results//outputs/` in the parent sandbox. The parent receives the paths, byte lengths, and SHA-256 hashes in the tool result (`outputFiles` in the stored agent result). It can read those files directly with code. Cotool also saves `final-message.txt` and, when available, `structured-output.json` in the run's result directory. Large inline responses are previews; these files contain the complete stored results. Publication supports regular files within the child's workspace mounts, up to 16 named files and 10 MiB total per child run. Symlinks are rejected. Final-message and structured-output files each have a separate 10 MiB limit. Structured output remains model-generated; saving it preserves the generated result, not an independently computed source file. Published snapshots survive worker restarts and do not require the child's sandbox to remain alive. Delivery retries use the same destination paths and verify file lengths and hashes. A failed or incomplete publication must be successfully republished; otherwise the handoff fails. After delivery retries are exhausted, the parent receives a tool error rather than a successful result. Parents should require a successful handoff before sending notifications or updating durable state; partial destination files from a failed transfer must not be used. This does not provide atomic notifications or locking between runs. # Context Documents Source: https://docs.cotool.ai/agents/context-documents Providing agents with context from Google Docs and Notion **Context documents** let you give agents access to reference material stored in Google Docs or Notion. This is perfect for runbooks, policies, procedures, contact lists, and other static knowledge that agents should reference. ## What Are Context Documents? Context documents are external documents (Google Docs or Notion pages) that: * Are automatically fetched and loaded at agent runtime * Provide reference material the agent can consult * Are maintained by humans outside of Cotool * Stay in sync with your source of truth Think of context documents as the agent's **reference library** - manuals, runbooks, and knowledge bases it can consult. ## Examples > [card] Runbooks & Procedures > > Standard operating procedures for common scenarios **Example**: "How to > respond to ransomware alerts" > [card] Known False Positives > > Lists of known false positives to avoid re-investigating **Example**: > "Approved admin tools that trigger alerts" > [card] Contact & Escalation Info > > Who to contact for different scenarios **Example**: "Security team > on-call rotation" > [card] Policies & Requirements > > Compliance requirements and organizational policies **Example**: "Data > handling requirements for PII" > [card] Glossary & Terminology > > Org-specific terms and definitions **Example**: "Our product names and > what they do" > [card] Historical Context > > Background on recurring issues or past incidents **Example**: "Known > infrastructure quirks" ## Adding Context Documents **1. Prepare Your Document** Create a Google Doc or Notion page with the reference material **Tips**: * Use clear headings and structure - Keep focused on one topic per document - Update regularly **2. Make Document Accessible** **For Google Docs**: Share with "Anyone with link can view" **For Notion**: Make page public or share with Cotool integration **3. Add to Agent** In agent configuration: 1. Click "Add Context Document" 2. Select source (Google Docs or Notion) 3. Paste document URL 4. Add description (what's in this doc) **4. Test** Use Builder to verify agent can access and use the document ## Document Format Best Practices ### Structure Use clear hierarchy with headings: ```markdown theme={null} # Security Alert Runbook ## Critical Alerts ### Ransomware Detection - **First steps**: Isolate affected endpoints immediately - **Evidence to collect**: Memory dump, process list, network connections - **Escalation**: Page on-call security manager ### Data Exfiltration - **First steps**: Block outbound connections ... ``` ### Keep It Scannable Agents work best with structured, scannable content: **Good**: ```markdown theme={null} ## Known False Positives **IT Admin Tools**: - `C:\AdminTools\PSExec.exe` - Used for remote management - `C:\Scripts\Backup.ps1` - Nightly backup script - Contact: it-team@company.com if questions **Developer Tools**: - Any activity from `devops_service_account` - Debuggers in development environment ``` **Bad (too narrative)**: ```markdown theme={null} So there's this tool that the IT team uses sometimes, it's called PSExec and it's located in the AdminTools folder, and sometimes it triggers alerts but that's okay... ``` ### Use Lists and Tables Agents parse structured data better than prose: **Tables for reference data**: | Team | On-Call | Email | Escalation | | - | - | - | - | | Security | @john | [sec@co.com](mailto:sec@co.com) | CISO | | IT Ops | @jane | [ops@co.com](mailto:ops@co.com) | IT Director | **Lists for procedures**: 1. Check alert severity 2. Search logs for related activity 3. If confirmed threat, isolate endpoint 4. Notify security team ### Include Examples Show the agent what good looks like: ```markdown theme={null} ## Jira Update Format Use this format: **Good example**: Severity: Critical Evidence: VirusTotal 15/70 vendors flagged as ransomware. Observed file encryption behavior. Recommendation: Isolate endpoint immediately. **Bad example**: This looks bad, probably should isolate. ``` ## Document Size Limits > [!NOTE] > > **Limits**: - Max 50KB per document (plain text equivalent) - Up to 10 > documents per agent - Total context budget: \~200KB (includes prompt + docs) If you hit limits: * Split large docs into focused topics * Use summaries instead of full detail * Split fast-changing reference data into smaller, easier-to-refresh documents ## Sync and Freshness **How syncing works**: * Documents are fetched fresh for each agent run * Changes in Google Docs/Notion appear immediately * No manual sync needed **Best practices**: * Keep docs updated as procedures change * Note last update date in document * Review docs quarterly for stale info ## Real-World Examples ### Example 1: False Positive List **Google Doc: "SentinelOne Known False Positives"** ```markdown theme={null} # Known False Positives - SentinelOne Alerts Last Updated: 2025-10-15 ## IT Administration Tools ### PSExec (Sysinternals) - **Hash**: a4b2c3d4e5f6... - **Path**: C:\AdminTools\PSExec.exe - **Reason**: Used for remote system administration - **Approved by**: Ticket CHG-1234 - **Contact**: IT Ops team ### PowerShell Scheduled Tasks - **Pattern**: PowerShell scripts in C:\Scripts\ - **Schedule**: Daily at 2am - **Reason**: Automated backups and maintenance - **Contact**: DevOps team ## Development Tools ### Visual Studio Debugger - **Process**: vshost.exe, devenv.exe - **Environment**: Dev workstations only - **Reason**: Legitimate development activity ## When to Ignore These FPs - Only on approved systems (see list below) - During business hours (or scheduled maintenance) - If signature hash matches exactly If activity deviates (wrong time, wrong system), investigate further. ## Approved Systems for IT Tools - ADMIN-01 through ADMIN-05 - DEVOPS-VM-\* ``` **How agent uses it**: ```markdown theme={null} In system prompt: Before classifying an alert as malicious, check the context document "Known False Positives" to see if this is approved activity. If the file hash, path, and system match the FP list, classify as False Positive and reference the ticket number. ``` ### Example 2: Contact Directory **Google Doc: "Security Team Contacts"** ```markdown theme={null} # Security Team Contacts ## On-Call Rotation **Primary**: - This week: John Smith (@john in Slack) - Email: john@company.com - Phone: +1-555-0100 **Backup**: - This week: Jane Doe (@jane) - Email: jane@company.com ## Escalation Paths ### Critical Incidents (SEV-1) 1. Page on-call via PagerDuty 2. Post to #security-incidents 3. Escalate to CISO: ciso@company.com ### High Severity (SEV-2) 1. Slack on-call in #security-alerts 2. Create incident ticket 3. If no response in 15 min, escalate to backup ### Medium/Low 1. Create ticket 2. Post in #security-alerts 3. No immediate page needed ## Team Specializations - **Malware/Endpoint**: John, Sarah - **Network/Infrastructure**: Mike, Lisa - **Cloud Security**: Alex, Jordan - **AppSec**: Chris, Taylor ## External Contacts - **Legal/Privacy**: legal@company.com - **Compliance**: compliance@company.com - **PR/Comms** (for breaches): pr@company.com ``` **How agent uses it**: ```markdown theme={null} In system prompt: When escalating alerts, reference the "Security Team Contacts" document for current on-call and escalation procedures. Use the severity-appropriate escalation path. ``` ### Example 3: Alert Response Runbook **Notion Page: "Ransomware Response Runbook"** ```markdown theme={null} # Ransomware Detection Response ## Immediate Actions (First 5 Minutes) 1. **Isolate affected endpoint(s)** - Use EDR containment feature - Block at network level if needed 2. **Stop spread** - Disable affected user account - Block suspicious IPs at firewall 3. **Alert** - Page on-call security - Post in #security-incidents - Create SEV-1 incident ticket ## Evidence Collection (First 15 Minutes) Gather: - Memory dump (if possible before isolation) - Process list and network connections - Recent file modifications - Authentication logs ## Analysis Steps 1. **Identify ransomware family** - Check file indicators in VirusTotal - Look for ransom note - Identify encryption patterns 2. **Determine scope** - How many systems affected? - What data encrypted? - When did encryption start? 3. **Find patient zero** - First infected system - Initial infection vector (phishing, vuln, etc.) ## Recovery - Do NOT pay ransom without exec approval - Restore from backups (verify backup integrity first) - Check with legal before any external communication ## Post-Incident - Full incident report required - Review and update detections - Conduct lessons learned ``` **How agent uses it**: ```markdown theme={null} In system prompt: If you detect ransomware indicators: 1. Immediately reference "Ransomware Response Runbook" 2. Follow the immediate action steps 3. Include runbook steps in your Jira update 4. Escalate per runbook escalation procedure ``` ## Prompt Instructions for Context Docs In your system prompt, tell the agent about context docs: ```markdown theme={null} ## Reference Materials You have access to these context documents: 1. **"Known False Positives"**: List of approved tools that trigger alerts. Check this before classifying as malicious. 2. **"Security Team Contacts"**: Current on-call rotation and escalation procedures. Use for all escalations. 3. **"Alert Response Runbooks"**: Procedures for different alert types. Follow these steps closely. When referencing these docs, cite them in your output: "Per the FP list, this is an approved IT tool (ticket CHG-1234)" ``` ## Troubleshooting > [accordion] Agent can't access document > > **Check**: - Is document URL correct? - Is document shared publicly or > with Cotool? - For Google Docs: Is link sharing enabled? - For Notion: > Is page published or shared with integration? > [accordion] Agent not using document info > > **Check**: - Is system prompt clear about when to use document? - Test > in Builder - can you see document in context? - Is document too large > (check size limits)? - Is relevant info buried deep in document? > **Fix**: Make documents more scannable with clear headings > [accordion] Document is too large > > **Fix**: - Split into multiple focused documents - Remove unnecessary > detail - Use summaries instead of full text > [accordion] Stale information in document > > **Fix**: - Update source document (changes appear immediately) - Add > "Last Updated" date in document - Set calendar reminders to review > quarterly ## Best Practices > [accordion] One Topic Per Document > > Don't create one massive document with everything. Split by topic: - > Separate FP list from contacts - Separate runbooks by alert type - One > procedure per document > [accordion] Keep Documents Updated > > Stale docs lead to bad agent decisions. Review regularly: - Update > contacts when team changes - Update procedures when processes change - > Note last review date in document > [accordion] Use Templates > > Create document templates for consistency: - Standard runbook format - > Standard contact info format - Makes docs easier for agents to parse > [accordion] Test After Updates > > When you update a critical document, test agent in Builder to verify it > uses new info correctly > [accordion] Document Your Documents > > In agent description, note which context docs it uses and why: "Uses FP > list to avoid re-investigating known tools" # Creating Agents Source: https://docs.cotool.ai/agents/creating-agents Step-by-step guide to creating your first agent ## Prerequisites Before creating an agent, you should: **1. Connect Integrations** Authenticate the tools your agent will use (Jira, Splunk, SentinelOne, etc.) Navigate to **Settings > Integrations** and connect relevant services **2. Define the Use Case** Be clear about what the agent should do: * What problem does it solve? * What triggers it? * What tools does it need? * What output should it produce? **3. (Optional) Prepare Context Docs** If your agent needs reference material (runbooks, policies, FP lists), have those ready in Google Docs or Notion ## Creation Methods You can create agents in three ways: > [card] From Chat (Recommended) > > Convert a successful chat session > [card] From Scratch (Advanced) > > Build a custom agent with full control > [card] From Template > > Start with a pre-built template > [!NOTE] > > **Prefer to manage agents as code?** You can also define response agents as > YAML in your own GitHub repo and let Cotool sync them in. See [Response > Agents as Code](/agents/response-agents-as-code). ## Method 1: Create From Scratch **1. Navigate to Agents** Click **Agents** in the sidebar, then **Create Agent** **2. Basic Information** Fill in the basics: **Name**: Short, descriptive name (e.g., "SentinelOne Alert Triage") **Description**: What does this agent do? Who uses it? **3. Write System Prompt** This is the core of your agent. Write clear instructions about: * The agent's role * What it should do * When to use which tools * How to format output > [card] > > **Prompt Engineering Guide** → Learn how to write effective prompts > > [Open](/core-concepts/system-prompts) **4. Select Tools** Choose which tools the agent can use: * Browse by category (SIEM, EDR, Ticketing, etc.) * Or search by name * Grant only what's needed for the task **Tip**: Start with fewer tools, add more as needed **5. Attach Skills (Optional)** Add reusable skills when part of the workflow should stay consistent across multiple agents: * Standard investigation procedures * Output formats and reporting templates * Reusable enrichment or triage playbooks Cotool will warn you if a selected skill requires tools this agent does not have. > [card] > > **Learn about Skills** -> Reusable instructions and resources for agents > > [Open](/agents/skills) **6. Add Context Documents (Optional)** Link Google Docs or Notion pages that provide reference information: * Runbooks and procedures * Known false positive lists * Contact directories * Policy documents The agent will have access to these during execution **7. Configure Settings** **Planning Mode**: * `never`: Agent acts immediately (faster, good for simple tasks) * `auto`: Agent decides if planning is needed * `always`: Agent always creates a plan first (better for complex tasks) **Max Tool Calls**: Limit how many tools the agent can call (default: 25) **Timeout**: Maximum execution time (default: 5 minutes) **8. Save and Test** Click **Create Agent**. You'll be taken to the agent detail page. Next, test it using the **Builder** interface! ## Method 2: Create From Template Templates are pre-built agents for common use cases: **1. Browse Templates** Click **Agents** > **Create Agent** > **From Template** **2. Choose Template** Select from templates **3. Customize** Templates come with: * Pre-written system prompt (edit to fit your needs) * Recommended tools (add/remove as needed) * Example context documents Customize these for your environment **4. Configure Integrations** Ensure you have the required integrations connected (template will list them) **5. Test & Deploy** Use Builder to test with real data, then set up triggers > [card] > > **Browse Use Cases** → See common agent patterns > > [Open](/use-cases/alert-triage) ## Method 3: Create From Chat If you've had a successful chat session, convert it to an agent: **1. Complete Chat Session** Use the Chat interface to work through your use case **2. Review the Session** Make sure the chat achieved the desired outcome with good tool usage **3. Click 'Create Agent'** In the chat interface, click **Create Agent from Chat** **4. Auto-Generated Prompt** Cotool analyzes the chat session and generates: - System prompt based on your conversation - Tool list from what was used - Planning mode based on complexity **5. Refine and Save** Review the generated prompt, make adjustments, and save > [card] > > **Learn More** → Creating agents from chat sessions > > [Open](/chat/creating-agents-from-chat) ## What Happens After Creation? Once you create an agent: > [tab] Test in Builder > > Use the Builder to: - Test with sample inputs - Refine the system prompt > > * Verify tool usage - Check output format **Don't skip this step!** > Testing before deploying prevents issues. > [tab] Set Up Triggers > > Make your agent autonomous: - **Jira trigger** - Runs when tickets are > created/updated - **Slack trigger** - Runs when mentioned in Slack - > **Cron trigger** - Runs on a schedule - **Email trigger** - Runs when > emails arrive > \[card] View all trigger types [Open](/agents/triggering-agents) > [tab] Monitor Performance > > Track your agent's executions: - Success rate - Average duration - User > feedback - Evaluation scores > [tab] Iterate & Improve > > Agents improve over time: - Review failed executions - Incorporate user > feedback - Use AI suggestions to refine prompts - A/B test different > versions > > > [card] > > > > Learn about optimization > > > > [Open](/improving-agents/ai-suggested-improvements) ## Common Patterns ### Pattern: Alert Enrichment Agent ``` Goal: Automatically enrich security alerts Tools Needed: - get_sentinelone_alert - search_splunk - virustotal_check_hash - update_jira_ticket Trigger: Jira issue created (type=Security Alert) Prompt Focus: - Extract indicators from alert - Search for related activity - Check threat intelligence - Summarize findings in ticket ``` ### Pattern: Scheduled Report Agent ``` Goal: Weekly access review report Tools Needed: - list_okta_users - list_aws_iam_roles - list_google_workspace_groups - send_slack_message Trigger: Cron (every Monday 9am) Prompt Focus: - Gather user/permission data - Identify anomalies or stale accounts - Generate formatted report - Post to #security-reports ``` ### Pattern: On-Demand Research Agent ``` Goal: Ad-hoc investigations via chat Tools Needed: - search_splunk - list_sentinelone_alerts - get_okta_user - virustotal_* Trigger: Chat (no automatic trigger) Prompt Focus: - Help analyst investigate indicators - Provide context and enrichment - Suggest next steps - Generate summary reports ``` ## Agent Configuration Options When creating an agent, you can configure: > [accordion] Model Selection > > Choose which LLM powers your agent: > > * **General-purpose hosted model**: Strong reasoning, tool use, and instruction following > * **High-speed/cost-optimized hosted model**: Good fit for simpler tasks or high volume > * **Custom or self-hosted**: Bring your own fine-tuned or on-prem model > [accordion] Planning Mode > > * **never**: Agent acts immediately (faster, 1-2 tool calls) > * **auto**: Agent decides if planning helps (balanced) > * **always**: Agent creates detailed plan first (complex multi-step tasks) > > **Tip**: Start with `auto`, adjust based on results > [accordion] Tool Access > > Grant only necessary tools. Over-granting tools: > > * Increases token usage (all tools described to LLM) > * Can confuse the agent > * Creates security risk > > **Best Practice**: Start minimal, add tools as needed > [accordion] Skills > > Skills let you attach reusable instructions and supporting files to multiple agents. > > Use them for: > > * Standard operating procedures > * Shared report formats > * Repeatable investigation workflows > > **Best Practice**: Put reusable workflow logic in skills, and keep the main system prompt focused on the agent's overall role. > [accordion] Context Documents > > Link up to 10 documents per agent. Documents are loaded into context at runtime. > > **Size Limits**: > > * 50KB per document (plain text equivalent) > * Agent has \~200KB total context window > > **Tip**: Keep docs focused and concise > [accordion] Evaluation Criteria > > Define how this agent should be evaluated: > > * Accuracy of findings > * Completeness of investigation > * Clarity of output > * Appropriate tool usage > > Used for automated scoring and prompt optimization ## Tips for Success > [!NOTE] > > **Start Small**: Create a focused agent that does one thing well. It's > easier to expand scope than to debug an overly complex agent. > [!NOTE] > > **Test Extensively**: Use Builder to test many scenarios before deploying > triggers. This catches issues early. > [!NOTE] > > **Monitor Early**: Check first 10-20 executions closely. This is when you'll > discover prompt issues or missing tools. > [!NOTE] > > **Iterate Quickly**: Don't aim for perfection on first try. Deploy, observe, > improve. Agents get better over time. ## Troubleshooting Common Issues > [accordion] Agent doesn't use the right tools > > **Fix**: Make tool usage more explicit in system prompt: "Always start > by calling `get_sentinelone_alert` to fetch full alert details" > [accordion] Output format is inconsistent > > **Fix**: Provide a template in the prompt: "Format your response exactly > like this: \[template]" > [accordion] Agent is too slow > > **Fix**: - Reduce number of granted tools - Set planning mode to `never` > > * Remove verbose context documents - Check if tools themselves are slow > (API performance) > [accordion] Agent makes wrong decisions > > **Fix**: - Add decision criteria to prompt - Provide examples of > good/bad decisions - Check if context documents have necessary info - > Verify tool outputs are correct # Planning Modes Source: https://docs.cotool.ai/agents/planning-modes Understanding agent planning strategies **Planning mode** controls whether and how agents create execution plans before taking action. This is a powerful feature that can significantly improve performance on complex tasks. ## What is Planning? When planning is enabled, the agent: 1. **Analyzes the task** before taking any action 2. **Creates a step-by-step plan** of what it will do 3. **Executes the plan** methodically 4. **Adjusts the plan** if needed based on results Without planning, agents act more reactively, deciding their next step after each tool call. ## Planning Modes Cotool offers three planning modes: > [tab] Never > > **No planning** - Agent acts immediately and reactively. **Behavior:** - > Agent decides next action after each tool call - More exploratory, > adaptive - Faster for simple tasks **Best for:** - Simple 1-3 tool call > workflows - Well-defined, linear tasks - Speed-critical applications - > Agents with very clear instructions **Example use case:** - Look up user > in Okta → Post result to Slack - Check file hash in VirusTotal → Update > Jira with score > [tab] Auto (Recommended) > > **Agent decides** whether planning would help. **Behavior:** - Agent > evaluates task complexity - Plans for multi-step workflows - Acts > immediately for simple tasks - Balances speed and thoroughness **Best > for:** - Most agents (this is the default) - Mixed complexity workloads > > * When you're unsure **Example use case:** - Alert triage (may or may > not need planning depending on alert type) - User requests (varies in > complexity) > [tab] Always > > **Always plan** before executing. **Behavior:** - Agent always creates > detailed plan first - More structured, methodical - Better for complex > multi-step tasks - Slightly slower but more reliable **Best for:** - > Complex investigations (5+ tool calls) - Multi-system coordination - > Tasks requiring specific sequencing - High-stakes workflows **Example > use case:** - User offboarding (deprovisioning across 10+ systems) - > Incident response coordination - Compliance audits with specific > procedures ## How Planning Works ### Without Planning (Reactive) ``` Task: "Tell me about the IP 8.8.8.8" Step 1: Agent thinks "I should check IP_lookup" → calls ip_lookup Step 3: Agent has enough info → responds ``` **Pros:** Low latency, good for extremely simple tasks or when you know the task is simple and well-defined **Cons:** May take inefficient paths, might miss important steps ### With Planning (Deliberate) ``` Task: "Investigate suspicious login from user@example.com" Planning Phase: Agent creates plan: 1. Get user details from Okta (roles, groups, last login) 2. Get authentication events from past 24h 3. Extract all source IPs from those events 4. Check IPs against threat intel 5. Determine if activity is anomalous 6. Summarize findings Execution Phase: Agent follows plan systematically, adjusting if needed ``` **Pros:** Thorough, systematic, less likely to miss steps **Cons:** Slightly slower, less exploratory ## Choosing the Right Mode > [accordion] Choose 'Never' When... > > * Task is simple and well-defined > * Speed is critical > * Agent instructions are very explicit about steps > * Typical run has 1-3 tool calls > > **Examples:** > > * Lookup and post result > * Simple enrichment (check one indicator) > * Status checks > [accordion] Choose 'Auto' When... > > * Task complexity varies > * You want balance of speed and thoroughness > * You're unsure which mode is best > * Agent handles diverse scenarios > > **Examples:** > > * Alert triage (varies by alert type) > * User requests via Slack > * General-purpose copilot agents > > **This is the recommended default.** > [accordion] Choose 'Always' When... > > * Task is consistently complex (5+ steps) > * Order of operations matters > * Missing a step would be problematic > * Thoroughness > speed > > **Examples:** > > * User offboarding workflows > * Compliance audits > * Multi-system incident response > * Scheduled reports with many data sources ## Real-World Examples ### Example 1: Alert Triage (Auto) ``` Agent configuration: - Planning Mode: Auto - Typical complexity: 3-7 tool calls Simple alert (agent skips planning): - Get alert details → check hash in VirusTotal → update ticket - 3 tool calls, completes in 10 seconds Complex alert (agent plans): - Creates plan: get alert → search logs → check indicators → correlate → determine severity → update ticket - 8 tool calls, completes in 45 seconds Result: Agent adapts to situation automatically ``` ### Example 2: User Lookup (Never) ``` Agent configuration: - Planning Mode: Never - Task: Always the same pattern Workflow: - Get Okta user details - Post to Slack Result: Fast, simple, no need for planning ``` ### Example 3: Offboarding (Always) ``` Agent configuration: - Planning Mode: Always - Task: 15+ steps across multiple systems Plan created: 1. Verify user in Okta 2. List all groups and roles 3. Remove from Okta groups 4. Disable AWS IAM access 5. Remove from Google Workspace 6. List Jira issues assigned to user 7. Reassign critical issues 8. Disable Slack account 9. Post summary to #security channel ... Result: Systematic, thorough, nothing missed ``` ## Impact on Performance | Metric | Never | Auto | Always | | - | - | - | - | | Average Duration | Fastest | Medium | Slowest (+10-20%) | | Token Usage | Lowest | Medium | Highest (+15-25%) | | Reliability | Good | Better | Best | | Thoroughness | Good | Better | Best | | Best for | Simple tasks | Mixed | Complex tasks | > [!NOTE] > > **Speed vs Thoroughness**: Planning adds 10-20% overhead but significantly > improves reliability for complex tasks. For most agents, "Auto" provides the > best balance. ## Plan Visibility When an agent creates a plan, you can see it in the execution logs: ``` 📋 Plan Created: Step 1: Get SentinelOne alert details - Tool: get_sentinelone_alert - Purpose: Fetch full alert context Step 2: Search Splunk for related activity - Tool: search_splunk - Purpose: Find user activity in past 24h Step 3: Check file hash in VirusTotal - Tool: virustotal_check_hash - Purpose: Determine if file is known malware Step 4: Assess severity based on findings - No tool needed - Purpose: Analyze data and make determination Step 5: Update Jira ticket with findings - Tool: update_jira_ticket - Purpose: Post results for analyst ``` This visibility helps you understand the agent's approach and debug issues. ## Dynamic Plan Adjustment Agents can adjust their plans based on discoveries: ``` Original Plan: 1. Get alert 2. Search logs 3. Check VirusTotal 4. Update ticket Adjustment: → Step 2 failed (Splunk unavailable) → Agent adapts: "Skip log search, proceed with VirusTotal" → Continues with modified plan ``` This adaptive behavior works in all planning modes. ## Prompt Guidance for Planning You can influence how agents plan with prompt instructions: ### For "Auto" Mode ```markdown theme={null} When planning your approach: - For Critical alerts, always create a detailed plan - For Low severity alerts, act quickly without extensive planning - If more than 3 tools are needed, plan your approach first ``` ### For "Always" Mode ```markdown theme={null} Your plan should include: 1. All data gathering steps (list them) 2. Analysis phase (what you'll evaluate) 3. Decision criteria 4. Action steps Ensure your plan covers all requirements before executing. ``` ### For "Never" Mode ```markdown theme={null} Follow this sequence: 1. First, always call [specific tool] 2. Then, based on result, call [next tool] 3. Finally, [action] (Being explicit compensates for lack of planning) ``` ## Testing Planning Modes Use Builder to compare modes: **1. Test with Current Mode** Run agent with complex test case, note duration and quality **2. Change Planning Mode** Switch to different mode (e.g., Auto → Always) **3. Rerun Same Test** Execute identical test case **4. Compare** * Which produced better output? - Which was more efficient? - Did Always mode catch steps Never mode missed? **5. Decide** Choose mode that best balances quality and speed for your use case ## Common Pitfalls > [!WARNING] > > **Over-planning for Simple Tasks**: Don't use "Always" for agents that > typically make 1-2 tool calls. You're just adding overhead. > [!WARNING] > > **Under-planning for Complex Tasks**: If your agent frequently misses steps > or acts inefficiently, try "Auto" or "Always" mode. > [!WARNING] > > **Expecting Perfect Plans**: Plans are guides, not guarantees. Agents may > deviate based on what they discover. ## Advanced: Plan Quality You can improve plan quality with: 1. **Clear system prompts**: Explain the typical workflow 2. **Context documents**: Provide runbooks or procedures 3. **Examples**: Show what good plans look like 4. **Evaluation criteria**: Define what "complete" means ## Monitoring Planning Track planning effectiveness with your internal monitoring and evaluation tools: * **Planning rate**: % of runs where planning occurred (for "Auto" mode) * **Plan adherence**: How closely the agent followed its plan * **Plan adjustments**: How often plans were modified * **Outcome comparison**: Planned vs unplanned success rates ## Best Practices > [accordion] Start with Auto > > Unless you have specific requirements, use "Auto" mode and let the agent > decide when planning helps. > [accordion] Test Both Extremes > > In Builder, test with "Never" and "Always" to understand the > quality/speed tradeoff for your specific agent. > [accordion] Match Mode to Task Complexity > > Simple agents → Never, Complex agents → Always, Variable agents → Auto > [accordion] Review Plans in Failed Executions > > When an agent fails, check if it planned (and if that plan was sound). > This reveals prompt gaps. > [accordion] Don't Overthink It > > Planning mode is an optimization. Focus on prompt quality first, then > tune planning mode. # Response Agents as Code Source: https://docs.cotool.ai/agents/response-agents-as-code Manage response agents as YAML in your own GitHub repo, synced automatically into Cotool Response Agents as Code lets you define and manage your response agents as **YAML files in your own GitHub repository**. Cotool polls the repo on a schedule, reconciles the files into your agents, and records every synced change in the agent's version history. This gives you a GitOps workflow for agents: code review on pull requests, change history in Git, and the ability to roll out the same agents across environments by editing files instead of clicking through the UI. > [!NOTE] > > **Managed vs. manual agents**: An agent synced from a repo is > **engine-owned** — it is read-only in the Cotool UI. You change a managed > agent by editing its YAML and letting the next sync apply it. Agents created > in the UI are unaffected; the two can coexist in the same organization. ## How It Works **1. You keep agent YAML in a Git repo** Each agent is one YAML file in a folder you choose (default `cotool/agents`). The file describes the whole agent: prompt, model, tools, skills, triggers, and more. **2. Cotool polls and reconciles** Roughly every 5 minutes, Cotool fetches the configured branch and makes your agents match the files — creating new agents, updating changed ones, and removing agents whose file disappeared. A commit-SHA check skips the fetch entirely when the branch hasn't moved. **3. Every change is versioned** Each synced create or update appends an entry to the agent's [version history](/improving-agents/system-prompt-versioning), tagged with the source commit. An unchanged re-sync adds nothing. ## Setup Response Agents as Code syncs from the [GitHub integration](/integrations/dev-tools/github). Connect GitHub first, then configure the sync. **1. Connect GitHub** Go to **Settings > Integrations** and connect GitHub. Install the GitHub App on the organization and repositories you want to sync from. **2. Open the Response Agents as Code card** On the GitHub tool page, find the **Response Agents as Code** card. (You need the `tool.manage` permission to configure it.) **3. Choose repo, branch, and paths** Pick the repository, branch, and the folder that contains your agent YAML files. The dropdowns are populated from the repos the GitHub App can access. The agents path defaults to `cotool/agents`, and the **skills path** (the folder scanned for [`SKILL.md`](#skills) definitions) defaults to `cotool/skills`. **4. Enable and save** Turn on **Enable sync** and click **Save config**. While enabled, the periodic sync includes your organization; while off, it skips it. **5. Sync now (optional)** Click **Sync now** to run a sync immediately instead of waiting for the next cycle. The card shows last-sync status and a per-file table with the synced agent or any error. ## File Format Each file defines one response agent. The format is intentionally distinct from the UI's bulk export/import format — here it's **one agent per file**, with the system prompt either inline or in a separate `.md` file. ```yaml theme={null} apiVersion: cotool.ai/v1 kind: ResponseAgent metadata: sync_key: triage-suspicious-login name: Triage Suspicious Login description: First-pass triage for IdP suspicious-login alerts. tags: - auth - p1 spec: modelAlias: anthropic:chat:sonnet-4.6 planningMode: auto toolNames: - slack_sendMessage - slack_replyToThread - slack_readChannelMessages - slack_getChannelDetails - slack_readThreadMessages - slack_reactToMessage - slack_getUsersByIds - slack_findUsers - slack_searchChannels - slack_downloadFile - slack_waitForUserResponse acceptanceCriteria: - Determines whether the login is expected travel or genuinely anomalous. triggers: - source: cron name: Hourly sweep schedule: '0 * * * *' systemPrompt: inline: | # Triage Suspicious Login You are a first-pass triage agent for identity-provider "suspicious login" alerts. Classify each as Expected or Anomalous. ``` ### Top-level fields | Field | Required | Notes | | - | - | - | | `apiVersion` | optional | Schema version, e.g. `cotool.ai/v1`. | | `kind` | optional | Must be `ResponseAgent` when present. | | `metadata` | required | Identity and human-readable info (see below). | | `spec` | required | The agent definition (see below). | ### `metadata` | Field | Required | Notes | | - | - | - | | `sync_key` | optional | Stable, org-unique identity for the agent (see [Identity](#identity)). | | `name` | required | Human-readable name. Can change freely — it is not the identity. | | `description` | optional | What the agent does. | | `tags` | optional | Free-text tags for categorizing the agent. | ### `spec` | Field | Required | Notes | | - | - | - | | `modelAlias` | required | Model alias, e.g. `anthropic:chat:sonnet-4.6`. | | `systemPrompt` | required | Either `{ inline: "..." }` or `{ file: "prompt.md" }` (path relative to the YAML file). | | `planningMode` | optional | `auto` (default), `never`, or `always`. See [Planning Modes](/agents/planning-modes). | | `agentFilesystem` | optional | Mount a persistent [Agent Filesystem](/agents/agent-filesystem) across runs (default `false`). | | `toolNames` | optional | Non-agent tool ids the agent may use. Prefer full action names such as `slack_sendMessage` — these are what the agent page's tool picker shows. A bare integration id (for example, `slack`) is also accepted and grants every matching `slack_*` action, but the UI cannot display it as a selection. | | `agentTools` | optional | Other managed agents this agent may call, by `sync_key` (see [Agent-to-agent](#agent-to-agent-references)). | | `cliNames` | optional | CLI integration ids the agent may use. | | `skills` | optional | Attached [skills](/agents/skills), each a **name** referencing a skill that exists in your org (created in the UI or defined as a `SKILL.md` synced from the repo). See [Skills](#skills). | | `acceptanceCriteria` | optional | [Acceptance criteria](/improving-agents/acceptance-criteria) evaluated for each run. | | `triggers` | optional | Inline triggers (see [Triggers](#triggers)). | | `structuredOutputSchema` | optional | JSON schema for [structured output](/agents/structured-outputs). | | `contextDocs` | optional | [Context documents](/agents/context-documents) attached to the agent. | > [!NOTE] > > The YAML is **strict** — unknown or misspelled keys (for example `syncKey` > instead of `sync_key`) are rejected with a validation error for that file > rather than being silently ignored. ## Identity Each file maps to exactly one agent. Cotool decides which agent a file represents by: 1. **`metadata.sync_key`** — an author-chosen identity, unique within your organization. **Recommended.** Because identity is independent of file content and location, you can rename the agent or move/rename the file without churning the agent or losing its triggers and history. 2. **File path** — used when no `sync_key` is set. Renaming or moving the file then changes its identity (Cotool treats it as a new agent). > [!NOTE] > > Set a `sync_key` for any agent you expect to rename or reorganize. It's the > only way to keep a webhook trigger's minted secret and URL stable across a > rename. ## Triggers Declare triggers inline under `spec.triggers`. The sync engine materializes them as engine-owned, read-only triggers on the agent. Supported sources: `cron`, `webhook`, `jira`, `jira-automation`, `slack`, `linear`, and `email`. ```yaml theme={null} spec: triggers: - source: cron name: Daily report schedule: '0 9 * * *' - source: webhook name: Inbound events sync_key: inbound # stable id; preserves the minted secret across renames - source: jira name: New security issues events: - jira:issue_created jqlFilter: project = SEC - source: slack name: Security channel allowedChannelIds: - C0123456789 ``` > [!WARNING] > > **Secrets never live in YAML.** Webhook secrets and inbound URLs are minted > server-side; Slack and Linear bind to your organization's connected > integration at sync time. If the required integration isn't connected, that > trigger is **skipped with a diagnostic** — the agent itself still syncs, and > the file's status shows *integration not connected* rather than failing. A trigger's `sync_key` is its stable identity **within the agent** (it defaults to a slug of `name`). Set it explicitly to rename a trigger without recreating its row — which, for webhook-family triggers, is what preserves the minted secret and URL. For the full set of fields per source, see [Triggering Agents](/agents/triggering-agents). ## Agent-to-Agent References A YAML agent can call another managed agent as a tool by referencing its `sync_key`: ```yaml theme={null} spec: toolNames: - slack_sendMessage - slack_replyToThread agentTools: - sync_key: enrich-alert - sync_key: notify-oncall ``` References are resolved in a second pass after all agents exist, so **forward references work** — the order of files doesn't matter. Always reference other agents via `agentTools` and `sync_key`, not via `toolNames`. ## Skills An agent **references** skills by name. It never defines a skill inline — skills are first-class resources whose lifecycle is independent of any one agent: ```yaml theme={null} spec: toolNames: - crowdstrike_listDetections - crowdstrike_getDeviceDetails - slack_sendMessage skills: - enrich-user # exists in your org (created in the UI) - triage-runbook # defined as code in a SKILL.md synced from this repo ``` A referenced skill resolves to a skill that exists in your organization — either one created in the **UI**, or one defined as code in a **`SKILL.md`** synced from your repo (below). A reference that doesn't resolve is **skipped** with a note (it does **not** fail the agent), so the agent still loads with the skills that resolve and the rest of its spec. References track each skill's latest version. ### Defining skills as code Skills live in their own directory in the repo — the **skills path** (`skills_path`, default `cotool/skills`), configured separately from the agents path. Each skill is a directory containing a standard [`SKILL.md`](/agents/skills) — YAML frontmatter (`name`, `description`, `allowed-tools`) plus a Markdown body — with any sibling `references/`, `assets/`, and `scripts/` files synced too: ```text theme={null} cotool/ agents/ triage.yaml # references skills by name skills/ phishing/ SKILL.md references/playbook.md assets/report-template.md triage-runbook/ SKILL.md ``` Cotool discovers each `SKILL.md` **on its own** — a skill exists because its file exists, not because an agent points at it. The skill's `name` (from frontmatter) is its identity, so: * The skill is **engine-managed**: Cotool creates it and records a new version only when its content actually changes (a no-op re-sync adds none). Like a managed agent, it's **read-only in the UI** — edit or remove it by changing its `SKILL.md`, not from the Skills page. * Any number of agents can reference it by name — and so can an agent **managed in the UI**. The skill is a single org-wide resource; referencing it never copies it. * If the `SKILL.md` is **removed**, the skill is **gently soft-deleted** (and resurrected if the file returns), just like agents. Because lifecycle tracks the *file*, retiring an agent that referenced the skill never deletes it — other agents keep working. * Two `SKILL.md` files with the **same name** are a conflict: both are flagged and neither is synced (names must be unique across the repo). * If the name collides with an existing **non-managed organization skill** created in the UI, the `SKILL.md` skill is **not** synced — Cotool never overwrites it. The collision is flagged on the skill file's sync status. Personal skills use a separate per-user namespace and can share the managed skill's name. > [!WARNING] > > A skill's required tools (its `SKILL.md` `allowed-tools`) must also be > granted to every agent that attaches it, via `toolNames` (or `cliNames`). A > requirement named by integration id (for example `crowdstrike`) is satisfied > by granting any action from that integration, such as > `crowdstrike_listDetections`. In the example above an agent attaching > `triage-runbook` therefore needs an action from each of that skill's > integrations in its `toolNames`. If a required tool is missing, that one > agent file syncs with a `schema_error` and is skipped — the rest of your > agents still reconcile. > [!NOTE] > > Skills round-trip through export cleanly, since agents carry only name > references. ## Reconcile Behavior Each sync makes your agents match the files: * **New file** → a new managed agent is created. * **Changed file** → the managed agent is updated, and the change is recorded as a version. * **Removed file** → the agent is **gently soft-deleted**. This keeps its triggers and tags and is reversible: if the file returns, the *same* agent is resurrected (not a fresh copy). * **Invalid file** → the last good version of that agent is **kept**. The error is recorded against that file and never blocks the others, so one bad file can't take down the rest of your agents. The card's per-file status table shows `ok`, `integration not connected`, or a parse/validation error for each file, with a link to the file at the synced commit. ## Validate Before Syncing `POST /api/agent-sync/validate` runs the **exact same** parse, schema, and cross-file graph validation as the sync engine, statelessly, over files you post — so it cannot drift from real sync behavior. It's the engine behind the CI Action below, and you can call it directly: ```bash theme={null} curl -X POST https://app.cotool.ai/api/agent-sync/validate \ -H "Authorization: Bearer $COTOOL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "files": [ { "path": "cotool/agents/triage.yaml", "content": "apiVersion: cotool.ai/v1\nkind: ResponseAgent\n..." } ] }' ``` The response carries a result per file — both agent YAML and any posted `SKILL.md` — with `errors` (would block sync) and `warnings`, plus an overall `valid` flag. Warnings are checks that depend on live org state the request can't see: an unprovided `systemPrompt.file`, an `agentTools` sync\_key not in the posted set, or a skill reference whose `SKILL.md` wasn't posted (it may be a UI-created org skill). Post your `SKILL.md` files (and set `skillsPath` if it isn't the default `cotool/skills`) to validate skill references and skill definitions too — with a skill's `SKILL.md` posted, validation also **errors** on any agent that attaches it without granting the skill's `allowed-tools`, exactly as sync would. See the [API Reference](/api-reference/agents-as-code/validate-response-agent-as-code-yaml) for the full schema. > [!WARNING] > > **Prefer GitHub OIDC over an API key.** The `$COTOOL_API_KEY` above is shown for direct or manual calls and for CI outside GitHub. For GitHub Actions, use the [OIDC-based Action](#validate-in-ci) below instead — it mints a short-lived, repo-scoped token, stores no secret, and authorizes as a **validate-only** principal. > > A Cotool API key, by contrast, is **long-lived** and carries the **full permissions of the user who created it** — it is *not* narrowed to validation, even though the endpoint only needs `tool.manage` — so a leaked key is as powerful as that user. If you must use one (non-GitHub or self-hosted CI), create it under a dedicated, least-privilege service account, keep it in a secrets manager, and rotate it regularly. ## Validate in CI The [`cotool/validate-agents`](https://github.com/cotool/validate-agents) GitHub Action validates your agent YAML on every pull request and annotates problems inline. The Action authenticates **only** via GitHub OIDC — there is no API-key input, and it is the **recommended** way to validate in CI. The job mints a short-lived, repo-scoped OIDC token; Cotool verifies it and maps the repository to your org via your GitOps sync configuration. Nothing to store or rotate, and the token grants validate-only access — never your broader API-key permissions. ```yaml theme={null} # .github/workflows/validate-agents.yml on: pull_request: paths: ['cotool/agents/**'] permissions: contents: read id-token: write # lets the job mint the OIDC token jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v5 - uses: cotool/validate-agents@v1 with: dir: cotool/agents ``` > [!NOTE] > > OIDC requires that this repository is configured as your org's agents source > under **Settings → Agents → GitOps sync** — that registration is what > authorizes the repo. To validate before configuring sync, or outside GitHub > CI, call the endpoint directly with an API key (the `curl` example above) > rather than the Action — subject to the API-key trade-offs noted above. ### Inputs | Input | Default | Description | | - | - | - | | `dir` | `cotool/agents` | Directory to scan for agent YAML (and referenced prompt `.md`). | | `file` | — | Comma-separated explicit file list; overrides directory discovery. | | `recursive` | `true` | Recurse into subdirectories of `dir`. | | `audience` | `cotool-validate` | OIDC audience requested from GitHub and verified by the Cotool API. | | `api_url` | `https://app.cotool.ai` | Base URL of the Cotool API. | | `fail_on_warnings` | `false` | Fail the check on warnings (errors always fail). | ### How validation gates a merge — and how syncing stays safe The Action (and the `/validate` endpoint behind it) is **advisory by default**: it reports problems on the pull request, but on its own it does not stop anything from syncing. Cotool's sync engine polls whatever is on your **configured branch** and reconciles it — it does not know or care whether a CI check ran or passed. Two separate mechanisms turn that into a safe GitOps workflow: 1. **Branch protection makes validation a merge gate (recommended).** In your repository settings, mark the validation check as a **required status check** on the branch you sync from. GitHub then blocks any pull request from merging until validation passes, so only validated YAML ever reaches the branch Cotool polls. This is the piece that actually *gates* syncing, and it lives in **your** GitHub settings — not in Cotool. 2. **The sync engine re-validates as a backstop.** Independently of CI, every sync runs the exact same parse, schema, and cross-file graph checks before applying a file. An invalid file is **skipped per-file** — its last good version is kept and the error is recorded against that file — so a bad file that slips past CI never corrupts your live agents (see [Reconcile Behavior](#reconcile-behavior)). **1. Open a pull request** An author edits agent YAML under your synced path and opens a PR. The `validate-agents` Action runs against the PR's files and annotates any errors or warnings inline. **2. The required check gates the merge** With branch protection enabled on your sync branch, the PR cannot merge until the validation check is green. Reviewers only ever merge validated YAML; broken YAML is blocked at the door. **3. Merge to the sync branch** Once approved and green, the PR merges into the branch you configured under **Settings → Agents → GitOps sync** (commonly your default branch). **4. Cotool polls and reconciles** Within \~5 minutes the sync engine fetches the branch HEAD, re-validates, and applies the changes — recording each as a version. Anything still invalid is skipped per-file, never blocking the rest. > [!NOTE] > > Cotool never reads your CI status — **branch protection** is what ensures > only validated YAML lands on the sync branch. If you sync from an > unprotected branch (or commit directly to it), the Action becomes a > non-blocking signal and the **server-side backstop** is your only guard > against invalid files. ## Exporting an Existing Agent To move a UI-built agent into Git, open the agent, use the version dropdown, and choose **Export as YAML**. The export emits the canonical sync shape — inline prompt as a literal block, stable `sync_key`s for agent-tool references, and triggers without any server-owned secrets — ready to commit to your repo. ## Recovery If the backing GitHub integration is disconnected, **synced agents keep running** — only syncing pauses. The card surfaces a *Reconnect GitHub* prompt. If you need to edit a managed agent while GitHub is disconnected, use **convert to manual**: Cotool makes an editable copy, moves the triggers to it, and parks the managed original (recoverable). The copy is an ordinary UI-owned agent from then on. ## Related > [card] > > **Agent Versioning** — how synced and manual changes share one timeline > > [Open](/improving-agents/system-prompt-versioning) > [card] > > **Triggering Agents** — all trigger types and their fields > > [Open](/agents/triggering-agents) > [card] > > **GitHub Integration** — connect GitHub and configure repository sync > > [Open](/integrations/dev-tools/github) > [card] > > **Creating Agents** — building agents in the UI > > [Open](/agents/creating-agents) > [card] > > **Skills** — reusable instructions, referenced by name or defined in > code > > [Open](/agents/skills) # Skills Source: https://docs.cotool.ai/agents/skills Reusable instructions and resources you can attach across chats and agents **Skills** are reusable bundles of instructions, supporting files, and tool requirements that you can attach across Cotool workflows. Use them when you have guidance that should stay consistent across chats or agents, such as: * A standard investigation procedure * A reporting format or escalation template * A repeatable enrichment workflow * Reference material that belongs with one specific workflow Instead of copying the same instructions into every system prompt, you can maintain them once and reuse them wherever needed. ## What a Skill Includes Each skill can contain: * **Name**: A short identifier used across your workspace * **Description**: What the skill does and when an agent should use it * **Content**: The main markdown instructions the agent will follow * **Required tools**: Tools the skill expects the agent to have * **Resources**: Optional supporting files such as runbooks, schemas, templates, or scripts > [card] Reusable > > Attach the same skill to multiple agents instead of duplicating > instructions > [card] Discoverable > > Search, browse, and sort skills from a dedicated Skills library > [card] Versioned > > Track changes over time from the Versions tab > [card] Portable > > Import or export skills as standard skill folders or zip files ## Organization, private, and managed skills Cotool supports more than one kind of skill: | Skill type | Who can use it | Where it works best | Best for | | - | - | - | - | | **Organization** | Shared across your workspace | Agents and chat | Team playbooks, shared procedures, common output formats | | **Private** | Only you | Your own chats | Personal helpers, drafts, one-off workflows | > [!NOTE] > > Private skills do not attach to agents. They stay user-scoped and only load > into your own chats. Cotool can also show **managed** skills that are read-only in the Skills page: * **Built-in** skills are generated from a connected integration and can link back to that integration. * **System-generated** skills are created by another product surface, such as Threat Model, and stay in sync from there. ## When to Use a Skill Skills are best for **repeatable workflow logic** that should travel with an agent. ### Good use cases * "Triage Microsoft 365 login alerts" * "Write executive-ready incident summaries" * "Enrich IPs and domains before making a recommendation" * "Follow our standard offboarding checklist" ### Better handled elsewhere * **System prompt**: The agent's overall role, scope, and decision-making rules * **Context documents**: External reference material that is maintained in Google Docs or Notion ## Creating a Skill **1. Open the Skills page** Navigate to **Skills** from the main sidebar. **2. Create a new skill** Click **Create Skill** and fill in: * **Name**: Lowercase letters, numbers, and hyphens * **Description**: A clear summary of when the skill should be used * **Content**: The actual procedure, instructions, examples, or output format **3. Add required tools** Select the tools the skill depends on. When someone attaches the skill to an agent that is missing one of those tools, Cotool shows a warning so the gap is visible before runtime. **4. Add supporting files** Upload optional reference files that belong with the skill, such as: * Runbooks * Lookup tables * Response templates * Schemas or sample payloads **5. Save and attach** Save the skill, then attach it to one or more agents from the agent builder. > [!NOTE] > > Prefer to stay in chat? Use `/create-skill` to build a new skill > through a guided conversation, or `/update-skill` to revise an > existing one. See [Slash Commands](/chat/slash-commands). ## Writing Good Skill Content The **Content** field is the heart of the skill. Write it like a focused operating procedure. **Good structure:** ```markdown theme={null} # IP enrichment workflow ## When to use Use this skill when an agent is asked to investigate an IP address. ## Steps 1. Query threat intel sources 2. Check internal telemetry 3. Identify whether the IP is internal, known-good, or suspicious ## Output format - Verdict - Evidence - Recommended next step ``` > [!NOTE] > > Keep the core instructions concise. If you need long reference material, > move that content into resource files instead of putting everything in the > main skill body. ## Importing Existing Skills Cotool can import skills that follow the Agent Skills folder format. The importer accepts more than a single skill archive. You can point it at: * A **single skill folder** * A **parent folder** that contains multiple skills * A **folder of plain markdown files** that Cotool converts into starter skills * A **.zip archive** ### Expected structure ```text theme={null} skill-name/ ├── SKILL.md required ├── scripts/ optional ├── references/ optional └── assets/ optional ``` ### What each folder is for | Folder | Purpose | | - | - | | `SKILL.md` | The main skill metadata and instructions | | `references/` | Supporting documents loaded on demand | | `assets/` | Static text-based resources such as templates or sample data | | `scripts/` | Executable helper files for sandbox-enabled workflows | > [!NOTE] > > Only text-based files are supported for import. If a file type is not > supported, Cotool will skip it and show you which files were ignored. If you import plain markdown, Cotool creates starter skills from those files and lets you rename them and adjust their descriptions before the import finishes. ## Managing Resources On an individual skill page, the **Resources** tab lets you organize supporting files into: * **References** for documentation and lookup material * **Assets** for static templates or data files * **Scripts** for executable helpers Scripts are marked as **sandbox only**, which makes them most relevant for agent workflows that run in sandbox mode. ## Version History Each editable skill has a **Versions** tab and a version picker so you can review how it has changed over time. This is useful when you want to: * Track prompt or procedure changes * Confirm what version was active during testing * Compare required tools or resource files across revisions * Safely iterate on a shared skill used by multiple agents **1. Open the version you want to inspect** Use the version picker to switch from **Current/latest** to an earlier version. **2. Review the historical snapshot** Historical versions open in read-only mode. The instructions, required tools, and resource files all reflect that point-in-time snapshot. **3. Restore when needed** If you want to bring an older version back, choose **Restore**. Cotool copies that snapshot forward as a new current version, while keeping the full history intact. > [!NOTE] > > Built-in integration skills and other managed skills are read-only in the > Skills page, so you inspect them there but edit them from their source > surface instead. ## Attaching Skills to Agents You attach organization and built-in skills from the agent builder. **1. Open an agent** Go to **Agents** and open the agent you want to update. **2. Find the Skills section** In the editor, open the **Skills** panel below tool selection. **3. Attach one or more skills** Browse or search the available skills, then select the ones you want. **4. Resolve any tool warnings** If a skill requires tools the agent does not have, Cotool highlights the missing tools so you can grant access before saving. **5. Test in Builder** Run the agent with representative inputs to confirm the skill improves behavior the way you expect. > [card] > > **Agent setup guide** -> See where skills fit in the full agent creation workflow > > [Open](/agents/creating-agents) > [!NOTE] > > Managing agents as code? You can **define** a skill directly in your repo as > a `SKILL.md` file (with its `references/`, `assets/`, and `scripts/`), > synced from the skills path. Agents then reference it by name — the same as > attaching one that already exists. See [Response Agents as Code → > Skills](/agents/response-agents-as-code#skills). ## Skills vs Context Documents These features complement each other, but they solve different problems: | Use this for... | Skills | Context documents | | - | - | - | | Reusable workflow instructions | Yes | No | | Shared output formats | Yes | No | | Long-lived runbooks stored outside Cotool | No | Yes | | Google Docs or Notion as source of truth | No | Yes | | Files bundled directly with a reusable workflow | Yes | No | ## Best Practices > [accordion] Keep each skill narrow > > A skill should solve one repeatable problem well. If it starts covering multiple unrelated jobs, split it into smaller skills. > [accordion] Describe when to use it > > The description should help humans and agents understand the trigger > conditions for using the skill. > [accordion] Declare required tools > > If the workflow depends on specific integrations, mark them as required so > missing access is visible when the skill is attached. > [accordion] Move bulky material into resources > > Put large examples, tables, schemas, or templates into resource files > instead of overloading the main instruction body. > [accordion] Test on real scenarios > > After attaching or editing a skill, run the agent with realistic examples in Builder to confirm the instructions behave as intended. ## Troubleshooting > [accordion] The skill attaches, but the agent warns about missing tools > > Add the missing tools to the agent, or remove the tool dependency from the skill if it is no longer required. > [accordion] Import failed > > Check that your folder or zip contains a valid `SKILL.md` file and only > supported text-based files. > [accordion] The skill is getting too large > > Keep the main content focused and move supporting material into > `references/`, `assets/`, or separate skills. > [accordion] I want to share a skill outside Cotool > > Use the export action on the skill detail page to download the active version as a zip file. # Agent Outputs Source: https://docs.cotool.ai/agents/structured-outputs Define structured JSON schemas for consistent agent output **Agent outputs** let you define a JSON schema that your agent returns at the end of every run. This ensures consistent output that can be displayed visually for easy verification, integrated with downstream systems, or used for reporting. ## What Are Agent Outputs? Instead of relying on freeform text responses, agent outputs enforce a specific structured data format: > [card] Consistent Format > > Every run produces the same shape of data, making it easy to verify > outcomes, compare results, and build reports. > [card] Rich Visualization > > Output is rendered with markdown formatting, classification badges, and > organized sections—not raw JSON. > [card] Template Library > > Start with pre-built templates for investigations, reports, enrichments, > and more. > [card] AI-Powered Generation > > Generate a schema automatically from your agent's system prompt. > [!NOTE] > > Agent outputs are **in addition to** the standard run timeline. You can > always view the full execution history, tool calls, and agent reasoning > alongside the structured output. ## When to Use Agent Outputs > [accordion] Use Agent Outputs When... > > * You need consistent, parseable output from every run - You want > classification labels (True Positive, False Positive, etc.) - Output > includes formatted reports with multiple sections - You want to surface > evidence behind agent decisions in an easier-to-read format - Results > will be displayed in a UI or dashboard - Results will be aggregated for > reporting > [accordion] Skip Agent Outputs When... > > * Agent output is conversational (e.g., Slack assistant) - Every run > produces fundamentally different types of output - You don't need to > parse or store the results ## Getting Started ### Enabling Agent Outputs **1. Open Agent Configuration** Navigate to your agent's configuration page and scroll to **Agent Output Schema** **2. Enable the Feature** Toggle the schema to **Enabled** **3. Choose a Starting Point** Select from: - **Generate Schema**: AI analyzes your system prompt and creates a relevant schema - **Template**: Start with a pre-built template for common use cases - **Blank**: Build from scratch with full control **4. Customize and Preview** Edit the schema to match your needs and preview how output will look **5. Save and Test** Save your agent and observe structured outputs for all future runs ## Templates Templates provide pre-built schemas for common agent patterns. They're great starting points that can either be used as-is or easily customized: > [tab] Investigator > > **Best for**: Alert triage, threat hunting, incident analysis > > Includes: > > * **Classification**: True Positive / False Positive verdict > * **Confidence**: High / Medium / Low confidence level > * **Report**: Structured sections for summary, evidence, and next steps > > ```json theme={null} > { > "classification": "True Positive", > "confidence": "High", > "report": { > "summary": "Executive summary of findings", > "evidence": "Key evidence and artifacts", > "nextSteps": "Recommended actions" > } > } > ``` > [tab] Report > > **Best for**: Simple reports, summaries, documentation > > Includes: > > * **Report**: Single markdown-formatted report field > > ```json theme={null} > { > "report": "# Summary\n\nMarkdown-formatted report content..." > } > ``` > [tab] Templated Report > > **Best for**: Structured investigations with multiple sections > > Includes: > > * **Report object** with: > * Summary section > * Evidence section > * Next steps section > > ```json theme={null} > { > "report": { > "summary": "High-level overview", > "evidence": "Detailed evidence and findings", > "nextSteps": "Recommended remediation" > } > } > ``` > [tab] Rule Evaluator > > **Best for**: Detection rule validation, rule tuning > > Includes: > > * **Classification**: Evaluation verdict > * **Report**: Analysis and reasoning > > ```json theme={null} > { > "classification": "False Positive", > "report": "Analysis of why this detection fired..." > } > ``` > [tab] Helper / Slack Bot > > **Best for**: Assistant agents, Slack bots, chat-based agents > > Includes: > > * **Steps Taken**: Array of actions performed > > ```json theme={null} > { > "stepsTaken": [ > "Looked up user in Okta", > "Checked recent login activity", > "Verified no anomalies detected" > ] > } > ``` > [tab] Enrichment > > **Best for**: Indicator enrichment, threat intelligence > > Includes: > > * **Report**: Markdown report of enrichment findings > > ```json theme={null} > { > "report": "# Enrichment Results\n\n**IP**: 8.8.8.8\n**Reputation**: Clean..." > } > ``` > [tab] Orchestrator > > **Best for**: Multi-step workflows, automation agents > > Includes: > > * **Steps Taken**: Log of orchestration actions > > ```json theme={null} > { > "stepsTaken": [ > "Triggered downstream agent A", > "Updated Jira ticket", > "Posted notification to Slack" > ] > } > ``` ## Schema Building ### Available Types The schema builder supports standard JSON types: | Type | Icon | Description | | - | - | - | | Object | `{}` | Container for named properties | | Array | `[]` | List of items | | String | `T` | Text values | | Number | `#` | Numeric values | | Boolean | `◎` | True/false values | | Null | `∅` | Null/empty value | ### Presets Presets are special field configurations with built-in rendering: > [accordion] Classification > > A string field with predefined enum values for categorization. > > **Default values**: "True Positive", "False Positive" > > **Rendered as**: Styled badge/chip > > **Use for**: Verdicts, severity levels, status values > > ```json theme={null} > { > "classification": "True Positive" > } > ``` > [accordion] Markdown > > A string field rendered with full markdown formatting. > > **Supports**: Headings, lists, tables, code blocks, bold/italic, links > > **Use for**: Reports, summaries, detailed analysis > > ```json theme={null} > { > "report": "# Investigation Summary\n\nThis is a **critical** finding..." > } > ``` > [accordion] Templated Report > > An object with predefined sections: summary, evidence, and next steps. > > **Structure**: > > * Summary (markdown) > * Evidence (markdown) > * Next Steps (markdown) > > **Use for**: Structured investigation reports > > ```json theme={null} > { > "report": { > "summary": "# Summary\n...", > "evidence": "## Evidence\n...", > "nextSteps": "## Recommendations\n..." > } > } > ``` ### Enum Values For string fields, you can restrict values to a predefined list: **1. Create String Field** Add a new string field to your schema **2. Enable Enum** Click the options menu (⋮) and select "Restrict to enum values" **3. Add Values** Type values separated by commas or press Enter after each value **Example enum values**: * Severity: `Critical, High, Medium, Low, Info` * Status: `Open, In Progress, Resolved, Closed` * Confidence: `High, Medium, Low` ### Required vs Optional Fields By default, all fields are **required**. To make a field optional: 1. Click the options menu (⋮) next to the field 2. Select "Optional" Optional fields can be omitted or set to null in the output. ## Schema Generation If you have a system prompt written, you can generate a schema tailored to your task automatically: **1. Write System Prompt First** Ensure your agent has a clear system prompt describing what it does **2. Click Generate Schema** In the schema builder, click "Generate Schema" **3. Review Generated Schema** AI analyzes your prompt and creates a relevant schema with: - Appropriate fields for your use case - Sensible presets (markdown, classification, etc.) - Semantically relevant example output preview **4. Customize** Modify the generated schema as needed > [!NOTE] > > Schema generation requires a system prompt. If your agent doesn't have one > yet, write it first before generating a schema. ## Viewing Agent Output When an agent run completes, the structured output is displayed in two ways: > [tab] Visual View > > The default view renders output with rich formatting: - > **Classifications** appear as styled badges - **Markdown** is rendered > with headings, lists, code blocks - **Numbers** display prominently with > labels - **Nested objects** show as organized sections - **Arrays** > render as lists or grids This view is designed for human consumption. > [tab] JSON View > > Toggle to JSON view to see the raw data structure: - Exact JSON payload > returned by the agent - Copy button for easy export - Schema reference > alongside the data This view is useful for debugging or integration. ## Real-World Examples ### Example 1: Alert Triage Agent **Use case**: Automatically triage SentinelOne alerts **Schema** (using Investigator template): ```json theme={null} { "type": "object", "properties": { "classification": { "type": "string", "enum": [ "True Positive", "False Positive", "Suspicious", "Inconclusive" ], "description": "Verdict for this alert" }, "confidence": { "type": "string", "enum": ["High", "Medium", "Low"], "description": "Confidence in the classification" }, "severity": { "type": "string", "enum": ["Critical", "High", "Medium", "Low"], "description": "Assessed severity if true positive" }, "report": { "type": "object", "properties": { "summary": { "type": "string", "description": "Executive summary of findings" }, "evidence": { "type": "string", "description": "Key evidence supporting the classification" }, "nextSteps": { "type": "string", "description": "Recommended actions for the analyst" } } } } } ``` **Example output**: ```json theme={null} { "classification": "True Positive", "confidence": "High", "severity": "Critical", "report": { "summary": "Confirmed ransomware execution on endpoint WORKSTATION-42...", "evidence": "- File hash matches known LockBit variant\n- Encryption behavior observed\n- Ransom note dropped in multiple directories", "nextSteps": "1. Isolate endpoint immediately\n2. Page on-call security\n3. Preserve forensic evidence" } } ``` ### Example 2: Weekly Report Agent **Use case**: Generate weekly security metrics **Schema** (custom): ```json theme={null} { "type": "object", "properties": { "reportDate": { "type": "string", "description": "Date range for this report" }, "alertsTotal": { "type": "number", "description": "Total alerts in period" }, "truePositives": { "type": "number", "description": "Confirmed true positives" }, "falsePositives": { "type": "number", "description": "Confirmed false positives" }, "report": { "type": "string", "description": "Detailed markdown report" } } } ``` **Example output**: ```json theme={null} { "reportDate": "2025-01-08 to 2025-01-15", "alertsTotal": 247, "truePositives": 12, "falsePositives": 198, "report": "# Weekly Security Report\n\n## Key Metrics\n- **Total Alerts**: 247\n- **True Positive Rate**: 4.9%\n- **MTTD**: 12 minutes\n\n## Notable Incidents\n..." } ``` ## Schema Builder Reference ### Field Options Each field supports these options: | Option | Description | | - | - | | **Type** | Data type (string, number, boolean, object, array, null) | | **Name** | Property name in JSON (alphanumeric, hyphens, underscores) | | **Description** | Guides the LLM on what to put in this field | | **Required** | Whether the field must be present (default: yes) | | **Enum** | For strings, restrict to specific values | | **Preset** | Apply special rendering (classification, markdown, etc.) | ### Property Name Rules Property names must: * Contain only letters, numbers, hyphens, and underscores * Be unique within their parent object **Valid**: `classification`, `risk-score`, `next_steps`, `reportV2` **Invalid**: `my field` (spaces), `report@v2` (special characters) > [!TIP] > > **Hyphenated names render nicely**: Property names with hyphens are > automatically formatted for display. For example, `executive-summary` > renders as **Executive Summary** in the visual output view. # Triggering Agents Source: https://docs.cotool.ai/agents/triggering-agents Understanding all trigger types and when to use them Triggers automatically invoke agents in response to events. They enable autonomous workflows without manual intervention. ## Available Trigger Types > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/74IYTN6-8-nuKYYu/images/jira_md.png?fit=max\&auto=format\&n=74IYTN6-8-nuKYYu\&q=85\&s=f85329118ba587c594ee51b46df99352) > > Jira Triggers > > Run agents when Jira issues are created or updated > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/2D7q2Y6FoJjh0OqV/images/slack_md.png?fit=max\&auto=format\&n=2D7q2Y6FoJjh0OqV\&q=85\&s=433eb6babddb3beee4d256d8cc3db0a6) > > Slack Triggers > > Invoke agents from Slack mentions and commands > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/hM2NTJzJXh_rAkg_/images/linear_sm.png?fit=max\&auto=format\&n=hM2NTJzJXh_rAkg_\&q=85\&s=e566bf43182c9aae85513879b066ce58) > > Linear Triggers > > Invoke agents via @mentions and assignments in Linear > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/YkFCFtl3swKv9Xqp/images/cron_md.png?fit=max\&auto=format\&n=YkFCFtl3swKv9Xqp\&q=85\&s=d463ff8117b8015da5733caa73328a35) > > Cron Triggers > > Schedule agents to run on a recurring basis > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/2D7q2Y6FoJjh0OqV/images/webhook_md.png?fit=max\&auto=format\&n=2D7q2Y6FoJjh0OqV\&q=85\&s=21f757e30c07c58150a3b5848e7f4e8a) > > Webhook Triggers > > Invoke agents via webhooks from any system > [card] > > ![](https://mintcdn.com/cotool-bcb49c92/YkFCFtl3swKv9Xqp/images/email_md.png?fit=max\&auto=format\&n=YkFCFtl3swKv9Xqp\&q=85\&s=528cf53aa5071889b11bb755092b91f7) > > Email Triggers > > Run agents when emails arrive at a dedicated address ## How Triggers Work When a trigger fires: 1. The event payload is captured 2. Your agent receives the event data as context 3. The agent executes with access to relevant tools 4. Results are logged and can be posted back to the source ## Creating Alerts from Triggers Response-agent triggers can also create first-class Cotool alerts. Use this when every trigger event should become trackable SOC work with a status, assignee, activity timeline, and final disposition. When creating or editing a trigger, use **Create alert on trigger** to control whether the trigger creates an alert before the response-agent run starts. | Trigger source | Default alert behavior | | - | - | | Jira | Create alerts | | Jira Automation | Create alerts | | Linear | Create alerts | | Email | Create alerts | | Webhook | Create alerts | | Bugcrowd | Create alerts | | SEON | Create alerts | | Slack | Do not create alerts | | Cron | Do not create alerts | Trigger-created alerts are assigned to the response agent that owns the trigger. Cotool stores the original trigger payload with the alert and shows it on the alert detail page when available. > [card] [Alerts](/alerts/overview) > > Learn how trigger-created alerts appear in the triage queue. ## Slack Triggers Slack triggers allow you to invoke agents by @mentioning the Cotool bot in channels where it's installed. In DMs, the bot can create personal chats or invoke agents depending on your trigger configuration. ### Setting Up a Slack Trigger 1. Navigate to your agent's **Triggers** tab 2. Click **Add Trigger** and select **Slack** 3. Choose the channel(s) where the trigger should be active, or select "All Channels" 4. Save the trigger Once configured, @mentioning the Cotool bot in the specified channels will invoke your agent with the message content as context. ### One Trigger Per Channel Each Slack channel can only have one active trigger. This prevents conflicts where multiple agents could respond to the same @mention. **What this means:** * You can create multiple Slack triggers for different channels (e.g., one for `#alerts`, another for `#support`) * You cannot create two triggers that both include the same channel * An "All Channels" trigger cannot coexist with any other Slack trigger **Example configurations:** | Configuration | Valid? | | - | - | | Trigger A: `#alerts` + Trigger B: `#support` | ✅ Yes | | Trigger A: `#alerts, #support` + Trigger B: `#incidents` | ✅ Yes | | Trigger A: `#alerts` + Trigger B: `#alerts, #support` | ❌ No (overlap on `#alerts`) | | Trigger A: All Channels + Trigger B: `#alerts` | ❌ No (all channels conflicts) | If you need different agents for the same channel based on context (e.g., user groups or keywords), consider using a single trigger with conditional logic in your agent's system prompt. ### Thread Conversations (Re-entry) When Cotool responds in Slack, users can continue the conversation by @mentioning Cotool in the same thread. This enables back-and-forth interactions without starting a new execution each time. **How it works:** * @mention Cotool in a thread that already has a Cotool response to continue that conversation * Both agent-triggered conversations and personal chats support thread re-entry * The conversation has full context of the previous messages in that thread * This allows for follow-up questions, clarifications, and iterative workflows **Note**: An @mention is required for all interactions with Cotool, including thread re-entry. Simply replying in a thread without @mentioning will not trigger a response. **Example flow (agent):** 1. User @mentions Cotool: *"@Cotool investigate alert #12345"* 2. Agent responds with initial findings 3. User replies in thread: *"@Cotool can you check if this IP has been seen before?"* 4. Agent continues the same execution with the new request **Example flow (personal chat):** 1. User DMs Cotool: *"@Cotool help me analyze this log file"* 2. Cotool responds with analysis 3. User replies in thread: *"@Cotool can you summarize the key findings?"* 4. Cotool continues the conversation and responds in the thread ### Permissions * **User matching**: The Slack user's email must match a Cotool account in your organization * **Agent execution**: Users must have the `agent.execute` permission for the specific agent to trigger or re-enter conversations * **Thread ownership**: Only users with appropriate permissions can continue agent conversations in threads ### Response Links Each Cotool response in Slack ends with a small **Open in Cotool** link that opens the full conversation in the web interface. For agent runs, the agent's name follows the link (for example, **Open in Cotool · Phishing Triage**), and runs that created alerts link to each alert too. The link gives quick access to the full conversation context, tool outputs, and any visualizations in the Cotool web interface. The agent-run link can be toggled per Slack tool action (Send Slack Message, Reply to Slack Thread, and Ask Slack User) from the tool's gear-icon configuration in the agent builder. The link is shown by default. ### DM vs Channel Behavior **Direct Messages (DMs)**: * DMs **always** create a personal chat accessible via the web interface * Slack triggers do not apply to DMs—this ensures consistent, predictable behavior * Thread re-entry works for both personal chats and agent conversations (see below) **Channels**: * @mentions in channels **require** a configured trigger for that channel * If no trigger is configured for the channel, users see a message prompting them to set up a trigger * This ensures public channel conversations are always handled by a configured agent with appropriate guardrails This separation provides a clear mental model: **DMs = personal assistant, Channels = agent workflows**. ### Thread Re-entry for Personal Chats Personal chats (started via DM) support thread re-entry just like agent conversations: 1. Start a conversation by @mentioning Cotool in a DM 2. Cotool responds in a thread 3. @mention Cotool in the thread to continue the conversation 4. Cotool will respond directly in the Slack thread **Note**: Only the original chat owner can continue personal chat conversations. The system verifies that the Slack user's email matches the Cotool account that owns the chat. ## Linear Triggers Linear triggers allow you to invoke agents by @mentioning or assigning Cotool directly in Linear issues. When triggered, the agent processes the request and streams real-time updates — including reasoning, tool actions, and plan progress — back into the Linear issue thread. ### Setting Up a Linear Trigger 1. Navigate to your agent's **Triggers** tab 2. Click **Add Trigger** and select **Linear** 3. Choose **Agent Session** mode (the default for new triggers) 4. Save the trigger Once configured and enabled, @mentioning or assigning Cotool in any Linear issue will invoke your agent with the issue context. Only one Agent Session trigger can be enabled per organization, making that agent the default destination for workspace events. ### Agent Sessions vs. Legacy Webhooks Linear triggers support two modes: | Mode | Description | When to Use | | - | - | - | | **Agent Session** (default) | Cotool registers as an agent in Linear. Triggered by @mentions and assignments. | New triggers — recommended for all new setups | | **Legacy Webhook** | Cotool receives a webhook when an issue is created. Requires manual webhook configuration. | Existing triggers created before Agent Session support | New triggers default to Agent Session mode. Existing legacy webhook triggers continue to work and can be kept as-is. ### How Agent Sessions Work When Cotool receives a Linear Agent Session event: 1. Cotool immediately acknowledges with a "Thinking..." status 2. The configured agent processes the request with full issue context 3. Progress is streamed to the Linear thread in real-time (reasoning, tool actions, plan steps) 4. The final response is posted as a reply with a link to the full run in Cotool ### Conversation Continuity Follow-up messages in the same Linear Agent Session thread continue the existing Cotool conversation. The agent retains full context from previous turns, enabling multi-step investigations and iterative workflows. **Example flow:** 1. User @mentions Cotool: *"Investigate alert #5678"* 2. Agent responds with initial findings 3. User follows up: *"Check if this IP was seen in other alerts this week"* 4. Agent continues the same conversation with the new request ### Routing from Tines or Other Automation External automation can select any agent without changing the organization's default Linear trigger. Only the default agent needs an enabled Agent Session trigger; targeted agents do not need Linear triggers of their own. ```bash theme={null} curl -X POST "https://app.cotool.ai/api/agents/$AGENT_ID/linear/agent-session" \ -H "Authorization: Bearer $COTOOL_API_KEY" \ -H "Content-Type: application/json" \ -d '{"issueId":"ITM-123"}' ``` The explicitly selected agent handles the initial request and every follow-up in that Linear Agent Session. The one enabled trigger remains the default transport for direct @mentions, assignments, and API-created sessions. See [Routing Different Agents from External Automation](/integrations/ticketing/linear#routing-different-agents-from-external-automation) for setup details, optional fields, and the response format. ### Fallback to Personal Chats If no Linear trigger is configured for your workspace, Cotool falls back to creating a personal chat for the requesting user (similar to Slack DMs). The user's Linear email must match a Cotool account. ### Stopping an Agent Users can stop a running agent directly from Linear. Cotool will interrupt the execution and confirm the stop in the Linear thread. For full details on the Linear integration, including setup, available tools, and best practices, see the [Linear Integration](/integrations/ticketing/linear) page. ## SEON Triggers SEON triggers run an agent, or create an alert, when SEON sends a webhook event such as a transaction, case, alert, or AML update. 1. On the agent's **Triggers** tab, click **Add trigger** and choose **SEON**. 2. Copy the webhook URL. 3. In SEON, go to **Settings > System > Webhooks**, click **Create new**, paste the URL, and pick the events to send. Cotool answers SEON's test ping so the webhook saves. 4. Add a signing key to the webhook in SEON, then paste it into the **SEON signing key** field in Cotool and save. Cotool checks the `SEON-Signature` header on every event and rejects unsigned or stale events. SEON retries a failed delivery with the same `Request-Id`, and Cotool runs each `Request-Id` only once. # Alerts Source: https://docs.cotool.ai/alerts/overview Track security work from detection through triage and disposition Alerts are first-class security work items in Cotool. They give analysts one place to see what needs attention, what produced it, who or what is working it, and how it was resolved. ## What creates alerts Cotool creates alerts from two source types: > [card] Cotool detections > > Recorded detection hits create alerts with the detection name, severity, > evidence, and source payload. > [card] Response-agent triggers > > Jira, Linear, email, webhook, Bugcrowd, Slack, and scheduled triggers > can create alerts when **Create alert on trigger** is enabled. > [!NOTE] > > Manual alert creation and human assignees are not part of the current alert > workflow. Alerts are generated by configured sources and can be assigned to > response agents for triage. ## Alert fields Each alert has: * **ID**: a readable `COT-###` identifier * **Title and description**: editable summary fields for the analyst-facing story * **Status**: the alert lifecycle and final disposition * **Severity**: `Low`, `Medium`, `High`, or `Critical` * **Source**: Cotool Detection or the trigger source that created the alert * **Detection**: the Cotool detection or extracted external detection name, when known * **Assignee**: the response agent currently triaging the alert * **Activity**: comments, status changes, assignment changes, triage runs, and source events * **Payload**: the original detection-hit or trigger payload, when available ## Statuses and dispositions Alert status combines workflow state and final disposition: | Status | Meaning | | - | - | | **Open** | The alert exists and is not actively being triaged. | | **In Progress** | A response agent or user has started triage. | | **Escalated** | Triage found something that needs higher-attention human review. | | **Closed · True Positive** | A human closed the alert as malicious or security-relevant. | | **Closed · False Positive** | The alert was not a valid finding. | | **Closed · Benign** | The activity was real but expected, authorized, or otherwise benign. | | **Duplicate** | The alert was archived because another alert is the canonical record. | Response agents cannot close an alert as **True Positive**. If an agent confirms malicious or security-relevant activity, it escalates the alert for a human to close. > [!NOTE] > > **Duplicate** is an archive state. Duplicate alerts are hidden from active > alert lists so your team can keep working from the canonical alert instead. ## The Alerts page Go to **Triage > Alerts** to review active security work. You can: * Search across alert IDs, titles, descriptions, detection names, and origin references * Filter by status, severity, source, and detection * Open an alert detail page from the list * Select multiple alerts and bulk update status * Assign one or more open, unassigned alerts to a response agent When your organization has no default response agent for detection-created alerts, the Alerts page shows a routing CTA. Detection alerts are still created, but they wait for manual assignment until routing is configured. ## Related pages > [card] [Work an alert](/alerts/working-alerts) > > Triage, comment, edit, assign, and close alerts. > [card] [Alert routing](/alerts/routing) > > Configure how detections and triggers reach response agents. # Alert Routing Source: https://docs.cotool.ai/alerts/routing Route new alerts to response agents and escalated alerts to destinations Alert routing controls where alerts go after Cotool creates them: which response agent triages each new alert, and where escalated alerts are announced. Both use the same kind of ordered **routes**, so they behave the same way. ## Open routing Go to **Settings > Routing**. The page has two sections, each with an ordered list of routes: * **Alert Triage Routing** chooses which response agent triages each new alert from a Cotool detection or an agent. * **Escalated Alert Notification Routing** chooses where an escalated alert is announced. Each section opens as a read-only table. Choose **Edit** to change it, then **Save** in the bar at the bottom of the page, or **Cancel** to leave without changes. You can also see routing where it applies: * A Cotool detection's **Settings** tab shows a small graph of where its next alert goes: the triage route it matches, the agent that triages it, then the escalation route and the destinations notified. * An agent's page shows the same graph for the alerts the agent creates, and, for an agent that triages alerts, every detection, agent, and trigger whose alerts it triages. Every node in these graphs links to its detection, its agent, or its section of **Settings > Routing**. ## How routes work A route has a name, one or more conditions, and what to do with the alerts it matches. Routes are checked from top to bottom, and the **first enabled route whose conditions all match** wins. Alerts that no route matches fall through to the default at the bottom of the list. A route can match on: | Condition | Matches | | - | - | | **Detection queries** | Alerts from Cotool detections whose published version queries any of the chosen Cotool Logs tables, such as Okta or Azure Event Hub › Entra ID diagnostic logs | | **Detection is** | Alerts from any of the chosen Cotool detections | | **Alert created by agent** | Alerts an agent created with its create-alert tool, and alerts raised by a legacy detection agent | When a route has several conditions, an alert has to match all of them. Because table conditions follow what a detection queries, a detection you add later, including one from the detection library, is routed as soon as it is published. ## Triage routing Triage routes decide which response agent triages a new alert from a Cotool detection or an agent. Each route either sends matching alerts to an agent, which starts a triage run right away, or leaves them **Unassigned** so they stay open for a person. Alerts that no route matches go to the **default agent**. If the default is **Leave unassigned**, those alerts stay open and unassigned. ### Edit triage routes 1. Go to **Settings > Routing** and choose **Edit** next to **Alert Triage Routing**. 2. Add, reorder, or remove routes, and choose an agent (or **Unassigned**) for each. 3. Choose the default agent in **Default route**. 4. Choose **Save**. To check where one detection's or agent's alerts go, open its page and look at its routing graph. If a route's agent is deleted, the route is skipped and its alerts fall through to the next matching route. A route never sends an agent's own alerts back to that agent. Routes can't send alerts between agents in a loop, for example Agent A's alerts to Agent B and Agent B's alerts back to Agent A, including through the default agent. Saving routes or a default agent that would do that fails and names the agents in the loop. If a loop forms later, for example when an agent gets the create-alert tool, Cotool doesn't start triage on an alert routed to an agent that already created an alert in the chain that led to it, or on an alert more than five alerts down such a chain. The alert stays unassigned, with a comment saying why. A list holds up to 50 routes. Routes copied from per-detection routing rules can make a longer list, which you can edit and save at its current length but can't add to. Changing triage routing requires the **Manage Alerts** permission. > [!TIP] > > Use an **Unassigned** route for detections that should create reviewable > alerts but should not automatically start agent triage. ## Escalation notifications Escalated alert notifications use the same kind of routes, so the same conditions match, plus one more: **Alert triaged by agent** matches the response agent the alert is assigned to for triage. Triage routes cannot use it, because they choose that agent. They are configured in **Settings > Routing** under **Escalated Alert Notification Routing**: choose **Edit** to turn notifications on, set a minimum severity, add routes that send matching escalations to their own destinations, and choose default destinations for everything else. **Settings > Notifications** shows how they are set and links there. Alerts created by triggers only match on the agent that triaged them, which is the trigger's own agent. Hunt alerts always go to the default destinations. Each destination on a route or in the defaults has its own severity setting next to it, on top of the minimum severity. **Any severity** sends it every escalation the minimum allows; **Critical only**, for example, sends it only critical alerts. A route can send every escalation to a Slack channel and only critical ones to incident.io this way. A route still handles every alert its conditions match, so an alert below all of its destinations' settings notifies nobody instead of moving on to the next route. Alerts of unknown severity go only to destinations set to **Any severity**. Hunt alerts honor the default destinations' settings. ### Status changes in Slack A Slack escalation notification keeps up with the alert. When anyone changes the alert's status, from Cotool, Slack, or a triage agent, the notification is edited to show the new status and the person who set it. A reply in its thread says what the status changed to, who changed it, and why. In a channel where the alert already has a thread, the reply goes in that thread instead. ### Declare incidents in incident.io An **incident.io** destination declares an incident in incident.io for each escalated alert it is sent, and the alert's notification card links to it. Connect incident.io in **Tools** first, then create the destination from an escalation route or the default destinations. Choose the incident.io severity to declare incidents with (a new destination starts on your least severe one), whether they are private or public, and optionally an incident type; otherwise incident.io applies its default type. Private is the default. Only the incident's responders and people with access to private incidents can open a private incident, so the link on the alert asks anyone else to request access. **Send test** declares a test incident, which does not page anyone. incident.io destinations only receive escalated alerts and Hunt alerts. A Hunt alert declares one incident per destination: when it is refreshed, its notification links to the incident it already declared. incident.io allows 10 new incidents an hour. Past that, Cotool keeps trying each incident for up to two hours, then reports the delivery as failed. ## Trigger-created alerts Response-agent triggers can create alerts when **Create alert on trigger** is enabled. Default behavior by trigger type: | Trigger | Default | | - | - | | Email | Create alerts | | Webhook | Create alerts | | Jira | Create alerts | | Jira Automation | Create alerts | | Linear | Create alerts | | Bugcrowd | Create alerts | | SEON | Create alerts | | Slack | Do not create alerts | | Schedule | Do not create alerts | You can change the toggle when creating or editing the trigger on its agent's page. Trigger-created alerts are assigned to the response agent that owns the trigger, and Cotool starts that agent's triage run from the alert. To move a trigger to another agent, edit it and choose the new **Agent**; its URL, secret, and email address keep working. Cotool stores the original trigger payload with the alert. The alert detail page shows the payload in **Alert Payload** when it is available. ## Routing outcomes | Source | If routing is configured | If routing is not configured | | - | - | - | | Cotool detection | Alert is created and the matching route's or the default agent's triage starts. | Alert is created open and unassigned. | | Response-agent trigger | Alert is created for the trigger's response agent when the toggle is on. | No alert is created when the toggle is off. | ## Keep routing healthy Review **Settings > Routing** when: * New detection alerts are piling up as open and unassigned * A response agent is deleted or disabled * A detection or a group of detections should be handled by a different response agent than the organization default * A trigger is producing too many or too few alerts # Working Alerts Source: https://docs.cotool.ai/alerts/working-alerts Investigate alerts, start response-agent triage, and record dispositions Use the alert detail page to move an alert from detection or intake through investigation and closure. ## Open an alert 1. Go to **Triage > Alerts**. 2. Search or filter the list. 3. Select an alert to open its detail page. The detail page shows the alert title, description, payload, source metadata, severity, status, assignee, and activity timeline. ## Update the alert record Analysts can keep the alert record current while triage progresses: * Click the title to rename it. * Click the description to edit the markdown summary. * Use the **Severity** menu to change severity. * Use the **Status** menu to move the alert through its lifecycle. * Add timeline comments in **Activity**. Every change is recorded in the alert activity timeline. ### Slack replies in Activity When Cotool posts an alert to Slack, as a New Alert post or an escalation, people's replies in that post's thread show in the alert's **Activity** as a Slack thread card. Edits and deletes in Slack update the card. Bot and agent replies are left out, and you reply from Slack, not from Cotool. The card keeps the latest 200 replies of each thread. Replies posted in the few seconds before Cotool records the Slack post are not mirrored. Response agents see the latest 20 replies of each thread, shortened, as context from channel members. > [!NOTE] > > Thread replies need the `message.channels` and `message.groups` bot events > in the Slack app. If your organization uses its own custom Slack app, an > admin must add both to its **Event Subscriptions**. They need no new scopes. ## Start response-agent triage Assigning a response agent starts triage immediately. **1. Choose an assignee** In the alert sidebar, open **Assignee** and select a response agent. **2. Cotool creates a triage run** Cotool starts a response-agent run with the alert context, recent activity, source metadata, and alert-triage instructions. **3. Review the live run** The triage run opens in a side drawer so you can watch reasoning, tool calls, and final output without leaving the alert. **4. Continue if needed** If the run asks for input or you want a follow-up, continue the conversation from the drawer. > [!NOTE] > > Only one response agent can actively triage an alert at a time. If a triage > run is still running, wait for it to finish or stop it from the timeline > before reassigning. ## What response agents do during alert triage When a response agent handles an alert, Cotool automatically adds alert-triage instructions to the run. The agent is expected to: * Read the latest alert context and timeline * Investigate with its available tools * Improve a generic title or description before changing status * Add a final summary comment with evidence, conclusion, and gaps * Update status before completing * Escalate confirmed malicious or security-relevant alerts for human review Response agents get native alert tools for reading the alert, adding comments, updating status, and updating title or description. They should not create a second alert for the same work. ## Close or reopen an alert Close an alert by choosing one of the terminal statuses: * **Closed · True Positive** * **Closed · False Positive** * **Closed · Benign** Reopen a closed alert by setting it back to **Open** or **In Progress**. The previous disposition remains visible in the activity timeline. ## Mark an alert as duplicate Use **Duplicate** when another alert should become the single record your team works from. **1. Choose Duplicate** From the alert's **Status** menu, select **Duplicate**. **2. Find the canonical alert** Search by alert ID or title, then choose the alert this one duplicates. **3. Confirm the link** Cotool marks the current alert as a duplicate of the canonical alert and records the relationship in both alert timelines. If you choose an alert that is itself a duplicate, Cotool links to its canonical alert instead. If the current alert already has duplicates, they move to the canonical alert too. **4. Continue work from the canonical alert** Duplicate alerts are archived and removed from active alert lists, so future triage should happen on the canonical alert. > [!NOTE] > > You can also mark multiple alerts as duplicates from the Alerts list by > using bulk status updates. ## Permissions Alert workflows use these permissions: | Permission | Allows | | - | - | | `alert.triage` | Comment on alerts and change alert status. | | `alert.manage` | Start response-agent triage and manage alert routing. | | `agent.execute` | Run the selected response agent. | | `agent.read` | Read alerts tied to agents the user can access. | Starting triage requires both `alert.manage` and `agent.execute` for the response agent. # Dismiss critical issue Source: https://docs.cotool.ai/api-reference/agent-runs/dismiss-critical-issue https://app.cotool.ai/api/docs/openapi.json post /api/critical-issues/{issueId}/dismiss Dismiss an open critical issue so it no longer appears in the active issues feed. # Get detailed feedback metrics for an agent Source: https://docs.cotool.ai/api-reference/agent-runs/get-detailed-feedback-metrics-for-an-agent https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/feedback-metrics Retrieves comprehensive feedback metrics for a single agent including time-series data, per-prompt breakdown (optional), and all-time statistics # Get LLM evaluation metrics Source: https://docs.cotool.ai/api-reference/agent-runs/get-llm-evaluation-metrics https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/llm-eval-metrics Retrieve system LLM evaluation metrics for an agent (default evaluator: llm-judge). # Get LLM evaluation metrics for multiple agents Source: https://docs.cotool.ai/api-reference/agent-runs/get-llm-evaluation-metrics-for-multiple-agents https://app.cotool.ai/api/docs/openapi.json post /api/agents/llm-eval-metrics/batch Retrieve system LLM evaluation metrics (llm-judge) for multiple agents in batch. # Get response-agent notification defaults Source: https://docs.cotool.ai/api-reference/agent-runs/get-response-agent-notification-defaults https://app.cotool.ai/api/docs/openapi.json get /api/response-agent-notification-defaults Retrieve organization-wide default notification settings for response-agent run failures, acceptance criteria failures, critical issues, and evaluation scores below the threshold. # List agent runs Source: https://docs.cotool.ai/api-reference/agent-runs/list-agent-runs https://app.cotool.ai/api/docs/openapi.json get /api/agent-runs Retrieve a paginated list of historical agent execution runs with optional filters. # List agent runs/chats Source: https://docs.cotool.ai/api-reference/agent-runs/list-agent-runschats https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/chats Retrieve a paginated list of runs/chats associated with a specific agent. # List critical issues Source: https://docs.cotool.ai/api-reference/agent-runs/list-critical-issues https://app.cotool.ai/api/docs/openapi.json get /api/critical-issues Retrieve normalized critical issues from agent evaluations and code-detection circuit breakers. # List output deliveries and notifications for an agent run Source: https://docs.cotool.ai/api-reference/agent-runs/list-output-deliveries-and-notifications-for-an-agent-run https://app.cotool.ai/api/docs/openapi.json get /api/agent-runs/{runId}/deliveries Returns each output delivery and acceptance-criteria notification issued for the run, with its status, what was sent, and the most recent error. # List trigger sources Source: https://docs.cotool.ai/api-reference/agent-runs/list-trigger-sources https://app.cotool.ai/api/docs/openapi.json get /api/agent-runs/trigger-sources Retrieve all distinct trigger sources used across agent runs in this organization. # Resend a failed output delivery or notification Source: https://docs.cotool.ai/api-reference/agent-runs/resend-a-failed-output-delivery-or-notification https://app.cotool.ai/api/docs/openapi.json post /api/agent-runs/{runId}/deliveries/{deliveryId}/resend Opens a new attempt for a failed delivery, sending the content the turn and evaluation hold now. Only deliveries in the failed state whose destination still exists can be resent; the send is real and may create a message/incident/issue/case in the destination. # Submit feedback for an agent run Source: https://docs.cotool.ai/api-reference/agent-runs/submit-feedback-for-an-agent-run https://app.cotool.ai/api/docs/openapi.json post /api/agent-runs/{runId}/feedback Submits user feedback (thumbs up/down) for a specific agent run, optionally including a comment and chat event reference # Submit feedback for multiple agent runs Source: https://docs.cotool.ai/api-reference/agent-runs/submit-feedback-for-multiple-agent-runs https://app.cotool.ai/api/docs/openapi.json post /api/agent-runs/feedback-batch Submits user feedback (thumbs up/down) for multiple agent runs in a single batch operation # Update response-agent notification defaults Source: https://docs.cotool.ai/api-reference/agent-runs/update-response-agent-notification-defaults https://app.cotool.ai/api/docs/openapi.json put /api/response-agent-notification-defaults Update organization-wide default notification settings inherited by response agents. # Change trigger settings Source: https://docs.cotool.ai/api-reference/agent-triggers/change-trigger-settings https://app.cotool.ai/api/docs/openapi.json patch /api/agents/{agentId}/trigger/{triggerId} Change some of a trigger's settings in one update, keeping the rest. allowedChannelIds applies only to Slack triggers and schedule only to cron triggers. # Create Linear agent session for an agent Source: https://docs.cotool.ai/api-reference/agent-triggers/create-linear-agent-session-for-an-agent https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/linear/agent-session Creates a Linear Agent Session on an issue and routes the session and its follow-ups to the selected agent using the organization's enabled Linear trigger. # Delete trigger Source: https://docs.cotool.ai/api-reference/agent-triggers/delete-trigger https://app.cotool.ai/api/docs/openapi.json delete /api/agents/{agentId}/trigger/{triggerId} Delete an existing trigger from an agent. # Get webhook fields Source: https://docs.cotool.ai/api-reference/agent-triggers/get-webhook-fields https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/trigger/{source}/fields Generate a webhook URL, secret, and any additional fields required to configure an external webhook for a trigger. # Get webhook fields for a trigger source Source: https://docs.cotool.ai/api-reference/agent-triggers/get-webhook-fields-for-a-trigger-source https://app.cotool.ai/api/docs/openapi.json get /api/trigger-sources/{source}/fields Generate a webhook URL, secret, and any additional fields required to configure an external webhook, before the trigger is assigned to an agent. # List agent triggers Source: https://docs.cotool.ai/api-reference/agent-triggers/list-agent-triggers https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/trigger Retrieve all triggers configured for a specific agent. # Move trigger to another agent Source: https://docs.cotool.ai/api-reference/agent-triggers/move-trigger-to-another-agent https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/trigger/{triggerId}/move Re-assign a trigger to a different agent. The webhook URL and secret are unchanged (they embed only the trigger id), so externally configured webhooks keep working. # Retrieve an agent trigger secret Source: https://docs.cotool.ai/api-reference/agent-triggers/retrieve-an-agent-trigger-secret https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/trigger/{triggerId}/secret Retrieve a trigger signing secret. Requires edit access to the owning agent. # Save trigger definition Source: https://docs.cotool.ai/api-reference/agent-triggers/save-trigger-definition https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/trigger/save Create and save a new trigger definition for Jira, Jira Automation, Slack, Linear, Cron, generic Webhook, HackerOne, Bugcrowd, Zscaler, Darktrace, or SEON sources. # Update trigger alert-created notification Source: https://docs.cotool.ai/api-reference/agent-triggers/update-trigger-alert-created-notification https://app.cotool.ai/api/docs/openapi.json put /api/agents/{agentId}/trigger/{triggerId}/alert-created-notification Choose the Slack destinations notified when the trigger creates an alert. The alert's status updates and escalations reply in the thread that notification starts. # Update trigger definition Source: https://docs.cotool.ai/api-reference/agent-triggers/update-trigger-definition https://app.cotool.ai/api/docs/openapi.json put /api/agents/{agentId}/trigger/{triggerId} Modify metadata or configuration of an existing trigger. # Update trigger event mode Source: https://docs.cotool.ai/api-reference/agent-triggers/update-trigger-event-mode https://app.cotool.ai/api/docs/openapi.json patch /api/agents/{agentId}/trigger/{triggerId}/event-mode Set whether a trigger creates an alert before running the agent or runs the agent directly. # Update trigger status Source: https://docs.cotool.ai/api-reference/agent-triggers/update-trigger-status https://app.cotool.ai/api/docs/openapi.json patch /api/agents/{agentId}/trigger/{triggerId}/status Enable or disable a trigger for the specified agent. # Webhook trigger Source: https://docs.cotool.ai/api-reference/agent-triggers/webhook-trigger https://app.cotool.ai/api/docs/openapi.json post /api/trigger/{source}/{triggerId} Invoke an agent trigger via incoming webhook. External services post to this endpoint. # Validate Response-Agent-as-Code YAML Source: https://docs.cotool.ai/api-reference/agents-as-code/validate-response-agent-as-code-yaml https://app.cotool.ai/api/docs/openapi.json post /api/agent-sync/validate Validate Response-Agents-as-Code YAML without syncing it. Runs the same parse, schema, and cross-file checks as the GitOps sync engine, so a CI check stays in step with real sync behavior. Typically used to validate agent files in a pull request before they merge. **Request.** Post each file as a `{ path, content }` pair. The validator has no access to your repo, so you send the raw file text. Post one file to check it on its own, or a whole directory to also catch cross-file issues like duplicate `sync_key` values and dependency cycles. Include any prompt `.md` files referenced by `systemPrompt.file` so those references resolve. **Response.** An overall `valid` flag, plus per file an `errors` list (these would block a sync) and a `warnings` list (non-blocking). Warnings are checks that need live workspace state the request cannot see, such as an unprovided `systemPrompt.file` or a reference to an agent that is not in the request. **Authentication.** Send a bearer token. **GitHub OIDC is the recommended method:** in GitHub Actions, use the [`cotool/validate-agents` Action](/agents/response-agents-as-code#validate-in-ci), which mints a short-lived, repo-scoped token (no stored secret; the repository must be connected for GitOps sync) that grants validate-only access. A Cotool API key with the `tool.manage` permission also works for non-GitHub or self-hosted CI, but it is long-lived and inherits the full permissions of the user who created it, so prefer OIDC and treat any API key as a sensitive, least-privilege secret. # Batch update agents Source: https://docs.cotool.ai/api-reference/agents/batch-update-agents https://app.cotool.ai/api/docs/openapi.json put /api/agents/batch Atomically update many agents in a single SERIALIZABLE transaction. The entire batch succeeds or rolls back together; this avoids partial-failure modes seen when issuing many concurrent single-agent updates that conflict on the same rows. # Change agent tag color Source: https://docs.cotool.ai/api-reference/agents/change-agent-tag-color https://app.cotool.ai/api/docs/openapi.json patch /api/agent-tags/{tagId}/color Change a tag display color for the organization. Requires setting.tags.manage permission. # Convert a disconnected managed agent into a manual agent Source: https://docs.cotool.ai/api-reference/agents/convert-a-disconnected-managed-agent-into-a-manual-agent https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/copy Convert a sync-managed (GitOps) agent whose integration is disconnected into an editable manual agent: copies its config + prompt, transfers its trigger rows (preserving email/webhook/Slack bindings), and parks the managed original as a recoverable soft-delete. # Create a new agent Source: https://docs.cotool.ai/api-reference/agents/create-a-new-agent https://app.cotool.ai/api/docs/openapi.json post /api/agents Create a new AI agent with specified configuration including system prompt, tools, and model settings # Create agent tag Source: https://docs.cotool.ai/api-reference/agents/create-agent-tag https://app.cotool.ai/api/docs/openapi.json post /api/agent-tags Create a new tag in the organization. # Delete agent Source: https://docs.cotool.ai/api-reference/agents/delete-agent https://app.cotool.ai/api/docs/openapi.json delete /api/agents/{agentId} Remove an agent from the system. # Delete agent tag Source: https://docs.cotool.ai/api-reference/agents/delete-agent-tag https://app.cotool.ai/api/docs/openapi.json delete /api/agent-tags/{tagId} Delete a tag from the organization. Requires setting.tags.manage permission. Will fail if the tag is still assigned to any agents. # Get agent Source: https://docs.cotool.ai/api-reference/agents/get-agent https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId} Retrieve detailed information about a specific agent by ID. # Get async run result Source: https://docs.cotool.ai/api-reference/agents/get-async-run-result https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/run-async/{runId}/result Retrieve the completed result of an asynchronous agent run. Use the status endpoint first and call this endpoint once the run status is `done`. # Get async run status Source: https://docs.cotool.ai/api-reference/agents/get-async-run-status https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/run-async/{runId}/status Retrieve streaming status or error information for an asynchronous agent run. Once the returned status is `done`, call `/api/agents/:agentId/run-async/:runId/result` for the completed payload. # Get async run status (deprecated) Source: https://docs.cotool.ai/api-reference/agents/get-async-run-status-deprecated https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/run-async/{runId} > ⚠️ **Deprecated** > Superseded by the run status endpoint, which returns the run status (queued, running, waiting, done, error, interrupted) and any status message instead of a bare isStreaming flag. Poll GET /api/agents/{agentId}/run-async/{runId}/status until status is done, error, or interrupted, then fetch GET /api/agents/{agentId}/run-async/{runId}/result. No sunset is scheduled. > **Use instead:** `/api/agents/:agentId/run-async/:runId/status` Retrieve streaming status or error information for an asynchronous agent run. # List agent run messages Source: https://docs.cotool.ai/api-reference/agents/list-agent-run-messages https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/run-async/{runId}/messages Page through an agent run's conversation, oldest first: messages to the agent, its replies, and its tool calls with their output. Works at any run status. A message keeps its offset as the run grows; the latest page starts at `totalCount - limit`. # List agent tags Source: https://docs.cotool.ai/api-reference/agents/list-agent-tags https://app.cotool.ai/api/docs/openapi.json get /api/agent-tags Retrieve all tags available in the organization with their usage counts. # List agent templates Source: https://docs.cotool.ai/api-reference/agents/list-agent-templates https://app.cotool.ai/api/docs/openapi.json get /api/agent-templates Retrieve all available agent templates for the current organization. # List agent versions Source: https://docs.cotool.ai/api-reference/agents/list-agent-versions https://app.cotool.ai/api/docs/openapi.json get /api/agents/{agentId}/versions List the whole-definition version timeline for an agent (newest first) # List all agents Source: https://docs.cotool.ai/api-reference/agents/list-all-agents https://app.cotool.ai/api/docs/openapi.json get /api/agents Retrieve a list of all AI agents available in the organization # Rename agent tag Source: https://docs.cotool.ai/api-reference/agents/rename-agent-tag https://app.cotool.ai/api/docs/openapi.json put /api/agent-tags/{tagId} Rename a tag in the organization. Requires setting.tags.manage permission. # Revert an agent to a previous version Source: https://docs.cotool.ai/api-reference/agents/revert-an-agent-to-a-previous-version https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/versions/{versionId}/revert Re-applies a previously-recorded version's whole-definition snapshot (prompt + spec + tags + skills) onto the live agent, recording a new head version equal to the chosen one. Requires agent.edit. # Run agent asynchronously Source: https://docs.cotool.ai/api-reference/agents/run-agent-asynchronously https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/run-async Start an asynchronous agent run and return a runId that can be polled for status updates. Once the run status is `done`, call `/api/agents/:agentId/run-async/:runId/result` to retrieve the same final payload shape returned by the synchronous run endpoint. # Run agent synchronously Source: https://docs.cotool.ai/api-reference/agents/run-agent-synchronously https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/run-sync Execute an agent run in a blocking manner and return the complete result once finished. A run still going after 8 minutes keeps running, and the request returns `202 Accepted` with code `run_still_running`, the `runId`, and a `Location` header pointing at `/api/agents/:agentId/run-async/:runId/status`; poll it (after `Retry-After` seconds) and read `/api/agents/:agentId/run-async/:runId/result` once it is `done`. Use `/api/agents/:agentId/run-async` for runs that can take longer. # Send a message to an agent run Source: https://docs.cotool.ai/api-reference/agents/send-a-message-to-an-agent-run https://app.cotool.ai/api/docs/openapi.json post /api/agents/{agentId}/run-async/{runId}/messages Continue an existing agent run with a follow-up message, as if it were typed in the run's chat. The agent keeps the run's full context. A run that is busy answers once its current turn ends. Poll `/api/agents/:agentId/run-async/:runId/status` until `done`, then read the reply from `/api/agents/:agentId/run-async/:runId/result`. # Update agent Source: https://docs.cotool.ai/api-reference/agents/update-agent https://app.cotool.ai/api/docs/openapi.json put /api/agents/{agentId} Modify an agent's configuration, such as tools, prompts, or model settings. # Add alert comment Source: https://docs.cotool.ai/api-reference/alerts/add-alert-comment https://app.cotool.ai/api/docs/openapi.json post /api/alerts/{alertId}/comments Append a timeline comment to an alert. # Confirm an alert feedback question Source: https://docs.cotool.ai/api-reference/alerts/confirm-an-alert-feedback-question https://app.cotool.ai/api/docs/openapi.json post /api/alerts/feedback-questions/{questionId}/confirm Confirm a question across the escalated alerts the reviewer was shown, closing each with its disposition. Alerts that are no longer escalated or no longer offer the explanation are skipped. Rejecting the question stops any closes still to come. # Get alert Source: https://docs.cotool.ai/api-reference/alerts/get-alert https://app.cotool.ai/api/docs/openapi.json get /api/alerts/{alertId} Retrieve one alert and its initial timeline page. # Get alert filter options Source: https://docs.cotool.ai/api-reference/alerts/get-alert-filter-options https://app.cotool.ai/api/docs/openapi.json get /api/alerts/filter-options Return alert filter options derived from readable alerts, including Cotool and externally extracted detections. # Get alert for run Source: https://docs.cotool.ai/api-reference/alerts/get-alert-for-run https://app.cotool.ai/api/docs/openapi.json get /api/alerts/for-run/{runId} Resolve the alert a run triaged or created, used to link an agent run back to its alert. # Get alert routing overview Source: https://docs.cotool.ai/api-reference/alerts/get-alert-routing-overview https://app.cotool.ai/api/docs/openapi.json get /api/alert-routing Return detection alert routing defaults, per-detection effective routing, alert producers, and response-agent handling summary. # Get alert source payload Source: https://docs.cotool.ai/api-reference/alerts/get-alert-source-payload https://app.cotool.ai/api/docs/openapi.json get /api/alerts/{alertId}/source-payloads/{sourcePayloadId} Retrieve the stored raw source payload for an alert. # Get alert timeline Source: https://docs.cotool.ai/api-reference/alerts/get-alert-timeline https://app.cotool.ai/api/docs/openapi.json get /api/alerts/{alertId}/timeline Retrieve paginated timeline entries for an alert. # Get alert triage routes Source: https://docs.cotool.ai/api-reference/alerts/get-alert-triage-routes https://app.cotool.ai/api/docs/openapi.json get /api/alert-triage-routes Return the ordered routes that choose which agent triages a new alert, with the organization default for alerts no route matches and the agent for Hunt Alerts, which skip both. # Get detection alert routing Source: https://docs.cotool.ai/api-reference/alerts/get-detection-alert-routing https://app.cotool.ai/api/docs/openapi.json get /api/detections/{id}/alert-routing Return a detection agent alert routing override and effective routing setting. # Get escalated alert notification defaults Source: https://docs.cotool.ai/api-reference/alerts/get-escalated-alert-notification-defaults https://app.cotool.ai/api/docs/openapi.json get /api/alert-escalation-notification-defaults Get the organization-wide destinations notified when an alert moves into escalated status. # List alert feedback questions Source: https://docs.cotool.ai/api-reference/alerts/list-alert-feedback-questions https://app.cotool.ai/api/docs/openapi.json get /api/alerts/feedback-questions List the questions grouped from alternative explanations on escalated alerts, ordered by how many alerts confirming one would close. Empty unless the caller can triage every alert. # List alerts Source: https://docs.cotool.ai/api-reference/alerts/list-alerts https://app.cotool.ai/api/docs/openapi.json get /api/alerts Retrieve first-class alert work items for the current organization. Archived dismissed, duplicate, and expired alerts are excluded unless a status filter is provided. # Reject an alert feedback question Source: https://docs.cotool.ai/api-reference/alerts/reject-an-alert-feedback-question https://app.cotool.ai/api/docs/openapi.json post /api/alerts/feedback-questions/{questionId}/reject Mark a question as not true, under either disposition. It is no longer asked on Home, and the explanation generator is told not to offer it again. The alerts stay escalated. # Replace alert triage routes Source: https://docs.cotool.ai/api-reference/alerts/replace-alert-triage-routes https://app.cotool.ai/api/docs/openapi.json put /api/alert-triage-routes Replace the ordered routes that choose which agent triages a new alert, and optionally the default agent for alerts no route matches, in one change. Routes are checked top to bottom; the first enabled route whose conditions all match wins. Returns 400 when the routes and default would send alerts between agents in a loop. # Start alert triage run Source: https://docs.cotool.ai/api-reference/alerts/start-alert-triage-run https://app.cotool.ai/api/docs/openapi.json post /api/alerts/{alertId}/triage-runs Assign an alert to a response agent and enqueue an alert-triage run. # Update alert details Source: https://docs.cotool.ai/api-reference/alerts/update-alert-details https://app.cotool.ai/api/docs/openapi.json patch /api/alerts/{alertId} Update an alert title and/or description and append matching timeline entries. # Update alert severity Source: https://docs.cotool.ai/api-reference/alerts/update-alert-severity https://app.cotool.ai/api/docs/openapi.json post /api/alerts/{alertId}/severity Update an alert severity and append a severity-change timeline entry. # Update alert status Source: https://docs.cotool.ai/api-reference/alerts/update-alert-status https://app.cotool.ai/api/docs/openapi.json post /api/alerts/{alertId}/status Update an alert lifecycle status and append a status-change timeline entry when the status changes. Optional feedback is appended as a comment in the same transaction. Duplicate status requires a canonical alert target. # Update default alert routing Source: https://docs.cotool.ai/api-reference/alerts/update-default-alert-routing https://app.cotool.ai/api/docs/openapi.json put /api/alert-routing/defaults Update the organization-wide default agent for alerts without an explicit route. # Update escalated alert notification defaults Source: https://docs.cotool.ai/api-reference/alerts/update-escalated-alert-notification-defaults https://app.cotool.ai/api/docs/openapi.json put /api/alert-escalation-notification-defaults Update the organization-wide destinations notified when an alert moves into escalated status, and the routes that send matching alerts elsewhere. # Update Hunt Alert routing Source: https://docs.cotool.ai/api-reference/alerts/update-hunt-alert-routing https://app.cotool.ai/api/docs/openapi.json put /api/alert-routing/hunt-alerts Set the agent that triages new Hunt Alerts, or null to leave them unassigned. Hunt Alerts do not use the organization default. # Get artifact Source: https://docs.cotool.ai/api-reference/artifacts/get-artifact https://app.cotool.ai/api/docs/openapi.json get /api/artifacts/{artifactId} Fetch the content and metadata of a stored artifact by its ID for a given chat. # Count audit logs Source: https://docs.cotool.ai/api-reference/audit-logs/count-audit-logs https://app.cotool.ai/api/docs/openapi.json get /api/audit-logs/count Return the total number of audit-log records that match a set of optional filters. # Get audit log entry Source: https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-entry https://app.cotool.ai/api/docs/openapi.json get /api/audit-logs/{id} Retrieve a single audit-log record by its unique identifier. # Get audit-log event catalog Source: https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-event-catalog https://app.cotool.ai/api/docs/openapi.json get /api/audit-logs/event-catalog Retrieve the canonical catalog of every audit-log event type the platform can emit, including events that have never been recorded for this organization. Use /api/audit-logs/filter-options to get only the values present in this org's audit logs. # Get audit-log filter options Source: https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-filter-options https://app.cotool.ai/api/docs/openapi.json get /api/audit-logs/filter-options Retrieve the distinct event types, actors, user IDs, and tool family slugs that appear in this org's audit logs. Used by the audit-logs UI to populate filter dropdowns with only values that actually yield results. # List audit logs Source: https://docs.cotool.ai/api-reference/audit-logs/list-audit-logs https://app.cotool.ai/api/docs/openapi.json get /api/audit-logs Return a paginated list of audit logs filtered by query parameters such as userId, event type, date range, etc. Supports two pagination modes: limit/offset (default), and keyset cursors for continuous export — when a page is full, the X-Next-Cursor response header carries an opaque cursor for the next page; pass it back as the cursor query parameter. An absent header (or a short page) means there is no more data. Cursor pages stay equally fast at any depth, unlike large offsets. # Delete chat Source: https://docs.cotool.ai/api-reference/chat/delete-chat https://app.cotool.ai/api/docs/openapi.json delete /api/chats/{chatId} Delete a chat conversation by its unique identifier. # Get chat history Source: https://docs.cotool.ai/api-reference/chat/get-chat-history https://app.cotool.ai/api/docs/openapi.json get /api/chat/history Retrieve all events and chat metadata for the specified chat conversation. If the chat has a structured output schema, the generated structured output is returned in `chat.result`. # Get chat metadata Source: https://docs.cotool.ai/api-reference/chat/get-chat-metadata https://app.cotool.ai/api/docs/openapi.json get /api/chat/meta Retrieve lightweight chat metadata (title and per-event feedback) without loading the full event history. Prefer this over /api/chat/history when only the chat header (title + feedback) is needed. # List chats Source: https://docs.cotool.ai/api-reference/chat/list-chats https://app.cotool.ai/api/docs/openapi.json get /api/chats Retrieve a paginated list of chats for the current user or agent. # Submit thumbs feedback for a chat Source: https://docs.cotool.ai/api-reference/chat/submit-thumbs-feedback-for-a-chat https://app.cotool.ai/api/docs/openapi.json post /api/chats/{chatId}/feedback Records a thumbs up/down for a chat if the user has access to it. # Disconnect CLI Source: https://docs.cotool.ai/api-reference/clis/disconnect-cli https://app.cotool.ai/api/docs/openapi.json delete /api/clis/{cliType}/disconnect Remove stored credentials for a CLI integration. # List CLI integrations Source: https://docs.cotool.ai/api-reference/clis/list-cli-integrations https://app.cotool.ai/api/docs/openapi.json get /api/clis/list Return a grouped list of CLI integrations available to the organization. # Add a detection library entry Source: https://docs.cotool.ai/api-reference/detections/add-a-detection-library-entry https://app.cotool.ai/api/docs/openapi.json post /api/detection-library/{slug}/add Creates an org-owned detection from the entry, publishes its notebook as version 1, and enables the entry's default schedule. # Generate a SIEM query using AI Source: https://docs.cotool.ai/api-reference/detections/generate-a-siem-query-using-ai https://app.cotool.ai/api/docs/openapi.json post /api/detection-queries/generate > ⚠️ **Deprecated** > Standalone query generation is superseded by detection authoring with agents. Run an agent that has your SIEM tool attached (POST /api/agents/{agentId}/run-sync) or author detections in the Cotool app. No sunset is scheduled; the endpoint will be removed once its remaining integration retires. > **Use instead:** `/api/agents/:agentId/run-sync` Generates a SIEM query based on a natural language prompt using AI. # List detection hits Source: https://docs.cotool.ai/api-reference/detections/list-detection-hits https://app.cotool.ai/api/docs/openapi.json get /api/detections/hits Retrieve a flattened hit feed across all detections in the current organization. Pass `detectionId` to restrict the feed (and its aggregate summary) to a single detection — used by the detection-agent detail page to surface verifier evidence + cited tool calls without leaving the page. Uses a single batch query instead of N concurrent queries per detection. # List detections Source: https://docs.cotool.ai/api-reference/detections/list-detections https://app.cotool.ai/api/docs/openapi.json get /api/detections Retrieve all detections for the current organization. # List the Cotool detection library Source: https://docs.cotool.ai/api-reference/detections/list-the-cotool-detection-library https://app.cotool.ai/api/docs/openapi.json get /api/detection-library Returns every library entry with eligibility derived at request time from the organization's connected tools, and the org detection created from it when already added. Never includes notebook source. Requires tool.read; added detection IDs are limited to detections the caller can read. # Read one detection library entry Source: https://docs.cotool.ai/api-reference/detections/read-one-detection-library-entry https://app.cotool.ai/api/docs/openapi.json get /api/detection-library/{slug} Returns the entry with its notebook source and the globally cached logic summary, for review before adding. Requires tool.read. # Dismiss a Threat Source: https://docs.cotool.ai/api-reference/hunt/dismiss-a-threat https://app.cotool.ai/api/docs/openapi.json post /api/threats/{id}/dismiss Explicitly dismiss a non-alert Threat (monitoring / covered / clear / blocked / not relevant) with an optional reason. Records who and when. New material positive evidence later auto-restores it. # Dispose a gap via a threat finding Source: https://docs.cotool.ai/api-reference/hunt/dispose-a-gap-via-a-threat-finding https://app.cotool.ai/api/docs/openapi.json post /api/threats/{id}/deliverables/{deliverableId}/gap-status Resolve or dismiss the observability gap behind a threat's gap finding, attributed to the acting human. The disposition applies to the shared gap entity — every linked threat's finding reflects it — and resolving a blocking gap re-assesses all blocked linked threats. # Dispose an observability gap Source: https://docs.cotool.ai/api-reference/hunt/dispose-an-observability-gap https://app.cotool.ai/api/docs/openapi.json post /api/hunt/gaps/{gapId}/status Resolve or dismiss an org-level observability gap once, for every threat it affects. Resolving a blocking gap enqueues a reassessment for each linked threat whose hunt it blocked. # Get Hunt Alert creation settings Source: https://docs.cotool.ai/api-reference/hunt/get-hunt-alert-creation-settings https://app.cotool.ai/api/docs/openapi.json get /api/hunt/alert-creation-settings Get the organization-wide minimum exposure band and compromise-signal override used to create or reopen Hunt Alerts. # Get Threat detail Source: https://docs.cotool.ai/api-reference/hunt/get-threat-detail https://app.cotool.ai/api/docs/openapi.json get /api/threats/{id} A Threat with its assessment runs (newest first), deliverables, and all linked Hunt Alert episodes. # Hunt overview Source: https://docs.cotool.ai/api-reference/hunt/hunt-overview https://app.cotool.ai/api/docs/openapi.json get /api/hunt/overview Landing dashboard: environment metric tiles, the intel -> exposure funnel, detection coverage distribution, and recent Threats / rule proposals / blocking gaps. # List threat actors Source: https://docs.cotool.ai/api-reference/hunt/list-threat-actors https://app.cotool.ai/api/docs/openapi.json get /api/hunt/actors Actor grouping nodes for the current organization, used as Threat catalog filter options. # List Threats Source: https://docs.cotool.ai/api-reference/hunt/list-threats https://app.cotool.ai/api/docs/openapi.json get /api/threats The durable Threat catalog. Filterable by derived status, canonical type, coverage state, exposure state, hunt result badge, actor, linked Alert state, and free-text query. # Reassess a Threat Source: https://docs.cotool.ai/api-reference/hunt/reassess-a-threat https://app.cotool.ai/api/docs/openapi.json post /api/threats/{id}/reassess Manually trigger a fresh Threat-scoped assessment (relevancy gate -> exposure). Enqueues the assessment job; the run streams in the Threat detail activity timeline. # Restore a dismissed Threat Source: https://docs.cotool.ai/api-reference/hunt/restore-a-dismissed-threat https://app.cotool.ai/api/docs/openapi.json post /api/threats/{id}/restore Clear an explicit dismissal, returning the Threat to its derived status. # Update Hunt Alert creation settings Source: https://docs.cotool.ai/api-reference/hunt/update-hunt-alert-creation-settings https://app.cotool.ai/api/docs/openapi.json put /api/hunt/alert-creation-settings Update the organization-wide minimum exposure band and compromise-signal override used to create or reopen Hunt Alerts. # Create intel source Source: https://docs.cotool.ai/api-reference/intel/create-intel-source https://app.cotool.ai/api/docs/openapi.json post /api/intel/sources Creates a custom RSS, MISP, or TAXII intel source # Delete intel source Source: https://docs.cotool.ai/api-reference/intel/delete-intel-source https://app.cotool.ai/api/docs/openapi.json delete /api/intel/sources/{id} Deletes a custom intel source and associated intel items # Get intel feed statistics Source: https://docs.cotool.ai/api-reference/intel/get-intel-feed-statistics https://app.cotool.ai/api/docs/openapi.json get /api/intel/stats Retrieves aggregated statistics for the threat intelligence feed including severity breakdown, platform breakdown, and recent items # Get specific intel item Source: https://docs.cotool.ai/api-reference/intel/get-specific-intel-item https://app.cotool.ai/api/docs/openapi.json get /api/intel/items/{id} Retrieves detailed information for a specific threat intelligence item by its ID # Get threat intel notification settings Source: https://docs.cotool.ai/api-reference/intel/get-threat-intel-notification-settings https://app.cotool.ai/api/docs/openapi.json get /api/intel/notification-settings Retrieve organization-wide threat intel notification settings and available destinations. # List flattened threat-intel indicators (IOCs) Source: https://docs.cotool.ai/api-reference/intel/list-flattened-threat-intel-indicators-iocs https://app.cotool.ai/api/docs/openapi.json get /api/intel/iocs Flattens indicators from all in-scope intel items, resolves per-indicator hunt status, and supports server-side search, status, and type filtering with pagination. # List intel sources Source: https://docs.cotool.ai/api-reference/intel/list-intel-sources https://app.cotool.ai/api/docs/openapi.json get /api/intel/sources Lists built-in and custom intel sources for the current organization # List threat intelligence items Source: https://docs.cotool.ai/api-reference/intel/list-threat-intelligence-items https://app.cotool.ai/api/docs/openapi.json get /api/intel/items Retrieves a paginated list of threat intelligence items with support for filtering by severity, platform, status, source, and text search # Trigger intel source sync Source: https://docs.cotool.ai/api-reference/intel/trigger-intel-source-sync https://app.cotool.ai/api/docs/openapi.json post /api/intel/sources/{id}/sync Enqueues an immediate sync job for a custom intel source # Update intel source Source: https://docs.cotool.ai/api-reference/intel/update-intel-source https://app.cotool.ai/api/docs/openapi.json put /api/intel/sources/{id} Updates a custom intel source or toggles a built-in source subscription # Update threat intel notification settings Source: https://docs.cotool.ai/api-reference/intel/update-threat-intel-notification-settings https://app.cotool.ai/api/docs/openapi.json put /api/intel/notification-settings Update organization-wide threat intel notification settings. # API Overview Source: https://docs.cotool.ai/api-reference/introduction Authenticate, understand responses, and find the endpoints for common integrations Everything you can do in the Cotool app is available over a JSON REST API at `https://app.cotool.ai/api`. If your organization signs in at a different host, use that host instead; the paths are the same. ## Authentication Create an API key at [Settings → API keys](https://app.cotool.ai/settings/api-keys). Creating keys requires the `setting.apiKey.manage` permission. The key is shown once; store it in your secrets manager. Send the key as a bearer token on every request: ```bash theme={null} curl "https://app.cotool.ai/api/agents" \ -H "Authorization: Bearer $COTOOL_API_KEY" ``` An API key acts as the user who created it: same organization, same role, same permissions. Requests that the user could not perform in the app return `403`. Keys cannot use admin-only capabilities or switch organizations, and a key stops working when it is revoked or when its user is deactivated. For integrations that run as a service rather than a person, create the key from a dedicated user whose role grants only the permissions the integration needs. See [Roles and permissions](/settings/roles-permissions-overview). ## Requests and responses Request and response bodies are JSON. Send `Content-Type: application/json` on `POST`, `PUT`, and `PATCH` requests. Errors return a JSON body with an `error` message: | Status | Meaning | Body | | - | - | - | | `400` | Invalid input | `{ "error": "Validation failed", "issues": [...] }` with one entry per failed field | | `401` | Missing, invalid, expired, or revoked API key | `{ "error": "Unauthorized" }` | | `403` | The key's role lacks a required permission | `{ "error": "...", "missingPerms": [...] }` | | `404` | Resource not found, or the endpoint has been removed | `{ "error": "..." }` | | `410` | The endpoint passed its published sunset date | `{ "error": "..." }` naming the replacement | List endpoints paginate with query parameters. Most use `limit` and `offset`; some, such as [List agent runs](/api-reference/agent-runs/list-agent-runs), use `page` and `pageSize`. Each endpoint's reference page lists its parameters and defaults. ## Finding endpoints The sidebar groups endpoints by product surface. Most integrations use a handful of them: * **Agents** run agents and read their results. **Agent Triggers** manage the schedules, webhooks, and integrations that start runs automatically. * **Agent Runs**, **Alerts**, and **Output Destinations** are the run history, the alerts agents raise, and the webhooks and integrations that runs push results to. * **Detections** and **Hunt** expose detection rules, hits, and Autonomous Hunt results for pipelines that pull findings into a SIEM or data lake. * **Audit Logs** exports the organization's audit trail. ## OpenAPI document The reference is generated from the live specification at [`https://app.cotool.ai/api/docs/openapi.json`](https://app.cotool.ai/api/docs/openapi.json). Use it to generate clients or import the API into tools such as Postman. # Get MITRE ATT&CK matrix with detection coverage Source: https://docs.cotool.ai/api-reference/mitre-coverage/get-mitre-att&ck-matrix-with-detection-coverage https://app.cotool.ai/api/docs/openapi.json get /api/mitre/matrix Retrieve the MITRE ATT&CK framework matrix showing detection rule coverage as a heatmap # Get MITRE ATT&CK technique labels Source: https://docs.cotool.ai/api-reference/mitre-coverage/get-mitre-att&ck-technique-labels https://app.cotool.ai/api/docs/openapi.json get /api/mitre/technique-labels Display labels for every technique ID in the MITRE ATT&CK version the platform currently serves # Get organization-level activity metrics Source: https://docs.cotool.ai/api-reference/organizations/get-organization-level-activity-metrics https://app.cotool.ai/api/docs/openapi.json get /api/org-metrics Returns summary counts and timeseries for agent runs, chats, and GitHub PR actions for the authenticated organization. # Create output destination Source: https://docs.cotool.ai/api-reference/output-destinations/create-output-destination https://app.cotool.ai/api/docs/openapi.json post /api/output-destinations Create a new output destination (webhook, Teams, Slack, PagerDuty, Linear, or Tines) for the organization. # Delete output destination Source: https://docs.cotool.ai/api-reference/output-destinations/delete-output-destination https://app.cotool.ai/api/docs/openapi.json delete /api/output-destinations/{destinationId} Delete an output destination and remove it from every agent and organization notification that routes to it. # Enable or disable output destination Source: https://docs.cotool.ai/api-reference/output-destinations/enable-or-disable-output-destination https://app.cotool.ai/api/docs/openapi.json put /api/output-destinations/{destinationId}/enabled Disable an output destination to stop every delivery to it while keeping its configuration and the agents and notifications routed to it, or enable it again. # List all output destinations Source: https://docs.cotool.ai/api-reference/output-destinations/list-all-output-destinations https://app.cotool.ai/api/docs/openapi.json get /api/output-destinations List all output destinations for the organization. # Send a test payload to an output destination Source: https://docs.cotool.ai/api-reference/output-destinations/send-a-test-payload-to-an-output-destination https://app.cotool.ai/api/docs/openapi.json post /api/output-destinations/{destinationId}/test Deliver an example payload to a single output destination so the configuration can be verified. The send is real and may create a message/incident/issue/case in the destination. # Send a test payload to an unsaved output destination Source: https://docs.cotool.ai/api-reference/output-destinations/send-a-test-payload-to-an-unsaved-output-destination https://app.cotool.ai/api/docs/openapi.json post /api/output-destinations/test Deliver an example payload to a configured-but-unsaved output destination so it can be verified before creating it. The send is real and may create a message/incident/issue/case in the destination. # Update output destination Source: https://docs.cotool.ai/api-reference/output-destinations/update-output-destination https://app.cotool.ai/api/docs/openapi.json put /api/output-destinations/{destinationId} Update an existing output destination (webhook, Teams, Slack, PagerDuty, Linear, or Tines). # Apply permission diff to a role Source: https://docs.cotool.ai/api-reference/roles/apply-permission-diff-to-a-role https://app.cotool.ai/api/docs/openapi.json post /api/roles/{id}/perms Apply a permission diff to a specific role # Create a role Source: https://docs.cotool.ai/api-reference/roles/create-a-role https://app.cotool.ai/api/docs/openapi.json post /api/roles Create a new role for the current organization # Delete a role Source: https://docs.cotool.ai/api-reference/roles/delete-a-role https://app.cotool.ai/api/docs/openapi.json delete /api/roles/{id} Delete an existing role for the current organization # Get permissions for a role Source: https://docs.cotool.ai/api-reference/roles/get-permissions-for-a-role https://app.cotool.ai/api/docs/openapi.json get /api/roles/{id}/perms Get the permissions for a specific role # Get role by id Source: https://docs.cotool.ai/api-reference/roles/get-role-by-id https://app.cotool.ai/api/docs/openapi.json get /api/roles/{id} Get a specific role by its ID # List roles for the current organization Source: https://docs.cotool.ai/api-reference/roles/list-roles-for-the-current-organization https://app.cotool.ai/api/docs/openapi.json get /api/roles List all roles for the current organization # Update a role Source: https://docs.cotool.ai/api-reference/roles/update-a-role https://app.cotool.ai/api/docs/openapi.json put /api/roles/{id} Update an existing role for the current organization # Create skill Source: https://docs.cotool.ai/api-reference/skills/create-skill https://app.cotool.ai/api/docs/openapi.json post /api/skills Create a reusable skill in the organization. # Delete skill Source: https://docs.cotool.ai/api-reference/skills/delete-skill https://app.cotool.ai/api/docs/openapi.json delete /api/skills/{skillId} Soft delete a skill. # Export skill Source: https://docs.cotool.ai/api-reference/skills/export-skill https://app.cotool.ai/api/docs/openapi.json get /api/skills/{skillId}/export Export a skill payload including current detail and version metadata. # Get skill Source: https://docs.cotool.ai/api-reference/skills/get-skill https://app.cotool.ai/api/docs/openapi.json get /api/skills/{skillId} Get one active skill by ID. # Get skill version Source: https://docs.cotool.ai/api-reference/skills/get-skill-version https://app.cotool.ai/api/docs/openapi.json get /api/skills/{skillId}/versions/{versionId} Get one specific skill version with references. # Import skill Source: https://docs.cotool.ai/api-reference/skills/import-skill https://app.cotool.ai/api/docs/openapi.json post /api/skills/import Import a skill package payload and create the skill. # List agents using skill Source: https://docs.cotool.ai/api-reference/skills/list-agents-using-skill https://app.cotool.ai/api/docs/openapi.json get /api/skills/{skillId}/agents List all agents currently using this skill. # List skill versions Source: https://docs.cotool.ai/api-reference/skills/list-skill-versions https://app.cotool.ai/api/docs/openapi.json get /api/skills/{skillId}/versions List all versions for a skill in descending order. # List skills Source: https://docs.cotool.ai/api-reference/skills/list-skills https://app.cotool.ai/api/docs/openapi.json get /api/skills List all active skills in the organization. # Restore a skill version Source: https://docs.cotool.ai/api-reference/skills/restore-a-skill-version https://app.cotool.ai/api/docs/openapi.json post /api/skills/{skillId}/versions/{versionId}/restore Restore a previous skill snapshot as a new current version. # Update skill Source: https://docs.cotool.ai/api-reference/skills/update-skill https://app.cotool.ai/api/docs/openapi.json put /api/skills/{skillId} Update an existing skill. # Get structured threat model board Source: https://docs.cotool.ai/api-reference/threat-model/get-structured-threat-model-board https://app.cotool.ai/api/docs/openapi.json get /api/threat-model/board Get the structured per-surface board (lean generated layer + live detection-agent overlay). # Get threat model Source: https://docs.cotool.ai/api-reference/threat-model/get-threat-model https://app.cotool.ai/api/docs/openapi.json get /api/threat-model Get the current threat model for the organization. # Get threat model version Source: https://docs.cotool.ai/api-reference/threat-model/get-threat-model-version https://app.cotool.ai/api/docs/openapi.json get /api/threat-model/versions/{versionId} Get one threat model version from the organization history by ID. # List threat model version history Source: https://docs.cotool.ai/api-reference/threat-model/list-threat-model-version-history https://app.cotool.ai/api/docs/openapi.json get /api/threat-model/versions List the full threat model version history for the organization. # Regenerate threat model Source: https://docs.cotool.ai/api-reference/threat-model/regenerate-threat-model https://app.cotool.ai/api/docs/openapi.json post /api/threat-model/regenerate Enqueue a threat model regeneration job using current environment data. # Update threat model Source: https://docs.cotool.ai/api-reference/threat-model/update-threat-model https://app.cotool.ai/api/docs/openapi.json put /api/threat-model Save a user-edited threat model as a new version in the organization history. # Disconnect tool Source: https://docs.cotool.ai/api-reference/tools/disconnect-tool https://app.cotool.ai/api/docs/openapi.json delete /api/tools/{toolType}/disconnect Remove stored credentials for a given tool type, disconnecting it from the organization. # Get raw tool output Source: https://docs.cotool.ai/api-reference/tools/get-raw-tool-output https://app.cotool.ai/api/docs/openapi.json get /api/tools/get-tool-use-raw-output Fetch raw data captured for a previous tool invocation specified by uuid. # List tools Source: https://docs.cotool.ai/api-reference/tools/list-tools https://app.cotool.ai/api/docs/openapi.json get /api/tools/list Return a grouped list of tools available to the organization. # Delete user Source: https://docs.cotool.ai/api-reference/users/delete-user https://app.cotool.ai/api/docs/openapi.json delete /api/users/{id} Delete a user by ID within your organization. # Get current user Source: https://docs.cotool.ai/api-reference/users/get-current-user https://app.cotool.ai/api/docs/openapi.json get /api/auth/me Return the authenticated user's profile information. # Get current user permissions and all available permissions Source: https://docs.cotool.ai/api-reference/users/get-current-user-permissions-and-all-available-permissions https://app.cotool.ai/api/docs/openapi.json get /api/perms Returns the current user's effective permissions and the list of all permission definitions available in the system. # List user organizations Source: https://docs.cotool.ai/api-reference/users/list-user-organizations https://app.cotool.ai/api/docs/openapi.json get /api/users/organizations Retrieve all organizations that the current user has access to. # List users Source: https://docs.cotool.ai/api-reference/users/list-users https://app.cotool.ai/api/docs/openapi.json get /api/users Retrieve all users within the current organization. # Update user Source: https://docs.cotool.ai/api-reference/users/update-user https://app.cotool.ai/api/docs/openapi.json put /api/users/{id} Update a user's role assignment within your organization. # Cotool Release Notes Source: https://docs.cotool.ai/changelog Product updates and release history **Nov 2, 2026** v0.78.0 ## v0.78.0 ✨ New * You can now add custom integrations from OpenAPI and Swagger specifications, with configurable authentication, operations, and approval requirements * Added ArmorCode and HaveIBeenPwned integrations for security finding management and breach exposure checks * Added managed log ingestion for AWS, GCP, Cloudflare, CrowdStrike Falcon Data Replicator, Tines audit logs, GitHub audit logs, and 1Password audit events * Added SentinelOne managed log ingestion with threat and alert investigation actions * Added Google Workspace domain-wide delegation with Alert Center access for agents * Added GPT-6.1 Terra to the model catalog 💎 Improvements * Cotool Router: `Auto` model selection is now even more intelligent and cost effective than before * Improved UI / UX of agent details page * Expanded Cotool MCP with Hunt, threat intelligence, detection, ingest health, alert routing, and agent follow-up actions * Improved delegated work by letting sub-agents run in the background while sharing the parent chat's sandbox * Improved code detection reliability by automatically proposing revisions to failing or broken detections * Enhanced alert workflows so agents can set severity, close true-positive alerts from Slack requests, and keep trigger alerts in one Slack thread through closure * Expanded Jira actions to set required fields when creating issues and update existing issues * Improved SAML setup with email-domain suggestions, validation, and support for legacy domains 🐞 Fixes * Fixed Vectra query results returning unusable positional rows and Microsoft Sentinel queries dropping empty fields * Fixed MCP OAuth registration errors and temporary API-key verification failures being reported as authentication failures * Fixed Slack wait prompts becoming unanswerable after timing out * Fixed Cloudflare environment maps remaining stale or showing only errors * Fixed custom integrations overriding built-in integrations with the same ID * Fixed recommended detection pagination overflowing its card and the agent terminal drawer scrolling past the page **Oct 26, 2026** v0.77.0 ## v0.77.0 ✨ New * Added Cotool MCP so you can securely use Cotool from ChatGPT, Claude, Cursor, Codex, VS Code, and custom AI clients with your existing login and permissions * Added a Cisco Umbrella integration for DNS activity and domain reputation, with approval-gated destination list remediation 💎 Improvements * Enhanced Tailscale connections with scoped OAuth client credentials * Improved agent reliability by stopping runs that repeatedly make the same tool call without making progress * Improved code detection auto-tuning so new tunings preserve previously approved changes and can recover changes dropped by earlier tunings 🐞 Fixes * Fixed BlueTally connections for account-specific subdomains and added clearer authentication errors * Fixed the chat context meter after compaction and when using Auto, and fixed slash command chips overlapping long messages * Fixed Jamf Pro computer inventory showing as stale between healthy scheduled updates * Fixed sandbox network access for AWS, Google Cloud, and Azure CLI commands in background and API-triggered agent runs **Oct 22, 2026** v0.76.0 ## v0.76.0 ✨ New * Added Vercel, TruffleHog, Jamf Pro, Material Security, and Zoom integrations with managed log ingestion and built-in detections * Added managed log ingestion and detections for Wiz audit logs, threat detections, and issues, and for Sublime Security audit logs and message groups * Added a SEON integration with a dedicated SEON webhook trigger * Added a Cotool Email tool so agents can send email to an allowlist of recipients, such as replying to employees who reported phishing * Added incident.io as an escalation destination, with severity floors for each destination * Added notifications to an agent's failure destinations when a run's evaluation score falls below a minimum you set * Added response actions to reset Google Workspace user passwords and to disable Microsoft Entra users and revoke their sessions 💎 Improvements * Customized detections now pick up new library versions through auto-tuning instead of falling behind * Improved Proofpoint triage by showing when a threat was removed from mailboxes and flagging verdicts reached after delivery * Added Created by and Updated by columns to the Agents list * Removed the extra confirmation step when signing in with SSO from Cotool * Improved Code42, Databricks, and Wiz connections with actor search, scoped OAuth secrets, and region validation before saving 🐞 Fixes * Fixed tool approvals showing an error or reopening after you approved them * Fixed intel Check exposure and Create detection actions starting without the intel attached * Fixed chat attachment uploads failing and chat streams closing between turns * Fixed duplicate role names failing without an error in the role dialog * Fixed Scanner, URLScan, HackerOne, and CrowdStrike NG-SIEM queries being rejected or returning errors **Oct 19, 2026** v0.75.0 ## v0.75.0 ✨ New * Added the ability to checkout Github repositories to the sandbox to make it easier for agents to put up pull requests * Added Workday, Microsoft Intune, Salesforce, and Doppel integrations with agent tools, managed log ingestion, and built-in detections * Added managed log ingestion for Microsoft 365, Snowflake, HiBob, HubSpot, Nightfall, and Azure VNet flow logs * Added a BlueTally integration for investigating company hardware, software licenses, asset assignments, and check-in and check-out history * Added visual alert routing in Settings, with separate triage and escalation routes and route graphs on alert detail pages 💎 Improvements * Expanded Linear actions so agents can assign people, set priority and due dates, edit issues and their own comments, and attach files * Improved alert workflows by resuming the assigned agent after a person changes an alert's status, allowing canonical alerts to be dismissed, and simplifying duplicate linking * Improved chat and alert readability with live narration between tool calls, clearer calibration verdicts and agent notes, and Slack-triggered inputs shown in chat * Improved file handling with streamed transfers, Slack file downloads, larger chat uploads, and support for large ZIP attachments 🐞 Fixes * Fixed multi-line strings being truncated in detection Code views and generated logic summaries * Fixed Wiz queries being rejected and Salesforce login-history ingestion failing on unsupported fields * Fixed slow Vectra investigations being resubmitted instead of resumed * Fixed concurrent alert triage starts leaving errored runs behind * Fixed Splunk searches failing on flexible time formats or consuming too much memory while paging through large result sets **Oct 12, 2026** v0.74.0 ## v0.74.0 ✨ New * Introduced a refreshed Cotool interface: every page now shares one consistent design in light and dark mode, with a redesigned sidebar, unified page headers and lists, and cleaner chat transcripts that group each exchange into a single work summary * Added a Sourcegraph integration for repository discovery, code search, file and commit retrieval, and read-only GraphQL queries * Added Microsoft Sentinel data lake queries and table mapping for long-retention investigations 💎 Improvements * Added "all except" role permissions, so administrators can grant access to every current and future resource except selected exclusions * Improved active chats by queueing follow-up messages instead of interrupting the agent's current work * Improved Git-managed agents with direct links to their source YAML and read-only synced triggers in alert routing * Improved Splunk, Freshservice, and Vectra reliability when provider concurrency or rate limits are reached 🐞 Fixes * Fixed chat crashes and scroll jumps while turns run and older history loads * Fixed Slack file posts becoming detached from their Cotool chat thread * Fixed billing data timing out for large EU accounts * Fixed duplicated ATT\&CK IDs and unclear attack paths in Threat Intel reports **Oct 8, 2026** v0.73.0 ## v0.73.0 ✨ New * Added Claude Haiku 5.5 to the model catalog, and added the extra-high reasoning effort level to Claude models * Added suggested dispositions to escalated alerts: confirm a statement about your environment from the alert page or Slack to close the alert, and later triage runs reuse it as context * Added a Proofpoint integration covering TAP, Proofpoint Essentials, and Threat Response, including threat events, forensics, campaigns, CTR incidents, and block and safe list management * Added a proxycheck.io integration for IP and email reputation, including proxy, VPN, TOR, and risk scoring 💎 Improvements * Rebuilt the [Databricks integration](https://docs.cotool.ai/integrations/security-tools/siem/databricks) with faster, read-only queries, service principal authentication, step-by-step table discovery, and a weekly map of your Databricks tables for agents and detection planning * Agents can now comment on, change the state of, and close HackerOne reports * Every agent and chat can now delegate focused subtasks to sub-agents * Added an explicit confirmation step to [SAML sign-in](https://docs.cotool.ai/integrations/identity/saml-scim) * Improved role management by showing each invite's role and confirming before a role is deleted, and blocking deletion of roles still used by invites or SCIM * Billing now shows the last known data as still updating instead of an error while usage refreshes * Agent chat links now open in a new tab 🐞 Fixes * Fixed the system prompt editor rewriting typed text, dropping links and list types, wrapping pasted markdown in a code block, and lagging on long prompts * Fixed agents set to all read-only tools bypassing tool permission checks * Fixed browser page visits timing out on sites that keep connections open * Fixed KnowBe4 PhishER raw email downloads * Fixed long Slack prompts that wait for a user response failing to post * Fixed Cloudflare traffic queries filtered by client ASN * Fixed SentinelOne agent lookups failing for devices without a serial number * Fixed GitHub environment mapping failing for repositories with many entry points **Oct 5, 2026** v0.72.0 ## v0.72.0 ✨ New * Added Claude Sonnet 5.5 and GPT-6.1 Sol, plus Latest model options that automatically follow the newest Opus, Sonnet, Sol, Terra, or Luna release * Added incident.io incident creation, including severity and incident-type lookup, to agent actions * Added JSON editing for Agent Output schemas, including pasted-schema normalization and live Builder and Preview synchronization 💎 Improvements * Redesigned Settings with dedicated navigation, consistent controls, save and discard states, and warnings before leaving unsaved changes * Improved chat errors with plain-language titles and descriptions instead of job IDs, stack traces, or internal error names * Added per-agent sandbox network overrides and a clearer allowlist editor * Improved alert detail pages with clear verdicts, recommended next steps, supporting evidence, and links to canonical duplicate alerts * Improved governance by showing who created and updated agents and skills, listing which agents use each integration, and allowing custom roles to view billing * Added controls to disable or delete output destinations without manually removing them from every agent and notification * Improved agent reliability with faster provider failover, retries for provider connection failures, and automatic sandbox recovery during long-running chats * Improved document analysis with native PDF handling, sandbox support for Office documents and OCR, and recovery from malformed attachments * Expanded the Wiz integration with typed searches across findings, detections, resources, network exposure, malware, and cloud events * Improved Slack workflows by accepting pasted channel links and letting tagged replies interrupt a busy thread to start a new turn 🐞 Fixes * Fixed scheduled threat-model board projections failing for some organizations * Fixed hyphens disappearing while naming a skill created from a prompt * Fixed Datadog log aggregations failing when multiple groupings exceeded provider limits * Fixed AWS onboarding failing during broker-user provisioning in EU deployments * Fixed billing configuration issues interrupting agent runs instead of recording the usage for later reconciliation **Sep 28, 2026** v0.71.0 ## v0.71.0 ✨ New * Added Claude Opus 5.5, GPT-6 Sol, and GPT-6 Luna to the model catalog * Added Sandbox network settings so administrators control which hosts and ports agent sandboxes can reach * Added Cotool Alerts to the agent tool picker so any agent can search, read, comment on, update, and create alerts 💎 Improvements * Updated [MITRE ATT\&CK coverage](https://docs.cotool.ai/detections/mitre-mapping) to v19.2, and new ATT\&CK releases now apply automatically * Added agent run and notification cards to the alert detail page, linking directly to the Slack thread, Linear issue, Tines case, or PagerDuty incident each escalation created * Added delivery tracking to agent runs, showing what each run sent and whether it succeeded, with one-click resend for failed deliveries * Agents now deliver every triggered result; the per-agent minimum severity filter that could hide lower-severity results has been removed * Improved agent investigations with dismissed and expired alerts in alert searches, Slack user lookup by email, Wiz Blue Agent analysis retrieval, and Code42 watchlist membership lookups * Improved the agent details page with a more readable system prompt, collapsible long prompts, and a layout that adapts to narrow widths * Added the app version to the sidebar with a reload prompt when a newer version is available * Added AWS CLI assume-role authentication for EU deployments * Teams destinations now reject browser channel links and explain how to use a workflow webhook URL instead 🐞 Fixes * Fixed selecting Slack channels and Linear labels inside destination and integration dialogs * Fixed Linear comments reporting an error after being posted successfully * Fixed Microsoft Graph Admin tenant discovery during setup * Fixed large sandbox file downloads failing **Sep 21, 2026** v0.70.0 ## v0.70.0 ✨ New * Added a Fleet integration for investigating hosts, policies, software, vulnerabilities, device activity, and live queries * Added an Azure CLI integration with workload identity federation so agents can investigate Azure tenants without stored client secrets * Added Grok 4.6 to the model catalog for coding and agent workflows * Added per-repository routing across Cotool-managed and bring-your-own [GitHub Apps](https://docs.cotool.ai/integrations/dev-tools/github), with conflict detection when both cover the same organization 💎 Improvements * Expanded `/hunt-intel` to hunt attached files, pasted reports, and hosted documents while ensuring explicit submissions always produce a hunt * Improved response-agent investigations by grounding conclusions in originating evidence and returning more complete Google Workspace audit results * Improved agent administration with bulk tag management, customizable tag colors, and consolidated output, delivery, and failure-notification settings * Added an ungrouped table view to Alerts with sortable detection names and more room for alert titles * Added detection proposal review controls to Hunt alerts and Slack notifications * Expanded Push Security to inspect browser-control configurations, blocked URLs, and custom detections * Improved agent reliability for large attachments, oversized tool inputs, named-agent file handoffs, and provider content-filter fallbacks 🐞 Fixes * Fixed the Agents list blocking navigation elsewhere in the app * Fixed Code42 authentication and added retry handling for transient Notion and Slack timeouts **Sep 14, 2026** v0.69.0 ## v0.69.0 ✨ New * Added a LaunchDarkly integration for searching account audit logs 💎 Improvements * Expanded agent failure notifications to alert configured destinations when a run fails * Added step-by-step Azure setup guidance for connecting [Microsoft Sentinel](https://docs.cotool.ai/integrations/security-tools/siem/microsoft-sentinel) * Improved load times for the Detections overview 🐞 Fixes * Fixed long-running sandbox commands losing proxy connections while waiting for upstream services * Fixed agent structured outputs failing when prompts or repository content contained malformed characters * Fixed agent runs failing when commands returned unusually large output or temporary workspace and model-provider errors occurred * Fixed agent creation workflows that could add integrations which were not visible or removable in the editor **Sep 10, 2026** v0.68.0 ## v0.68.0 ✨ New * New Serval integration. Agents can look up users, groups, access requests, tickets, and workflow runs * New Lumos integration. Agents can look up users, apps, groups, access requests, and activity logs * Tines agents can now create, update, and query records * [Okta](https://docs.cotool.ai/integrations/identity/okta) can now be connected with private key JWT authentication * When you connect Slack, your default response agent is automatically set up to respond to @mentions ([docs](https://docs.cotool.ai/integrations/communication/slack)) * You can start a [Linear](https://docs.cotool.ai/integrations/ticketing/linear) agent session with any agent through the API * Added GLM 5.3 Flash, GLM 5.2 Fast, and DeepSeek V4 Flash models 💎 Improvements * Product URLs now include your organization name. Old links still work * Redesigned the agent create and edit pages. The prompt is the main document and settings live in a side rail * Response agents now need concrete evidence before escalating an alert * Alert timelines quote the Slack message that prompted a follow-up and collapse repeated duplicate entries * The detections table now shows true positive, benign, and false positive rates in one sortable column * Added a "Select read-only" button to the chat tool selector * Agents can write markdown tables in [Jira](https://docs.cotool.ai/integrations/ticketing/jira) comments and descriptions * Refreshed form controls, dropdowns, and code blocks 🐞 Fixes * Chats no longer get stuck as running after a timed wait expires * Splunk searches no longer fail when a time bound has no timezone * CrowdStrike NG-SIEM, Huntress, and Google Admin queries are more reliable * Threat intel ingestion no longer fails on content filter refusals or missing fields * Triaging a closed alert now returns a clear error instead of a server error * Fixed minor UI bugs **Sep 1, 2026** v0.67.0 ## v0.67.0 🚀 Introducing Unified Agents 🚀 * Detection and Response agents are now unified under a redesigned Agents tab * The unified agents have a fully editable system prompt and all the configuration you are used to from "Response" agents. * All existing detection agents have been migrated as-is to the new format and should continue running as expected ✨ New * Added Hunt settings for configuring minimum exposure thresholds and compromise signal overrides when creating alerts 💎 Improvements * Improved Autonomous Hunt to prioritize actionable exposure and compromise findings while reducing posture and hygiene noise * Clarified Hunt alerts with consolidated source attribution and activity details when automatic response-agent triage is skipped 🐞 Fixes * Fixed failed alert triage runs incorrectly escalating alerts by returning them to Open for retry and showing a clear Failed state * Fixed threat assessments and structured outputs failing when generated responses exceeded prior size limits * Fixed detection filters returning errors for some alert types and made detection selection searchable in a side panel * Fixed layout overflow for long pasted log lines in chat and longer alert IDs on Home **Aug 31, 2026** v0.66.0 ## v0.66.0 ✨ New * Added a Cloudflare integration for investigating HTTP traffic, firewall events, Zero Trust Gateway activity, DNS, zones, and devices * Added Auth0 and 1Password integrations for investigating identity configurations, users, audit events, sign-ins, and sensitive item activity * Added a Tailscale integration for investigating devices, users, and configuration changes across tailnets 💎 Improvements * Improved alert triage by attaching evidence to every detection hit, giving response agents prior-alert context and duplicate handling, and escalating uncertain cases for human review * Enhanced Slack alert notifications with concise evidence summaries, in-message status controls, and threaded follow-up with the assigned response agent * Improved the Detections overview with infinite scrolling, compact filters, bulk disable, and consistent true-positive metrics * Improved alert investigation with clearer source attribution, more readable structured payloads, and optional feedback when closing alerts as benign or false positives * Expanded Linear with duplicate issue handling and Notion with paginated database queries * Improved threat models with safer regeneration, persistent progress, longer-running generation, and automatic availability to the default response agent 🐞 Fixes * Fixed expired sessions exposing raw authorization errors and blocking sign-out, with in-place reauthentication that preserves unsaved work * Fixed chat history failing to load for conversations using a retired model and chats remaining stuck as running after execution expires * Fixed detection creation failing to generate structured plans in EU deployments * Fixed custom Slack app changes disconnecting working integrations and Datadog refresh failures overwriting existing environment maps **Aug 24, 2026** v0.65.0 ## v0.65.0 ✨ New * Added a Microsoft Sentinel integration for querying logs, triaging incidents, managing analytics rules, and powering detection authoring and environment mapping * Added a Control D integration for investigating DNS activity and managing custom filtering rules across sub-organizations * Added GitHub Actions workflow tools for creating and updating pull requests, protected by explicit permissions 💎 Improvements * Enhanced structured outputs with table-based nested data views and drag-and-drop schema editing that preserves existing fields * Improved detection coverage accuracy by linking external alerts to verified rules from connected security platforms * Improved agent editing and execution reliability by automatically correcting invalid instruction changes and switching providers when model streams stall * Improved Hunt research reliability by retaining valid findings when individual evidence fields are malformed 🐞 Fixes * Fixed Splunk detection generation rejecting valid low-frequency queries and failing without actionable validation feedback * Fixed audit logs recording internal proxy addresses instead of the originating client IP * Fixed GitHub synchronization hanging on stalled API requests and showing disconnected installations as server errors **Aug 17, 2026** v0.64.0 ## v0.64.0 ✨ New * Added a [Zscaler](https://docs.cotool.ai/integrations/security-tools/network/zscaler) integration with ZIA, ZPA, ZDX, and Client Connector tools, detection-rule sync, alert triggers, and permission validation * Added first-class Darktrace webhook triggers so response agents can run immediately on model-breach and AI Analyst alerts * Added the ability to create response agents from chat or templates 💎 Improvements * Redesigned navigation and page layouts around Home, Detect, Hunt, Respond, Knowledge, Platform, and Settings, with consistent breadcrumbs and support for existing links * Added live progress from delegated agents to chat and agent timelines * Expanded [Linear](https://docs.cotool.ai/integrations/ticketing/linear), Silobreaker, and Notion with parent-child issue updates, broader threat-intelligence research, and complete nested page content * Improved coding agents with more reliable file editing and command execution * Improved Audit Logs page load times by showing entries before the total count finishes loading * Improved administration workflows with clearer GitHub installation controls, copyable invite links, and confirmation before disconnecting integrations * Improved reliability for long-running agent jobs and background operations 🐞 Fixes * Fixed RunReveal and Vectra detection inventory synchronization * Prevented invalid Slack output channels from being saved when the Cotool bot cannot post to them * Fixed temporary Code42 and Microsoft outages incorrectly showing integrations as disconnected * Fixed malformed text and tool results causing agent runs or long-chat context recovery to fail * Fixed GitHub environment mapping failures for repositories with incomplete summaries * Fixed Hunt investigation counts, threat-relevance filtering, and detection proposal updates **Aug 11, 2026** v0.63.0 ## v0.63.0 ✨ New * Added a Barracuda email security integration for investigating and remediating email threats * Added an OX Security integration to search applications, artifacts, and SBOMs and investigate issues and attack paths * Added a Supabase integration for organization and project security posture, configuration review, and project logs * Added [Slack](https://docs.cotool.ai/integrations/communication/slack) emoji-reaction triggers so reacting to a message can run an agent * Added multi-organization [GitHub](https://docs.cotool.ai/integrations/dev-tools/github) App installation scoping * Added a per-organization session length setting in Settings 💎 Improvements * Redesigned the Agents and Detections tables * Improved performance of GCP and AWS CLIs * Added a minimum-severity filter for escalated alert notifications * Reduced document parsing latency * Improved the agent harness to allow for even longer horizon tasks 🐞 Fixes * Fixed long-running detection and chat resume jobs * Better webhook reliability across integrations * Fixed legacy GitHub installation routing * Fixed Slack rate-limit hangs and raised the sub-agent timeout to 60 minutes * Hardened Slack event acknowledgements * Fixed sandbox file uploads when the model omits a file path **Aug 4, 2026** v0.62.0 ## v0.62.0 ✨ New * Added full-text [Linear](https://docs.cotool.ai/integrations/ticketing/linear) issue search with team, status, archive, and comment filters * Added guided, user-approved model upgrades for agents, including supporting research for each recommendation * Added support for [GitHub](https://docs.cotool.ai/integrations/dev-tools/github) tools to upload sandbox-generated files 💎 Improvements * Added skill version history with the ability to inspect and restore earlier versions * Improved long conversations with provider-native compaction that preserves more useful context * Made agent runs, delegated sub-agents, tool calls, waiting prompts, and handoffs durable across worker restarts * Expanded Huntress support for MSP and MSSP accounts with optional organization scoping * Expanded Darktrace with actions to acknowledge, reopen, and comment on model breaches * Expanded Kolide report queries and improved multi-value parameter handling * Added instruction-aware integration recommendations directly in the agent builder * Distinguished API agent executions from interactive runs in audit logs 🐞 Fixes * Fixed chats silently switching to Auto when reopened * Fixed archived Slack output channels remaining selectable until reconfigured * Fixed the tool selector overflowing when many integrations were selected **Jul 28, 2026** v0.61.0 ## v0.61.0 ✨ New * Added a StepSecurity integration for investigating GitHub Actions security posture, runtime detections, network and process activity, policy evaluations, compromised components, and supply-chain threats * Added an Expired alert status and 14-day inactivity checks for stale alerts 💎 Improvements * Improved sub-agent handoffs with reusable execution receipts that preserve successful tool calls and output files, reducing duplicate lookups * Unified suggested detection agents with detection-rule suggestions, including investigation-plan review and direct acceptance into the detection builder * Redesigned model settings with a searchable provider catalog, clearer Cotool Auto routing, and dedicated custom endpoint management * Redesigned the integrations directory with search, category and connection-status filters, and clearer integration details * Expanded Recorded Future with alert and alert-rule search plus full alert detail retrieval * Improved Cloudsmith setup with connect-time credential validation and owner-aware tool errors * Reduced database load from agent run polling to improve performance and reliability 🐞 Fixes * Fixed control characters causing malformed structured outputs * Fixed GitHub environment jobs repeatedly retrying permanent failures * Fixed cron serialization conflicts aborting built-in agent runs **Jul 27, 2026** v0.60.0 ## v0.60.0 ✨ New * Added a `/hunt-intel` slash command to ingest a threat report URL through the Hunt pipeline, with a dedicated timeline in chat * Added Recorded Future, Silobreaker, and TAXII 2.1 threat intelligence sources * Added Huntress, Railway, Kolide, and Cloudsmith integrations * Added CrowdStrike Spotlight vulnerability-management actions * Added Claude Opus 5 and open-weight models like Kimi K3, GLM 5.2, and several others. Open-weight models have the same data residency and ZDR guarantees that proprietary models provide. * Added `Auto` Model Routing for chat and agents to allow Cotool to choose the model backing a task * Added a Duplicate alert status and faster indexed alert search * Added support for creating draft [GitHub](https://docs.cotool.ai/integrations/dev-tools/github) pull requests 💎 Improvements * Handles content-filter refusals cleanly and automatically falls back to another model when configured * Renders CLI-based tool calls (gcloud/aws) with terminal-style visuals in chat * Enhanced Linear output destination workflows for detections and response agents * Improved Hunt indicator trustworthiness, detection reuse, and stopped autonomous hunts from repackaging existing integration findings * Made agent tag counts clickable and removed beta tags from product surfaces * Guarded unsaved skill editor changes and blocked sandbox tools until background setup is ready * Added audit logs for agent status changes and status-explainer tooltips on Threats group headers 🐞 Fixes * Fixed GitHub-managed agent Slack configs and tool grants * Fixed Linear issue team resolution * Fixed unresolved tool calls in sub-agent forks * Fixed alert description links incorrectly entering edit mode * Fixed remembered login email persistence * Fixed clipped usage chart axis labels and next-turn context usage display * Fixed raw citations in the threat assessment drawer and strict intel URL schema handling **Jul 15, 2026** v0.59.0 ## v0.59.0 ✨ New * Introducing Hunt V2: Cotool now continuously assesses incoming threat intelligence against your environment, hunts for exposure, and raises alerts with a clear verdict when a threat is relevant to your organization * Added slash commands to chat, with persisted commands for detection agents and a refreshed command header in the chat input * Added GPT-5.6 models and made GPT-5.6 Sol the default chat model * Added separate personal and organization skill namespaces * Added a canonical audit-log event catalog endpoint with documentation 💎 Improvements * Made bulk selection on the Alerts page more forgiving and added contextual Cmd+K status commands * Webhook URLs and secrets are now visible on GitOps-managed triggers * Retry transient Slack file upload and Notion page fetch failures automatically * Tool calls now fail fast on argument-validation errors with clearer guidance * Environment coverage now infers platform defaults from available evidence * Consolidated global notification settings to alerts and failures * Sub-agent tool chips now link to the agent details page * Invited users now receive an email when added by an administrator * Added Linear label support * Added bulk dismiss for detection suggestions 🐞 Fixes * Fixed custom MCP OAuth token refresh handling * Fixed GitHub integration showing incorrect repository visibility, and made repository sync opt-in by default * Fixed stale Slack thread agents and escaped newlines in alert comments * Fixed dates displaying in UTC instead of local time * Fixed notification settings failing to save under contention * Fixed inline code overflowing on the alert detail page * Fixed empty and placeholder prompt suggestion outputs **Jul 7, 2026** v0.58.0 ## v0.58.0 ✨ New * Added an OpenCTI threat intelligence integration for enriching investigations with threat intel * Added [Agent Skills](https://docs.cotool.ai/agents/skills) as code — much like agents, skills can be managed and sync from GitHub * Added the ability to test output destinations directly from the UI by sending an example payload * Added a Slack reply scope setting so triggers can respond to anyone or only Cotool users in a thread * Added a service account authentication option for Jira * Added a human-only Dismissed status that archives alerts * Added support for closing alerts in Obsidian * Reworked the notifications page with tabs and added escalated-alert notifications 💎 Improvements * Annotated which triggers create alerts on the response agents table, with a bulk toggle * Eval scores now appear inline on alert triage run timelines * Added direct links to the alerts created by detection hits, both in agent responses and as buttons on Slack notifications * Agents now ask questions in the originating Slack thread * Improved alert triage behavior by default response agent * Polished chat message styling 🐞 Fixes * Fixed UX issues when creating an agent from a chat * Fixed detection hit suppression failure modes and detection intent truncation with reserved XML tags * Fixed detection exploration output schemas and detection agent URLs * Fixed Slack channel history pagination * Fixed stuck alert triage runs and resumed cron triage runs * Fixed LLM stream heartbeat timeouts that could drop responses **Jun 26, 2026** v0.57.0 ## v0.57.0 ✨ New * Added first-class [Alerts](https://docs.cotool.ai/alerts/overview) for security triage, including an alert inbox, detail pages, activity timelines, comments, assignments, dispositions, bulk actions, and response-agent triage * Added a HackerOne connector with webhook-triggered alert intake for vulnerability response workflows * Added Claude Opus 4.8 and GPT-5.5 models, and made GPT-5.5 the default chat model 💎 Improvements * Improved [Response Agents as Code](https://docs.cotool.ai/agents/response-agents-as-code) with API-based schema validation, canonical YAML imports, refreshed documentation, and support for multiple GitHub sync repositories per organization * Added detection notification severity filters so teams can choose which detection hits should notify downstream destinations * Improved onboarding by sending user invite emails * Added a MITRE coverage view for environment-level threat model analysis * Added Tines record retrieval tools and expanded VirusTotal relationship pagination for deeper investigations 🐞 Fixes * Fixed Slack pagination, attachment forwarding, trigger-scope replies, and expected file-upload failure handling * Fixed tool raw-output lookups to return the correct 404 or 401 response instead of a server error * Fixed bulk agent model updates, Opus 4.8 thinking settings, and stale skill extraction results * Fixed URLScan results that do not include screenshots **Jun 19, 2026** v0.56.0 ## v0.56.0 ✨ New * Added a Bugcrowd integration with webhook triggers for vulnerability intake and response automation * Added a ChartHop integration for people and organization context in investigations * Response Agents as Code with GitHub GitOps sync, sample YAML agents, and managed-agent protections. Read more about it [here](https://cotool.ai/docs/response-agents-as-code). 💎 Improvements * Enhanced agent improvement generation to allow for tool suggestions and richer review flows * Added sub-agent timeline drilldown in the agent execution panel * Improved navigation with semantic browser tab titles, a collapsible sidebar, and unified loading indicators * Made response output destinations more flexible by allowing delivery without a structured schema * Added configurable timeouts for unanswered Slack confirmations 🐞 Fixes * Fixed deleted URLScan result handling * Fixed checkpointed cron execution resume **Jun 15, 2026** v0.55.0 ## v0.55.0 ✨ New * Added a Darktrace integration for network detection and response investigations * Added a KnowBe4 integration with PhishER GraphQL support for phishing triage * Added Adaptive Shield (Falcon Shield) SaaS security support to the CrowdStrike tool * Added custom Slack app integration setup * Added agent versioning so you can track and revert agent changes over time * Added inline chart rendering in the chat timeline with polished light and dark theming * Added the ability to reply to and follow up with built-in response agents 💎 Improvements * Reduced chat and agent time-to-first-token for noticeably faster responses * Replaced the three-dots typing indicator with a smoother dither loader * Added a friendlier experience for declined tools that distinguishes a rejection from an approval timeout * Added dark-mode contrast handling so dark tool logos stay legible * Refined the GitHub environment map UI on the integration details page * Chunked large Slack file uploads for more reliable delivery * Enriched detection agent run event responses with more detail 🐞 Fixes * Hardened SAML organization ID handling and blocked mismatched agent chat URLs * Fixed sub-agent chat ownership and restored visibility of historical agent runs * Fixed multiple sub-agents incorrectly showing as typing after completing * Fixed Slack DM file uploads, missing Slack credential handling, and trigger routing for event team mismatches * Fixed detection output citation rendering * Fixed stale threat-hunt state when navigating to the intel detail page * Fixed persistent workspace upload finalization and attach-file path resolution across all sandbox mounts * Fixed RunReveal environment map checkpointing * Fixed conversation continuations **Jun 8, 2026** v0.54.0 ## v0.54.0 ✨ New * Added a Persistent Agent Filesystem so agents can save and reuse files across runs * Added a Spacelift integration for infrastructure-as-code investigations * Added Jira Service Management alert creation as an agent output destination * Added a Linear team issue listing tool for richer ticket investigations * Added job dependencies so scheduled and chained jobs run in the correct order * Added configurable SCIM provisioning, plus public SAML and SCIM identity provider documentation * Added support for sandbox file attachments in Slack messages 💎 Improvements * Redesigned the home page feed into clearer sections * Added a better error handling on the frontend * Enhanced the executive dashboard with URL-encoded time windows, a one-year preset, and a refined date picker * Consolidated threat intel exposure and relevancy into a single exposure badge, with cited evidence on the detail page * Improved prompt suggestions with deterministic diff patches, an upgraded model, and timeout retries * Improved sandbox reliability with runtime file rehydration, emoji support in generated PDFs, and fewer storage writes for sub-agents * Optimized agent run feed query performance 🐞 Fixes * Fixed recurring job failure handling, scheduler serialization conflicts, and preserved agent error status on execution failure * Fixed sandbox recovery after mid-flight container termination and Anthropic assistant prefill failures * Fixed detection workflows including draft chat conflicts, validation error preservation, default output delivery, and SentinelOne custom rule filters * Fixed threat intel IOC status normalization, duplicate source error handling, and hunt intel filtering * Fixed built-in agent filtering, the agent runs table loading spinner, and the Cotool Eval popover overflow **May 29, 2026** v0.53.0 ## v0.53.0 ✨ New * Added organization notification settings for detection and response output delivery * Added ExtraHop RevealX, Semgrep, ClickHouse, and Obsidian Security integrations * Added GitHub commit history and blame tools for richer repository investigations * Added IOC list views and MISP Hunt intel sources for easier threat intelligence review 💎 Improvements * Improved threat intelligence management by combining sources, cleaning up MISP sync, and retrying failed API sync results * Enhanced detection workflows with evidence on detail pages, agent type filtering, cleaner hit displays, and unified run pagination * Improved sub-agent UX with progress previews, drawer breadcrumbs, and clearer nested agent timelines * Enhanced audit logs with richer filters, user and tool filtering, native tool hiding, and infinite scroll * Improved Slack agent workflows with run-button configuration and support for user replies * Improved performance and reliability for chat history rendering, large tool outputs, worker scaling, and queued jobs 🐞 Fixes * Fixed SAML definitions and tool-auth redirects that could land on removed routes * Fixed cached token usage counts, chat title fetching, and audit log load-more loops * Fixed paused job re-enqueueing, stale timed-wait resumes, blocked cron rescheduling, and chat deletion cleanup * Fixed Freshworks endpoint handling, Sumo Logic monitor listing, and Google Maps tool rendering * Fixed streaming permissions and ambiguous Linear workspace bindings **May 15, 2026** v0.52.0 ## v0.52.0 ✨ New * Linear ticket output destinations for detection agents, so generated detections can be delivered directly into Linear * Linear agent trigger endpoint for starting Linear-linked agent workflows programmatically * Detection hit evidence capture with cited tool calls, richer query result displays, and clearer evidence review * Bulk skill imports from folders to make large skill library setup faster 💎 Improvements * Improved Wiz investigations by consolidating agent tools and streamlining principal activity handling * Enhanced Datadog detection authoring with better rule generation, validation, and helper coverage * Improved Sumo Logic compiler feedback with stronger parsing advisories and empty-result validation * Refined structured output rendering with schema previews and a cleaner detection output viewer * Improved custom RSS feed setup with URL validation before feeds are saved * Enhanced threat intelligence ingestion with cross-source deduplication, huntability filtering, and Socket Blog support 🐞 Fixes * Fixed stale assistant-final chat jobs that could leave conversations in an inconsistent state * Fixed Slack upload and channel handling edge cases in agent workflows **May 10, 2026** v0.51.0 ## v0.51.0 ✨ New * FireHydrant incident response integration for bringing incident context into agent workflows * Glean search and document access as a new knowledge source for agents * Detection hit denoising with subagents to help reduce noisy findings * Bulk deletion for response agents to make cleanup faster 💎 Improvements * Sumo Logic query validation now uses a formal parser, improving detection query feedback and reliability * Sumo Logic environment mapping now supports editable descriptions, runtime variable updates, and larger mappings * Detection agent workflows now support step reordering and a cleaner detection hits interface * Structured output generation is more consistent, including retries after interrupted generation * Agent run acceptance criteria now evaluate errored executions so failures still get useful feedback * Executive dashboard chart legends and MITRE previews have clearer layouts * Restored complete agent YAML exports for easier backup and migration 🐞 Fixes * Fixed Glean visibility in the integrations list * Fixed Sumo Logic environment mapping edge cases and mapping limits * Fixed detection hit handling and display issues * Fixed chat resume, sandbox race, and job enqueue edge cases that could interrupt agent runs **May 5, 2026** v0.50.0 ## v0.50.0 ✨ New * Private skills for keeping organization-specific workflows scoped to the right users and agents * Exa web search as a selectable agent tool for fresh web context 💎 Improvements * Detection hit workflows that let detection agents inspect hits and call tools from hit context * Enhanced diff rendering and change review for agent instructions and detection suggestions * Added agent run rate limiting and clearer API-triggered run reporting * Improved skills pages with better private skill visibility and invocation counts * Improved tool auth redirects, Panther setup guidance, and remote MCP failure handling 🐞 Fixes * Agent instruction feedback can now use full conversation history * Fixed LLM-based agent timeouts and duplicate job handoff execution errors * Fixed detection hit row display when no category is set * Fixed executive dashboard copy * Various additional bug fixes **Apr 28, 2026** v0.49.0 ## v0.49.0 ✨ New * Executive Dashboard in the app, with one-click export to PDF or Markdown * Pin chats to keep important conversations at the top of your sidebar 💎 Improvements * Detection generation jobs can now leverage any tools, CLIs, and MCPs * TheHive case attachment uploads so agents can attach files directly to cases * Vectra close detection workflow for closing detections from agent runs * Datadog detection authoring now respects the groupSignalsBy ⊆ groupByFields constraint, reducing invalid rule attempts 🐞 Fixes * Prevent overlapping Slack thread executions so concurrent triggers no longer interfere with each other * Fixed quote finding in threat model * Gracefully handle invalid agent output settings instead of erroring * Fixed detection wait resume payload lookup so paused detection agents reliably resume **Apr 24, 2026** v0.48.0 ## v0.48.0 ✨ New * Auto Detect: Cotool will automatically generate detection agents grounded in your threat model * Microsoft Teams as an output destination for agents and detections alongside Slack * threatER IOC lookup integration for threat intelligence enrichment * Jira file attachment action so agents can attach files directly to issues * PDF generation in chat and agent runs * AWS assumed-role authentication for CLI-backed cloud investigations 💎 Improvements * CLI data sources are now available in threat model generation, built-in agents, and new detection agents * Custom instructions can be provided per detection agent run for more targeted generation * Improved investigation plan editing with clearer affordances * Skills now surface missing-tool warnings inline when assigning to agents * Agent YAML import and export now supports skills * Structured outputs are gated to the first chat turn to avoid interfering with follow-up messages * Enhanced error handling and reliability for Push Security, VirusTotal, SentinelOne custom rules, and Wiz principal investigations * Removed the legacy memory framework to simplify agent and tool configuration 🐞 Fixes * Added a dedicated retrying status for background jobs to prevent premature failure marking * Fixed chart SVG escaping that broke rendered chart images * Fixed unstable chat asset selection and assistant message markdown rendering * Fixed agent run rename ownership so only the owning user can rename * Fixed legacy agents breaking when assigned skills with mismatched tool requirements * Fixed full-screen modal backdrops, dark mode checkbox styling in tool and CLI selectors, and new-button overflow on agent pages **Apr 15, 2026** v0.47.0 ## v0.47.0 ✨ New * Threat Model Beta: Cotool builds a dynamic threat model on your behalf and makes it available as a skill to your agents. * Dynamically provisioned sub-agents are now available in chat and agents by default. These increase performance (latency and improve context use) * Support for AWS Google Cloud CLI support in sandbox chats and agents. Integrate us directly into your cloud infra for detection and response 💎 Improvements * Expanded Armis support with site listing, site-scoped asset search, and a smoother authentication flow * Tool selection is faster with new Select all and Clear all actions in the tool selector modal * Prompt version history now sorts newest versions first 🐞 Fixes * Improved handling for Anthropic context reduction errors in long or tool-heavy conversations * Vectra investigations now fail more gracefully when data is temporarily unavailable **Apr 13, 2026** v0.46.0 ## v0.46.0 ✨ New * Added Armis, Nightfall, Vectra, and CircleCI integrations * Parallel tool calling: Agent turns now execute tool calls in parallel for faster multi-tool workflows 💎 Improvements * Expanded GitHub workflows with PR review and inline comment retrieval, clearer progressive disclosure, and more resilient environment summarization * Improved Microsoft Graph admin investigations with richer user profiling * Expanded Wiz investigation coverage across issues, cloud resources, network exposures, configuration findings, detections, users, and application endpoints * Improved chat usability with one-click copying for assistant messages and code blocks * Improved Okta system log search reliability and rate-limit handling 🐞 Fixes * Fixed GitHub pagination limits that could previously truncate results for large repositories * Fixed Slack directory refresh jobs when required scopes are missing **Apr 7, 2026** v0.45.0 ## v0.45.0 ✨ New * Improved Detection Agent experience: no base-queries, just runbooks * Added Twingate integration * Added WhiteIntel integration 💎 Improvements * Reworked detection authoring and tool configuration for a smoother builder experience * GitHub integration now supports repository rulesets * SentinelOne now supports endpoint lookup and secure file fetches from agents * Chat and home page now remember your selected tools more reliably * Added invite-based account onboarding and bootstrap setup flow 🐞 Fixes * Various bug fixes and perf improvements **Apr 2, 2026** v0.44.0 ## v0.44.0 ✨ New * Slack tool actions can be configured to only operate on approved channels * CrowdStrike NG SIEM integration for querying next-generation SIEM data directly in Cotool * Socket integration now supports listing alerts 💎 Improvements * IOC indicators on threat intelligence detail pages can now be exported as CSV * Improved file attachment handling during memory extraction for more reliable context capture * New and improved tool section UX 🐞 Fixes * Various minor UI fixes **Mar 30, 2026** v0.43.0 ## v0.43.0 ✨ New * Acceptance criteria for response agents: add acceptance criteria to your agents to get notifications when they go off-trajectory * Universal CMD+K command bar for quickly navigating agents, chats, and actions from anywhere in the app * Custom RSS feed management for threat intelligence — add and manage your own feeds 💎 Improvements * Faster chat loading with optimistic prefetching of message history * Reddit r/cybersecurity added as a built-in threat intelligence source * Copy-to-clipboard button added to markdown code blocks in the agent details panel * File downloads in chat — the agent can now surface generated files directly in the conversation timeline * Detection authoring now shows the full agent run experience with streaming output 🐞 Fixes * Fixed chat requests being rejected when some tools were temporarily unavailable * Fixed filtering on the agent runs list * Improved our slack integration * Fixed sandbox desktop file browser height **Mar 24, 2026** v0.42.0 ## v0.42.0 ✨ New * Redesigned home page * Desktop view and file browser for sandbox environments * Full-text search across agent run * Agent-to-agent trigger indicators and bulk-editing on the Agents page 💎 Improvements * Redesigned threat intelligence detail page with improved research layout and feed filters * Chat lifecycle audit logs for tracking chat events * Improved prompt version history with date-sorted versions and scrollable containers 🐞 Fixes * Fixed Linear OAuth token refresh and re-authentication flow * Fixed Sublime detection sidebar branding * Fixed Detection Suggestion custom instructions character limit bug **Mar 16, 2026** v0.41.0 ## v0.41.0 ✨ New * Everything Computer: sandbox mode is now on by default in all agents and chats. * Skills: Create reusable instruction packages that can be shared across agents, with support for importing and exporting Agent Skills 💎 Improvements * GPT-5.4 is now the default model for new chats * Suggested Detections now supports instructions, manual "Run now" controls, and clearer job status visibility * Improved long-chat reliability with automatic context compaction and better handling for tool-heavy conversations * Code blocks in chat now include a one-click copy button 🐞 Fixes * Fixed Datadog querying and detection authoring issues caused by custom `@` field handling * Fixed TheHive alert update behavior and related integration issues * Misc Bug Fixes **Mar 10, 2026** v0.40.0 ## v0.40.0 ✨ New * Wait tool: Agents can now pause and automatically resume on a schedule, enabling timed workflows and delayed actions * Detection suggestion review and query generation: Overhauled detection authoring with suggestion refinement and query validation * GPT-5.4 model support 💎 Improvements * Enhanced detection editor sidebar with improved Datadog log utilities * Improved Code42 event retrieval * Eval harness now surfaces critical issue status reporting with evaluation score * Detection run results now link directly to the agent that generated them * Better sandbox file handling * Improved agent run reliability 🐞 Fixes * Fixed issues with browserbase integration in sandbox mode **Feb 26, 2026** v0.39.0 ## v0.39.0 ✨ New * Detection Hits Page: A centralized feed of all hits across your detection agents [View here](https://app.cotool.ai/detections) * Freshworks integration for managing tickets * Response agent output hooks: Configure where your response agent's structured output gets delivered after each run. From the response agent's settings page, add one or more output destinations — Slack channels, webhooks, or PagerDuty — and Cotool will automatically POST the run metadata and structured output to each destination every time it executes. 💎 Improvements * GPT-5.3-Codex model support * LLM judge now flags critical issues for review * Ability to disable Datadog detection rules directly from the editor 🐞 Fixes * Fixed Slack Markdown rendering * Fixed OAuth login redirect after authentication * Improved Notion experience when not authenticated * Misc bug fixes **Feb 18, 2026** v0.38.0 ## v0.38.0 ✨ New * Improved Detection rule authoring experience * Sublime Security ActionMessage analysis for enriched alert context * Slack user group search tool for finding and messaging groups * Claude Sonnet 4.6 (with 1 million token context length) support 💎 Improvements * Improved Slack Trigger experience * Added Material Security mark-in-progress support 🐞 Fixes * Misc bug fixes and performance improvements **Feb 12, 2026** v0.37.0 ## v0.37.0 ✨ New * Detection Rule Authoring: Complete experience overhaul with inline result previews and draft, proposal, and publishing workflows * Linear Agents: @mention or assign Cotool directly in Linear issues to trigger agents with real-time streaming responses, live progress updates, and conversation continuity in your issue threads * Sandbox mode for response agents with sandboxed computer-use capabilities * Claude Opus 4.6 model support (released Feb 5, 2026) * Intel Feed tool support for automated detection rule exploration 💎 Improvements * Faster load times for chat messages and agent execution history * Github tools now include closing and merging PRs * Enhanced Linear trigger setup and webhook configuration experience * Improved detection agent output formatting * Deep linking to detection agents from execution history * Dynamic tool list rendering in chat interface 🐞 Fixes * Fixed detection authoring entity tabs and agent instruction input * Fixed multiple agent loop error handling issues for better user-visible messaging **Feb 2, 2026** v0.36.0 ## v0.36.0 ✨ New * Tines Cases integration * RunReveal integration * New Audit Logging UI / UX 💎 Improvements * Detection agents now display query hit counts for better visibility * Minor detection agent improvements * SumoLogic environment mapping enhancements * Agent builder UI improvements 🐞 Fixes * Fixed custom Databricks & MCP server logos display * Fixed title truncation and button labels in UI * Fixed structured outputs rendering in chat * Fixed diff generation for prompt suggestions **Jan 27, 2026** v0.35.0 ## v0.35.0 ✨ New * Suggested Detections Tab: Cotool now automatically suggests good detection rule candidates to improve coverage in your environment * RunReveal integration for log analysis and detection authoring * MCP Resources support for attaching context from MCP servers to chats 💎 Improvements * Enhanced Slack tooling: Slack now supports file attachments alongside sent messages (screenshots, charts, pdfs, etc.) * Code42 integration improvements 🐞 Fixes * More reliable evaluations * Fixed share option appearing incorrectly on agent pages **Jan 22, 2026** v0.34.0 ## v0.34.0 💬 Slack Improvements 💬 * Replying to Cotool in a thread will continue the existing agent run * You can now DM Cotool and it will create a private chat which can be continued in 🧵 * The full details are [here](https://docs.cotool.ai/integrations/communication/slack). You will have to [reauth the Slack integration](https://app.cotool.ai/tools/slack) to use the DM feature. ✨ Additional New Features * PagerDuty integration (also is supported as a Detection Agent Destination) * API key authentication support for custom MCP servers 💎 Improvements * Slack threads with Agents are now re-entrant * GPT-5.2 is now the default model for new chats * Enhanced sandbox code execution display in chat event drawer * Improved email parsing for triggers with better decoding and formatting 🐞 Fixes * Fixed Slack integration issues for large organizations * Fixed trigger save errors when configuring agent triggers * Fixed miscellaneous alert display issues **Jan 15, 2026** v0.33.0 ## v0.33.0 ✨ New * Chat sharing for collaboration on agent conversations * Slack as a detection output destination * Slack confirmations allowing agents to request user approval before taking actions * GPT-5.2 model support 💎 Improvements * Enhanced agent template capabilities with tool associations * Increased frontend timeout values for long-running operations 🐞 Fixes * Fixed Scanner tool definition backwards compatibility issue **Jan 9, 2026** v0.32.0 ## v0.32.0 ✨ New * Sumo Logic integration 💎 Improvements * Enhanced Scanner indexing with improved detection suggestions * In-agent Scanner validation for detection authoring * Admin controls to disable login methods (Google, password, SAML) 🐞 Fixes * Fixed GitHub create PR tool * Fixed Formal integration **Dec 30, 2025** v0.31.0 ## v0.31.0 ✨ New * Tags for agents and detections with sortable, filterable tables * Custom scheduling cadence for detection agents * Google Admin integration for detection authoring 💎 Improvements * Agent run infrastructure is more durable * Detection agents can now use other agents as tools * Improved reasoning token streaming and updated reasoning UI behavior * Detection authoring experience improvements * Chat interruption handling with improved UI feedback * Agent details full screen button now has a tooltip * Schedule status chips for detection agents * Improved detection and agent list pages with better table controls 🐞 Fixes * Various visual UI and UX fixes * Fixed missing fields in detection builder * Fixed memories CSV export error **Dec 19, 2025** v0.30.0 ## v0.30.0 ✨ New * Agent templates for quick setup and common use cases * Output destinations for detection agents * Toggle to enable or disable detection agents 💎 Improvements * Unsaved changes warning now appears across all pages 🐞 Fixes * Fixed streaming state not updating correctly in chat * Fixed execution plan display in chat message timeline **Dec 14, 2025** v0.29.0 ## v0.29.0 ✨ New * *🔎 Our Agentic Detections Platform is out in Beta 🔍*: Our detection platform allows for users to specify complex detections which go beyond rule-based detections to catch complex threats in their environment. * Check out the detections tab in Cotool to see detection suggestions for your environment! 💎 Improvements * TheHive: Create case from alert capability * Improved Splunk querying capabilities * Enhanced datetime handling utilities 🐞 Fixes * Fixed Jira 204 response handling * Fixed detection authoring for Scanner **Dec 10, 2025** v0.28.0 ## v0.28.0 ✨ New * Slack integration now supports targeting groups and channels in addition to individual users 💎 Improvements * Enhanced Splunk query validation with parser that identifies invalid fields * Added listApps tool and improved detection tools for Splunk integration * Improved subagent tools display and UX in chat interface * Added updatedAt filter to TheHive listCases and updated listAlerts 🐞 Fixes * Fixed Unix timestamp conversion in datetime utilities * Fixed table component rendering issues * Fixed trigger email rename functionality * Fixed agent run deletion from chat page **Dec 03, 2025** v0.27.1 ## v0.27.1 💎 Improvements * Enhanced theHive integration with improved filtering capabilities 🐞 Fixes * Fixed persistent context compression notice remaining visible across chat navigation * Fixed navigation bug after deleting a chat * Fixed memory handling for code42 integration * Agent triggers are now automatically deleted when their parent agent is deleted **Dec 02, 2025** v0.27.0 ## v0.27.0 ✨ New * Claude Opus 4.5 model now available for agent conversations 💎 Improvements * Improved structured output schema handling with dedicated JSON schema types * Added comprehensive documentation for structured outputs * Refreshed tool environment map UI for better usability * Improved pie chart component consistency 🐞 Fixes * Fixed login page styling issues * Fixed "show raw output" button in tool result drawer * Fixed automatic saving and scrolling in schema builder JSON mode * Fixed Crowdstrike integration errors **Nov 24, 2025** v0.26.0 ## v0.26.0 ✨ New * Structured outputs for agents: Define JSON schemas to receive structured responses from agent runs * GPT 5.1 model support * Formal integration for infrastructure access management 💎 Improvements * URLScan now prefers private scans by default for enhanced privacy * Improved retry configuration for better reliability * Restored tool call ordering for consistent execution * Enhanced timeout logging for background jobs * Reduced MITRE map file size for improved performance 🐞 Fixes * Fixed prompt suggestions type handling and checkpoints * Fixed socket connection stability issues * Fixed sending messages from the side panel * Fixed various agent loop bugs **Nov 17, 2025** v0.25.0 ## v0.25.0 ✨ New * Role Based Access Control is now live!!! See the [documentation](https://docs.cotool.ai/settings/roles-permissions-overview) for how to get started 💎 Improvements * Enhanced Splunk query refinement and tool prompts * Context counter now displays warning when approaching limits * Detection documentation published * Splunk timeout configuration now available in frontend * Webhook details now displayed when editing 🐞 Fixes * Fixed JSON repair handling for empty objects and nullable fields * Fixed icon display issues in documentation **Nov 12, 2025** v0.24.0 ## v0.24.0 ✨ New * Integration enable/disable feature: You can now enable or disable integrations from the tools details page without removing credentials 💎 Improvements * Enhanced Splunk search with pagination, automatic query timeout (with query cancelation) after 2 minutes * Removed Splunk wildcards on index parameter and prefix wildcards to prevent performance degradation 🐞 Fixes * Made endTime parameter required for SentinelOne PowerQuery **Nov 6, 2025** v0.23.0 ## v0.23.0 ✨ New * Built-in Managed Investigation Agent with Intel Feed exposure checking * Planning mode selector in agent creation UI 💎 Improvements * Filter built-in agents from agent builder UI * User email now included in application logs * Google Drive auth now displays authenticated user * Delete user button added to accounts page * Cron-triggered agent run titles are now static 🐞 Fixes * Fixed SentinelOne and agent system prompt issues * Streamlined Google Drive authentication flow * Fixed type errors in agent loop * Removed `any` type usage for better type safety * Agent loop no longer throws unhandled errors * Fixed missing tools in agent execution loop **Nov 5, 2025** v0.22.0 ## v0.22.0 ✨ New * Elasticsearch integration with MITRE mapping * Sublime Security MDM documentation tool * Account listing functionality 💎 Improvements * theHive comment function requirements clarified * Visual feedback when saving settings 🐞 Fixes * Fixed ephemeral authentication failure issue **Oct 29, 2025** v0.21.0 ## v0.21.0 ✨ New * Confluence documentation integration * Agent performance metrics in logs and lists * Scanner environment job with dedicated UI 💎 Improvements * Added support for observables in theHive * API documentation improvements 🐞 Fixes * Fixed 400 error responses * Removed LRU cache from tool credentials * Fixed insights page default graph and tab * Fixed documentation generation **Oct 27, 2025** v0.20.0 ## v0.20.0 ✨ New * Mintlify documentation site 💎 Improvements * MITRE rule mapping optimization * Chat access permissions simplified 🐞 Fixes * Fixed memory tool association bug in UI * Fixed missing chat retrieval bug **Oct 20, 2025** v0.19.0 ## v0.19.0 ✨ New * Scanner environment job and UI 💎 Improvements * Consolidated and deduped prompt suggestions * Updated Linear webhook configuration 🐞 Fixes * Fixed document search authentication issues * Fixed chat repository issues * Fixed token counter for LLM judge **Oct 7, 2025** v0.18.0 ## v0.18.0 ✨ New * AI-powered agent suggestions feature * Evaluation scores in agent run detail headers 💎 Improvements * Context manager applied to LLM judge evaluations 🐞 Fixes * Fixed API documentation rendering * Fixed possible recursive agent reference issue **Sep 29, 2025** v0.17.0 ## v0.17.0 ✨ New * Task planning in chat and agents 💎 Improvements * Extended agent execution loop retry policy * Wiz integration with projectId filtering * Improved model selector UI 🐞 Fixes * Fixed context error when generating agents from chat * Fixed Document Parser 404 responses * Multiple database query fixes **Sep 26, 2025** v0.16.0 ## v0.16.0 💎 Improvements * Linear status detection for better model understanding * More aggressive context window management **Sep 23, 2025** v0.15.0 ## v0.15.0 ✨ New * LLM judge scoring in agent details UI * Context manager implementation 💎 Improvements * User deletion capability for admins 🐞 Fixes * Fixed visual bugs in agent evaluation UI * Fixed chat interruption error display * Fixed Splunk and Hive schemas for Gemini/OpenAI * Fixed time conversion tool for OpenAI **Sep 22, 2025** v0.14.0 ## v0.14.0 ✨ New * Organization insights dashboard with metrics 💎 Improvements * Slack message writing guidance 🐞 Fixes * Fixed time conversion tool schema for Gemini **Sep 22, 2025** v0.13.0 ## v0.13.0 💎 Improvements * Token counter improvements 🐞 Fixes * Fixed webhook trigger errors * Fixed 404 error handling * Fixed null/undefined content checks **Sep 16, 2025** v0.12.0 ## v0.12.0 ✨ New * Tool cache versioning 💎 Improvements * Jira tool updates * Reasoning token saving for Anthropic models 🐞 Fixes * Fixed agent follow-up in agent details **Sep 16, 2025** v0.11.0 ## v0.11.0 ✨ New * Agent details page redesign * Stop chat during tool call execution 💎 Improvements * Token counter and context window improvements * Agent linking to sub-agents 🐞 Fixes * Fixed critical error display * Fixed Document Parser image parsing * Fixed deleted chat error **Sep 9, 2025** v0.10.0 ## v0.10.0 ✨ New * Chat title updates now stream in real-time 💎 Improvements * Error classification and handling improvements * Token counting accuracy 🐞 Fixes * Fixed SentinelOne 504 errors * Fixed Linear tool null pointer exception * Fixed thumbs feedback icon in light mode **Sep 7, 2025** v0.9.0 ## v0.9.0 ✨ New * Material Security integration 💎 Improvements * Sentry error tracking improvements * Scanner query timeout extended * Splunk tool descriptions 🐞 Fixes * Fixed sliding context window implementation **Sep 5, 2025** v0.8.0 ## v0.8.0 ✨ New * Intel Feed integration * Sentry error tracking 💎 Improvements * Memory tool improvements * Splunk mapping with retry logic 🐞 Fixes * Fixed SentinelOne issues * Fixed object generation flakiness * Fixed memory bugs **Sep 2, 2025** v0.7.0 ## v0.7.0 ✨ New * Email trigger functionality 💎 Improvements * SentinelOne MITRE mapping * Splunk mapping optimizations 🐞 Fixes * Fixed email trigger issues **Sep 1, 2025** v0.6.0 ## v0.6.0 ✨ New * Time conversion tool * Detection authoring capabilities 🐞 Fixes * Fixed agent system prompt bug * Fixed tool schema parsing **Aug 28, 2025** v0.5.0 ## v0.5.0 ✨ New * Scheduled job execution 💎 Improvements * Slack attachment parsing * IP lookup tool error handling 🐞 Fixes * Fixed detection counts * Fixed Splunk issues * Fixed browser-use error rendering **Aug 26, 2025** v0.4.0 ## v0.4.0 ✨ New * Memory management in UI * Splunk exploration capabilities 💎 Improvements * SentinelOne tool enhancements 🐞 Fixes * Fixed chat migration issues * Tool call loop error handling improved * Fixed Scanner implementation **Aug 25, 2025** v0.3.0 ## v0.3.0 ✨ New * SAML login audit logging * Scanner integration with MITRE mapping * Splunk integration with MITRE mapping 💎 Improvements * SentinelOne PowerQuery functionality * Auto-provision access for SAML logins * Agent description notice improvements **Aug 24, 2025** v0.2.0 ## v0.2.0 ✨ New * SAML authentication support * Hive integration * Splunk integration 💎 Improvements * Increased Claude Sonnet context window 🐞 Fixes * Fixed Hive authentication **Aug 19, 2025** v0.1.0 ## v0.1.0 ✨ New * File attachments in chat * Browser automation tool 💎 Improvements * Distributed caching for tool status * Cross-organization chat support 🐞 Fixes * Fixed tool use confirmation rendering * Chat stop functionality restored # Creating Agents from Chat Source: https://docs.cotool.ai/chat/creating-agents-from-chat Convert successful chat conversations into reusable agents Turn successful chat sessions into reusable, automated agents. ## Why Convert to Agent? If you find yourself asking the same questions repeatedly in chat, convert to an agent: * Automate with triggers * Run on schedule * Standardize process * Share with team ## How to Convert **1. Complete Chat Session** Have a successful conversation that achieves desired outcome **2. Click 'Create Agent'** Button appears at end of chat session **3. AI Generates Prompt** Cotool analyzes conversation and generates system prompt **4. Review & Customize** Edit the generated prompt as needed **5. Add Triggers** Set up automation (Jira, Slack, cron, etc.) ## What Gets Captured From your chat conversation: * Tools used * Investigation approach * Decision-making logic * Output format ## Example **Chat conversation**: ``` You: Investigate alert SEC-123 Agent: [Checks SentinelOne, Splunk, VirusTotal] Agent: Determined to be false positive You: Update the ticket Agent: [Updates Jira] ``` **Generated agent**: ```markdown theme={null} You are an alert triage agent. When given a ticket ID: 1. Fetch alert details from SentinelOne 2. Search Splunk for related activity 3. Check indicators in VirusTotal 4. Determine severity 5. Update Jira ticket with findings [Rest of generated prompt...] ``` ## Best Practices * Use chat to prototype complex workflows * Test the generated agent in Builder before deploying * Refine the auto-generated prompt * Add error handling and edge cases > [card] [Creating Agents](/agents/creating-agents) > > Learn more about agent creation # File Attachments Source: https://docs.cotool.ai/chat/file-attachments Attach images, PDFs, and documents to your chat messages Upload files to Chat for analysis by the agent. ## Supported File Types > [tab] Images > > * PNG, JPG, GIF, WEBP - Screenshots of alerts, dashboards - Network > diagrams - Max 10MB per file > [tab] Documents > > * PDF (text extraction) - TXT, CSV (direct reading) - JSON, YAML > (structured data) - Max 5MB per file > [tab] Logs > > * Plain text logs - PCAP files (metadata only) - Max 25MB per file ## Use Cases **Screenshot Analysis**: Upload alert screenshot, ask agent to investigate **Log Analysis**: Upload log file, ask agent to find anomalies **Report Parsing**: Upload PDF report, extract key findings **Email Analysis**: Forward email as file, analyze for phishing ## How It Works 1. Click attachment icon in chat 2. Upload file 3. Agent automatically processes based on type 4. Ask questions about the file content ## Example **You**: \[Uploads suspicious email EML file] `Analyze this email for phishing indicators` **Agent**: ``` Analyzing email... From: support@paypa1-security.com (SUSPICIOUS - typosquatting) Subject: Urgent: Account Verification Required Red flags detected: - Sender domain mimics PayPal (paypa1 vs paypal) - Contains urgency language - Includes suspicious link: hxxp://verify-account-paypa1[.]com - Link domain registered 2 days ago Verdict: PHISHING ⚠️ Recommendation: Block sender, report to email security team ``` # Generating Reports Source: https://docs.cotool.ai/chat/generating-reports Create formatted reports from chat conversations Generate formatted reports from your chat investigations. ## How It Works **1. Complete Investigation** Chat with agent to gather all necessary information **2. Request Report** "Generate a report of our findings" **3. Agent Formats** Agent creates structured report from conversation **4. Export** Download as PDF, markdown, or send via email/Slack ## Report Types > [tab] Investigation Summary > > * Timeline of events - Key findings - Evidence gathered - > Recommendations > [tab] Incident Report > > * Incident overview - Impact assessment - Response actions taken - > Lessons learned > [tab] Access Review > > * Users audited - Permissions found - Anomalies detected - > Recommendations ## Example **After investigation**: **You**: `Create an investigation report` **Agent**: ``` # Security Investigation Report Generated: Oct 21, 2025 ## Summary Investigated suspicious login activity for user john@example.com ## Findings - Last login: 2025-10-21 14:30 from 192.168.1.50 (HQ office) - No failed login attempts - IP address clean (VirusTotal 0/90) - No endpoint security alerts ## Conclusion Activity appears legitimate. No action required. ## Evidence [Links to Splunk queries, VirusTotal results] ``` \[Download PDF] \[Email] \[Post to Slack] # Slash Commands Source: https://docs.cotool.ai/chat/slash-commands Start guided chat workflows for agents, detections, skills, and Hunt Start a message with `/` to open Cotool's slash command menu. Slash commands are the fastest way to switch chat into a guided workflow without leaving the composer. ## What slash commands do Cotool uses slash commands in two ways: * **Guided workflows** start a chat that is optimized for one job, such as creating an agent or ingesting a threat report into Hunt. * **In-place actions** operate on the current conversation, such as compacting it so you can keep going with a shorter context window. ## Available commands | Command | What it does | Best when | | - | - | - | | `/create-agent` | Starts a guided conversation for creating a reusable agent | You have a workflow in mind and want to turn it into an agent | | `/create-detection` | Starts a Code Mode conversation that builds a detection notebook | You want to describe a detection in plain language and run it in Cotool | | `/create-skill` | Packages instructions into a reusable skill | You want repeatable guidance that can be reused later | | `/hunt-intel` | Sends a report URL, attachment, or pasted text into Hunt | You already have an advisory, PDF, or report and want Hunt to process it immediately | | `/update-agent` | Starts a guided workflow for editing an existing agent | You need to change an agent's prompt, tools, or behavior | | `/update-skill` | Starts a guided workflow for editing an existing skill | You want to revise a shared or personal skill | | `/compact` | Compacts the current conversation and keeps working in the same chat | The chat is long and you want to continue without starting over | ## How to use them **1. Start with /** In Chat, begin a message with `/` to open the command menu. Keep typing to filter the list. **2. Choose the workflow** Select the command that matches what you want to do. **3. Provide any extra context** Some commands ask for one more choice before you continue: **4. Finish in chat** Continue the guided conversation, attach files if needed, and let Cotool drive the workflow from there. ## Tips * Commands that require permissions can appear disabled until you have the right access. * `/create-detection` is most useful after you have connected the destination platform you want to write into. * `/create-agent` can read your existing agents. Name one as a starting point, for example "like our phishing triage agent, but for Slack reports", and it drafts the new agent from that agent's instructions and tools. It also tells you when an existing agent already does what you asked. * `/hunt-intel` works with report URLs, pasted text, and chat attachments such as PDFs and Office documents. * `/compact` stays in the current chat instead of opening a new one. ## Related guides > [card] [Using Chat](/chat/using-chat) > > Learn the core chat workflow. > [card] [Creating Agents](/agents/creating-agents) > > See how guided agent creation fits into the broader setup flow. > [card] [Skills](/agents/skills) > > Learn when to create or update a reusable skill. > [card] [Hunt](/hunt/overview) > > Learn what happens after `/hunt-intel` submits a report. # Using Chat Source: https://docs.cotool.ai/chat/using-chat Interactive chat interface for ad-hoc investigations The Chat interface provides an interactive copilot experience for ad-hoc investigations and exploratory work. Chat is helpful for ad-hoc investigations or exploring your environment. It is also a helpful starting point to [build agents](/chat/creating-agents-from-chat) ## How Chat Works **1. Start Conversation** Navigate to **Chat**, select relevant tools/integrations (by default, all tools are selected) **2. Ask Questions** Natural language queries about your environment **3. Chat Investigates** Calls tools, gathers data, analyzes **4. Iterative Refinement** Follow-up questions, drill deeper **5. (Optional) Create Agent** Convert successful chat to reusable [agent](/chat/creating-agents-from-chat) ## Use Cases > [card] Investigations > > Explore alerts, users, indicators > [card] Research > > Gather information across systems > [card] Troubleshooting > > Debug issues with AI assistance > [card] Report Generation > > Create formatted reports from conversations > [card] Agent Creation > > Convert successful chat to reusable > [agent](/chat/creating-agents-from-chat) ## Example Conversation **You**: `Investigate user john@example.com - check for suspicious activity` **Cotool Chat**: ``` Searching across systems... ✓ Okta: Found user, last login 2 hours ago from 192.168.1.50 ✓ AWS: User has admin access to production ✓ Splunk: 0 security alerts in past 24h ✓ SentinelOne: No endpoint alerts for john's devices Summary: No suspicious activity detected. Normal activity pattern. ``` **You**: `Check that IP address 192.168.1.50` **Cotool Chat**: ``` ✓ VirusTotal: IP clean (0/90 vendors flagged) ✓ Internal records: IP belongs to HQ office network ✓ Geolocation: San Francisco, CA (matches office location) Verdict: Legitimate office IP ✅ ``` ## Features **File Attachments**: Upload logs, screenshots, documents to chat for analysis **Slash Commands**: Start guided workflows like `/create-agent`, `/create-skill`, or `/hunt-intel` directly from the composer **Create Agent**: Convert successful chat to reusable [agent](/agents/creating-agents) ## Slash Commands Start a message with `/` to open Cotool's slash command menu. Use slash commands when you want chat to switch into a more guided workflow, such as: * creating or updating an agent * creating or updating a skill * writing a detection for a connected platform * sending a report directly into Hunt with `/hunt-intel` * compacting a long conversation without starting a new chat > [card] [Slash Commands](/chat/slash-commands) > > See the available commands and when to use each one > [card] [File Attachments](/chat/file-attachments) > > Learn about uploading files to chat # System Prompts Source: https://docs.cotool.ai/core-concepts/system-prompts Writing effective prompts for your agents The **system prompt** (also called **agent instructions**) is the most important part of your agent. It defines the agent's role, behavior, decision-making logic, and output format. Think of it as the agent's **job description** and **operating manual**. ## What is a System Prompt? A system prompt is natural language text that tells the agent: * **Who it is** - Its role and persona * **What it does** - Its responsibilities and goals * **How it works** - When to use tools, decision criteria * **What it produces** - Output format and tone > [!NOTE] > > Unlike traditional code, agents understand **natural language > instructions**. You don't write if/then logic - you explain the task like > you would to a smart colleague. ## Anatomy of a Good Prompt Effective system prompts typically include these sections: ### 1. Role and Context Define who the agent is and what domain it operates in. ```markdown theme={null} You are a security alert triage agent. Your role is to analyze security alerts, gather relevant context, and determine if they require immediate action or can be safely closed. You work for a financial services company with strict compliance requirements. Security is paramount, but false positives waste analyst time. ``` ### 2. Core Responsibilities List the agent's main tasks. ```markdown theme={null} Your responsibilities: 1. Analyze the alert details and extract key indicators (IPs, domains, file hashes) 2. Search Splunk logs for related activity in the past 24 hours 3. Check indicators against threat intelligence (VirusTotal, internal feeds) 4. Determine alert severity: Critical, High, Medium, Low, or False Positive 5. Update the Jira ticket with your findings and recommended actions ``` ### 3. Decision Logic Explain how the agent should make decisions. ```markdown theme={null} Severity Criteria: **Critical**: - Known malware detected (VirusTotal > 5 detections) - Ransomware indicators - Privilege escalation on production systems **High**: - Suspicious file execution from temp directories - Multiple failed authentication attempts (> 10 in 1 hour) - Lateral movement detected **Medium**: - Single suspicious event with no corroborating evidence - Policy violations without malicious intent **Low / False Positive**: - Known false positives (reference the FP list in context docs) - Legitimate admin activity - Testing by authorized users ``` ### 4. Output Format Specify how the agent should structure its response. ```markdown theme={null} Format your Jira update as: **Severity**: [Critical|High|Medium|Low|False Positive] **Summary**: Brief one-sentence assessment **Evidence**: - List key findings with timestamps - Include relevant Splunk events - Include VirusTotal scores if applicable **Recommended Actions**: - Clear next steps for analyst - If Critical/High, include specific containment actions **Confidence**: [High|Medium|Low] - How confident are you in this assessment? ``` ## Complete Example Here's a full system prompt for an alert triage agent: > [accordion] View Complete Example Prompt > > ```markdown theme={null} > You are a security alert triage agent for Acme Financial. Your role is to analyze endpoint security alerts from SentinelOne, gather context, and determine severity and next steps. > > ## Your Responsibilities > > 1. Extract key indicators from the alert (IPs, domains, file hashes, users, hosts) > 2. Search Splunk for related activity in the past 24 hours > 3. Check file hashes and URLs against VirusTotal > 4. Assess severity based on evidence > 5. Post detailed findings to the Jira ticket > 6. If Critical, also post to #security-alerts Slack channel > > ## Severity Guidelines > > **Critical** (requires immediate response): > > - Confirmed malware (VirusTotal > 5 vendors OR known ransomware families) > - Active C2 communication > - Credential dumping or privilege escalation on production systems > - Data exfiltration attempts > > **High** (escalate to analyst within 1 hour): > > - Suspicious file execution from non-standard locations > - Multiple failed auth attempts (>10 in 1 hour) followed by success > - Lateral movement between hosts > - Process injection or memory tampering > > **Medium** (review within 24 hours): > > - Single suspicious event with no corroborating activity > - Policy violations without malicious indicators > - Unapproved software installation > > **Low / False Positive** (can close): > > - Known IT admin activity (check Splunk for approved change tickets) > - Testing by security team (look for "test" in user notes) > - Known false positives from our FP list (see context docs) > > ## Investigation Steps > > 1. Start by understanding the alert: what triggered it, when, and on which host > 2. Search Splunk for the affected user and host over the past 24h > 3. If a file hash is involved, check it in VirusTotal > 4. Look for patterns: is this an isolated event or part of a campaign? > 5. Check if the user or host has a history of alerts > 6. Make your severity determination based on evidence, not assumptions > > ## Output Format > > Always post to Jira with this structure: > > **Severity**: [Critical|High|Medium|Low|False Positive] > **Confidence**: [High|Medium|Low] > > **Summary**: One sentence describing the alert > > **Evidence**: > > - Key findings with timestamps > - Splunk event counts and notable patterns > - VirusTotal results if applicable > - Any historical context > > **Analysis**: > Explain your reasoning and key factors in your severity decision > > **Recommended Actions**: > > - Specific next steps > - If High/Critical, include containment recommendations > - If False Positive, explain why and suggest tuning the rule > > ## Important Notes > > - If you're uncertain, err on the side of caution and escalate > - For Critical alerts, post to Slack immediately after updating Jira > - Reference the alert ID and ticket number in all communications > - Be concise but thorough - analysts need to act quickly > > ## Tone > > Professional, direct, and evidence-based. No speculation. State confidence level when uncertain. > > ``` ## Prompt Engineering Tips > [accordion] Be Specific, Not Vague > > **Bad**: "Use VirusTotal to check things" > > **Good**: "Use VirusTotal to check any file hashes from the alert. If more than 5 vendors flag it as malicious, classify as Critical." > [accordion] Provide Examples > > Show the agent what good looks like: > > ```markdown theme={null} > Example good summary: "Suspicious PowerShell execution from temp directory on USER-123. VirusTotal flagged as trojan (8/70 vendors). No lateral movement detected." > > Example bad summary: "Alert triggered." > ``` > [accordion] Explain Edge Cases > > Cover scenarios where the agent might get confused: > > ```markdown theme={null} > **Edge Cases**: > - If VirusTotal returns no data (new/unknown file), classify as Medium and recommend sandbox analysis > - If Splunk is unavailable, note this in findings and proceed with available data > - If the user is "admin_service_account", check if activity matches scheduled jobs > ``` > [accordion] Set Boundaries > > Tell the agent what NOT to do: > > ```markdown theme={null} > **Do NOT**: > - Isolate endpoints without Critical severity classification > - Make assumptions about user intent without evidence > - Close High severity alerts automatically > - Share sensitive data outside the security team Slack channel > ``` > [accordion] Use Structured Sections > > Break your prompt into clear sections with headers. This helps agents parse and follow instructions better. ## Improving Prompts Automatically Once your agent is deployed, Cotool automatically evaluates every run and suggests improvements when issues are detected: **1. Write Initial Prompt** Start with clear instructions covering role, responsibilities, and decision logic **2. Deploy and Monitor** Agent runs are automatically evaluated (scored 0-100) **3. Review Suggestions** When runs score poorly, system detects issues and suggests prompt fixes **4. Accept Improvements** Click "Generate Diff" to see suggested changes, then accept or reject **5. Track Versions** Each accepted improvement creates a new version automatically > [card] [Learn About Automatic Evaluations](/improving-agents/evaluations) > > See how every run is scored and improvement suggestions are generated ## Common Pitfalls > [!WARNING] > > **Too Vague**: "Analyze the alert and do the right thing" > > Agents need specific instructions about what "the right thing" means. > [!WARNING] > > **Too Rigid**: "Always check these 5 tools in this exact order" > > Over-constraining the agent removes its adaptive reasoning capability. Guide, don't dictate. > [!WARNING] > > **Conflicting Instructions**: "Be thorough" vs "Respond in under 30 seconds" > > Make tradeoffs explicit and prioritize clear goals. > [!WARNING] > > **No Examples**: Agents learn patterns from examples. Show don't just tell. ## Context Documents In addition to the system prompt, agents can reference external documents: > [card] [Learn About Context Documents](/agents/context-documents) > > Provide agents with runbooks, policies, and reference docs from Google Docs or Notion ``` ``` # Tools and Integrations Source: https://docs.cotool.ai/core-concepts/tools-and-integrations How tools power your AI agents **Tools** are the bridge between agent intelligence and real-world actions. Each tool is a structured function that agents can call to interact with your security stack, query data, or automate workflows. ## What Are Tools? Tools are discrete, well-defined actions that agents can perform. Each tool: * Has a **clear purpose** (e.g., "Search Splunk logs", "Create Jira ticket") * Accepts **typed parameters** (search query, ticket title, etc.) * Returns **structured data** that agents can reason about * Is **authenticated** and scoped to your organization > [!NOTE] > > Think of tools as the agent's **hands** - they allow it to interact with the world beyond just thinking and reasoning. ## How Agents Use Tools Agents decide which tools to use based on: **1. Task Understanding** Agent analyzes the task and identifies what information it needs or what actions it should take. **2. Tool Selection** Agent chooses relevant tools from its available toolset based on the tool descriptions and current context. **3. Parameter Construction** Agent constructs appropriate parameters for the tool call (e.g., search query, filters, identifiers). **4. Execution** Tool is invoked with the provided parameters. The integration handles authentication and API calls. **5. Result Processing** Agent receives structured results and incorporates them into its reasoning for next steps. ## Integrations vs Tools It's important to understand the distinction: > [tab] Integrations > > **Integrations** are authenticated connections to external services. > > * You authenticate once (OAuth, API key) > * Credentials are stored securely > * One integration can power multiple tools > * Example: The **Jira integration** powers tools like: > * `create_jira_ticket` > * `update_jira_ticket` > * `list_jira_issues` > * `add_jira_comment` > [tab] Tools > > **Tools** are specific actions within an integration. > > * Each tool does one thing well > * Tools are stateless and idempotent when possible > * Tools accept structured parameters > * Tools return structured results > * Example: `create_jira_ticket` is a tool that uses the Jira integration ## Granting Tool Access Agents only have access to tools you explicitly grant. When creating or editing an agent: 1. Browse available tools by category or integration 2. Select which tools the agent can use 3. Agent can only call tools in its allowed list > [!WARNING] > > Agents cannot discover or use tools they haven't been granted. This prevents unintended actions from being taken by agents. # What is an Agent? Source: https://docs.cotool.ai/core-concepts/what-is-an-agent Understanding AI agents in Cotool An **agent** is an AI-powered workflow that can reason, make decisions, and take actions across your security stack. Unlike traditional automation that follows predefined logic, agents use Large Language Models (LLMs) to understand context, plan their actions, and adapt to different situations. ## How Agents Work Agents combine four key components: > [accordion] Large Language Models (LLMs) > > Agents use state-of-the-art LLMs (hosted or custom) to: - Understand > natural language instructions - Reason about complex problems - Decide > which tools to use and when - Generate human-readable summaries > [accordion] Tools > > Tools are structured functions that agents can call to: - Query APIs > (search Splunk logs, list SentinelOne alerts) - Take actions (create > Jira tickets, send Slack messages) - Transform data (parse emails, > extract indicators) - Access context (fetch documents, reference tool > data) > [accordion] Context > > Agents can access relevant context from: - Google Docs and Notion pages > (runbooks, policies) - Integration data (user info, asset inventories) - > Trigger payloads (the event that invoked them) > [accordion] Instructions (System Prompts) > > System prompts guide agent behavior by defining: - The agent's role and > responsibilities - When and how to use tools - Output format and tone - > Decision-making criteria ## Agent Execution Flow When an agent runs, it follows this lifecycle: **1. Invocation** Agent receives a task from: - **Trigger** (Jira issue created, Slack mention, cron schedule) - **Chat** (user asks a question in the UI) - **API call** (programmatic invocation) **2. Context Loading** Agent loads relevant context: - System prompt and configuration - Context documents (Google Docs, Notion) - Trigger payload data **3. Planning (Optional)** If planning mode is enabled, the agent: - Analyzes the task - Creates a step-by-step plan - Identifies required tools and information **4. Execution Loop** Agent iteratively: - Decides next action (call a tool or respond) - Calls tools to gather data or take actions - Evaluates results and plans next steps - Continues until task is complete **5. Response** Agent produces output: - Text summary of findings and actions - Structured data (JSON, tables, charts) - Side effects (tickets created, messages sent) ## Agent Types Cotool supports two primary agent modes: > [tab] Autonomous Agents > > **Autonomous agents** run without human intervention, triggered > automatically by events. **Examples:** - Alert triage (triggered by > security alerts) - Ticket enrichment (triggered when Jira issues are > created) - Scheduled reports (triggered by cron) - Phishing analysis > (triggered by emails) > [tab] Copilot Agents > > **Copilot agents** assist humans interactively through chat or API. > **Examples:** - Ad-hoc investigations - Complex troubleshooting - > Research and data gathering - Report generation ## Key Capabilities > [card] Multi-Tool Orchestration > > Agents can coordinate across dozens of tools in a single run, fetching > data from Splunk, enriching with VirusTotal, and updating Jira—all > autonomously. > [card] Adaptive Reasoning > > Agents adapt their approach based on what they discover. If one data > source is unavailable, they can pivot to alternatives. > [card] Context-Aware > > Agents can reference organizational knowledge stored in documents, > prompts, and live integration data. > [card] Auditable & Safe > > Every tool call is logged. Agents only have access to explicitly granted > tools and integrations. # MITRE Coverage Mapping Source: https://docs.cotool.ai/detections/mitre-mapping Unified detection coverage across your entire security stack Cotool automatically maps all detections across your security tools to MITRE ATT\&CK, providing a single, consolidated view of your detection coverage. ## The Problem with Traditional MITRE Maps Security teams typically face these challenges: **Time-Consuming**: Manually maintaining MITRE coverage maps across multiple tools takes hours per tool **Fragmented**: Separate maps for endpoint, SIEM, detection-as-code platforms—no unified view **Inaccurate**: Maps quickly become outdated as detections change ## Cotool's Approach **1. Automatic Discovery & AI-Powered MITRE Mapping** Detections from connected tools are analyzed and mapped to relevant MITRE ATT\&CK techniques using AI: * Analyzes detection names and descriptions * Reviews query logic and detection body * Considers tags and metadata * Generates confidence scores for each mapping **2. Unified View** All detections are aggregated into a single MITRE matrix showing coverage across your entire stack **3. Weekly Updates** The classification job runs weekly to keep the map current as detections are added or modified ## Viewing Your Coverage Map Navigate to **Detections > Coverage Map** to see: ![Unified MITRE Coverage Map](https://mintcdn.com/cotool-bcb49c92/Y4VA5op2o1wCcBuQ/assets/mitre-map.gif?s=31949eb50d906276337b216e5288b328) ### Map Features The MITRE coverage map shows: **Detection Density**: Visualize how many detections cover each MITRE technique * Color-coded heatmap showing coverage levels * Click any technique to see which detections cover it **Tool Breakdown**: See which platform each detection comes from: * Splunk, Datadog, Scanner, Elastic (SIEM/query-based) * SentinelOne (Endpoint) * Panther, Sublime (Detection-as-Code) **Confidence Scores**: Each technique mapping includes a confidence score (0-1) indicating how strongly the detection relates to that technique **Tactic Grouping**: View coverage organized by MITRE tactics (Initial Access, Execution, Persistence, etc.) ## Understanding Coverage Details Click on any MITRE technique to see: > [accordion] Detection List > > All detections covering this technique, showing: - Detection name - > Source platform (Splunk, Panther, SentinelOne, etc.) - Confidence score > for the mapping - Reasoning for why it maps to this technique Example: > > ```T1053.005 - Scheduled Task/Job: Scheduled Task ├── SentinelOne (2 theme={null} > detections) │ ├── "Suspicious Scheduled Task Creation" (confidence: > 0.92) │ └── "SchTasks.exe Command Line" (confidence: 0.88) │ └── Splunk > (1 detection) └── "Windows Scheduled Task Created" (confidence: 0.85) > ``` > [accordion] Detection Details > > For each detection, see: - **Platform**: Where this detection runs - > **Description**: What the detection monitors - **Confidence**: How > strongly it relates to this technique - **Classification Reasoning**: > Why Cotool mapped it to this technique - **Last Updated**: When the > classification was performed > [accordion] Multiple Techniques > > A single detection may map to multiple MITRE techniques if it covers > multiple attack patterns. Each mapping has its own confidence score. ## How the Classification Works The MITRE classification job runs weekly and: 1. **Fetches detections** from all connected platforms 2. **Analyzes each detection** using Cotool to understand what it detects 3. **Maps to techniques** with confidence scores (0-1 scale) 4. **Validates mappings** against the official MITRE ATT\&CK framework 5. **Stores results** for visualization in the coverage map Cotool considers: * Detection names and descriptions * Query/rule logic and body content * Tags and metadata (including platform-provided MITRE mappings like SentinelOne's) * Severity levels and rule types ## Frequently Asked Questions > [accordion] How does Cotool map detections to MITRE techniques? > > Cotool uses AI to analyze each detection's name, description, query > logic, and metadata. Cotool generates mappings to relevant MITRE > techniques with confidence scores. For platforms like SentinelOne that > provide their own MITRE mappings, Cotool can use those provider-supplied > mappings directly. > [accordion] How often does the map update? > > The MITRE classification job runs automatically once per week (Sunday at > midnight). You can also trigger it manually if you've added many new > detections and want an immediate update. > [accordion] What happens to old detections when the job re-runs? > > The classification job is idempotent—it skips detections that have > already been classified. Only net-new detections are analyzed and > mapped. This makes the weekly job efficient. > [accordion] Can I manually adjust mappings? > > Currently, mappings are generated automatically by Cotool. If you > believe a mapping is incorrect, you may want to improve the detection's > description or metadata to help Cotool classify it more accurately. # Detections Overview Source: https://docs.cotool.ai/detections/overview Comprehensive detection management across your security stack Cotool maps detection coverage across your security stack, from endpoints to email to SIEMs, and runs the detections you author in Cotool. ## Key Features > [card] [Unified MITRE Coverage Map](/detections/mitre-mapping) > > Visualize detection coverage across all tools in one consolidated view > [card] [AI Detection Authoring](/detections-platform/authoring) > > Build, test, and publish detections that run in Cotool > [card] [Pattern-Based Detection](/detections/pattern-based-detection) > > Deploy agents that detect anomalies without rigid rule-based logic ## Detection Alerts Recorded Cotool detection hits create first-class alerts. Alerts track the lifecycle after detection: assignment to a response agent, triage activity, comments, escalation, and final disposition. Detection-created alerts can automatically start response-agent triage: 1. Set the default agent in **Settings > Routing**. 2. Optionally add a triage route that sends one detection, or the detections that query a table, to a different agent. 3. Choose **Unassigned** on a route for detections that should create alerts without automatic triage. > [card] [Alert Routing](/alerts/routing) > > Configure how detection-created alerts reach response agents ## How It Works **1. Ingest Existing Detections** Cotool automatically discovers and classifies detections from: - **SIEM platforms** - **Endpoint tools** - **Email security tools** - **Detection-as-Code pipelines** **2. Map to MITRE ATT\&CK** AI analyzes each detection's name, description, and query logic to map it to relevant MITRE ATT\&CK techniques, creating a unified view of coverage across your stack **3. Visualize Coverage** See which techniques are covered, by which tools, with confidence scores for each mapping **4. Author New Detections** Use `/create-detection` to build a detection as a Python notebook that runs in Cotool: - Query connected tools or Cotool Logs - Test the draft against real data - Publish a validated version > [card] [Detection Authoring Guide](/detections-platform/authoring) > > Learn more about authoring detections in Cotool ## Pattern-Based Detection with Agents Not all threats follow rigid patterns. Cotool allows you to deploy scheduled agents that hunt for suspicious patterns without being bound to rule-based logic. **Example**: Deploy a weekly agent that: * Reviews user login patterns * Identifies anomalous behavior * Creates alerts for investigation This approach catches threats that evade traditional signatures. > [card] [Pattern-Based Detection](/detections/pattern-based-detection) > > Learn about behavioral detection with agents ## Getting Started **1. Connect Your Security Tools** Navigate to **Settings > Integrations** and authenticate your detection platforms **2. View Your Detection Map** The MITRE classification job will automatically run weekly to map your detections to MITRE ATT\&CK techniques **3. Author Detections** Use `/create-detection` to build, test, and publish detections that run in Cotool **4. Define Pattern-Based Detection Agents** Define pattern-based agents that hunt for suspicious activity without being bound to rule-based logic # Pattern-Based Detection with Agents Source: https://docs.cotool.ai/detections/pattern-based-detection Detect threats using behavioral analysis beyond rigid rule-based logic Not all threats follow predictable patterns. Pattern-based detection uses AI agents to hunt for suspicious behaviors without being constrained by rigid, rule-based logic. ## The Limitations of Traditional Detections Traditional detections are rule-based: **if X happens, alert**. This works well for known threats but has limitations: > [card] Rigid Logic > > Rules only catch exactly what you specify. Attackers easily evade by > slight variations. > [card] High Maintenance > > Rules require constant tuning as environments and threats evolve. > [card] Context-Blind > > Rules can't consider broader context like user behavior patterns or > organizational norms. > [card] Signature-Dependent > > Rules need known indicators. Novel attacks slip through. **Pattern-based detection** solves these problems by using AI agents to identify anomalous behaviors rather than matching fixed signatures. ## How Pattern-Based Detection Works Instead of writing rules, you deploy **scheduled agents** that: **1. Observe Behavior** Agent queries your security tools to observe activity: - User login patterns - Process execution on endpoints - Network communication - Cloud resource access - Email behaviors **2. Analyze Context** Agent analyzes with full context: - Historical baselines for this user/host - Peer behavior (similar roles/departments) - Threat intelligence - Organizational policies - Time-of-day and day-of-week patterns **3. Identify Anomalies** Agent detects suspicious patterns: - Deviations from normal behavior - Unusual combinations of activities - Timing anomalies - Access to unexpected resources **4. Create Alerts** Agent generates alerts with rich context: - What's anomalous and why - Supporting evidence - Risk assessment - Recommended response actions This approach catches threats that evade traditional signatures. ## Creating a Pattern-Based Detection Agent **1. Define the Behavior to Monitor** Decide what suspicious patterns you want to detect: * User behavior anomalies * Resource access patterns * Configuration drift * Communication anomalies **2. Determine Schedule** How often should the agent run? * **Hourly**: For active monitoring * **Daily**: For broader pattern analysis * **Weekly**: For trend analysis and reporting **3. Create the Agent** Navigate to **Agents > Create Agent** Configure: * **Name**: "User Behavior Anomaly Detection" * **Type**: Scheduled (Cron) * **Schedule**: "0 \*/6 \* \* \*" (every 6 hours) * **Tools**: Grant access to relevant tools (SIEM, EDR, etc.) **4. Write the System Prompt** Write a detailed prompt explaining: * What to look for (specific patterns) * What context to consider (baselines, peer behavior) * What to ignore (known false positives) * How to format output (alerts, tickets, reports) > [card] > > Learn about writing effective system prompts > > [Open](/core-concepts/system-prompts) **5. Add Context Documents** Provide reference material: * List of known false positives * IT asset inventory (to understand normal software) * Org chart (to understand peer groups and reporting relationships) * Approved maintenance windows **6. Configure Actions** Define what the agent should do when it finds anomalies: * Create Jira tickets * Send Slack notifications * Update a detection dashboard * Quarantine/isolate automatically (for high-confidence threats) **7. Test & Deploy** Test the agent manually in Builder before enabling the schedule: * Run against recent data * Verify it identifies known suspicious patterns * Check that it doesn't over-alert * Review output format and quality **8. Monitor & Tune** After deployment: * Review agent findings daily for the first week * Provide feedback on true positives vs. false positives * Add new false positive filters to context docs * Adjust schedule if needed (more/less frequent) > [card] [Creating Agents](/agents/creating-agents) > > Detailed guide on agent creation ## Combining Rule-Based and Pattern-Based Detection The most effective detection strategy **combines both approaches**: > [tab] Rule-Based Detection > > **Best for:** - Known threat techniques - High-confidence indicators - > Real-time alerting - Compliance requirements **Examples:** - Detect > PsExec execution - Alert on failed login thresholds - Monitor for > specific malware signatures > [tab] Pattern-Based Detection > > **Best for:** - Novel threats - Behavioral anomalies - Context-dependent > threats - Low-and-slow attacks **Examples:** - Unusual user behavior > patterns - Anomalous resource access - Sophisticated payloads that evade > rule-based detections **Layered Defense Strategy:** ``` Layer 1: Rule-Based Detections ├── Known threats (high confidence) ├── Real-time alerting └── Immediate response Layer 2: Pattern-Based Detection Agents ├── Behavioral anomalies ├── Scheduled analysis (hourly, daily) └── Catches what rules miss Layer 3: Human Analysis ├── Review agent findings ├── Deep-dive investigations └── Tune both rule-based and pattern-based detections ``` > [!NOTE] > > **Best Practice**: Use rule-based detections for known threats requiring > immediate response. Use pattern-based agents to hunt for novel threats and > behavioral anomalies that evade signatures. ## Tips for Effective Pattern-Based Detection > [!NOTE] > > **Start Broad, Then Focus**: Begin with wide behavioral monitoring. As you > identify common patterns, refine the agent to focus on high-value anomalies. > [!NOTE] > > **Provide Context Documents**: Give the agent reference material like org > charts, asset inventories, and known FP lists to improve accuracy. > [!NOTE] > > **Review Findings Regularly**: Especially in the first few weeks, review > agent findings to understand what patterns it's identifying. > [!NOTE] > > **Combine with Rules**: Use pattern-based detection to supplement, not > replace, traditional detections. ## Frequently Asked Questions > [accordion] Won't this generate too many alerts? > > You control alert volume by: - Specifying confidence thresholds in the > prompt - Defining what constitutes "suspicious" clearly - Providing > exclusion lists for known benign patterns - Choosing output destinations > (tickets vs. notifications) Start conservative and broaden based on > results. > [accordion] How is this different from UEBA tools? > > UEBA tools use statistical models and machine learning to detect > anomalies. Pattern-based detection agents use LLMs to understand > **context and reasoning**. Benefits of agent-based approach: - Explains > **why** something is suspicious (not just a statistical outlier) - > Adapts to new threat patterns without retraining models - Incorporates > organizational context (roles, policies) - You control the logic via > prompts (no black box) > [accordion] Can I use this for compliance monitoring? > > Yes! Deploy agents to monitor for: - Policy violations (unauthorized > access) - Compliance drift (configuration changes) - Audit requirements > (privileged user monitoring) Agents generate audit trails and reports > automatically. > [accordion] How do I measure success? > > Track these metrics: - **Detection Rate**: Threats caught by the agent > vs. missed - **False Positive Rate**: Benign alerts vs. genuine findings > > * **Time to Detect**: How quickly agent identifies suspicious activity - > **Investigation Time**: How long it takes analysts to act on agent > findings Use [evaluations](/improving-agents/evaluations) to measure and > improve agent performance. # Getting Started Source: https://docs.cotool.ai/getting-started Get up and running with Cotool in under 15 minutes Welcome to Cotool! This guide will help you create your first AI agent and run it successfully. ## Quick Start Paths In order to get started, do the following in order: > [card] [Connect Integrations](/integrations/overview) > > Set up your security and productivity tools > [card] [Try Chat](/chat/using-chat) > > Explore capabilities with chat first > [card] [Create Your First Agent](/agents/creating-agents) > > Follow a step-by-step guide to build your first agent ## What You'll Learn **1. Understand Agents** Learn what agents are and how they work in Cotool **2. Connect Your Tools** Authenticate your security and productivity integrations **3. Build Your First Agent** Create an agent using the Builder interface **4. Set Up Triggers** Automate your agent with triggers from Jira, Slack, or cron **5. Monitor Performance** Track agent runs and iterate on your prompts # Hunt Source: https://docs.cotool.ai/hunt/overview Turn threat intelligence into tracked threats, exposure assessments, and Hunt alerts Hunt helps your team turn incoming threat intelligence into a durable workflow. Cotool ingests intel, decides whether it is relevant to your environment, checks for exposure or compromise signals, tracks coverage gaps, and creates alerts when something needs attention. ## Main Hunt surfaces Hunt has four main screens in the product: > [card] Overview > > A summary of recent intel, assessed threats, exposure alerts, rule > proposals, and observability gaps. > [card] Threats > > The durable catalog of tracked threats, with grouped, table, and board > views. > [card] Intel Feed > > The raw stream of ingested threat intelligence items. > [card] Intel Sources > > Where you manage built-in sources plus your own RSS, MISP, and TAXII > feeds. ## How Hunt works At a high level, Hunt follows this flow: **1. Ingest intel** Cotool pulls threat intelligence from built-in sources, custom intel sources, or the `/hunt-intel` chat command. **2. Create or update a threat** Related intel is grouped into a durable threat record so the same threat can be tracked across assessments, alerts, and follow-up work. **3. Assess relevance and exposure** Cotool decides whether the threat applies to your environment and, when it does, runs an exposure assessment. **4. Capture outcomes** Hunt records findings such as compromise signals, exposure, no exposure, existing detection coverage, or telemetry gaps. **5. Open follow-up work** If Hunt finds something actionable, it creates a Hunt alert in [Triage > Alerts](/alerts/overview). It can also propose new detection rules or track blocking observability gaps. ## Understanding threat statuses Threats move through derived statuses as Cotool learns more about them: | Status | Meaning | | - | - | | **Hunting** | A Hunt assessment is running right now. | | **Active** | Hunt created an open alert that needs attention. | | **Blocked** | Hunt could not reach a verdict because required telemetry was missing. | | **Monitoring** | Some residual exposure remains and is being watched. | | **Covered** | An existing detection already covers this threat. | | **Clear** | No meaningful exposure was found in your environment. | | **Resolved** | The Hunt alert for this threat was investigated and closed. | | **Dismissed** | A user manually dismissed the threat. | | **Not relevant** | The threat does not apply to your environment, so Hunt did not pursue it further. | > [!NOTE] > > **Active** and **Resolved** follow the linked Hunt alert. For those threats, > the source of truth is the alert workflow in > [Working Alerts](/alerts/working-alerts). ## Add and manage intel sources Go to **Hunt > Intel Sources** to manage what Hunt ingests. You can add three custom source types: * **RSS feed** for vendor blogs, advisories, and newsletters * **MISP server** for private or public MISP-backed feeds * **TAXII server** for STIX 2.1 collections The Intel Sources page shows: * Source health * Last sync time * Item volume over the last 24 hours * Whether the source is enabled Built-in sources are managed by Cotool and appear automatically. For custom sources, you can enable or disable them, edit them, trigger a sync, or delete them when you no longer want their intel in Hunt. > [!NOTE] > > TAXII and MISP sources can use public feeds or authenticated servers. If > your server requires a token, provide it when you create the source. ## Use the Intel Feed The **Intel Feed** is where you review individual ingested intel items before or alongside threat-level analysis. Use it when you want to: * See which sources are producing new material * Open a specific advisory, post, or report * Trace a threat back to the underlying intel that produced it The feed complements the **Threats** catalog: * **Intel Feed** = individual source items * **Threats** = durable, tracked threat records ## Ingest a report from chat with `/hunt-intel` If you already have a report in hand, the fastest workflow is chat: **1. Start a chat command** In chat, type `/hunt-intel`. **2. Hand over the report** Provide the report in whichever form you have it: Several reports in one message are ingested one by one. **3. Review the ingest result** Cotool runs the Hunt intel pipeline and streams progress in the chat timeline. An explicit submission is always hunted: when the report carries no CVE, advisory id, malware family, or campaign name, the threat is keyed by the report title, and when the pipeline rates the material as low hunt value the card says so while the hunt still runs. **4. Continue from Hunt** From there, review the resulting intel item or threat record in the Hunt product area for follow-up. ## Work a threat Open **Hunt > Threats** to review the durable threat catalog. The Threats page supports: * **Grouped view** for status-based triage * **Table view** for scanning and sorting * **Board view** for a kanban-style workflow * Search by threat key, title, aliases, and actor * Filters for status, type, result, coverage, and actor Open a threat to see its detail page. Depending on the threat, that page can include: * The latest assessment summary * Exposure and relevance indicators * Assets and evidence tied to the threat * Detection coverage * Proposed detection rules * Blocking telemetry gaps * A linked Hunt alert * A full activity timeline If new intel arrives or your environment changes, use **Reassess** to rerun the Hunt workflow for that threat. ## Related pages > [card] [Alerts overview](/alerts/overview) > > See how Hunt findings turn into triage work items. > [card] [Working alerts](/alerts/working-alerts) > > Investigate and close Hunt alerts when exposure needs action. # Acceptance Criteria Source: https://docs.cotool.ai/improving-agents/acceptance-criteria Define pass/fail conditions that are checked on every agent run Acceptance criteria let you define specific conditions each agent run must satisfy. After every run, the Cotool Eval Harness evaluates each criterion individually and reports which passed and which failed. When any criterion is not met, you can automatically send notifications to Slack, webhooks, or PagerDuty. ## How It Works Criteria you define are injected into the agent's system prompt so the agent actively tries to satisfy them. After every run, the Cotool Eval Harness independently grades each criterion as **met** or **not met** and explains why. Failed criteria can optionally trigger notifications to Slack, webhooks, or PagerDuty. ## Adding Acceptance Criteria 1. Navigate to your agent's details page 2. Click **Edit** 3. Scroll to the **Acceptance Criteria** section 4. Add each criterion as a clear, evaluable statement 5. Click **Save Changes** > [!TIP] > > Write criteria as specific, observable conditions the Cotool Eval Harness > can verify from the run transcript. Vague criteria like "be helpful" produce > unreliable results. ### Good vs. Poor Criteria | Good | Poor | | - | - | | "Check EDR telemetry before closing an alert as false positive" | "Investigate alerts properly" | | "Never disable a detection rule without documenting justification" | "Be careful with rule changes" | | "Correlate across at least two log sources before determining scope" | "Use tools correctly" | | "Escalate to Tier 2 if lateral movement indicators are present" | "Don't miss threats" | ## Viewing Results After each run, acceptance criteria results appear in two places: * **Eval score popover** — click the evaluation score badge on any run to see which criteria passed or failed, along with the judge's explanation for each * **Run issues warning** — a warning icon appears next to runs that have failed criteria, combined with any critical issues the judge identified ## Notifications Acceptance criteria failures can trigger notifications through the same output destinations used for agent outputs (Slack, webhooks, PagerDuty). Notification configuration is independent from regular output delivery — you can enable one without the other. ### Setting Up Notifications 1. Click **Edit** on the agent details page 2. In the **Acceptance Criteria** section, toggle **Notify on failure** 3. Select one or more destinations from the dropdown (or create a new one) 4. Click **Save Changes** > [!NOTE] > > Destinations are shared across your organization. A Slack channel or webhook > created for output delivery can also be used for acceptance criteria > notifications. ### Notification Format **Slack** messages include the agent name (linked to the run), a timestamp, a pass/fail summary, and each failed criterion with the judge's explanation. **Webhooks** receive a JSON payload: ```json theme={null} { "organizationId": "...", "agentId": "...", "agentName": "My Agent", "runId": "...", "runTimestamp": "2026-03-25T00:28:23.667Z", "failedCriteria": [ { "criterion": "Provide a severity rating", "explanation": "The agent responded without including any severity classification" } ] } ``` **PagerDuty** creates an alert with the failed criteria count in the summary and individual criteria details in custom fields. ## Best Practices > [accordion] Start with 2–3 criteria > > Begin with the most important conditions and expand over time. Too many criteria can dilute signal and slow down the feedback loop. > [accordion] Write falsifiable statements > > Each criterion should be something the judge can clearly confirm or deny > from the run transcript. "Always include a confidence score" is falsifiable; > "produce good output" is not. > [accordion] Use criteria to catch regressions > > If a prompt change fixes a recurring issue, add a criterion that encodes the > fix (e.g. "Never close an alert without checking log ingestion status"). > This prevents the behavior from regressing silently. > [accordion] Pair with suggested improvements > > When criteria consistently fail, check the Suggested Improvements panel. The system may already have a prompt fix ready for you. ## Limits * Maximum **20 criteria** per agent * Each criterion can be up to **500 characters** # AI-Suggested Improvements Source: https://docs.cotool.ai/improving-agents/ai-suggested-improvements Automatic prompt improvements based on evaluation results When agent runs score poorly on automatic evaluations, Cotool analyzes the issues and suggests specific prompt improvements. You simply review the suggested changes and accept or reject them - no manual prompt writing required. ## How It Works **1. Pattern Detection** System identifies repeated issues across multiple low-scoring runs **2. Issue Clustering** Similar problems are grouped together to identify common root causes **3. Suggested Improvements Panel** You see a panel showing detected patterns and a "Generate Diff" button **4. Generate Diff** Click the button - AI generates specific prompt changes to fix the issues **5. Review Changes** See side-by-side diff of current vs. improved prompt **6. Accept or Reject** Apply the changes or reject if they don't fit your needs > [!NOTE] > > **You don't write the improvements** - The AI analyzes what went wrong and generates the fix. Your role is to review and approve, not write from scratch. ## Suggested Improvements Panel When available, you'll see a panel below the system prompt with suggested improvements. Here's an example: ``` Issues Found • Agent encountered empty log query results and immediately concluded the alert was noise without investigating why logs were missing • Aent disabled the detection rule globally (enabled: false) rather than implementing targeted tuning or allow lists • Agent marked the issue as 'Done' and took irreversible action without considering data ingestion issues or alternative explanations for missing logs Suggested Change • Require investigation before disabling rules • Add validation for file hash existence • Clarify severity thresholds Citations • Agent Execution: f9c63e37-dfa9-422f-bcc9-d27e36d255ca • Eval Score: 60/100 ``` ## Issue Categories The system automatically detects and suggests fixes for: > [card] Missing Steps > > Agent skipped important investigation or validation steps > > **Fix**: Add explicit steps to prompt > [card] Poor Decision Logic > > Agent made incorrect conclusions or didn't follow criteria properly > > **Fix**: Clarify decision criteria and edge cases > [card] Tool Misuse > > Wrong tools used, correct tools skipped, or inefficient patterns > > **Fix**: Add tool usage guidance > [card] Output Issues > > Missing information, unclear formatting, or insufficient detail > > **Fix**: Specify required output structure ## Generating the Diff When you click **"Generate Diff"**, the AI: 1. Analyzes the specific issues identified 2. Reviews your current system prompt 3. Generates targeted changes to fix the problems 4. Shows you a side-by-side comparison **Example Diff View**: > [tab] Before (Current) > > ```markdown theme={null} > ## Your Responsibilities > 1. Analyze the alert details > 2. Search logs for related activity > 3. Determine if alert is valid > 4. Update the ticket > ``` > [tab] After (Suggested) > > ```markdown theme={null} > ## Your Responsibilities > 1. Analyze the alert details and extract key indicators > 2. Search logs for related activity > - If logs are empty, investigate WHY before concluding > - Check data ingestion status > - Verify time range and query syntax > 3. Determine if alert is valid based on evidence > - Do not dismiss alerts solely due to missing logs > - Consider alternative data sources > 4. Update the ticket with findings and confidence level > ``` > [!NOTE] > > Changes are **highlighted** in the diff view. Green shows additions, red shows removals, yellow shows modifications. ## Multiple Improvements You may see multiple suggestion cards if several low-scoring runs identified different issues: ``` Suggested Improvements (3) 1. Require investigation before disabling rules Eval: 60/100 | Run: f9c63e37... 2. Add validation for file hash existence Eval: 55/100 | Run: a3d12f89... 3. Clarify severity thresholds Eval: 68/100 | Run: 7bd94c21... ``` You can: * Generate diffs for each individually * Address the lowest-scoring issue first * Reject suggestions that don't apply to your use case ## What Gets Improved > [accordion] Investigation Completeness > > **Issue**: Agent skipped checking user history before closing alert > > **Fix**: "Before determining severity, always: 1) Check user's recent activity..." > [accordion] Error Handling > > **Issue**: Agent failed when API returned no data > > **Fix**: "If VirusTotal returns no data (404), classify as Medium and note that hash is unknown..." > [accordion] Edge Case Handling > > **Issue**: Agent mishandled service account activity > > **Fix**: "If user matches pattern 'svc\_*' or 'service-*', verify activity against scheduled job list..." > [accordion] Output Specificity > > **Issue**: Agent output was vague: "Alert looks suspicious" > > **Fix**: "Always include: 1) Specific indicators found, 2) Confidence level (High/Medium/Low), 3) Recommended actions..." ## Best Practices > [accordion] Act on Repeated Issues > > If you see the same issue across multiple runs, accept the suggestion. Repeated patterns indicate a real problem. > [accordion] Test After Accepting > > Use Agent Builder to test the updated prompt with edge cases before relying on it in production. > [accordion] Monitor Impact > > After accepting changes, watch evaluation scores for the next 10-20 runs to confirm improvement. > [accordion] Don't Over-Optimize > > Not every low score needs a prompt change. Sometimes the issue is data quality, API availability, or legitimate edge cases. ## Example: Real Improvement Flow **Run #1834 - Evaluation Score: 60/100** **Issue Detected**: ``` Agent encountered empty Splunk results and immediately marked alert as false positive without investigating why logs were missing. This could miss real threats if log ingestion is delayed. ``` **Generated Diff**: ```diff theme={null} ## Investigation Steps 1. Search Splunk for related activity + - If query returns 0 results, verify: + a) Data ingestion status (check indexer health) + b) Time range (expand if near ingestion delay window) + c) Query syntax (test with broader search) + - Only conclude "no activity" after ruling out data issues 2. Assess findings - - No logs = likely false positive + - No logs = investigate further before concluding + - Document if missing logs prevent full assessment ``` **You**: Review diff, looks good ✅ **Action**: Click "Accept" **Result**: Prompt v5 created, agent now handles empty query results properly **Validation**: Next 15 runs average 82/100 (up from 65/100) ## Manual Prompt Editing You can always edit prompts manually instead of using suggestions: 1. Go to Agent Settings → System Prompt 2. Click "Edit" 3. Make changes directly 4. Save (creates new version) But the AI-suggested flow is faster and often catches issues you might miss. # Automatic Evaluations Source: https://docs.cotool.ai/improving-agents/evaluations Every agent run is automatically scored to identify improvement opportunities Every agent execution is automatically evaluated by an LLM judge that scores performance from 0-100. These scores drive automatic improvement suggestions and help you track agent quality over time. ## How It Works **1. Agent Executes** Your agent completes a run (triggered by user, schedule, or event) **2. Automatic Evaluation** Immediately after completion, an LLM judge analyzes the execution and assigns a score (0-100) **3. Score Recorded** Score is logged and displayed in run history **4. Improvement Suggestions** Low-scoring runs automatically trigger AI-generated improvement suggestions > [!NOTE] > > **No configuration needed** - Evaluations run automatically on every > execution. The system learns what "good" looks like based on your agent's > goals and past performance. ## What Gets Evaluated The LLM judge assesses multiple dimensions: > [card] Accuracy > > Did the agent correctly assess the situation and reach the right > conclusion? > [card] Completeness > > Did it gather all necessary information before deciding? > [card] Tool Usage > > Were tools used appropriately and efficiently? > [card] Output Quality > > Is the response clear, well-formatted, and actionable? ## Evaluation Scores Scores range from 0-100: * **90-100**: Excellent - Agent performed optimally * **75-89**: Good - Minor improvements possible * **60-74**: Acceptable - Some issues identified * **Below 60**: Needs improvement ## Improvement Workflow When multiple runs show similar low-scoring patterns, the system automatically: 1. **Analyzes the execution** to identify specific issues 2. **Generates improvement suggestions** for your system prompt 3. **Shows "Suggested Improvements" panel** (see AI-Suggested Improvements) 4. **Lets you review and apply fixes** with one click > [card] [AI-Suggested Improvements](/improving-agents/ai-suggested-improvements) > > Learn how to review and apply automatic improvement suggestions ## Best Practices > [accordion] Review Low-Scoring Runs > > When you see low scores, click into the run to understand what went > wrong. The evaluation breakdown shows exactly what needs improvement. > [accordion] Apply Suggested Improvements > > Don't ignore the "Suggested Improvements" panel. Most issues can be > fixed by accepting the AI-generated prompt changes. > [accordion] Track Trends, Not Individual Runs > > One low score isn't a problem. Look for patterns - if average score is > declining or consistently low for certain scenarios, take action. > [accordion] Complement with Manual Feedback > > Evaluations are automatic, but you can also provide thumbs up/down > feedback to give additional signal about what's working. ## What Makes a Good Score? > [!WARNING] > > **Don't aim for perfect 100s** - Agents don't need to be perfect, they need > to be useful. A consistent 80-90 range usually indicates a well-tuned agent. Focus on: * **Consistency**: Is the agent reliable across different scenarios? * **Improvement**: Are scores trending upward after applying suggestions? * **User satisfaction**: Do evaluation scores align with user feedback? # Manual Feedback Source: https://docs.cotool.ai/improving-agents/feedback-system Supplement automatic evaluations with manual user feedback While every agent run is automatically evaluated, you can also provide manual thumbs up/down feedback to give additional signal about what's working. This supplements the automatic evaluation system with human judgment. > [!NOTE] > > **Manual feedback is optional** - Automatic evaluations already drive > improvement suggestions. Use manual feedback when you want to provide > additional context or when the automatic score doesn't capture the full > picture. ## How It Works After each agent run, users can: * 👍 **Thumbs up** - Good execution, agent performed well * 👎 **Thumbs down** - Poor execution, something went wrong * 💬 **Optional comment** - Explain what was good or bad ## Where to Provide Feedback Feedback options appear in multiple places: **Agent Execution Detail Page**: * Click into any run from agent history * Thumbs up/down buttons at the top * Comment field for additional context **Slack Bot Responses** (if Slack trigger enabled): * React with 👍 or 👎 emoji * Reply in thread for comments **Email Responses** (if email trigger enabled): * Reply with "+1" (positive) or "-1" (negative) * Include explanation in email body **API Responses**: * Include feedback via API when invoking programmatically * See API documentation for details ## How Feedback Complements Evaluations | Automatic Evaluations | Manual Feedback | | - | - | | Every run, always | Optional, when users have opinion | | Objective LLM assessment | Subjective human judgment | | Scores specific criteria | Overall impression | | Drives AI suggestions | Adds context to patterns | | Primary improvement method | Supplementary signal | > [!NOTE] > > Think of manual feedback as a way to say "I agree/disagree with the > automatic eval" or to highlight something the automatic system might have > missed. ## When to Provide Feedback > [accordion] When Auto-Eval Seems Wrong > > If a run scored 85/100 but you think it was actually poor (or vice > versa), provide feedback to give corrective signal. > [accordion] For Subjective Qualities > > Tone, professionalism, or style preferences that automatic evals might > not capture well. > [accordion] To Highlight Patterns > > If you notice the same issue across multiple runs, feedback comments > help identify the pattern. > [accordion] For Business Impact > > "This saved our analyst 2 hours" or "This missed a critical finding" - > context the eval can't measure. ## Using Feedback Insights Feedback is tracked alongside automatic evaluations: **On Agent Dashboard**: ``` Last 30 Days Avg Eval Score: 82/100 User Feedback: 87% thumbs up (45 total) ``` **In Run History**: * Filter by feedback (show only thumbs up/down runs) * Sort by feedback sentiment * See feedback comments **For Improvement Analysis**: * Common themes in thumbs-down comments inform prompt improvements * Feedback helps validate that eval-driven changes are working * Disagreement between eval scores and feedback indicates calibration needs ## Feedback-Driven Improvements While automatic evaluations drive most improvements, feedback helps identify issues to prioritize: **Example Pattern**: ``` 5 runs with thumbs down + comments like: "Too slow" "Takes forever" "Can you make this faster?" Average eval scores: 80/100 (objectively fine) ``` **Action**: Even though eval scores are good, clear user dissatisfaction about speed → investigate performance optimization. ## Best Practices > [accordion] Focus on Actionable Feedback > > **Good**: "Agent didn't check user history before concluding" **Less > useful**: "This was bad" > [accordion] Don't Over-Think It > > Feedback should take 5 seconds. If a run was clearly good or bad, just > click thumbs up/down. Comments optional. > [accordion] Use for Exceptions > > You don't need to feedback every run. Focus on runs that surprise you > (much better or worse than expected). > [accordion] Be Specific in Comments > > When you do comment, mention specific issues or wins: "Missed checking > VirusTotal" or "Perfect triage, saved me time". ## Feedback Metrics Track feedback trends over time: > [card] Satisfaction Rate > > % thumbs up out of total feedback given > [card] Feedback Volume > > How many runs receive feedback (higher = more engagement) > [card] Sentiment Trend > > Is satisfaction improving or declining? > [card] Common Themes > > Text analysis of comments to identify patterns ## Correlation with Evaluations Monitor how manual feedback aligns with automatic evaluations: **Strong Agreement** (good): ``` High eval scores (80+) → mostly thumbs up Low eval scores (<70) → mostly thumbs down ``` **Disagreement** (investigate): ``` High eval scores → lots of thumbs down OR Low eval scores → lots of thumbs up ``` Disagreement suggests: * Evaluation criteria might need adjustment * There's a subjective quality not being measured * Users value different things than the eval judges ## Example: Feedback in Action **Run #2048 - Automatic Eval: 78/100** **User Feedback**: 👎 + Comment ``` "Agent correctly identified the alert as a false positive, but the explanation was too technical for our tier-1 analysts to understand. Need simpler language." ``` **Result**: * Automatic eval scored it as "acceptable" (78/100) * User feedback highlights a gap: audience-appropriate language * This becomes a factor in future prompt improvements ## When Feedback Overrides Evals Manual feedback is particularly valuable when: 1. **Business context matters** - "Technically correct but missed our policy" 2. **Audience matters** - "Right answer, wrong communication style" 3. **Edge cases** - "Eval couldn't know this is a known false positive" 4. **Performance matters** - "Correct but too slow for our SLA" # Agent Versioning Source: https://docs.cotool.ai/improving-agents/system-prompt-versioning Track changes to the whole agent definition, diff versions, and restore previous ones Cotool keeps a version history for each agent. A version is a snapshot of the agent's **whole definition** — not just its prompt — so you can see exactly what changed between any two points, and roll back if a change makes things worse. ## What a Version Captures Each version is a snapshot of the entire definition: * System prompt * Model and planning mode * Tools (including agent-as-tool references) and skills * Inputs and acceptance criteria * Structured-output schema and tags * Triggers Versions are **append-only**: each one is recorded as a new entry in the timeline, and identical definitions are de-duplicated so a no-op change doesn't create noise. ## When a New Version Is Recorded Cotool appends a version whenever the agent's **definition** changes: * Editing the system prompt * Accepting an [AI-suggested improvement](/improving-agents/ai-suggested-improvements) * Creating, editing, or deleting a trigger * A change applied by [Response Agents as Code](/agents/response-agents-as-code) sync (tagged with the source commit) Toggling a trigger on or off does **not** create a version — whether a trigger is enabled is runtime state, not part of the definition. ## Viewing and Comparing Versions Agent versions are visible in two places: * **When editing an agent** — open the version dropdown to browse history, **diff** any two versions, and **Export as YAML** for the current definition. * **On the Evaluations tab** — the per-version breakdown is labeled by version (`v1`, `v4`, …) so you can see which version produced each run and compare performance across versions. ## Restoring Previous Versions If a new version performs worse, you can restore an earlier one: 1. Open the agent's version history 2. Select the version you want to restore 3. Click **Restore** Restoring appends a **new** version that matches the one you chose (history is never rewritten — `A → B → restore-to-A` is three entries, not a rollback of the timeline). It also reconciles the agent's triggers back to that version: recreating, updating, or deleting them to match, minting fresh webhook secrets where needed, and resolving Slack/Linear integrations. A trigger whose integration isn't connected is skipped rather than failing the restore. The agent immediately uses the restored definition for all new runs. > [!NOTE] > > For agents managed by [Response Agents as > Code](/agents/response-agents-as-code), the version history shows synced and > manual changes together in one timeline. Since managed agents are read-only > in the UI, you roll them back by reverting the change in Git. # Introduction Source: https://docs.cotool.ai/index ![Hero Light](https://mintcdn.com/cotool-bcb49c92/YkFCFtl3swKv9Xqp/images/DitherComponent.png?fit=max\&auto=format\&n=YkFCFtl3swKv9Xqp\&q=85\&s=515410d4373175ba87c8200aeb8d60c5) Cotool is a platform for building and deploying AI agents to automate any kind of security work. Use it to turn manual workflows into repeatable, reliable agents—whether you're investigating alerts, managing access, enriching data, or handling inbound requests. Cotool helps security engineers, analysts, and developers design agents that reason through tasks, call APIs, and take secure actions across your stack. ## Get Started > [card] [Getting Started](/getting-started) > > Set up your first agent in under 15 minutes > [card] [Core Concepts](/core-concepts/what-is-an-agent) > > Understand how agents, tools, and triggers work > [card] [Alerts](/alerts/overview) > > Track security work from detection through triage and closure ## Overview Cotool provides three core capabilities: * **Copilots**: Interactive agents for ad-hoc investigations and workflows * **Autonomous Agents**: Trigger-based workflows that execute without human input * **Triage**: Alerts and response agents for tracking security work through disposition * **Detection Engineering**: Map detection coverage across your stack and collaboratively author new detections All behavior is traceable, auditable, and safe by design. # Cotool Email Source: https://docs.cotool.ai/integrations/communication/cotool-email Let agents send plain-text email from a Cotool address The **Cotool Email** integration lets agents send email, for example to tell an employee what happened to the phishing email they reported. Messages come from `agent-no-reply@cotoolmail.com`, so you don't need to connect a mailbox. ## How it works * Agents call the **Send Email** action with a list of up to 50 recipients, a subject, and a plain-text body. All recipients get one message and can see each other. HTML and Markdown are shown as literal text. * Each message ends with a footer naming your organization and stating that replies are not monitored. * Agents cannot email `cotoolmail.com` addresses, and Cotool ignores agent email that is forwarded back to an email trigger, so an agent cannot start itself or another email-triggered agent. ## Allowed recipients Each agent can only email the recipients on its own allowlist. An agent without one cannot send email, and neither can chats or code detections. **1. Add the tool to the agent** In the agent's tools, select **Send Email** under Cotool Email. **2. Add allowed recipients** Click the gear next to **Send Email** and enter one email address or domain per line, for example `example.com` or `security-team@example.org`. A domain allows every address at that domain, but not its subdomains: add `mail.example.com` separately if the agent needs it. If any recipient of a message is not allowed, nothing is sent. Keep the list as narrow as the agent's job allows: agents that read attacker-written content, such as a reported phishing email, can be tricked into emailing whoever that content names. ## Enabling and disabling The **Cotool Email** integration on the [Integrations page](https://app.cotool.ai/platform/integrations) is connected automatically and needs no credentials. Disable it to stop all agents in your organization from sending email. # Slack Integration Source: https://docs.cotool.ai/integrations/communication/slack Connect Cotool to Slack for team communication and agent triggers The Slack integration enables your AI agents to communicate with your team directly in Slack. Agents can respond to messages, reply in threads, send rich formatted messages, and be triggered by @mentions in channels. ## Features > [card] Direct Messages > > Chat with Cotool directly via DM. The bot creates a personal chat for each conversation. > [card] Channel Triggers > > @mention the bot in channels to trigger agents with specific capabilities. > [card] Emoji Reactions > > React to any message with a configured emoji to run an agent on that message. > [card] Thread Conversations > > Agents automatically reply in threads to keep channels organized. > [card] Rich Messages > > Send formatted messages with buttons, charts, and file attachments. ## Setup **1. Navigate to Integrations** Go to **Settings > Integrations** in Cotool and find the Slack integration. **2. Install the Slack App** Click **Connect** to begin the OAuth flow. You'll be redirected to Slack to authorize the Cotool app. **3. Grant Permissions** Review and approve the requested permissions. The app needs access to: * Read messages in channels where it's mentioned * Read and respond to direct messages * Post messages and reactions * Read the workspace's custom emoji (so emoji reaction triggers can be picked from a list) * Upload files, and download files shared in channels the bot is a member of **4. Select Workspace** Choose which Slack workspace to connect. You can connect multiple workspaces if needed. ## How It Works ### Direct Messages You can start a conversation with Cotool by sending a direct message to the bot: 1. Find **Cotool** in your Slack workspace's Apps section 2. Send a message describing what you need help with 3. The bot reacts with 👀 to acknowledge receipt 4. A personal chat is created in Cotool and the agent processes your request 5. The agent replies directly in the Slack thread with its findings > [!NOTE] > > DM conversations create personal chats in Cotool. You can continue the > conversation by replying in the same thread, and the agent will have full > context of previous messages. ### Channel @Mentions (Agent Triggers) When you connect Slack and have no Slack triggers yet, Cotool creates a default Slack trigger on your organization's default response agent, so @mentioning the bot in any channel it has been added to works right away. Anyone in the workspace can @mention it; only Slack users linked to a Cotool account can continue the thread. The trigger appears on that agent's **Triggers** tab marked **Default**. You can disable it, restrict it to specific channels, change who can reply, or move it to another agent from the Alert Routing page; it is removed automatically if Slack is disconnected. An agent that hosts it cannot be deleted until you move it elsewhere. The default is not created on GitOps-managed agents; configure their Slack triggers in the repository. If the same Slack workspace is connected to multiple Cotool organizations, the shared app uses only explicitly configured triggers, even if another organization's triggers are disabled. Custom Slack apps route to their own organization. To route specific channels to a different agent, add a **Slack trigger** to that agent. Your own triggers always take precedence over the default one for the channels they cover: **1. Create or Edit an Agent** Navigate to the agent you want to trigger from Slack. **2. Add a Slack Trigger** In the agent's **Triggers** tab, click **Add Trigger** and select **Slack**. **3. Configure Access (Optional)** Optionally restrict which users, user groups, or channels can trigger the agent. **4. @Mention in Slack** In any channel where the bot is present, @mention the bot with your request: `@Cotool investigate the alert for IP 192.168.1.100` When you @mention the bot: 1. The bot reacts with 👀 to acknowledge it received your message 2. The configured agent processes your request 3. The agent replies in a thread under your message with its findings > [!WARNING] > > Channel @mentions are answered by a Slack trigger. If the default trigger is > disabled and no other trigger covers the channel, the bot replies with a > link to set one up. ### Emoji Reactions (Agent Triggers) An agent can also be triggered by adding an emoji reaction to a message — useful when you spot something worth investigating and don't want to retype it. **1. Configure the Emoji** On the agent's Slack trigger, under **Which emoji reactions trigger this agent?**, pick the emoji that should trigger it. The picker searches your workspace's custom emoji alongside the standard set, so you can search by name or keyword (typing `alarm` finds 🚨). There is no separate on/off switch: picking at least one emoji enables reaction triggering, and leaving the field blank disables it. **2. React in Slack** Add one of those reactions to any message in a channel the trigger allows. When someone adds a configured reaction: 1. The bot reacts with 👀 to acknowledge it 2. The agent runs with **that specific message** as its subject, and can read the surrounding thread for context 3. If the message is already in a thread, the agent replies in that thread. If it isn't, the agent's reply **starts a new thread on the message** > [!NOTE] > > The trigger's channel and user allow lists apply to the person who added the > reaction, exactly as they do for @mentions. If the channel is allowed but > the reactor isn't, the bot explains why nothing happened (once per message > and emoji) rather than running the agent. In a channel the trigger doesn't > cover, the reaction is ignored silently — the bot won't post in channels it > wasn't configured for. A few behaviors worth knowing: * **One run per message and emoji.** If several people add the same reaction to the same message, or someone removes and re-adds it, the agent runs once — not once per person. * **Reactions continue an existing conversation.** If the thread already has a Cotool chat, reacting adds to that chat instead of starting a new one. * **Cotool's own reactions never trigger anything**, including its 👀 acknowledgement. * Reactions are only honored for emoji configured on a Slack trigger. Because each channel can have only one Slack trigger you create (the default trigger doesn't count), all the emoji configured for a channel route to that trigger's agent. * **There is a cap of 30 reaction-triggered runs per 30 minutes per trigger** — the same budget an agent already has for its own runs, so a single trigger is no more limited than before. Beyond it, reactions are skipped (no 👀) and the bot posts one message in the thread explaining why. Hitting this almost always means an emoji is configured more broadly than intended — narrow the emoji list, or the channels, on the trigger. Runs resume automatically. The agent's own overall run rate limit applies too, and is reported the same way. > [!WARNING] > > Emoji reactions require the `reaction_added` bot event to be subscribed in > the Slack app. This is already configured for the Cotool-hosted Slack app. > If your organization uses its own custom Slack app, an admin must add > `reaction_added` to its **Event Subscriptions**. ### Thread Replies All agent responses are sent as thread replies to keep channels organized. If you reply to an existing thread where Cotool has responded, the agent will: 1. Re-enter the existing conversation with full context 2. Process your follow-up message 3. Reply in the same thread This enables natural back-and-forth conversations without cluttering the main channel. ## Available Tools When an agent has the Slack integration enabled, it can use these tools: | Tool | Description | | - | - | | `slack_sendMessage` | Send a message to a channel or user | | `slack_replyToThread` | Reply to a specific thread | | `slack_listChannels` | List channels in the workspace | | `slack_searchMessages` | Search for messages across channels | | `slack_getChannelHistory` | Get recent messages from a channel | | `slack_getUserInfo` | Get information about a Slack user | | `slack_listUsers` | List users in the workspace | | `slack_uploadFile` | Upload a file to a channel | | `slack_downloadMessageFiles` | Save the files posted in a message or thread reply to the agent's sandbox, under their original names (up to 30 MB each). The bot must be a member of the channel. | | `slack_waitForUserResponse` | Send a message with buttons and wait for user input. Unanswered prompts time out by alert severity (15 minutes for critical up to 24 hours for low) unless you set a fixed timeout; an answer after the timeout still reaches the agent, unless the run was stopped | ## Example Use Cases > [accordion] Security Alert Notifications > > Create an agent that monitors your SIEM and sends formatted alerts to a > `#security-alerts` channel with relevant context and recommended > actions. > [accordion] On-Call Assistant > > Set up a trigger so on-call engineers can @mention the bot to quickly > investigate incidents, gather context from multiple tools, and summarize > findings. > [accordion] Access Request Handling > > Build an agent that processes access requests posted in a channel, > checks user permissions, and either approves or escalates based on > policy. > [accordion] Daily Standup Summaries > > Schedule an agent to post daily summaries of open tickets, pending > alerts, or team metrics to keep everyone informed. ## Best Practices > [!TIP] > > **Use descriptive agent names** - When multiple agents have Slack triggers, > clear names help users know which agent to @mention. > [!TIP] > > **Restrict channel access** - Use trigger configuration to limit which > channels can trigger sensitive agents, preventing accidental exposure in > public channels. > [!TIP] > > **Leverage thread context** - Agents automatically read the full thread > history, so users can have multi-turn conversations without repeating > context. # GitHub Integration Source: https://docs.cotool.ai/integrations/dev-tools/github Connect Cotool to GitHub for repository access and Response Agents as Code sync The GitHub integration connects Cotool to repositories through a GitHub App. Agents can read repository context, work with pull requests, and, when enabled, sync [Response Agents as Code](/agents/response-agents-as-code) YAML files from a repo into Cotool. You can connect with the **Cotool-managed GitHub App**, with a **GitHub App you own** (bring your own App), or both. The most common reason to bring your own App is to **enforce read-only access**: you register an App with only read permissions, and GitHub — not Cotool — rejects any write on every request made through it. Agents can still investigate code and pull requests in those repositories, but cannot commit, open pull requests, or change workflows there, no matter what they are asked to do. Pair it with the managed App on your other repositories to keep full pull-request workflows where you want them. ## Features > [card] Repository access > > Let agents inspect files, commits, blame, pull requests, branch rules, and repository metadata. > [card] Pull request workflows > > Allow agents to create, update, review, and close pull requests — including > as drafts — when their workflow needs to change code. > [card] Response Agents as Code > > Sync response-agent definitions from YAML files in a selected GitHub repo, > branch, and folder. > [card] Scoped installation > > Control exactly which GitHub organizations and repositories Cotool can > access through the GitHub App installation. > [card] Bring your own GitHub App > > Connect a GitHub App you register and own, so your organization chooses the permissions Cotool is granted — including read-only. ## Choosing How to Connect | | Cotool-managed App | Bring your own App | | - | - | - | | **Who owns the App** | Cotool | Your GitHub organization | | **Permissions** | Fixed by Cotool; supports the full set of agent GitHub tools | Chosen by you when you create the App; GitHub enforces them on every Cotool request | | **Setup** | Click **Connect** and install | Create a GitHub App, paste its credentials into Cotool, then install it | | **Typical use** | Default; fastest path | Read-only access to sensitive repos, or stricter permission review requirements | Either App can be installed on multiple GitHub organizations, and both Apps can be connected to the same Cotool organization at once — even on the same GitHub organization, as long as each repository is selected for only one of them. See [Installing across GitHub organizations](#installing-across-github-organizations) and [Using both Apps together](#using-both-apps-together). ## Setup with the Cotool-managed App **1. Open the GitHub integration** In Cotool, go to **Settings > Integrations** and open **GitHub**. **2. Install the GitHub App** Under **Cotool-managed GitHub App**, click **Connect**. GitHub will ask you to install the Cotool GitHub App on an organization or user account. For a GitHub organization, an organization owner must complete the installation. **3. Choose repository access** Select the repositories Cotool should be able to access. You can grant access to all repositories or only selected repositories. **4. Authorize your GitHub user** After installing the app, authorize Cotool as a GitHub user who can access the new installation. Cotool verifies this access before linking the installation to your Cotool organization. **5. Finish the connection** After authorization, GitHub returns you to Cotool. The GitHub integration page will show the connection state and any feature cards that depend on GitHub. > [!WARNING] > > Cotool does not support GitHub's pending installation-request flow. If > GitHub offers **Request** instead of **Install**, ask an organization owner > to open the GitHub integration in Cotool and complete the connection. > [!NOTE] > > You need permission to install GitHub Apps in the target GitHub > organization. In Cotool, connecting GitHub and configuring GitHub-dependent > sync settings require the `tool.manage` permission. ## Setup with Your Own GitHub App Use this when your organization wants to control the permissions Cotool is granted. You create the App in GitHub, give Cotool its credentials, then install it on your organization the same way as the managed App. **1. Open the custom App setup** In **Settings > Integrations > GitHub**, find **Bring your own GitHub App** and click **Set up custom App**. The dialog shows the exact values to paste into GitHub's **Create GitHub App** form. **2. Create the App in GitHub** In your GitHub organization, go to **Settings > Developer settings > GitHub Apps > New GitHub App** and fill in the form using the values from the Cotool dialog: * **Identifying and authorizing users** — add Cotool's callback URL as a **Redirect URI**. Leave *Request user authorization (OAuth) during installation* unchecked. * **Post installation** — use the same callback URL as the **Setup URL**. Leave *Redirect on update* unchecked. * **Webhook** — GitHub requires a Webhook URL before it will create the App. Paste the Cotool-provided URL now, leave **Active** unchecked and **Secret** blank for the moment. * **Permissions** — choose what Cotool may do. See [Permissions](#permissions-on-your-own-app) below. **3. Paste the App's credentials into Cotool** After GitHub creates the App, copy its **App ID** and **Client ID**, generate a **client secret**, and generate and download a **private key**. Paste all four into the Cotool dialog and save. Cotool verifies the credentials against GitHub — the App ID, private key, and client ID must all belong to the same App, and the required Members permission must be present — before storing anything. **4. Finish the webhook** Once Cotool shows **Credentials verified**, it displays a Cotool-generated webhook secret. Back in GitHub's App settings, paste that secret into the **Webhook** section, turn **Active** on, and subscribe to the **Installation**, **Installation target**, and **Installation repositories** events. These let Cotool keep repository routing current as you change the App's repository access. **5. Install the App** Click **Add organization** under **Bring your own GitHub App**. GitHub walks you through installing *your* App on an organization and choosing repositories, then Cotool verifies your GitHub user and links the installation — exactly as with the managed App. ### Permissions on your own App GitHub enforces your App's permissions on every request Cotool makes, so choose them to match what you want agents to be able to do: | Cotool capability | GitHub permission required | | - | - | | Read files, commits, blame, branch rules, repository metadata | **Contents: Read** (and Metadata, which GitHub always grants) | | Read and list pull requests | **Pull requests: Read** | | Commit files to a branch | **Contents: Read and write** | | Open, update, or close pull requests; request reviewers | **Contents: Read and write** and **Pull requests: Read and write** | | Create or update GitHub Actions workflow files | additionally **Workflows: Read and write** | | Complete setup (verify the installer is an organization owner) | **Organization → Members: Read** — *required* | > [!WARNING] > > **Organization → Members: Read** is the one permission Cotool requires on a > bring-your-own App. Cotool uses it during setup to confirm that the person > connecting the installation is an owner of the GitHub organization. Without > it, the installation cannot be linked and Cotool reports that a GitHub > organization owner must approve the App's permission update before retrying. #### Recipe: a read-only App To guarantee agents can never modify a set of repositories, create your App with exactly: * **Repository → Contents: Read** * **Repository → Pull requests: Read** * **Organization → Members: Read** (required for setup) and leave every other permission at *No access*. Install it on the repositories you want protected. Agents can read files, history, blame, branch rules, and pull requests there, but every commit, pull-request, or workflow write is refused by GitHub itself, so the guarantee does not depend on Cotool's behaviour or on how an agent is prompted. Cotool's write tools remain visible to agents, and `github_listRepositories` reports these repositories as `read-only` with every write capability `false`, so agents know not to attempt them — see [What agents can see](#what-agents-can-see-about-their-access). If you change the App's permissions later, GitHub asks an organization owner to approve the new permissions for each existing installation. Cotool picks up the approved permissions on its next request; no reconnect is needed. ### Managing your App **Manage App** under **Bring your own GitHub App** lets you update the App's credentials, rotate the Cotool-generated webhook secret, or remove the App configuration. Switching to a different App ID or removing the configuration is blocked while any of its installations are still connected — disconnect those first. ## Installing Across GitHub Organizations A single GitHub App — managed or your own — can be installed on as many GitHub organizations (or user accounts) as you need, and Cotool treats each installation as a separate connection. Click **Connect** / **Add organization** again to install the same App on another organization. The integration page groups your installations by GitHub organization. ## Using Both Apps Together Your Cotool organization can have the managed App and your own App connected at the same time, and the two Apps may be installed on **different** GitHub organizations or on the **same** one. Every repository is served by exactly one installation, so Cotool routes each repository as follows: * A repository visible to only one installation is routed through that installation. * **Two Apps may share a GitHub organization as long as they are installed on disjoint sets of repositories** — each repository selected for one App and not the other. This is how you run a read-only App on sensitive repositories and the managed App on everything else within a single GitHub organization. * If you install a second App on an organization and its selected repositories overlap an existing Cotool installation, the new installation is rejected and Cotool shows the exact overlapping repositories. If an already-connected installation later gains a repository that another installation already serves, that whole installation is marked **Blocked** — none of its repositories are used — until the overlap is resolved. * To resolve an overlap, change the repository selection on one App in GitHub so each repository is selected for only one App. Cotool reconciles automatically via the installation webhooks and unblocks the installation; rejected installations are retried without any action in Cotool. The integration page groups installations by GitHub organization and shows which App serves each, along with any blocked state and links to each App's repository settings in GitHub. ## What Agents Can See About Their Access When an agent lists repositories (`github_listRepositories` / `github_searchRepositories`), each repository includes a `cotool_access` block describing the App and installation that serve it and what Cotool is permitted to do there, based on the permissions GitHub actually granted that installation: ```json theme={null} { "full_name": "acme/payments", "cotool_access": { "app_slug": "acme-cotool-readonly", "app_source": "customer", "installation_id": "12345678", "level": "read-only", "can": { "read": true, "commit": false, "open_pull_request": false, "edit_workflows": false, "request_reviewers": false }, "granted_permissions": { "contents": "read", "pull_requests": "read", "members": "read", "metadata": "read" } } } ``` The response also lists every connected App under `apps`, with the permissions granted to each of its installations. Agents use this to answer questions like *"which repositories are you read-only on?"* directly, and to check before attempting a write that the serving App allows it. ## Searching Code Across Organizations `github_searchCode` searches code in every connected GitHub organization and user account in one call, so an agent can answer *"do we use this vulnerable package anywhere?"* without going through repositories one by one. It runs one [GitHub code search](https://docs.github.com/en/rest/search/search#search-code) per connected account, through the installation that serves it, and merges the results. Each result names the matching file and its repository and includes the matched lines. The response also lists the matching repositories, so an agent can follow up with `github_readFile`, `github_searchContent`, or a checkout. * Results only include repositories your installations were granted. When an installation is limited to selected repositories, matches in that organization's other public repositories are dropped. * `returned` is the number of results in the response, and `github_total_count` is GitHub's own count. For an installation limited to more selected repositories than fit in one search, GitHub's count also includes the organization's ungranted public repositories, so the response sets `total_count_exact` to `false` to mark it as an upper bound. * Set `org` to search one connected account. Agents cannot widen the search with `org:`, `user:`, `owner:`, or `repo:` qualifiers. * GitHub's code search covers default branches only, skips files larger than 384 KB, has no regular expression support, and returns at most 1,000 results per account. GitHub also rate-limits code search per installation. ## Checking Out Repositories `github_checkoutRepository` gives an agent a local copy of a repository in its sandbox, at `/repos//`. With a checkout, the agent can search the code with `rg`, read history with `git log` and `git blame`, and edit files. These are faster and more thorough than reading files one API call at a time. * **What gets checked out:** the default branch, or any branch, tag, or commit SHA the agent names. A commit is checked out detached, like a tag. * **How much history:** Cotool picks it from the repository size. Repositories up to 300 MB get their full history, larger ones the last 12 months, and repositories over 2 GB the last 3 months. Agents can ask for a different amount, but not the full history of a repository over 2 GB. * **How the copy is made:** the agent's sandbox never holds a GitHub credential and cannot reach github.com, so `git push` and `git fetch` fail there. Cotool clones in a separate, isolated worker with a short-lived, read-only token scoped to that one repository and revokes the token right after. The packaged copy is reused for 15 minutes, so several agents checking out the same repository don't each clone it. * **Running code:** agents are instructed never to run code from a checkout. They read and edit it but don't install, build, or test it. * **Lifetime:** a checkout lives only as long as the sandbox. To turn edits into a pull request, `github_createPullRequestFromWorkspace` commits every changed file in one verified commit through the GitHub API, on a new branch, and opens the PR. `github_updatePullRequestFromWorkspace` pushes later edits to a pull request Cotool opened. Both need write access to the repository: they fail on repositories served by a read-only App. They refuse changes to `.github/workflows/`, which go through `github_createWorkflowPullRequest`. ## Repository Access Cotool uses the GitHub App installation token for the repositories you selected during setup. If a repository does not appear in Cotool: * Confirm a connected GitHub App (managed or your own) is installed on the organization or user account that owns the repo. * Confirm that installation has access to that specific repository. * Check the integration page for a **Blocked** installation — a repository selected for both Apps disables the affected installation until the overlap is removed. * Reconnect or update the GitHub App installation if repository access changed after the original setup. The same installations are used by both agent GitHub tools and the Response Agents as Code sync picker, so the repository, branch, and folder dropdowns only show resources Cotool can actually read. If a write tool fails with a permissions error on a repository served by your own App, check that App's permissions in GitHub — Cotool cannot exceed what the App was granted. ## Response Agents as Code Sync After GitHub is connected, the GitHub integration page includes a **Response Agents as Code** card. Use it to point Cotool at the folder that contains your agent YAML files: **1. Select a repository** Choose from repositories available to the GitHub App installation. **2. Select a branch** Pick the branch Cotool should poll. The picker defaults to the repository's default branch when possible, otherwise `main`. **3. Select a path** Choose the folder containing one-agent-per-file YAML definitions. The default path is `cotool/agents`. **4. Enable and save sync** Turn on **Enable sync** and click **Save config**. Cotool will include your organization in the periodic sync. **5. Run an immediate sync** Click **Sync now** to sync without waiting for the next scheduled poll. The card shows the latest sync status, the synced commit SHA, and a per-file table. Each row links to the YAML file at the synced commit and shows whether the file synced successfully, failed validation, failed to fetch, or skipped an integration-dependent trigger because the required integration is not connected. For the YAML format, identity behavior, trigger reconciliation, and rollback model, see [Response Agents as Code](/agents/response-agents-as-code). ## Disconnecting or Reconnecting If GitHub is disconnected, synced agents keep running with their last synced definition, but Cotool cannot fetch new YAML changes until the integration is reconnected. Reconnect GitHub when: * the GitHub App installation was removed, * repository access changed and Cotool cannot see a repo, * the Response Agents as Code card shows a reconnect prompt, * or agent GitHub tools fail because the installation is unavailable. Changing your own App's permissions or repository selection in GitHub does not require reconnecting; Cotool picks up the change on its next request or webhook. ## Related > [card] > > **Response Agents as Code** — manage response agents as YAML in GitHub > > [Open](/agents/response-agents-as-code) > [card] > > **Triggering Agents** — configure agent triggers in the UI or YAML > > [Open](/agents/triggering-agents) # Microsoft Graph Admin Integration Source: https://docs.cotool.ai/integrations/identity/microsoft-graph-admin Connect Cotool to Microsoft Graph with tenant-wide admin consent for Entra ID, Microsoft 365, and Intune investigations The Microsoft Graph Admin integration gives Cotool agents organization-wide visibility into Microsoft Entra ID, Microsoft 365 activity, and Microsoft Intune managed devices, plus two account containment actions: disabling a user and revoking their sign-in sessions. It is designed for security investigations, access reviews, user offboarding, and incident response workflows where an agent needs to answer questions like: * What groups, directory roles, and enterprise applications does this user have access to? * Which applications have delegated OAuth grants that can act as this user? * What sign-in, directory audit, or provisioning activity happened in the tenant? * Which users or groups match a specific investigation lead? * Which devices does this user have, and are they managed, encrypted, and compliant? * Who wiped this device or changed this Intune policy? ## Integration model Microsoft Graph does not use Google Workspace-style domain-wide delegation (DWD). The Microsoft equivalent for this integration is **tenant-wide admin consent** to a Microsoft Entra application, followed by **application-only Microsoft Graph access**. > [!NOTE] > > After an administrator grants consent, Cotool uses the OAuth 2.0 client > credentials flow to request Microsoft Graph tokens for the customer's > tenant. The admin integration does not require Cotool to handle an end-user > Microsoft password, and it does not depend on an individual user's mailbox > or session token. At a high level: 1. A Cotool admin starts setup from **Settings > Integrations** and selects **Microsoft Graph (Admin)**. 2. Cotool asks for the Microsoft tenant domain, such as `contoso.com` or `contoso.onmicrosoft.com`. 3. Cotool redirects the administrator to Microsoft's admin consent endpoint for that tenant: ```text theme={null} https://login.microsoftonline.com/{tenant}/adminconsent ``` 4. The Microsoft administrator reviews the permissions configured on Cotool's Entra application and grants tenant-wide consent. 5. Microsoft redirects back to Cotool with the consent result. 6. Cotool stores the tenant identifier for the organization and uses app-only Graph tokens scoped to that tenant when agents run Microsoft Graph Admin tools. ## OAuth and consent flow details Cotool uses two Microsoft identity platform flows: | Stage | Microsoft flow | Purpose | | - | - | - | | Initial setup | Tenant-wide admin consent | Grants the Cotool application permission to read approved Microsoft Graph resources for the tenant. | | Tool execution | OAuth 2.0 client credentials | Retrieves a short-lived app-only access token for Microsoft Graph. | During execution, the token request uses: ```text theme={null} grant_type=client_credentials scope=https://graph.microsoft.com/.default ``` The `.default` scope tells Microsoft to issue a token containing the application permissions that were already configured on the Cotool app registration and consented by the tenant administrator. Cotool does not dynamically request additional Microsoft Graph permissions at runtime. Because this is app-only access, Graph calls are not limited to the Microsoft account of the administrator who completed setup. They are limited by the Graph application permissions consented in the customer's tenant. ## Required Microsoft Graph permissions The admin integration uses Microsoft Graph **application permissions**. In Microsoft terminology, these are app roles granted to the Cotool enterprise application; they are not delegated user scopes. These permissions require Microsoft administrator consent. | Permission | Type | Used for | | - | - | - | | `AuditLog.Read.All` | Application | Read Entra directory audit logs, sign-in logs, and provisioning events from `/auditLogs/*` endpoints. | | `Directory.Read.All` | Application | Read users, groups, directory roles, direct and transitive memberships, app role assignments, and broad Entra ID directory metadata needed to explain access paths. | | `Application.Read.All` | Application | Read service principal and enterprise application metadata used to enrich app assignment and consent findings with application names, app IDs, roles, and scopes. | | `RoleManagement.Read.Directory` | Application | Read Entra role management data, including role definitions and active or eligible Privileged Identity Management (PIM) role schedules. | | `Policy.Read.ConditionalAccess` | Application | Populate applied conditional access policy outcomes on sign-in log records. Microsoft omits `appliedConditionalAccessPolicies` from sign-in responses for callers without conditional access read permission. | | `IdentityRiskEvent.Read.All` | Application | Read Identity Protection risk detections from `/identityProtection/riskDetections` for the risk detections log ingest stream. Requires an Entra ID P2 license. | | `DeviceManagementManagedDevices.Read.All` | Application | Read Intune managed devices (owner, compliance state, encryption, remote action history) and Windows Defender protection state from `/deviceManagement/managedDevices`. Requires an Intune license. | | `DeviceManagementApps.Read.All` | Application | Read the Intune audit log from `/deviceManagement/auditEvents`; Microsoft Graph accepts no other read-only permission for this endpoint. Requires an Intune license. | | `User.EnableDisableAccount.All` | Application | Disable a user account (`accountEnabled: false`) with `msft_graph_admin_disableUser`. | | `User.RevokeSessions.All` | Application | Revoke a user's refresh tokens and session cookies with `msft_graph_admin_revokeUserSessions`. | ### Office 365 Management APIs permissions The [Microsoft 365 unified audit log streams](#microsoft-365-unified-audit-log-ingest) read from the Office 365 Management Activity API, a separate resource on the same Cotool app registration. Its application permissions are granted in the same admin consent, and its tokens are requested with `scope=https://manage.office.com/.default`. | Permission | Type | Used for | | - | - | - | | `ActivityFeed.Read` | Application | Read the unified audit log content types `Audit.Exchange`, `Audit.SharePoint`, `Audit.General`, and `Audit.AzureActiveDirectory`. | | `ActivityFeed.ReadDlp` | Application | Read `DLP.All` for the Microsoft 365 DLP events stream. DLP records include the sensitive content that matched a policy. | > [!NOTE] > > Some Microsoft Graph endpoints list narrower least-privilege alternatives. > Cotool relies on the permissions above so agents can answer cross-tenant > access and audit questions consistently. The only write permissions are the > two account containment permissions, and each containment action asks a > Cotool user to confirm before it runs. > [!NOTE] > > Tenants that granted admin consent before a permission was added to the > Cotool app registration must re-run admin consent to grant the newer > permissions: use **Reauth** on the Microsoft Graph Admin integration, which > sends an administrator back through Microsoft's consent screen for the > connected tenant. Cotool reads the permissions Microsoft actually granted > from the application token: the Log Ingest card refuses to enable a stream > whose permission is missing and names the permission to grant, and an > already-enabled stream shows the same notice while its runs are skipped. A > stream the tenant is not licensed for (for example, risk detections without > Entra ID P2) is reported separately, since re-consenting does not resolve > it. Until consent is granted, sign-in log records also lack applied > conditional access policy details. Once consent is granted, ingestion > resumes and backfills automatically. ## What agents can read The read tools below do not create, update, or delete users, groups, roles, app assignments, grants, or logs. | Tool | What it does | | - | - | | `msft_graph_admin_getUser` | Resolves a user by object ID, user principal name, email address, or display name. | | `msft_graph_admin_listUsers` | Lists and searches organization users. | | `msft_graph_admin_listGroups` | Lists and searches organization groups. | | `msft_graph_admin_listUserGroupMemberships` | Reads direct and transitive Entra group memberships for a user. | | `msft_graph_admin_listUserDirectoryRoles` | Reads direct and group-inherited Entra directory roles for a user. | | `msft_graph_admin_listUserAppRoleAssignments` | Reads enterprise application assignments for a user and enriches them with service principal details. | | `msft_graph_admin_listUserOAuth2PermissionGrants` | Reads delegated OAuth2 grants associated with a user and enriches them with app/API scope metadata. | | `msft_graph_admin_listUserPimRoleSchedules` | Reads active and eligible PIM role schedules for a user. | | `msft_graph_admin_searchOrgAuditLogs` | Searches organization-wide directory audit, sign-in, and provisioning logs. | | `msft_graph_admin_listIntuneManagedDevices` | Lists Intune managed devices, filtered by user, device name, serial number, OS, compliance state, or Entra device ID. | | `msft_graph_admin_getIntuneManagedDevice` | Reads one Intune managed device, including its remote action history and, for Windows devices, its Defender protection state. | | `msft_graph_admin_searchIntuneAuditEvents` | Searches the Intune audit log for admin changes and remote device actions such as wipe and retire. | Intune tools need the two `DeviceManagement*` permissions. If a tenant connected before they were added, the tools return an error naming the missing permission until an administrator re-runs consent with **Reauth**. ## Account containment | Tool | What it does | | - | - | | `msft_graph_admin_disableUser` | Disables a user account (`PATCH /users/{id}` with `accountEnabled: false`), blocking new sign-ins. | | `msft_graph_admin_revokeUserSessions` | Revokes the user's refresh tokens and session cookies (`POST /users/{id}/revokeSignInSessions`), forcing re-authentication. | Both actions require a Cotool user to confirm before they run. Disabling an account does not end existing sessions, so containment usually uses both. Access tokens that were already issued stay valid until they expire (typically up to an hour) unless the app supports continuous access evaluation. Microsoft does not let an app disable a user who holds a privileged Entra admin role unless the app also holds a sufficiently privileged Entra role, such as Privileged Authentication Administrator. Without one, disabling an admin fails with a permission error and non-admin users are unaffected. Common questions agents can answer include: * "What groups and nested groups give this user access?" * "Which Entra roles does this user have directly or through a group?" * "Which enterprise applications can this user access?" * "Which apps have delegated consent to act as this user?" * "Show sign-ins, directory changes, or provisioning events for this user over the last 30 days." * "Is the device in this sign-in managed by Intune and compliant?" * "Who wiped or retired devices this week?" ## Microsoft Graph endpoints used | Capability | Microsoft Graph data used | | - | - | | Resolve and list users | `/users` and `/users/{id}` with selected identity fields. | | List groups | `/groups` with optional search, OData filters, and group-type filters. | | Enumerate group membership | `/users/{id}/memberOf/graph.group` and `/users/{id}/transitiveMemberOf/graph.group`. | | Enumerate directory roles | `/users/{id}/memberOf/graph.directoryRole` and `/users/{id}/transitiveMemberOf/graph.directoryRole`. | | Review enterprise app assignments | `/users/{id}/appRoleAssignments`, enriched with `/servicePrincipals/{id}` metadata. | | Review delegated OAuth grants | `/users/{id}/oauth2PermissionGrants`, enriched with service principal and OAuth permission scope metadata. | | Review PIM access | `/roleManagement/directory/roleAssignmentScheduleInstances`, `/roleManagement/directory/roleEligibilityScheduleInstances`, and role definition details. | | Search tenant activity | `/auditLogs/directoryAudits`, `/auditLogs/signIns`, and `/auditLogs/provisioning`. | | Inspect Intune devices | `/deviceManagement/managedDevices`, `/deviceManagement/managedDevices/{id}`, and `/deviceManagement/managedDevices/{id}/windowsProtectionState`. The activation lock bypass code is never returned to agents. | | Search Intune activity | `/deviceManagement/auditEvents`. | ## Microsoft 365 unified audit log ingest With Cotool Logs, the Microsoft Graph Admin integration can also continuously ingest the Microsoft 365 unified audit log into the `microsoft_365_audit` table. Enable the streams on the integration's **Log Ingest** card: | Stream | Content types | Covers | | - | - | - | | Microsoft 365 audit log | `Audit.Exchange`, `Audit.SharePoint`, `Audit.General` | Exchange Online mailbox and admin activity, SharePoint Online, OneDrive, Microsoft Teams, and other workloads. | | Microsoft 365 audit log: Entra ID events | `Audit.AzureActiveDirectory` | Entra ID logons and directory changes as recorded in the unified audit log. | | Microsoft 365 DLP events | `DLP.All` | Microsoft Purview DLP policy matches. Requires `ActivityFeed.ReadDlp`. | Requirements and behavior: * Auditing must be turned on in the tenant (it is on by default) and the tenant needs a Microsoft 365 or Office 365 subscription that includes Audit (Standard). Tenants without one are reported as not licensed. * Tenants that consented before the Office 365 Management APIs permissions were added must use **Reauth** to grant them. Until then the Log Ingest card names the missing permission. * Cotool starts the tenant's Management Activity API subscriptions on the first run. Microsoft only publishes audit content from the moment a subscription starts, and the first content can take up to 12 hours to appear. Events from before that point are not available. * Cotool checks for new content every five minutes. Microsoft does not guarantee how quickly records become available after the activity; typical delays range from minutes to several hours. * Microsoft keeps content available for seven days. If ingestion is interrupted for longer than that, the older content cannot be recovered. * Microsoft can deliver the same record more than once. Rows are keyed by the record ID, so query with `FINAL` to collapse duplicates. * Only commercial Microsoft 365 tenants are supported. GCC, GCC High, and DoD tenants are not. > [!NOTE] > > The Azure Event Hub integration's `EnrichedOffice365AuditLogs` category > covers only SharePoint Online traffic forwarded through Global Secure > Access, so it does not replace these streams. Microsoft 365 does not offer a > native export of the unified audit log to Event Hubs. ## Data access and storage Cotool stores the connected tenant identifier and integration credential metadata for the customer's organization. For the admin integration, Cotool does **not** store an end-user Microsoft access token or refresh token. Graph data is fetched when agents call the integration tools and is used to produce the agent response, reports, and normal Cotool audit/history records for the workspace. Log streams you enable on the Log Ingest card, including the Microsoft 365 unified audit log, are stored in your Cotool Logs warehouse under its retention settings. ## Security and revocation Administrators can revoke access from Microsoft Entra ID by removing tenant-wide admin consent or deleting the Cotool enterprise application/service principal from the tenant. After revocation, Microsoft stops issuing app-only Graph tokens for Cotool, and Microsoft Graph Admin tools in Cotool will fail authentication. The integration can also be disconnected from Cotool. Recommended controls for customers: * Review the requested Microsoft Graph application permissions during admin consent. * Limit who in Cotool can configure integrations and run agents with sensitive tools. * Monitor Cotool agent activity and workspace audit logs for investigations that use Microsoft Graph Admin data. * Periodically review enterprise applications and admin consent grants in Microsoft Entra ID. ## Operational notes * Sign-in log availability depends on the customer's Microsoft Entra licensing and log retention settings. * Microsoft Graph can return partial results or endpoint-specific errors if a tenant policy, license, or permission prevents access to a specific log or object type. * The admin integration is separate from Cotool's user-delegated Microsoft Graph integration, which is used for user-scoped Teams, OneDrive, mail, and delegated workflows. ## Common prospect questions ### Is this Google Workspace DWD? No. Google Workspace uses domain-wide delegation for service accounts. Microsoft uses tenant-wide admin consent to an Entra application plus application permissions. The security outcome is similar: after administrator approval, Cotool can query tenant-wide data for approved permissions without requiring each end user to sign in. ### Does Cotool need a Global Administrator account password? No. The Microsoft administrator authenticates directly with Microsoft during the consent flow. Cotool receives the consent result and later uses app-only Microsoft Graph tokens issued by Microsoft. ### Are the tools read-only? All but two. The read tools resolve identities, list users and groups, enumerate access paths, inspect role and app assignments, inspect delegated grants, inspect PIM schedules, read Intune devices, and search Entra and Intune audit logs. The two [account containment](#account-containment) tools disable a user and revoke their sessions, and each needs a Cotool user's confirmation. Cotool cannot create or delete users or change groups, roles, or app assignments. The Intune permissions are read-only, so Cotool cannot wipe, retire, or reconfigure devices. ### Why are broad directory permissions required? Access investigations need to correlate users, groups, directory roles, service principals, app role assignments, delegated grants, and audit logs. Microsoft Graph splits those records across directory, application, role management, and audit-log APIs, so several application permissions are required to build a complete answer. # Okta Integration Source: https://docs.cotool.ai/integrations/identity/okta Connect Cotool to Okta for identity and access management Cotool supports Okta SSO and lifecycle provisioning through standard **SAML 2.0** and **SCIM 2.0** configuration. Use the full [SAML and SCIM IdP setup guide](/integrations/identity/saml-scim) for endpoint formats, supported SCIM operations, assertion requirements, and troubleshooting. ## Okta SAML setup Create a SAML 2.0 app in Okta and use the organization-specific values from [Cotool Authentication Settings](https://app.cotool.ai/settings/saml). | Okta field | Cotool value | | - | - | | Single sign-on URL | Cotool ACS URL | | Recipient URL | Cotool ACS URL | | Destination URL | Cotool ACS URL | | Audience URI (SP Entity ID) | Cotool Entity ID | | Name ID format | `EmailAddress` | | Application username | Email | After creating the app, copy Okta's IdP metadata XML or metadata URL into Cotool. ## Okta SCIM setup Enable provisioning for the Okta app and use: | Okta field | Cotool value | | - | - | | SCIM connector base URL | Cotool SCIM base URL | | Unique identifier field for users | `userName` | | Supported provisioning actions | Create users, update user attributes, deactivate users | | Authentication mode | HTTP Header / Bearer token | | Bearer token | Token generated in Cotool | Use Okta's **Test Connector Configuration** action after saving the SCIM base URL and bearer token. # SAML and SCIM IdP setup Source: https://docs.cotool.ai/integrations/identity/saml-scim Public endpoint reference for configuring Cotool in identity providers such as Okta Use this page when configuring Cotool as a first-class application in an identity provider (IdP), such as Okta, Microsoft Entra ID, Google Workspace, OneLogin, or Ping Identity. Cotool uses **SAML 2.0** for single sign-on and **SCIM 2.0** for user provisioning. A Cotool admin can find the organization-specific values and generate SCIM tokens from [Authentication Settings](https://app.cotool.ai/settings/saml). > [!NOTE] > > All examples use Cotool Cloud at `https://app.cotool.ai`. ## SAML SSO Cotool is the SAML service provider (SP). Your IdP is the identity provider. | Field | Value | | - | - | | SAML version | `2.0` | | ACS URL / Single sign-on URL | `https://app.cotool.ai/api/auth/saml/{orgId}/callback` | | SP Entity ID / Audience URI | The Entity ID shown in Cotool. By default, this is the ACS URL. | | Recipient / Destination | Same as the ACS URL. | | Default RelayState | Leave blank unless you are sending users to a specific Cotool path. | | SSO initiation | SP-initiated SSO is supported. IdP-initiated SSO can post assertions to the ACS URL. | | SAML response binding | HTTP POST to the ACS URL. | | Single logout | Not currently supported. | Cotool-initiated SSO signs the browser in after the identity provider returns a response tied to that browser's sign-in request. IdP-initiated SSO shows the account email and organization for confirmation before signing the browser in. The confirmation expires after five minutes. ### Login URLs Use either of these SP-initiated login URLs: | Purpose | URL | | - | - | | Email discovery login | `https://app.cotool.ai/api/auth/saml/login?email=user@example.com` | | Organization-scoped login | `https://app.cotool.ai/api/auth/saml/{orgId}/login` | The email discovery URL resolves the Cotool organization from the configured SAML email domain, then starts the SAML flow. ### Required SAML assertion fields Cotool identifies users by email address. Configure the IdP to send the user's work email as one of: * `NameID` * `email` * `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress` Recommended IdP settings: | Setting | Recommended value | | - | - | | Name ID format | `EmailAddress` | | Application username | Email address | | Assertion signing | Enabled | | Response signing | Enabled if required by your IdP policy | | Encryption | Not required | Cotool validates SAML assertions with the IdP signing certificate from the metadata XML configured in Cotool. ### Cotool admin setup 1. Open [Authentication Settings](https://app.cotool.ai/settings/saml). 2. Enable **SAML Single Sign-On**. 3. Enter the email domain used for login discovery, such as `example.com`. 4. Copy the Cotool **ACS URL** and **Entity ID** into your IdP application. 5. Paste your IdP metadata XML into Cotool, or fetch it from your IdP metadata URL. 6. Save the settings and test SP-initiated login. ## SCIM provisioning Cotool implements SCIM 2.0 user provisioning with bearer-token authentication. | Field | Value | | - | - | | SCIM version | `2.0` | | SCIM base URL | `https://app.cotool.ai/api/scim/v2/{orgId}` | | Users endpoint | `https://app.cotool.ai/api/scim/v2/{orgId}/Users` | | Authentication | `Authorization: Bearer {scimToken}` | | Groups | Not currently supported | | Password sync | Not supported | | Bulk operations | Not supported | Generate or rotate the SCIM bearer token in [Authentication Settings](https://app.cotool.ai/settings/saml). Cotool shows the token only once, so copy it into the IdP when it is generated. ### Supported SCIM endpoints | Method | Endpoint | Purpose | | - | - | - | | `GET` | `/ServiceProviderConfig` | Return SCIM capability metadata. | | `GET` | `/Users` | List users with pagination and optional filters. | | `POST` | `/Users` | Create a user, or update an existing user matched by email or `externalId`. | | `GET` | `/Users/{userId}` | Fetch a user by Cotool user ID. | | `PUT` | `/Users/{userId}` | Replace supported user fields. | | `PATCH` | `/Users/{userId}` | Update supported user fields. | | `DELETE` | `/Users/{userId}` | Deactivate the user by setting `active` to `false`. | ### Supported user attributes Cotool accepts and returns these SCIM user fields: | Attribute | Notes | | - | - | | `schemas` | Optional on input. Responses include the SCIM core User schema. | | `id` | Cotool user ID. Returned by Cotool. | | `externalId` | Stored and used for matching provisioned users. | | `userName` | Required unless `emails[0].value` is present. Must be a valid email address. | | `name.givenName` | Optional. | | `name.familyName` | Optional. | | `name.formatted` | Optional. | | `emails[].value` | Optional when `userName` is present. The primary or first email is used. | | `active` | `false` deactivates the user. | New SCIM-created users receive the default role selected in Cotool's SCIM settings. ### Filtering and pagination `GET /Users` supports: | Query parameter | Support | | - | - | | `filter` | `userName eq "user@example.com"`, `emails.value eq "user@example.com"`, or `externalId eq "abc123"` | | `startIndex` | 1-based index. Defaults to `1`. | | `count` | Defaults to `100`. Maximum `200`. | Sorting is not currently supported. ### PATCH support Cotool supports SCIM `add` and `replace` operations for these paths: * `active` * `userName` * `externalId` * `name` * `emails` `remove` operations are not currently supported. ## Okta configuration notes ### SAML application In Okta, create a SAML 2.0 application and use: | Okta field | Cotool value | | - | - | | Single sign-on URL | Cotool ACS URL | | Recipient URL | Cotool ACS URL | | Destination URL | Cotool ACS URL | | Audience URI (SP Entity ID) | Cotool Entity ID | | Name ID format | `EmailAddress` | | Application username | Email | After creating the app, copy Okta's IdP metadata XML or metadata URL into Cotool. ### SCIM provisioning Enable SCIM provisioning for the Okta application and use: | Okta field | Cotool value | | - | - | | SCIM connector base URL | Cotool SCIM base URL | | Unique identifier field for users | `userName` | | Supported provisioning actions | Create users, update user attributes, deactivate users | | Authentication mode | HTTP Header / Bearer token | | Bearer token | Token generated in Cotool | Use Okta's **Test Connector Configuration** action after saving the SCIM base URL and bearer token. ## Troubleshooting | Symptom | Check | | - | - | | SAML login cannot find the organization | Confirm the user's email domain matches the domain configured in Cotool. | | SAML assertion is rejected | Confirm the IdP metadata XML in Cotool contains the active signing certificate and SSO URL. | | User signs in but lands on an error page | Confirm the assertion includes the user's email as `NameID` or a supported email attribute. | | SCIM returns `401` | Rotate the SCIM token in Cotool and update the IdP. | | SCIM returns `403` | Confirm SCIM is enabled in Cotool for the organization. | | SCIM returns `409` | Confirm the email address or `externalId` is not already assigned to another user. | # Integrations Overview Source: https://docs.cotool.ai/integrations/overview Connect Cotool to 40+ security and productivity tools Cotool integrates with your existing security and productivity stack. Agents use these integrations to fetch data, take actions, and coordinate workflows across your tools. All integrations are available at [app.cotool.ai/tools](https://app.cotool.ai/tools) and integrate via **API**, **OAuth**, or **custom MCP**. ## Integration Categories > [card] Ticketing > > Jira, Linear, and issue tracking systems > [card] Communication > > Slack, Teams, and messaging platforms > [card] Identity & Access > > Okta, Azure AD, Google Workspace, and IAM > [card] EDR & Endpoint Security > > SentinelOne, CrowdStrike, Microsoft Defender > [card] SIEM & Log Analytics > > Splunk, Elastic, and log management > [card] Cloud Security > > Wiz, Orca, Lacework, and CSPM tools > [card] Email Security > > Abnormal, Proofpoint, Mimecast > [card] Threat Intelligence > > VirusTotal, URLScan, AbuseIPDB, and threat feeds > [card] Developer Tools > > GitHub, GitLab, and version control > [card] Vulnerability Management > > Tenable, Qualys, and vulnerability scanners ## Popular Integration Workflows > [accordion] Alert Triage with Multiple Tools > > Combine **SentinelOne**, **Splunk**, and **Jira** to automatically > enrich alerts, query logs, and update tickets > [accordion] Phishing Response > > Use **Email Security**, **VirusTotal**, and **Slack** to analyze > phishing emails, check indicators, and notify teams > [accordion] Access Reviews > > Connect **Okta**, **AWS**, and **Google Workspace** to audit permissions > and generate reports > [accordion] Incident Response > > Coordinate across **PagerDuty**, **Jira**, **Slack**, and **EDR** tools > for rapid response # Zscaler Integration Source: https://docs.cotool.ai/integrations/security-tools/network/zscaler Connect Cotool to Zscaler for ZIA, ZPA, ZDX, and Client Connector access, detection-rule sync, and alert-driven response agents ## Overview The Zscaler integration gives Cotool agents access to ZIA (Internet Access), ZPA (Private Access), ZDX (Digital Experience), and Zscaler Client Connector through Zscaler's OneAPI, and lets Zscaler push alert events into Cotool to trigger response agents. It provides three capabilities: 1. **Agent tools** — URL classification and Sandbox verdicts, threat blocklist management, ZIA/ZPA policy inspection, config activation, user directory, admin audit logs, ZDX alerts and device health, and Client Connector device management. 2. **Detection-rule sync** — ZIA policy rules, ZIA Security & UEBA alert rules, and ZPA AppProtection profiles are synced weekly into Cotool's detection-rule repository, where they appear on the Detections overview and threat-model coverage board. 3. **Alert ingestion** — a branded Zscaler trigger source receives alert events pushed from Zscaler (Cloud NSS feeds or alert-rule webhooks) and can start a response agent, creating a Cotool alert for each event. ## Connecting the integration The integration uses a **Zidentity OneAPI client** (client-credentials OAuth). Tenants that have not migrated to Zidentity are not supported. 1. In the **ZIdentity Admin Portal**, go to **Integration > API Clients** and create an API client. 2. Assign it roles covering the products you use: * **ZIA**: URL lookup, security policy, policy activation, user management (read), and audit reports. * **ZPA / ZDX / ZCC**: the corresponding read (and for ZCC device removal, write) roles. 3. In Cotool, open **Tools > Zscaler > Connect** and enter: * **Client ID** and **Client Secret** from the API client. * **Vanity domain** — the `acme` in `acme.zslogin.net`. * **Cloud** — production (default) or beta. * **ZPA customer ID** — optional; required only for ZPA tools (find it in the ZPA Admin Portal under Company Details). Cotool validates the credentials against Zscaler before saving them. ## Alert ingestion (response agent trigger) Zscaler delivers alert events by push only. Create a **Zscaler trigger** on a response agent (Agent > Triggers > Add Trigger > Zscaler); Cotool generates a webhook URL and a token. Then point one or both Zscaler channels at it: ### Option 1: Cloud NSS alert feed (recommended) 1. In ZIA, go to **Administration > Nanolog Streaming Service > Cloud NSS Feeds** and add a feed. 2. Set **SIEM Type** to `Other`, the log type to **Alert** (optionally add the UEBA alert feeds), and the output format to JSON. 3. Set the **API URL** to the trigger's webhook URL. 4. Add an HTTP header `X-Cotool-Webhook-Token` with the trigger's token. 5. Activate the change. Cloud NSS is a separately licensed Zscaler feature. Feeds can also be created programmatically via `POST /zia/api/v1/nssFeeds`. ### Option 2: ZIA alert-rule webhooks 1. In ZIA, go to **Administration > Alerts** and add a webhook destination pointing at the trigger's webhook URL, using bearer authentication with the trigger's token. 2. Attach the webhook to the Security Alert / UEBA rules you want to route to Cotool. ### Notes * Keep **Create Alert** enabled on the trigger so each event mints a Cotool alert and starts the response agent. Incoming alerts are automatically linked to synced Zscaler detection rules by name. * **ZDX alerts have no webhook** — they are pull-only and covered by the `zscaler_zdx_get_alerts` agent tool. * **ZPA has no alert channel**; its session logs stream only to a self-hosted LSS collector. ## Detection-rule sync Once connected, the weekly classification job ingests: * **ZIA policy rules** — URL filtering, firewall filtering, DNS control, IPS control, Sandbox, web DLP, and SSL inspection rules. * **ZIA alerting rules** — alert definitions, Security Alert rules, and UEBA rules (these are what fire into the webhook trigger). * **ZPA AppProtection** — inspection profiles and custom controls (requires the ZPA customer ID). Rule inventories the tenant is not licensed for are skipped automatically. ## Local development Populate `cogent-backend/.env` with `ZSCALER_CLIENT_ID`, `ZSCALER_CLIENT_SECRET`, `ZSCALER_VANITY_DOMAIN` (optionally `ZSCALER_CLOUD`, `ZSCALER_ZPA_CUSTOMER_ID`) and run `npm run bootstrap-tools ` from the repo root. # AWS S3/SQS Log Ingestion Source: https://docs.cotool.ai/integrations/security-tools/siem/aws-s3-sqs Ingest CloudTrail, GuardDuty, Security Hub, VPC flow, load balancer, CloudFront, WAF, S3 access, Route 53 Resolver, and other JSON logs from S3 through a dedicated SQS queue The AWS S3/SQS integration reads log files your AWS services already write to S3. Each new object is announced on an SQS queue dedicated to Cotool; Cotool assumes a role in your account, receives the notification, reads the object, and indexes its events into Cotool Logs. ```mermaid theme={null} flowchart LR Producer["CloudTrail, GuardDuty, or another AWS service"] --> S3["S3 bucket"] S3 -- "ObjectCreated notification" --> SQS["Dedicated SQS queue"] SQS --> Cotool["Cotool (assumes your role)"] Cotool -- "s3:GetObject" --> S3 ``` You can connect several named sources, for example one per environment or AWS organization, and pause, edit, or remove each independently. ## Log types Each source carries one log type. Give each AWS service its own source and prefix: the setup suggests one per service. | Log type | Cotool Logs table | What Cotool does | | - | - | - | | AWS CloudTrail | `aws_cloudtrail` | Unwraps CloudTrail's `Records` envelope and maps actor, action, service, resource, source IP, outcome, account, and region into columns shared with `gcp_cloud_audit`. Digest files are skipped. Events are keyed by `eventID`. | | Amazon GuardDuty findings | `aws_guardduty_findings` | Reads exported findings (and findings wrapped in EventBridge events) into finding type, severity, resource, actor, access key, API, remote IP, and timestamps. Each update of a finding is kept as its own version. | | AWS Security Hub findings | `aws_security_hub_findings` | Reads ASFF findings from `Security Hub Findings - Imported` events into title, severity, product, compliance and workflow status, resource, and remote IP. Each update of a finding is kept as its own version. | | Amazon VPC flow logs | `aws_vpc_flow_logs` | Parses text flow logs in the default or any custom field order, one row per flow. `NODATA` and `SKIPDATA` records are dropped. | | Application Load Balancer access logs | `aws_alb_access_logs` | Parses each request: client, target, status codes, timings, bytes, request line, user agent, TLS, and the matched rule and actions. | | Amazon CloudFront access logs | `aws_cloudfront_logs` | Parses standard logs as text (with their `#Fields` header) or JSON: client, edge location and result, method, host, URI, status, bytes, and timings. Requests are keyed by their edge request ID. | | AWS WAF logs | `aws_waf_logs` | Reads each inspected request with its web ACL, the rule and action that decided it, client IP and country, and the HTTP request. | | Amazon S3 server access logs | `aws_s3_access_logs` | Parses each request: bucket, requester, operation, key, status, error code, bytes, and authentication. Requests are keyed by their request ID and object key. | | Route 53 Resolver query logs | `aws_route53_resolver_logs` | Reads each DNS query from your VPCs with its source, name, type, response code, answers, and any firewall rule action. | | Generic JSON | `aws_generic_logs` | Stores each JSON record with its original payload, top-level fields as a searchable `fields` map, and the object it came from. Records are not normalized and no detection coverage is implied. | Supported formats are JSON, JSON arrays, newline-delimited JSON, the text formats AWS writes for flow, load balancer, CloudFront, and S3 access logs, and gzip-compressed versions of each. Objects in other formats (Parquet, ZIP, and so on) are reported with an actionable error on the source instead of being ingested. Flow logs must be delivered as plain text. If the access test reads objects that look like another built-in log type, for example flow logs on a source set to Generic JSON, it offers to switch. ## Step 1: Create the queue and role On the integration page, select **Add log source** and choose what to ingest: CloudTrail, one of the AWS services in the table above, or other JSON logs. Then enter each bucket and prefix, and any customer-managed KMS keys that encrypt the objects. Choosing a service suggests a prefix for it, like `guardduty/`. The setup section fills them, the **Cotool principal**, and your **External ID** into a Terraform configuration, an AWS CLI script, and a CloudFormation template. Each creates: * a dedicated SQS queue (`cotool-log-ingest-`) with a dead-letter queue, and a queue policy that accepts notifications from your log buckets, * an IAM role (`CotoolLogIngest-`) that trusts the Cotool principal only with your external ID, and can: * `sqs:ReceiveMessage`, `sqs:DeleteMessage`, `sqs:ChangeMessageVisibility`, and `sqs:GetQueueAttributes` on that queue, * `s3:GetObject` and `s3:GetObjectVersion` on each bucket prefix, * `kms:Decrypt` on the log keys, when objects are encrypted with customer-managed KMS keys. `` is a short random value generated for each setup, so several sources can live in the same account. Cotool only assumes roles whose name starts with `CotoolLogIngest`; keep that prefix if you rename the role. > [!WARNING] > > Use a queue dedicated to Cotool. Cotool deletes messages once their objects > are ingested, so sharing a queue with another SIEM would take messages away > from it. If another tool already consumes the bucket's notifications, have > the bucket notify an SNS topic and subscribe both queues to it by adapting > the generated configuration to use SNS. ## Step 2: Deploy it Deploy in the buckets' account and region: S3 only notifies queues in its own region. S3 keeps a single notification configuration per bucket, so the generated notification script adds `s3:ObjectCreated:*` notifications for each prefix only to buckets that have none, and prints what to add to the others. > [tab] Terraform > > 1. Save the configuration in your infrastructure repository, and configure the AWS provider for the buckets' account and region. > 2. Run `terraform init`, review `terraform plan`, then run `terraform apply`. > 3. Run the generated `cotool-bucket-notifications.sh`, which reads the queue from `terraform output`. The configuration only manages the notifications itself when you set `manage_bucket_notifications = true`, because `aws_s3_bucket_notification` replaces a bucket's entire notification configuration. If Terraform already manages a bucket's notifications, add the queue to that resource instead. > 4. `terraform output` prints `queue_url` and `role_arn` for the connection form. > [tab] AWS CLI > > 1. Save the script. It needs AWS CLI v2, signed in to the buckets' account with permission to create SQS queues and IAM roles and to change the buckets' notifications. > 2. Run `AWS_REGION= bash cotool-log-ingest.sh`. > 3. It prints `queue_url` and `role_arn` for the connection form. If a bucket already has notifications, the script leaves them in place and prints the queue ARN to add to them. > [tab] CloudFormation > > 1. Save the template, and deploy it in the buckets' region with the generated `aws cloudformation deploy` command (stack `cotool-log-ingest-`), or upload it under **Create stack** in the CloudFormation console. > 2. A stack can't change a bucket it didn't create, so add the notifications once the stack is up: run the generated `cotool-bucket-notifications.sh`, or in the S3 console open each bucket's **Properties > Event notifications** and send all object create events for the prefix to the `cotool-log-ingest-` queue. > 3. The stack's `QueueUrl` and `RoleArn` outputs go into the connection form. To create the resources in the console instead, expand **Setting it up in the console?** for the principal and external ID the role must trust. ## Step 3: Connect the source 1. **Connect**: enter the queue URL (the region fills in from it), the role ARN, and each bucket and prefix Cotool may read. Objects outside these prefixes are skipped even if they reach the queue. 2. **Test**: Cotool assumes the role, reads the queue attributes, samples up to ten messages, and reads one announced object. Sampled messages are returned to the queue, not deleted. If the queue is empty, paste a sample log. 3. **Format**: name the source and confirm the format: the service you chose, **Generic JSON**, or **Custom format, normalized to OCSF**. Cotool previews the sampled events parsed with that format. 4. Select **Enable source**, or **Save paused** to enable it later. Enabling needs a passing test. ## Step 4: Point the service at the bucket For a built-in service, the last connection step gives the commands that turn on its delivery to your bucket and prefix, filled in from the bucket, the queue's region and account, and the KMS key. The source's **Setup guide** shows them again later. AWS constrains where some services can write: | Service | Delivery | | - | - | | CloudTrail | A multi-region trail. Skip this if a trail, such as an organization trail, already writes to the bucket. | | GuardDuty | A publishing destination per region with a detector, publishing every 15 minutes. GuardDuty only exports findings encrypted with a symmetric KMS key in the bucket's region, so the source requires the key ARN. | | Security Hub | Security Hub has no S3 export. The generated script creates an EventBridge rule for imported findings and a Firehose stream that writes them to the bucket. Run it in Security Hub's aggregation region. It reads Security Hub CSPM findings in ASFF, not the OCSF findings of `Findings Imported V2` events. | | VPC flow logs | Flow logs per VPC, as plain text. The command uses a custom format with every field Cotool reads; the default format works too. | | Application Load Balancer | Access logs per load balancer. The bucket must be in the load balancer's region and use S3-managed encryption (SSE-S3). | | CloudFront | Standard logs per distribution, delivered as JSON and configured in `us-east-1`. Legacy standard logs are read too. | | WAF | Logging per web ACL. WAF only writes to buckets whose names start with `aws-waf-logs-`; the setup warns when the bucket doesn't. | | S3 server access logs | Server access logging on each bucket to watch. The log bucket must be in the same region and account and use SSE-S3. | | Route 53 Resolver | A query logging configuration, associated with each VPC. | ## Reliability * Messages are deleted only after the object's events are archived and indexed. If Cotool restarts mid-run, the message becomes visible again and is reprocessed. * A temporary failure (throttling, a network error, or access denied while permissions are being fixed) keeps the message on the queue and retries it with backoff up to 15 minutes, for about a day with the template's dead-letter settings. * Malformed lines are skipped individually and kept in the raw archive with the reason. Objects that can never be read (unsupported format, deleted, too large) are recorded on the source and their messages removed so they cannot block the queue. * Redelivered notifications do not create duplicates: CloudTrail events are keyed by `eventID`, GuardDuty and Security Hub findings by finding ID and update time, CloudFront and S3 access log requests by request ID, WAF records by their content, and other records by object version and position. ## Status Each source shows its health, last successful ingestion, events and bytes read in the last 24 hours, the age of the oldest message received, the approximate queue depth, and recent errors with the object they concern. # Azure Blob Storage Log Ingestion Source: https://docs.cotool.ai/integrations/security-tools/siem/azure-blob-storage Ingest Azure Network Watcher VNet flow logs from Blob Storage as Event Grid announces them The Azure Blob Storage integration reads the flow logs Network Watcher writes to your storage accounts. Event Grid sends each new block of a log blob to a Storage queue dedicated to Cotool; Cotool drains the queue every minute, reads only the bytes it has not read yet, and indexes the flow tuples into Cotool Logs. ```mermaid theme={null} flowchart LR Watcher["Network Watcher flow logs"] --> Blobs["Storage container"] Blobs --> Grid["Event Grid BlobCreated"] Grid --> Queue["Dedicated Storage queue"] Queue --> Cotool["Cotool (federated managed identity)"] Blobs --> Cotool ``` You can connect several named sources, for example one per subscription or region, and pause, edit, or remove each independently. ## Log types | Log type | Cotool Logs table | What Cotool does | | - | - | - | | Azure VNet flow logs | `azure_flow_logs` | Reads virtual network flow logs (and legacy NSG flow logs) into one row per flow tuple: source and destination IP and port, protocol, direction, flow state, encryption, packet and byte counters, the matched NSG and rule, the covered resource, and IP geolocation and threat-feed labels for the remote peer (the source of an inbound flow, the destination of an outbound one). | By default Cotool indexes denied flows, and flow begin and end tuples that involve a public IP address. Continuation tuples and allowed traffic between private addresses are kept in the raw archive only, so byte totals in `azure_flow_logs` cover the indexed flows. The Azure detections in the detection library read `azure_flow_logs`: internet access to management and database ports, scans followed by an allowed connection, internal and outbound denied bursts, traffic with threat-listed addresses, outbound connections to restricted countries, and DNS sent to unapproved resolvers. They are written to work with this default filter. ## Authentication Cotool signs in as a **user-assigned managed identity** in your tenant through a federated identity credential, so no client secret or storage key is created or stored. Cotool's runtime identity presents a Google-signed token (issuer `https://accounts.google.com`) whose audience is unique to your Cotool organization; the federated credential accepts only Cotool's subject and that audience, so no other Cotool customer can use your identity. The identity holds two roles, each scoped as narrowly as Azure allows: * **Storage Queue Data Message Processor** on the Cotool queue, to read and delete its messages. * **Storage Blob Data Reader** on each log container, to read the flow log blobs. ## Step 1: Create the queue, Event Grid subscription, and identity On the integration page, select **Add log source** and enter the storage account and container that hold the flow logs. Network Watcher writes VNet flow logs to the `insights-logs-flowlogflowevent` container and legacy NSG flow logs to `insights-logs-networksecuritygroupflowevent`. Add a prefix to limit Cotool to part of a container. VNet flow logs are stored under `flowLogResourceID=/_/_/`, so `flowLogResourceID=/_` limits a source to one subscription. NSG flow logs are stored under `resourceId=/SUBSCRIPTIONS//`. Azure writes these folder names in upper case; copy the prefix from the container in the Azure portal. The setup section fills the containers and Cotool's **Subject** and your **Audience** into a Terraform configuration and an Azure CLI script. Each creates: * a Storage queue dedicated to Cotool (`cotool-logs-`) in the first log storage account, * an Event Grid system topic for each log storage account, or reuses the one it already has (a storage account can have only one), * an event subscription for each container and prefix that sends `Microsoft.Storage.BlobCreated` events to the queue, with the queue's 7-day maximum message lifetime, * a user-assigned managed identity (`cotool-logs-`) with a federated credential that trusts only Cotool's subject and your audience, * the two role assignments above, * **Storage Queue Data Message Sender** on the queue for each system topic's system-assigned managed identity, which Event Grid delivers as, so delivery works from every log storage account and with shared-key access disabled. `` is a short random value generated for each setup, so several sources can live in the same subscription. > [!WARNING] > > Use a queue dedicated to Cotool. Cotool deletes messages once their blobs > are ingested, so sharing the queue with another tool would take messages > away from it. Deploy it signed in as someone who can create managed identities, role assignments, Storage queues, and Event Grid subscriptions in the subscription: > [tab] Terraform > > 1. Save the configuration in your infrastructure repository, and sign in with `az login`. > 2. Run `terraform init`, review `terraform plan`, then run `terraform apply`. It asks for the subscription that holds the storage accounts and a resource group for the managed identity. If a storage account already has an Event Grid system topic, name it in `existing_system_topics` and enable its system-assigned managed identity. > 3. `terraform output` prints `queue_url`, `tenant_id`, and `client_id` for the connection form. > [tab] Azure CLI > > 1. Save the script, sign in with `az login`, and select the subscription with `az account set --subscription `. > 2. Run `RESOURCE_GROUP= bash cotool-log-ingest.sh`. It reuses a storage account's existing Event Grid system topic, enabling its system-assigned managed identity if it has none. > 3. It prints `queue_url`, `tenant_id`, and `client_id` for the connection form. To create the resources in the portal instead, expand **Setting it up in the console?** for the issuer, subject, and audience the federated credential must trust. > [!NOTE] > > The storage accounts must allow access from public networks. Cotool cannot > reach storage accounts that only accept private endpoints. ## Step 2: Connect the source 1. **Connect**: enter the storage accounts, containers, and prefixes. Deploy the setup, then paste the queue URL, tenant ID, and client ID. 2. **Test**: Cotool signs in as the managed identity, checks that it can read the queue, and peeks at up to ten messages without removing them. It reads the start of the first blob they announce to check blob access. If the queue is empty, paste a sample flow log record. 3. **Format**: name the source. Cotool previews the sampled flow tuples. 4. Select **Enable source**, or **Save paused** to enable it later. Enabling needs a passing test. ## Reliability * Network Watcher appends a block to each hourly `PT1H.json` blob about once a minute, and Event Grid announces every block. Cotool stores how far it has read each blob, so each run reads only the new bytes, and several announcements of the same blob in a run become one read. * Messages are deleted only after their bytes are archived and indexed. If Cotool restarts mid-run, or a run ends before reaching every message it received, the messages become visible again when the run's time budget ends and are read again. * Rereading a blob does not create duplicates: flow tuples are keyed by their blob and byte position. * A blob that is deleted, or a message for a blob outside the allowed containers, is skipped and reported in the source's recent errors. * Permission errors leave the messages on the queue, so they are read once access is fixed, until the queue's 7-day message lifetime expires. ## Status Each source shows its health, last successful ingestion, events and bytes read in the last 24 hours, the age of the oldest message received, the number of queued messages, and recent errors. # Azure Event Hub Integration Source: https://docs.cotool.ai/integrations/security-tools/siem/azure-event-hub Stream Azure Activity Logs, resource diagnostic logs, Entra ID diagnostic logs, Defender for Cloud alerts, and Microsoft Intune logs into Cotool Logs The Azure Event Hub integration continuously ingests Azure platform logs into Cotool Logs. Azure Event Hubs is Microsoft's designated export path for third-party security tooling: you point Azure diagnostic settings (and Defender for Cloud Continuous Export) at an event hub in your tenant, and Cotool consumes the hub and indexes the events into queryable, tenant-isolated warehouse tables. ## What gets ingested The integration exposes five independently toggleable log streams: | Stream | Cotool Logs table | Contents | | - | - | - | | Activity Log | `azure_activity` | Subscription control-plane audit events (role assignments, resource writes/deletes, key listings, policy and security events) exported through a subscription-level diagnostic setting. | | Resource logs | `azure_resource_logs` | Data-plane diagnostic logs: Azure Firewall, Application Gateway and Front Door WAF/access logs, AKS control-plane logs (`kube-audit`), PostgreSQL Flexible Server, Storage, Key Vault, Container Registry, and Azure OpenAI / Cognitive Services. Categories Cotool does not yet model land in the same table as passthrough rows — data is never dropped. | | Entra ID diagnostic logs | `azure_entra_logs` | Tenant-level Microsoft Entra ID categories, primarily the ones not available through the Graph reporting API: `MicrosoftGraphActivityLogs` and `EnrichedOffice365AuditLogs`. | | Defender for Cloud alerts | `azure_defender_alerts` | Security alerts streamed through Defender for Cloud Continuous Export. | | Intune logs | `azure_intune_logs` | Microsoft Intune diagnostic categories: `AuditLogs` (admin changes and remote device actions such as wipe and retire), `OperationalLogs` (enrollment and Autopilot outcomes), `Devices` and `DeviceComplianceOrg` (daily per-device inventory and compliance snapshots), and `Windows365AuditLogs`. Off by default; turn it on after Step 2. | > [!NOTE] > > Every ingested event is archived in full before indexing, and each table > keeps the complete provider record in `raw_payload`, so nothing is lost to > normalization. ## Step 1: Create the event hub 1. Create (or reuse) an **Event Hubs namespace** in your tenant. A Standard-tier namespace with 1 throughput unit and auto-inflate enabled is a good starting point. 2. Create an event hub with **4 partitions** and **7-day retention**. Retention is your replay buffer: if ingest is ever paused longer than the retention window, the overflow is unrecoverable. 3. You can point every log source at a single hub — Cotool routes each record by its content, not by which hub it arrived on — or use one hub per source. If you let Azure Monitor create hubs automatically it makes one per category (`insights-logs-`); listing them all in Cotool works, but a single explicit hub is simpler. > [!WARNING] > > Diagnostic settings can only stream to an event hub **in the same region** > as the resource. Multi-region estates need one hub (or namespace) per > region; list them all when connecting. Optionally create a dedicated **consumer group** named `cotool` on each hub. The default `$Default` group works, but a dedicated group is required if another tool already reads the same hub. ## Step 2: Point your log sources at the hub * **Activity Log**: in the Azure portal, go to **Monitor → Activity log → Export Activity Logs**, add a diagnostic setting on each subscription, select the categories you want (at minimum `Administrative`, `Security`, and `Policy`), and stream to the event hub. * **Resource logs**: on each resource (Firewall, Application Gateway, AKS cluster, PostgreSQL flexible server, storage account service, key vault, container registry, Azure OpenAI account), add a **diagnostic setting** that streams the desired log categories to the event hub. For AKS, `kube-audit-admin` is a lower-volume alternative to `kube-audit` that omits get/list reads. * **Entra ID**: in the Entra admin center, go to **Monitoring & health → Diagnostic settings** (requires Security Administrator) and stream the desired categories. The namespace must be in a subscription associated with the Entra tenant. * **Defender for Cloud**: in **Environment settings → your subscription → Continuous export**, enable export of **Security alerts** to the event hub (Azure Policy can roll this out at scale). * **Intune**: in the Intune admin center, go to **Reports → Diagnostic settings → Add diagnostic setting** (requires the Intune Service Administrator role), select `AuditLogs`, `OperationalLogs`, `DeviceComplianceOrg`, `Devices`, and optionally `Windows365AuditLogs`, and choose **Stream to an event hub**. Then enable the **Intune logs** stream in Cotool. ### Licensing caveats * `MicrosoftGraphActivityLogs` requires **Microsoft Entra ID P1 or P2** and is high volume (roughly 60k events per month per 1,000 users). * `EnrichedOffice365AuditLogs` requires **Global Secure Access (Internet Access) licensing** with the Microsoft traffic forwarding profile enabled, and currently covers **SharePoint Online only**. It does not replace the [Microsoft 365 unified audit log ingest](/integrations/identity/microsoft-graph-admin#microsoft-365-unified-audit-log-ingest). * Entra sign-in log exports require Entra ID P1/P2. Sign-in and audit categories streamed to the hub are ingested as passthrough rows in `azure_entra_logs`; if you also use the Microsoft Graph Admin integration's Entra log ingest, the same events will exist in both the `entra` and `azure_entra_logs` tables. * Intune diagnostic export requires an active Intune license and an Azure subscription for the event hub. Intune and Entra both name their audit category `AuditLogs`; Cotool tells them apart by content, so Intune audit records land in `azure_intune_logs` (and are dropped while the **Intune logs** stream is off) and never in `azure_entra_logs`. * Microsoft sends `Devices` and `DeviceComplianceOrg` snapshots once a day, up to 48 hours late, and the Intune export can re-deliver up to a day of data. Cotool collapses re-delivered audit records on their audit event ID and snapshots on their batch and device ID. ## Step 3: Grant Cotool access Choose one of two authentication modes. ### Option A: User-assigned managed identity (recommended) This mode uses workload identity federation — no secret is ever created or stored. 1. Create a **user-assigned managed identity** in your tenant (e.g. `cotool-log-ingest`). 2. On the Event Hubs **namespace** (or narrower scope), assign the identity the **Azure Event Hubs Data Receiver** role. 3. On the managed identity, open **Federated credentials → Add credential → Other issuer** and enter: * **Issuer**: `https://accounts.google.com` * **Subject identifier**: copy it from the **Subject identifier** box on the Cotool connect form (**Settings → Integrations → Azure Event Hub → Connect**). It is the unique ID of the Google service account your Cotool deployment runs as, so it differs between Cotool regions. * **Audience**: copy it from the **Audience** box on the same connect form. It has the form `api://AzureADTokenExchange/cotool/` and is unique to your Cotool organization; do not use the default `api://AzureADTokenExchange`. 4. In Cotool, connect the **Azure Event Hub** integration with your **tenant ID**, the managed identity's **client ID**, and the event hub list. At runtime Cotool exchanges its own cloud identity token for an Entra token as your managed identity, scoped to Event Hubs. You can revoke access at any time by deleting the federated credential or the role assignment. > [!NOTE] > > Connections created before organization-specific audiences existed were set > up with the shared audience `api://AzureADTokenExchange` and keep working > unchanged. To move such a connection over, add a second federated credential > on the managed identity with the values from the connect form, then click > **Connect** again. Cotool switches to the new audience once it validates, > after which you can delete the old federated credential. The connect form > shows a **Move to your organization audience** section while a connection is > still on the shared audience. ### Option B: SAS connection string 1. On the Event Hubs **namespace**, create a shared access policy with only the **Listen** claim (a namespace-scoped policy covers every hub in the namespace). 2. Paste the policy's primary connection string into the Cotool connect form along with the event hub list. The connection string is stored in Cotool's encrypted secret store and never returned by the API. ## Step 4: Connect and enable streams 1. In Cotool, go to **Settings → Integrations → Azure Event Hub**. 2. Enter the event hubs as `/` entries (one per line), e.g. `contoso.servicebus.windows.net/insights-logs`, plus the credentials from Step 3 and the consumer group if you created one. 3. Cotool validates access to each hub before saving. A missing role assignment or bad SAS policy blocks the save with the provider error; a transient network failure does not. 4. On the integration page, enable the log streams you configured in Step 2. Ingest starts within a few minutes and consumes each hub partition from the start of its retained buffer. ## Add or remove event hubs To add a hub to an existing source, for example when you stand up a new region, select **Edit** on the source and add the hub to its event hub list. You don't need to create a new source. Grant the source's managed identity **Azure Event Hubs Data Receiver** on the new hub (or its namespace) first, because Cotool validates access to every listed hub before saving. If the source uses a connection string, every hub must be in that connection string's namespace. * Hubs that stay in the list keep their positions, so no events are replayed. * An added hub is read from the start of its retained buffer. * A removed hub stops being read, and logs already ingested from it are kept. If you add it back to the same source later, ingest resumes from where it stopped, or from the oldest retained event if Azure has expired that position since. * A hub can belong to only one source. To move a hub, remove it from its current source first. The other source then reads it from the start of its retained buffer, which can duplicate logs and detections already ingested by the first source. * The consumer group can't be changed. To read with a different consumer group, add a new source. ## How ingest works * Cotool polls every hub partition on a fixed schedule and drains it from the last durably indexed position (Event Hub sequence numbers). There is no checkpoint container in your storage account — resume positions live in Cotool. * Delivery is at-least-once; the warehouse deduplicates on the hub position (and Intune audit and snapshot rows on their provider IDs), so replays never create duplicate rows. * Each run reports per-partition lag (partition head minus indexed position) in the ingest run history on the Log Ingest page. Status rows on the integration page are per hub partition (shown as ` · partition `), not per enabled log stream — every partition carries a mix of the streams routed through the hub. * Ingest requires outbound AMQP (TCP 5671) from Cotool to `.servicebus.windows.net`; no inbound connectivity to your tenant is needed. # Databricks Integration Source: https://docs.cotool.ai/integrations/security-tools/siem/databricks Connect Cotool to a Databricks SQL warehouse for read-only investigation, detection, and hunting queries over Lakehouse security data ## Overview The Databricks integration lets Cotool agents query security data in your Lakehouse through a **Databricks SQL warehouse**. It provides: 1. **Data discovery** — browse Unity Catalog catalogs, schemas, and tables, search for tables by name, and inspect a table's columns, partition and clustering columns, comments, and sample rows. 2. **Read-only SQL** — run Databricks SQL for investigations, alert triage, threat hunting, and code detections. Results include typed columns and a `truncated` flag when more rows matched than were returned. Cotool connects through the Databricks REST APIs (SQL Statement Execution and Unity Catalog) as a **service principal** using OAuth machine-to-machine credentials. A personal access token is supported as a fallback. Cotool only needs to read from Databricks. Databricks SQL has no read-only session mode, so the service principal's grants are what keep Cotool read-only: grant only what is listed below. ## Before you start You will need: * A Databricks workspace with **Unity Catalog** enabled. Legacy `hive_metastore` tables also work; see [Legacy Hive metastore tables](#legacy-hive-metastore-tables). * **Workspace admin** rights, to create a service principal and generate an OAuth secret for it. * A **SQL warehouse** Cotool can use. We recommend a dedicated **serverless** SQL warehouse: * Serverless warehouses start in seconds. Classic and pro warehouses can take several minutes to start after auto-stop, and Cotool's first queries after an idle period may time out while they start. * A dedicated warehouse keeps Cotool's queries and their cost separate from your other workloads. Every Cotool query runs on your warehouse and consumes DBUs. Set an auto-stop interval that suits your budget. * The **owner** of the catalogs or schemas holding your security data (or a metastore admin), to grant read access. > [!NOTE] > > Cotool queries through a SQL warehouse, not an all-purpose cluster. If the > HTTP path you have starts with `sql/protocolv1/o/`, it belongs to a cluster; > create or pick a SQL warehouse instead. ## Set up Databricks **1. Create a service principal** 1. In your workspace, click your username in the top bar and open **Settings > Identity and access**. 2. Next to **Service principals**, click **Manage**, then **Add service principal > Add new**. 3. Enter a recognizable name (for example `cotool`) and click **Add**. 4. Open the service principal and copy its **Application ID** (a UUID). This is the **Client ID** in Cotool. **2. Give it Databricks SQL access** On the service principal's **Configurations** tab, make sure **Databricks SQL access** is checked, and click **Update**. > [!NOTE] > > This entitlement is easy to miss. Without it, the service principal cannot use any SQL warehouse, even with **Can use** permission on one, and Cotool's connection check fails with a permission error. **3. Generate an OAuth secret** 1. On the service principal, open the **Secrets** tab and click **Generate secret**. 2. Choose a lifetime (up to 730 days). 3. Under **Scopes**, select `sql` and `unity-catalog`. Cotool runs queries through the `sql` APIs and discovers tables through the `unity-catalog` APIs, so it does not need **All APIs**. Secrets created without scopes, or with **All APIs**, also work. 4. Click **Generate**. 5. Copy the **Secret** value immediately. Databricks shows it only once. > [!WARNING] > > On Azure Databricks, the secret must be generated here, in Databricks. A Microsoft Entra ID app registration's client secret does not work, even for an Entra ID-managed service principal. Secrets expire. Before then, generate a new one and update it in Cotool under **Platform > Integrations > Databricks > Edit**. **4. Grant access to a SQL warehouse** 1. Open **SQL Warehouses** and select the warehouse Cotool should use. 2. Click **Permissions**, add the service principal, choose **Can use**, and click **Add**. 3. On the **Connection details** tab, copy the **Server hostname**. Copy the **HTTP path** (for example `/sql/1.0/warehouses/1234567890abcdef`) only if you want to pin this warehouse. If you leave the HTTP path blank in Cotool, Cotool picks a warehouse the service principal can use: serverless first, then a running warehouse, then pro over classic. If that warehouse is later deleted, Cotool switches to another one. Pin a warehouse when you need Cotool's queries and their cost on a specific one. **5. Grant read access to your security data** In the SQL editor (or **Catalog Explorer > Permissions**), grant the service principal read access to the catalog that holds your security data. In `GRANT` statements, refer to a service principal by its Application ID: ```sql theme={null} -- Replace `security` with your catalog and the UUID with the Application ID from step 1. GRANT USE CATALOG ON CATALOG security TO `11111111-2222-3333-4444-555555555555`; GRANT USE SCHEMA ON CATALOG security TO `11111111-2222-3333-4444-555555555555`; GRANT SELECT ON CATALOG security TO `11111111-2222-3333-4444-555555555555`; ``` Privileges granted on a catalog apply to every schema and table in it, including ones created later. To limit Cotool to specific data, grant `USE SCHEMA` and `SELECT` on individual schemas or tables instead. `USE CATALOG` on the parent catalog is always required. Do not grant `MODIFY`, `ALL PRIVILEGES`, or ownership. Cotool only needs to read. ## Connect in Cotool 1. In Cotool, go to **Platform > Integrations > Databricks** and click **Connect**. 2. Enter the values you collected: | Cotool field | Where it comes from | | - | - | | Workspace host | **Server hostname** from the warehouse's Connection details (step 4), or the workspace URL from your browser | | SQL warehouse HTTP path | Optional. **HTTP path** from the warehouse's Connection details (step 4), to pin that warehouse | | Authentication method | **OAuth service principal** (recommended) | | Service principal client ID | The service principal's **Application ID** (step 1) | | Service principal OAuth secret | The **Secret** value generated in step 3 | 3. Click **Connect**. Cotool exchanges the credentials for a token and reads (or picks) the SQL warehouse to confirm both work before saving. If the warehouse is not serverless, the connect form shows a warning, because its first query after auto-stop waits for it to start. If the check fails, the error explains which part to fix (see [Troubleshooting](#troubleshooting)). Workspace hosts look like this: | Cloud | Example host | | - | - | | AWS | `dbc-1234abcd-5678.cloud.databricks.com` | | Azure | `adb-1234567890123456.7.azuredatabricks.net` | | GCP | `1234567890123456.7.gcp.databricks.com` | Cotool only sends credentials to Databricks-operated domains, including the GovCloud and Azure Government and China variants. Custom vanity domains are not supported; use the workspace's Databricks hostname. ### Personal access token (fallback) If your organization cannot create service principals, choose **Personal access token** and paste a token instead of the client ID and secret. Generate it for a dedicated, least-privilege identity rather than a person's account, because Cotool can read whatever that identity can. Tokens expire, and workspace admins can disable them; when that happens Cotool's queries start failing with HTTP 401 until you paste a new token. ## Network access If your workspace restricts inbound access, Cotool must be able to reach it: * **IP access lists** — allow Cotool's egress IP addresses, listed on the Databricks connect form in Cotool (**Platform > Integrations > Databricks > Connect**). * **Private Link with public access disabled** — Cotool cannot reach the workspace. Keep a public front-end endpoint restricted by IP access list instead. Blocked connections show as `HTTP 403` (IP access list) or a connection failure before any response (Private Link or firewall). ## How Cotool queries Databricks * **Discovery is incremental.** Agents list catalogs, then schemas, then tables, and describe only the tables they need. Discovery uses the Unity Catalog metadata APIs, which do not wake the SQL warehouse. Sampling rows does use the warehouse. * **Results are capped.** Queries return 500 rows by default and at most 10,000, with a 4 MiB result cap. When more rows match, the response says `truncated: true`, and the agent narrows or aggregates the query. * **Queries time out and are cancelled.** Each statement has a timeout (300 seconds by default, at most 30 minutes). Cotool cancels statements that exceed it, so abandoned queries do not keep running on your warehouse. * **Queries are attributable.** Cotool's statements appear in Databricks **Query History** under the service principal, so you can audit and cost them. Agents query fastest when security tables are laid out for time-bounded reads: * Partition or liquid-cluster large log tables on an event date or timestamp column. Cotool shows agents these columns and tells them to filter on them first. * Add table and column comments describing each source (for example, "AWS CloudTrail management events"). Agents see comments during discovery and use them to pick the right table. * Use one table per log source rather than one mixed table, so agents do not have to filter by source type. ## Environment map After you connect, and weekly after that, Cotool maps everything the service principal can read: every catalog, schema, and table, each with a one-sentence summary of what it holds. Tables that hold timestamped logs or events also show their event time column, partition or clustering columns, and when they last changed. View the map on the Databricks integration page in Cotool. * Agents get the map's overview, catalog index, log and event tables, and one line per schema. When they list a schema's tables with discovery, each table includes its summary. * Detection planning uses the same overview to know which log sources you have. * Cotool lists Unity Catalog objects with the metadata APIs, which do not start the warehouse. Listing `hive_metastore` uses `SHOW` statements, so it briefly starts the warehouse. * Summaries are written from table names, comments, and column names. Cotool never reads rows to build the map. * Schemas with many similarly named tables, such as dbt staging models, are summarized as a pattern with a few notable tables instead of one line per table. * The map lists catalogs and schemas the service principal cannot read. To keep Cotool from seeing a catalog, revoke the service principal's `USE CATALOG` on it. * Objects created between runs are not in the map until the next run, but agents can still find them with discovery. ## Legacy Hive metastore tables Tables in the workspace-local `hive_metastore` catalog are not served by the Unity Catalog APIs, so Cotool discovers them with `SHOW` and `DESCRIBE` statements on the SQL warehouse. This works, with these differences: * Table-name search across the catalog is not available; agents browse schema by schema. * Discovery wakes the SQL warehouse. * Access is controlled by legacy table access control rather than Unity Catalog grants. Grant the service principal `USAGE` and `SELECT` on the relevant databases, or upgrade the tables to Unity Catalog. ## Troubleshooting | Error mentions | What to fix | | - | - | | `invalid_client`, or "Databricks rejected the OAuth client credentials" | The client ID or secret is wrong, expired, or an Entra ID secret. Generate a new secret on the service principal's **Secrets** tab (step 3). | | "Scopes ... are not assigned to the client" | The OAuth secret lacks a scope Cotool needs. Generate a new secret with the `sql` and `unity-catalog` scopes (step 3); scopes cannot be added to an existing secret. | | "is not a Databricks workspace host" | Enter the workspace's Databricks hostname (see the table above), not a vanity domain or a non-Databricks URL. | | "belongs to an all-purpose cluster" | The HTTP path is for a cluster. Use a SQL warehouse's HTTP path (step 4). | | `HTTP 403` / `PERMISSION_DENIED` on connect | The service principal lacks **Can use** on the warehouse (step 4) or the **Databricks SQL access** entitlement (step 2), or an IP access list blocks Cotool. | | `HTTP 404` on connect | The HTTP path's warehouse ID does not exist in this workspace. Copy the HTTP path again from the warehouse's Connection details. | | "No SQL warehouses are visible to this identity" | The HTTP path was left blank and the service principal has no warehouse permission. Grant it **Can use** on a SQL warehouse (step 4), preferably serverless. | | `TABLE_OR_VIEW_NOT_FOUND`, or catalogs and tables missing from discovery | The service principal lacks `USE CATALOG`, `USE SCHEMA`, or `SELECT` on that data (step 5). Unity Catalog hides objects an identity cannot access. | | "did not finish within N seconds" and "warehouse is STARTING" | A classic or pro warehouse was starting after auto-stop. Retry in a few minutes, or switch Cotool to a serverless warehouse. | | "did not finish within N seconds" on a running warehouse | The query scanned too much data. Filter on the table's partition or clustering column, or give the warehouse more capacity. | | Connection failure before any response | The workspace is not reachable from Cotool. See [Network access](#network-access). | ## Local development Populate `cogent-backend/.env` with `DATABRICKS_HOST`, `DATABRICKS_HTTP_PATH`, `DATABRICKS_CLIENT_ID`, and `DATABRICKS_CLIENT_SECRET`, then run `npm run bootstrap-tools ` from the repo root. # GCP Pub/Sub Log Ingestion Source: https://docs.cotool.ai/integrations/security-tools/siem/gcp-pubsub Ingest GCP Cloud Audit Logs, network, DNS, and load balancer logs, Security Command Center findings, and other log entries from a dedicated Pub/Sub subscription The GCP Pub/Sub integration reads log entries that a Cloud Logging sink publishes to a Pub/Sub topic in your project, or the findings a Security Command Center notification config publishes there. Cotool pulls from a subscription dedicated to it and indexes the entries into Cotool Logs. ```mermaid theme={null} flowchart LR Logging["Cloud Logging"] --> Sink["Filtered sink"] Sink --> Topic["Pub/Sub topic"] SCC["Security Command Center"] --> Notification["Notification config"] Notification --> Topic Topic --> Subscription["Dedicated subscription"] Subscription --> Cotool["Cotool (workload identity federation)"] ``` You can connect several named sources, for example one per project or organization-wide sink, and pause, edit, or remove each independently. ## Log types Each source carries one log type. | Log type | Cotool Logs table | What Cotool does | | - | - | - | | GCP Cloud Audit Logs | `gcp_cloud_audit` | Maps Admin Activity, Data Access, System Event, and Policy Denied entries into actor, action, service, resource, source IP, outcome, project, and region columns shared with `aws_cloudtrail`, plus impersonation chains and permissions. Other entries are rejected. | | Security Command Center findings | `gcp_scc_findings` | Stores each finding create and update with its category, class, severity, state, mute, affected resource, the principal and API call behind threat findings, MITRE ATT\&CK tactic and techniques, and indicators. Each state or mute change is a row of its own. `account_id` holds the finding's project, or the organization ID for an organization-level finding with no project. | | GCP VPC Flow Logs | `gcp_vpc_flow_logs` | One row per sampled connection, with both endpoints, the reporter, the VM, VPC, and location on each side, and byte, packet, and RTT counts. | | GCP firewall rule logs | `gcp_firewall_logs` | Allowed and denied connections with the matching rule, its priority, action, direction, source ranges, target tags, and the VM it applied to. | | Cloud DNS query logs | `gcp_dns_logs` | Queries from VMs and GKE pods with the normalized query name and type, response code, answers, and the IPs they resolved to. | | GCP load balancer and Cloud Armor logs | `gcp_load_balancer_logs` | Application Load Balancer requests (global, regional, and internal) with the client, request, status, latency, and the Cloud Armor policy, outcome, and matched WAF rules. | | Generic JSON | `gcp_generic_logs` | Stores each entry with its original payload, top-level fields as a searchable `fields` map, and the Pub/Sub message attributes. Entries are not normalized and no detection coverage is implied. | ## Authentication Cotool uses **workload identity federation**, so no service account key is created or stored. Cotool's runtime identity presents a Google-signed token whose audience is unique to your Cotool organization; your workload identity provider accepts only that subject and audience, so no other Cotool customer can use your setup. You can grant the subscription to the federated principal directly, or have Cotool impersonate a service account of yours. > [!NOTE] > > If your organization restricts workload identity pool providers with the > `iam.workloadIdentityPoolProviders` policy, allow > `https://accounts.google.com`. ## Step 1: Create the sink, subscription, and federation On the integration page, select **Add log source**, enter your project ID, and choose what to ingest: **Cloud Logging** through a log sink, or **Security Command Center** findings through a notification config. The setup section fills these, the logs to route, and Cotool's **Subject** and your **Audience** into a Terraform configuration and a gcloud script. Each creates: * a topic and a subscription dedicated to Cotool (`cotool-logs-`; 120-second ack deadline, 7-day retention, no expiry), * a dead-letter topic and subscription (`cotool-logs--dead-letter`) that keep messages Pub/Sub could not deliver after 100 attempts, with the Pub/Sub service agent allowed to move them there, * for Cloud Logging, a log sink with the filter you build under **Logs to route**, with permission to publish to the topic, * for Security Command Center, a notification config on your organization (or the project, if you leave **Organization ID** blank) that publishes findings matching its filter to the topic, * a workload identity pool (`cotool-`) and OIDC provider that trust `https://accounts.google.com` only for Cotool's subject and your audience, * `roles/pubsub.subscriber` on the subscription for the federated principal. `` is a short random value generated for each setup, so several sources can live in the same project. Under **Logs to route**, choose one of: * **Log types**: combine Cloud Audit Logs (the default), VPC flow logs, firewall rule logs, Cloud DNS queries, load balancer and Cloud Armor logs, GKE workloads, Cloud Run, and Compute Engine VMs. * **All logs**: every entry in the project. * **Custom filter**: any [Cloud Logging query](https://cloud.google.com/logging/docs/view/logging-query-language), for example `resource.type="k8s_container" AND severity>=WARNING`. VPC flow logs, firewall rule logs, Cloud DNS queries, and load balancer logs are off in GCP until you turn them on for each subnet, rule, network, or backend service. Expand **Turn on logging in GCP** for the gcloud commands. For Security Command Center, the default finding filter, `state = "ACTIVE" OR state = "INACTIVE"`, sends every finding create and update. Security Command Center only publishes an update that matches the filter, so a filter such as `state = "ACTIVE"` never sends the update that resolves a finding. Security Command Center must be activated on the organization or project, and an organization-wide config needs the Security Center Notification Configurations Editor role (`roles/securitycenter.notificationConfigEditor`) on the organization. Cotool keeps the filter with the source, so the setup guide on its settings shows the same configuration later. > [!WARNING] > > Use a subscription dedicated to Cotool. Cotool acknowledges messages once > they are ingested, so sharing a subscription with another SIEM would take > messages away from it. Other tools can have their own subscription on the > same topic. Deploy it signed in as someone who can manage Pub/Sub, log sinks or Security Command Center notifications, IAM policies, and workload identity pools in the project: > [tab] Terraform > > 1. Save the configuration in your infrastructure repository, and authenticate the Google provider, for example with `gcloud auth application-default login`. > 2. Turn on the APIs it uses if they are off: `gcloud services enable pubsub.googleapis.com logging.googleapis.com iam.googleapis.com sts.googleapis.com --project=`. > 3. For an organization-wide sink, use `google_logging_organization_sink` with `include_children = true` instead of the project sink. > 4. Run `terraform init`, review `terraform plan`, then run `terraform apply`. > 5. `terraform output` prints `subscription` and `workload_identity_provider` for the connection form. > [tab] gcloud CLI > > 1. Save the script, and sign in with `gcloud auth login`. > 2. Run `bash cotool-log-ingest.sh`. It turns on the APIs it needs first. > 3. It prints `subscription` and `workload_identity_provider` for the connection form. To create the resources in the console instead, expand **Setting it up in the console?** for the issuer, subject, and audience the provider must trust. ## Step 2: Connect the source 1. **Connect**: enter your project ID and choose the logs to route or the findings to export. Deploy the setup, then paste the subscription path, the workload identity provider resource name, and optionally a service account to impersonate. 2. **Test**: Cotool exchanges its token at your provider, checks that it can consume the subscription, and pulls up to ten messages. Tested messages are returned to the subscription, not acknowledged. If the subscription is empty, paste a sample log entry. 3. **Format**: name the source and choose a format. Cotool previews the sampled entries parsed with it. A sink that routes a single log type reads with that type's format, and Security Command Center sources use **Security Command Center findings**. Each of these formats rejects other entries, so choose **Generic JSON** or **Custom format, normalized to OCSF** when the sink routes several log types. To keep each log type in its own table, connect one source per log type. 4. Select **Enable source**, or **Save paused** to enable it later. Enabling needs a passing test. ## Reliability * Messages are acknowledged only after their entries are archived and indexed. If Cotool restarts mid-run, the ack deadline lapses and Pub/Sub redelivers them. * A temporary failure delays redelivery with backoff and leaves the messages in the subscription. The dead-letter policy is what lets Pub/Sub report each message's delivery attempt: without one, the access test warns, Pub/Sub redelivers failing messages indefinitely, and entries Cotool Logs rejects are kept only in the raw archive after their first delivery. * Undecodable messages are kept in the raw archive with their original bytes and the reason, and acknowledged so they cannot block the subscription. * Redeliveries do not create duplicates: Cloud Logging entries are keyed by log name, insert ID, and timestamp, Security Command Center findings by finding name, event time, state, and mute, and generic entries by message ID. ## Status Each source shows its health, last successful ingestion, events and bytes read in the last 24 hours, the age of the oldest message received, and recent errors. # Microsoft Sentinel Integration Source: https://docs.cotool.ai/integrations/security-tools/siem/microsoft-sentinel Connect Cotool to Microsoft Sentinel for KQL log search, incident triage, and analytics-rule management ## Overview The Microsoft Sentinel integration gives Cotool agents access to a Sentinel-enabled Log Analytics workspace through Azure's REST APIs. It provides: 1. **KQL log search** — run Kusto queries against any table in the workspace (`SigninLogs`, `SecurityEvent`, `OfficeActivity`, Defender `Device*` tables, and so on). 2. **Data lake KQL** — run the same kind of query against the Sentinel data lake tier, for historical data kept beyond the analytics retention window. 3. **Incident triage** — list and read incidents, their alerts, entities, and comments; add comments; update severity, owner, labels, and status; close incidents with a classification. 4. **Analytics rules** — list and read analytics rules, and create or update Scheduled (KQL) rules. Once connected, Cotool also syncs your rules into its detection coverage views. Cotool authenticates as a **Microsoft Entra app registration** (service principal) using client credentials. Access is granted with a single Azure RBAC role on the resource group that contains your workspace — no Microsoft Graph or Log Analytics API application permissions are required. Data lake queries use that same app, tenant, and workspace. Cotool requests a separate access token for the [Sentinel data lake KQL API](https://learn.microsoft.com/en-us/azure/sentinel/datalake/kql-queries-api). Entra directory roles and Defender XDR unified RBAC do not authorize that API for a service principal; the Azure RBAC role on the workspace does. ## Before you start You will need: * Permission to create app registrations in Microsoft Entra ID (for example the **Application Developer** role). * **Owner** or **User Access Administrator** on the resource group that contains your Sentinel Log Analytics workspace, to assign a role to the app. Choose the role for Cotool based on what you want agents to be able to do: | Role | What Cotool can do | | - | - | | **Microsoft Sentinel Reader** | Read only: KQL queries, list and read incidents, list and read analytics rules | | **Microsoft Sentinel Responder** | Everything in Reader, plus update, comment on, and close incidents (**recommended**) | | **Microsoft Sentinel Contributor** | Everything in Responder, plus create and update analytics rules | ## Set up Azure **1. Register an app in Microsoft Entra** 1. In the [Azure portal](https://portal.azure.com), open **Microsoft Entra ID > App registrations > New registration**. 2. Enter a recognizable **Name** (for example `Cotool`). Leave the account type at the default (single tenant) and leave **Redirect URI** blank. 3. Click **Register**. 4. On the app's **Overview** page, copy the **Application (client) ID** and the **Directory (tenant) ID**. You will paste these into Cotool as **Client ID** and **Tenant ID**. **2. Create a client secret** 1. On the app, open **Certificates & secrets > Client secrets > New client secret**. 2. Enter a description, choose an expiry, and click **Add**. 3. Copy the secret **Value** immediately. Azure shows it only once, and the **Secret ID** column is not the secret. > [!NOTE] > > Client secrets expire. Note the expiry date; before then, create a new secret and update it in Cotool under **Platform > Integrations > Microsoft Sentinel > Edit**. **3. Assign a Microsoft Sentinel role to the app** 1. In the Azure portal, open the **resource group** that contains your Sentinel Log Analytics workspace. 2. Select **Access control (IAM) > Add > Add role assignment**. 3. On the **Role** tab, search for and select **Microsoft Sentinel Responder** (or Reader / Contributor, per the table above), then click **Next**. 4. On the **Members** tab, set **Assign access to** to **User, group, or service principal**, click **Select members**, search for the app you registered in step 1, and select it. 5. Click **Review + assign** (twice, if prompted). > [!NOTE] > > Assign the role on the **resource group**, not just the workspace. Microsoft recommends this for Sentinel, and it ensures the role covers both incident/rule operations and KQL queries. New role assignments can take a few minutes to take effect. **4. Copy the workspace details** 1. In the Azure portal, open **Microsoft Sentinel** and select your workspace, then go to **Settings > Workspace settings**. This opens the underlying Log Analytics workspace. (You can also go directly to **Log Analytics workspaces** and select the workspace.) 2. On the workspace **Overview** page, copy: * **Subscription ID** * **Resource group** * **Workspace name** — the resource name shown as the page title * **Workspace ID** — a GUID, distinct from the Subscription ID ## Connect in Cotool 1. In Cotool, go to **Platform > Integrations > Microsoft Sentinel** and click **Connect**. 2. Enter the values you collected: | Cotool field | Where it comes from | | - | - | | Tenant ID | **Directory (tenant) ID** on the app registration Overview page (step 1) | | Client ID | **Application (client) ID** on the app registration Overview page (step 1) | | Client secret | The secret **Value** copied when you created it (step 2) | | Subscription ID | Log Analytics workspace Overview page (step 4) | | Resource group | Log Analytics workspace Overview page (step 4); the group you assigned the role on in step 3 | | Workspace name | Log Analytics workspace resource name (step 4) | | Workspace ID | The **Workspace ID** GUID on the workspace Overview page (step 4) | 3. Click **Connect**. After connecting, Cotool schedules a job that maps the workspace's analytics-tier tables, data lake tables, and analytics rules so agents know which data sources are available. Data lake tables are labeled separately from the analytics tier. ## Troubleshooting * **HTTP 401 / 403 on any action** — confirm the role assignment from step 3 is on the correct resource group and targets the app (not a user), wait a few minutes for it to propagate, and confirm the client secret has not expired. * **HTTP 404** — double-check the Subscription ID, Resource group, and Workspace name; the Workspace name must be the Azure resource name, not a friendly display name. * **KQL queries fail but incidents work** — the Workspace ID is wrong (it is the GUID on the workspace Overview page, not the Subscription ID). * **Reads work but incident updates or rule writes fail with 403** — the app's role is too low. Incident changes need **Microsoft Sentinel Responder**; creating or updating analytics rules needs **Microsoft Sentinel Contributor**. * **Analytics queries work but data lake queries return 403** — the app needs an Azure RBAC role that can query the workspace. **Microsoft Sentinel Reader** (and the higher Sentinel roles) include that access. Entra directory roles and Defender XDR unified RBAC do not apply to the data lake API when Cotool signs in as a service principal. If the Sentinel role is already assigned and data lake queries still return 403, also assign **Log Analytics Reader** on the workspace. ## Local development Populate `cogent-backend/.env` with `MICROSOFT_SENTINEL_TENANT_ID`, `MICROSOFT_SENTINEL_CLIENT_ID`, `MICROSOFT_SENTINEL_CLIENT_SECRET`, `MICROSOFT_SENTINEL_SUBSCRIPTION_ID`, `MICROSOFT_SENTINEL_RESOURCE_GROUP`, `MICROSOFT_SENTINEL_WORKSPACE_NAME`, and `MICROSOFT_SENTINEL_WORKSPACE_ID`, then run `npm run bootstrap-tools ` from the repo root. # Snowflake Integration Source: https://docs.cotool.ai/integrations/security-tools/siem/snowflake Connect Cotool to Snowflake for read-only investigation, detection, and hunting queries over security data in your warehouse, and to ingest Snowflake's login, query, and access history ## Overview The Snowflake integration lets Cotool agents query security data in your Snowflake account, and collects Snowflake's own login, query, and access history into Cotool. It provides: 1. **Data discovery**: browse databases, schemas, tables, and views, search for tables by name, and inspect a table's columns, clustering key, size, comments, and sample rows. 2. **Read-only SQL**: run Snowflake SQL for investigations, alert triage, threat hunting, and code detections. Results include typed columns and a `truncated` flag when more rows matched than were returned. 3. **Log ingest**: collect `LOGIN_HISTORY`, `QUERY_HISTORY`, and `ACCESS_HISTORY` from `SNOWFLAKE.ACCOUNT_USAGE` for search and detections. See [Log ingest](#log-ingest). Cotool signs in as a dedicated Snowflake user, preferably with **key-pair authentication**. Snowflake has no read-only session mode, so the user's role is what keeps Cotool read-only, and it decides what Cotool can see: grant only what is listed below. To use Snowflake only for log ingest, without giving agents access to your data, see [Ingest-only access](#ingest-only-access). ## Before you start You will need: * A role with `USERADMIN` (or `SECURITYADMIN`) to create a user and role, and the **owner** of the databases holding your security data to grant read access. * A **warehouse** Cotool can use. We recommend a dedicated X-Small warehouse with auto-suspend and auto-resume: * Every Cotool query runs on that warehouse and consumes credits. A dedicated warehouse keeps Cotool's cost separate from your other workloads. * Discovery uses `SHOW` and `DESCRIBE`, which do not need a running warehouse. Queries and sample rows do. ## Set up Snowflake **1. Create a key pair** Generate an RSA key pair on your machine. The private key goes into Cotool; the public key goes on the Snowflake user. ```bash theme={null} openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out cotool_key.p8 -nocrypt openssl rsa -in cotool_key.p8 -pubout -out cotool_key.pub ``` To encrypt the private key, drop `-nocrypt` and enter the passphrase in Cotool as well. **2. Create a role, a warehouse, and a service user** ```sql theme={null} USE ROLE USERADMIN; CREATE ROLE IF NOT EXISTS COTOOL_READER; CREATE USER IF NOT EXISTS COTOOL_SVC TYPE = SERVICE DEFAULT_ROLE = COTOOL_READER DEFAULT_WAREHOUSE = COTOOL_WH RSA_PUBLIC_KEY = ''; GRANT ROLE COTOOL_READER TO USER COTOOL_SVC; USE ROLE SYSADMIN; CREATE WAREHOUSE IF NOT EXISTS COTOOL_WH WAREHOUSE_SIZE = XSMALL AUTO_SUSPEND = 60 AUTO_RESUME = TRUE INITIALLY_SUSPENDED = TRUE; GRANT USAGE ON WAREHOUSE COTOOL_WH TO ROLE COTOOL_READER; ``` > [!NOTE] > > Snowflake blocks single-factor password sign-in for `TYPE = SERVICE` users. Password authentication remains available in Cotool for human users, but Snowflake is phasing it out; use key-pair authentication. **3. Grant read access to your security data** Skip this step for [ingest-only access](#ingest-only-access). ```sql theme={null} -- Replace SECURITY with the database that holds your security data. GRANT USAGE ON DATABASE SECURITY TO ROLE COTOOL_READER; GRANT USAGE ON ALL SCHEMAS IN DATABASE SECURITY TO ROLE COTOOL_READER; GRANT SELECT ON ALL TABLES IN DATABASE SECURITY TO ROLE COTOOL_READER; GRANT SELECT ON ALL VIEWS IN DATABASE SECURITY TO ROLE COTOOL_READER; GRANT USAGE ON FUTURE SCHEMAS IN DATABASE SECURITY TO ROLE COTOOL_READER; GRANT SELECT ON FUTURE TABLES IN DATABASE SECURITY TO ROLE COTOOL_READER; GRANT SELECT ON FUTURE VIEWS IN DATABASE SECURITY TO ROLE COTOOL_READER; ``` Do not grant ownership, `INSERT`, `UPDATE`, `DELETE`, or `ALL PRIVILEGES`. Cotool only needs to read. **4. Grant access to Snowflake's audit views** Log ingest reads `SNOWFLAKE.ACCOUNT_USAGE`, and agents can query these views too. Grant the database roles for the streams you will turn on: ```sql theme={null} USE ROLE ACCOUNTADMIN; GRANT DATABASE ROLE SNOWFLAKE.SECURITY_VIEWER TO ROLE COTOOL_READER; -- LOGIN_HISTORY, SESSIONS GRANT DATABASE ROLE SNOWFLAKE.GOVERNANCE_VIEWER TO ROLE COTOOL_READER; -- QUERY_HISTORY, ACCESS_HISTORY ``` Prefer these database roles over `GRANT IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`, which works but exposes every view in the `SNOWFLAKE` database. ## Connect in Cotool 1. In Cotool, go to **Platform > Integrations > Snowflake** and click **Connect**. 2. Enter the values you collected: | Cotool field | Where it comes from | | - | - | | Account | Your account identifier, for example `myorg-myaccount` (or the legacy `xy12345.us-east-1`) | | Username | The service user, for example `COTOOL_SVC` | | Authentication method | **Key pair** (recommended) | | Private key (PEM) | The contents of `cotool_key.p8`, including the `BEGIN` and `END` lines | | Private key passphrase | Only if the key is encrypted | | Warehouse | Optional. Leave blank to let Cotool pick one, or enter a warehouse to pin it | | Default database, schema, and role | Optional. Agents fully qualify table names, so these are rarely needed. The role defaults to the user's default role | 3. Click **Connect**. Cotool signs in and confirms the warehouse before saving. If the check fails, the error explains which part to fix (see [Troubleshooting](#troubleshooting)). If you leave the warehouse blank, Cotool uses the user's default warehouse when the role can use it. Otherwise it picks a warehouse the role can use: a running one first, then the smallest standard warehouse. It never picks a suspended warehouse without auto-resume. If that warehouse is later dropped or the grant is revoked, Cotool switches to another one. Enter a warehouse when Cotool's queries and their cost must stay on a specific one. ## Network access If a Snowflake network policy restricts access, allow Cotool's egress IP addresses, listed on the Snowflake connect form in Cotool (**Platform > Integrations > Snowflake > Connect**). Cotool cannot reach accounts that only accept PrivateLink connections. A blocked connection fails with "IP ... is not allowed to access Snowflake". ## How Cotool queries Snowflake * **Discovery is incremental.** Agents list databases, then schemas, then tables and views, and describe only the tables they need. Discovery uses `SHOW` and `DESCRIBE`, which read metadata and do not resume the warehouse. Sampling rows does use the warehouse. * **Queries are read-only and single-statement.** Cotool accepts only `SELECT`, `WITH`, `SHOW`, `DESCRIBE`, and `EXPLAIN`, and Snowflake rejects more than one statement per call. The role's grants remain the real boundary. * **Results are capped.** Queries return 500 rows by default and at most 10,000. When more rows match, the response says `truncated: true`, and the agent narrows or aggregates the query. * **Queries time out and are cancelled.** Each statement has a timeout (300 seconds by default, at most 30 minutes), enforced by Snowflake and by Cotool, so abandoned queries do not keep running on your warehouse. * **Queries are attributable.** Cotool's statements appear in **Query History** under the service user with the query tag `cotool-agent`, so you can audit and cost them. * **Values are exact.** Timestamps come back as UTC ISO-8601. Numbers beyond 2^53 and decimals come back as strings, so IDs and amounts keep full precision. Agents query fastest when security tables are laid out for time-bounded reads: * Cluster large log tables on an event date or timestamp column. Cotool shows agents the clustering key and tells them to filter on it first. * Add table and column comments describing each source (for example, "Okta System Log events"). Agents see comments during discovery and use them to pick the right table. * Use one table per log source rather than one mixed table, so agents do not have to filter by source type. ## Environment map After you connect, and weekly after that, Cotool maps the account's tables and views: each one's columns, clustering key, row count, a few sample rows, and a summary of what it holds (for example, which log source it is). Agents start from this map instead of rediscovering the account, and detection planning uses it to know which log sources you have. View it on the Snowflake integration page in Cotool. * The map covers the tables and views the role can see, up to 300. It skips the `SNOWFLAKE` and `SNOWFLAKE_SAMPLE_DATA` databases, Native App databases, and `INFORMATION_SCHEMA`; agents can still query those directly, and already know the `SNOWFLAKE.ACCOUNT_USAGE` views. * Listing and describing tables does not resume the warehouse. Sampling runs one `SELECT * ... LIMIT 3` per table, so mapping briefly resumes it. If sampling keeps failing, Cotool maps the remaining tables without sample rows. * Tables created between runs are not in the map until the next run, but agents can still find them with discovery. ## Log ingest Cotool can collect three of Snowflake's `ACCOUNT_USAGE` views using the same connection. Each stream is off until you turn it on in the integration's **Log Ingest** settings (see [Connect log sources](/log-ingest/connect-sources)). | Stream | Source view | Database role needed | Snowflake publishes rows up to | | - | - | - | - | | Login history | `SNOWFLAKE.ACCOUNT_USAGE.LOGIN_HISTORY` | `SNOWFLAKE.SECURITY_VIEWER` | 2 hours late | | Query history | `SNOWFLAKE.ACCOUNT_USAGE.QUERY_HISTORY` | `SNOWFLAKE.GOVERNANCE_VIEWER` | 45 minutes late | | Access history | `SNOWFLAKE.ACCOUNT_USAGE.ACCESS_HISTORY` | `SNOWFLAKE.GOVERNANCE_VIEWER` | 3 hours late | * Access history requires Snowflake Enterprise Edition or higher. * Cotool polls each stream every 15 minutes, and stays behind real time by that stream's publication delay so it reads only windows Snowflake has finished publishing. Events and detections on a stream therefore run up to that delay behind. An hourly pass re-reads older windows to pick up rows published even later. Duplicate rows are removed. * Every poll runs on the connected warehouse and appears in **Query History** with the query tag `cotool-log-ingest`. * Query history stores each query's full text. That text can include secrets written into statements, for example credentials in `CREATE STAGE` or `ALTER USER`. ### Ingest-only access To collect logs without giving agents access to your own data, give the role only: * `USAGE` on the warehouse (step 2). * The database roles for your streams (step 4). Skip step 3, and do not grant `IMPORTED PRIVILEGES ON DATABASE SNOWFLAKE`. With this role: * **Log ingest works** for every stream whose database role is granted. * **Agents cannot read your databases.** The role has no grants on them, so Snowflake hides them from discovery and rejects queries against them. * **The environment map is empty.** The only database the role can see is `SNOWFLAKE`, which the map skips. Mapping still runs on connect and weekly, but it only lists metadata, so it does not resume the warehouse and samples no rows. * **Agents can still query the audit views.** The Snowflake query and discovery tools stay available, and can read the `SNOWFLAKE.ACCOUNT_USAGE` views the granted database roles cover, including query text in `QUERY_HISTORY`. Most of this is the same data log ingest collects. You cannot turn off agent access while keeping ingest: disabling the Snowflake integration also stops its log ingest. ## Troubleshooting | Error mentions | What to fix | | - | - | | `390144`, or "JWT token is invalid" | The public key on the user does not match the private key, or the account or username is wrong. `DESC USER COTOOL_SVC` shows `RSA_PUBLIC_KEY_FP` to compare. | | `390100`, or "Incorrect username or password" | The password is wrong, or the user is `TYPE = SERVICE`, which cannot use passwords. Switch to key-pair authentication. | | "is not allowed to access Snowflake" | A network policy blocks Cotool. See [Network access](#network-access). | | "is not granted to this user" | The role entered in Cotool is not granted to the user. `GRANT ROLE TO USER `, or clear the role field. | | "does not exist, or ... lacks USAGE on it" on connect | The entered warehouse is wrong or the role cannot use it. `GRANT USAGE ON WAREHOUSE TO ROLE `, or leave the warehouse blank. | | "No warehouse is usable by ..." | The role cannot use any warehouse. Grant it `USAGE` on one (step 2). | | `000606`, or "No active warehouse selected" | The pinned warehouse was dropped or its grant revoked. Fix the grant, or edit the integration and clear the warehouse. | | `002003`, or "does not exist or not authorized" | The role lacks `USAGE` on the database or schema, or `SELECT` on the table or view (step 3). Snowflake hides objects a role cannot access. | | "did not finish within N seconds" | The query scanned too much data. Filter on the table's event-time or clustering column, aggregate, or give the warehouse more capacity. | | "could not reach Snowflake" | The account identifier is wrong, or the account only accepts PrivateLink connections. | # IPinfo IP Enrichment Source: https://docs.cotool.ai/integrations/threat-intel/ipinfo Ingest-time IP geolocation and ASN enrichment for Cotool Logs, powered by IPinfo Cotool enriches logs ingested into Cotool Logs with IP context at ingest time. Events that carry a public client IP gain geolocation and ASN columns (`geo_country_iso_code`, `geo_country_name`, `geo_continent_code`, `geo_continent_name`, `as_number`, `as_organization_name`, `as_domain`), so questions like "logins from outside the US" or "activity from hosting-provider ASNs" are a single query with no external lookups. ## How it works * IPs are resolved against the **IPinfo Lite** database, which Cotool downloads and refreshes periodically and keeps **locally on Cotool's servers** — no IP addresses are ever sent to an external service during ingest. * Only publicly routable IPs are enriched; private and reserved-range IPs index with `NULL` enrichment columns. * Enrichment happens once, at ingest time. Events indexed before enrichment was enabled keep `NULL` columns. ## Enabling and disabling The **IPinfo** integration on the [Integrations page](https://app.cotool.ai/platform/integrations) is connected automatically and requires no credentials. Disabling it stops IP enrichment for newly ingested events; re-enabling resumes enrichment from that point forward. ## Attribution IP address data powered by [IPinfo](https://ipinfo.io). Cotool uses the IPinfo Lite database, which is licensed under [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). # Linear Integration Source: https://docs.cotool.ai/integrations/ticketing/linear Connect Cotool to Linear for issue tracking and AI agent sessions The Linear integration enables your AI agents to work directly inside Linear. Agents can manage issues, respond to @mentions and assignments, stream real-time progress updates, and be triggered by Linear Agent Sessions — all without leaving your project management workflow. ## Features > [card] Agent Sessions > > @mention or assign Cotool in Linear issues to trigger agents with > real-time streaming responses. > [card] Issue Management > > Create, update, and comment on Linear issues programmatically from any > agent. > [card] Live Progress > > See agent reasoning, tool actions, and plan steps streamed directly into > the Linear issue thread. > [card] Conversation Continuity > > Follow up in the same thread — the agent picks up full context from > previous messages. ## Setup **1. Navigate to Integrations** Go to **Settings > Integrations** in Cotool and find the Linear integration. **2. Connect Linear** Click **Connect** to authenticate. Cotool will register as an app-actor in your Linear workspace, enabling it to be assigned to and mentioned in issues. **3. Verify Permissions** The integration requires the following scopes: * Read and write access to issues and comments * App assignable (Cotool can be assigned to issues) * App mentionable (Cotool can be @mentioned in issues) > [!NOTE] > > If you previously connected Linear before the Agent Session feature was > available, you'll see a prompt to **Reconnect** to upgrade your credentials. > This upgrades to app-actor credentials that support assignment and mentions. ## How It Works ### Linear Agent Sessions Linear Agent Sessions are the primary way to interact with Cotool from within Linear. When you @mention or assign Cotool on a Linear issue, Linear creates an Agent Session and sends a webhook to Cotool. Cotool then processes the request and streams its response directly back into the issue thread. **1. Trigger Cotool in Linear** @mention Cotool or assign it to an issue in Linear. You can include a description of what you'd like the agent to do. **2. Agent Acknowledges** Cotool immediately responds with a "Thinking..." status so you know your request was received. **3. Live Progress Updates** As the agent works, you'll see real-time updates streamed into the Linear thread: * **Thoughts** — the agent's reasoning process * **Actions** — tool calls the agent makes (e.g., querying a SIEM, checking an EDR) * **Plan steps** — if the agent creates a plan, each step and its status syncs to Linear's Agent Plan UI **4. Final Response** When the agent completes, its final summary is posted as a response in the thread, along with a link to view the full run in Cotool. ### Agent Triggers vs. Personal Chats Cotool supports two modes when receiving a Linear Agent Session event, similar to how the [Slack integration](/integrations/communication/slack) handles channels vs. DMs: **Agent Triggers (Recommended)** One enabled Linear Agent Session trigger acts as the default for your organization. Its agent handles Agent Sessions created by @mentions and assignments from your Linear workspace. Only one Linear Agent Session trigger can be enabled at a time. External automation can use that trigger as the Linear transport while routing individual sessions to any agent in the organization. **Personal Chats (Fallback)** If no agent trigger is configured, Cotool falls back to creating a personal chat for the requesting user. The user's Linear email must match a Cotool account. This is useful for ad-hoc queries without a dedicated agent. > [!WARNING] > > Personal chats require a matching Cotool account. If no account is found for > the Linear user's email, Cotool will respond with an error message in the > Linear thread. ### Conversation Continuity When you send a follow-up message in a Linear Agent Session thread, Cotool continues the existing conversation with full context of the previous exchange. This enables multi-turn interactions: 1. @mention Cotool: *"Investigate the suspicious login from IP 10.0.0.5"* 2. Agent responds with findings 3. Follow up: *"Can you also check if this IP appears in any other alerts?"* 4. Agent continues with the new request, retaining context from step 2 > [!TIP] > > Each Linear Agent Session stays bound to the Cotool chat created for it. > Follow-ups and stop requests return to that same agent and conversation. ### Stopping an Agent If an agent is taking too long or you want to cancel a request, you can stop it directly from Linear. Cotool will: 1. Interrupt the running agent execution 2. Acknowledge the stop in the Linear thread with a confirmation message 3. Mark the chat as interrupted in Cotool ## Setting Up an Agent Trigger To route Linear Agent Sessions to a specific agent: **1. Create or Edit an Agent** Navigate to the agent you want to trigger from Linear. **2. Add a Linear Trigger** In the agent's **Triggers** tab, click **Add Trigger** and select **Linear**. **3. Select Agent Session Mode** Choose **Agent Session** mode (the default). This uses Linear's native agent protocol instead of legacy issue-created webhooks. **4. Save the Trigger** Save the trigger. Cotool will now handle all Linear Agent Session events for your workspace using this agent. > [!NOTE] > > **Legacy webhook mode** is still available for backward compatibility. > Legacy triggers fire when a Linear issue is created and require manual > webhook configuration. New triggers should use Agent Session mode. ## Routing Different Agents from External Automation If an external system such as Tines already decides which agent should triage an issue, use the agent-specific endpoint to start the Linear Agent Session: ```bash theme={null} curl -X POST "https://app.cotool.ai/api/agents/$AGENT_ID/linear/agent-session" \ -H "Authorization: Bearer $COTOOL_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "issueId": "ITM-123" }' ``` Cotool creates the Linear Agent Session on the issue and binds it to the selected agent's chat. Progress and the final response appear in Linear. Replies and stop requests in that Agent Session return to the same agent with the existing conversation context. ### Configure Multiple Agent Entry Points 1. Configure one enabled **Agent Session** Linear trigger as the default for direct @mentions and assignments. 2. Create or select the agents that external automation may invoke. These targeted agents do not need their own Linear triggers. 3. In Tines, call the endpoint with the selected agent's ID and the Linear issue ID or identifier. The request body supports: | Field | Required | Description | | - | - | - | | `issueId` | Yes | Linear issue UUID or identifier, such as `ITM-123` | | `externalUrls` | No | Links to related resources to display in the Linear Agent Session | Example response: ```json theme={null} { "success": true, "message": "Linear agent session created.", "agentSessionId": "2b08de70-1d3d-4f2f-b972-13bb4ab21bcb", "triggerId": "9b1bd0df-a87f-49cf-a649-889ee748982d" } ``` ## Available Tools When an agent has the Linear integration enabled, it can use these tools: | Tool | Description | | - | - | | `linear_createIssue` | Create an issue, optionally with an assignee, priority, status, due date, labels, and files from the agent's sandbox | | `linear_getIssue` | Get an issue's details, including priority, labels, due date, attachments, and comments with their IDs | | `linear_updateIssue` | Edit an issue's title, description, priority, assignee, status, or due date | | `linear_addCommentToIssue` | Add a comment to an existing issue, optionally with files from the agent's sandbox | | `linear_attachFileToIssue` | Attach a file from the agent's sandbox to an existing issue | | `linear_updateComment` | Edit a comment that Cotool posted. Comments written by anyone else cannot be edited. | | `linear_addLabelsToIssue` | Add existing Linear labels to an issue | | `linear_removeLabelsFromIssue` | Remove labels from an issue | | `linear_listStatuses` | List all available statuses for an issue | | `linear_updateIssueStatus` | Update the status of an issue | | `linear_updateIssueParent` | Set or remove an issue's parent | | `linear_markIssueAsDuplicate` | Mark an issue as a duplicate of another issue | | `linear_listUsers` | List workspace users, for example to find who to assign | | `linear_listMyIssues` | List issues assigned to a user | | `linear_listTeamIssues` | List active issues for a team | | `linear_searchIssues` | Full-text search issues | > [!NOTE] > > Cotool cannot assign issues to itself, because assigning Cotool starts a new > Linear Agent Session. Files from the agent's sandbox are uploaded to Linear. Images appear inline in the issue or comment, and other files appear as download links. Each file can be up to 30 MB. ## Example Use Cases > [accordion] Security Alert Triage > > Create an agent that, when @mentioned on a Linear issue, automatically > investigates the referenced alert — querying your SIEM, checking EDR > telemetry, and summarizing findings directly in the issue thread. > [accordion] Incident Response Coordinator > > Assign Cotool to an incident ticket in Linear. The agent gathers context > from Datadog, PagerDuty, and Slack, then posts a structured summary with > recommended next steps. > [accordion] Access Review Assistant > > @mention Cotool on access review tickets to have it check Okta group > memberships, verify last login dates, and recommend whether access > should be renewed or revoked. > [accordion] Detection Engineering Support > > When creating a new detection rule ticket, @mention Cotool to have it > research similar detections, check MITRE ATT\&CK mappings, and draft an > initial detection rule. ## Best Practices > [!TIP] > > **Use agent triggers for team workflows** — Configure an Agent Session > trigger on a dedicated agent so your entire team gets consistent behavior > when interacting with Cotool in Linear. > [!TIP] > > **Leverage plan syncing** — Agents that use the `todo_write` tool will have > their plan steps automatically synced to Linear's Agent Plan UI, giving you > visibility into the agent's progress at a glance. > [!TIP] > > **Keep agent prompts Linear-aware** — Agents triggered from Linear > automatically receive context instructions, but you can further customize > behavior by mentioning Linear in your agent's system prompt (e.g., "When > triggered from Linear, always include a summary at the end"). > [!TIP] > > **Reconnect if prompted** — If you see a "Reconnect" banner on the Linear > integration page, reconnect to upgrade to the latest app-actor credentials. > This enables assignment, mentions, and agent session features. # Connect Log Sources Source: https://docs.cotool.ai/log-ingest/connect-sources Configure an integration, enable its log streams, and confirm events are arriving. ## Enable a source 1. Open [Integrations](https://app.cotool.ai/platform/integrations) and select the source you want to collect from. 2. Connect the integration and make sure it is enabled. 3. Find its **Log Ingest** settings. Complete any additional credential or provider setup shown there. 4. Choose **Enable** for each required stream and confirm the change. 5. Check the stream status and **Last run** after ingestion begins. Log ingestion is opt-in per stream. Streams marked as coming soon cannot be enabled. If a stream is blocked, resolve the displayed reason, such as a missing provider permission or ingest credential, before enabling it. ## API collection and provider delivery For API-based sources, Cotool uses the configured credentials to collect logs. A successful integration connection does not guarantee that its credentials have permission to read every log stream. Follow the stream-specific requirements on the integration page. For sources that push events, complete the provider-side configuration with the endpoint and credentials issued by Cotool. Enabling a stream in Cotool alone does not configure the provider to send events. If you replace an endpoint or its credentials, update the provider's delivery configuration as well. Some integrations support multiple delivery methods. Follow the setup for the selected method rather than configuring an unrelated webhook or token. ## Verify collection Check these signals together: * **Last success** shows when ingestion last succeeded. * **Ingested through** shows the event-time boundary reached by ingestion. * **Last run** reports indexed events, a skipped run, or a failure. * The table inventory shows the tables available for the source. An empty successful run can mean there were no new events. Table counts refresh separately from stream status, so a new source can initially show an unmeasured count. Use [monitoring](/log-ingest/monitoring) to distinguish delayed inventory from a collection problem. ## Pause collection Use **Disable** on the individual stream and confirm the change. This controls collection for that stream; it is not a request to delete previously collected logs. Check detections that depend on the stream before pausing it. Next: [monitor ingestion](/log-ingest/monitoring) or [search your logs](/log-ingest/search). # Export Logs to Your Storage Source: https://docs.cotool.ai/log-ingest/exporting Continuously mirror newly ingested Cotool logs into object storage you control. Logging sinks continuously copy newly ingested Cotool logs into object storage you own. Use them when you want long-term retention outside Cotool, a lakehouse feed for downstream analytics, or a copy of selected security data in your own cloud environment. Open [Platform > Log Ingest](https://app.cotool.ai/platform/log-ingest) to view existing sinks or create a new one. ## Before you begin * A logging sink only exports logs that Cotool ingests after the sink is created. It does not backfill historical data. * The source you want to export must already be connected and ingesting into Cotool Logs. * You need a destination bucket or container that Cotool can write to. ## What you can export ### Destinations Cotool can write to: * Amazon S3 * Google Cloud Storage * Azure Blob Storage * S3-compatible storage such as Cloudflare R2, MinIO, Wasabi, or Backblaze B2 ### Sources For each sink, choose either: * **All sources** to export every supported log source in the workspace * **Selected sources** to export only the integrations or named sources you choose Source detail pages also show which logging sinks export that source. ### Output formats Choose one of these output styles: | Output | Best for | Notes | | - | - | - | | **Normalized** | Lakehouse analytics, typed schemas, downstream pipelines | Exports typed columns by dataset. You can choose **Parquet** or **JSON Lines**. Records that fail normalization stay in Cotool and are counted on the sink, but are not written to normalized output. | | **Raw** | Archival copies, reprocessing, preserving the original source payload | Exports each record exactly as the source sent it. Raw output is written as gzipped **JSON Lines** and includes records that failed normalization. | ## Create a logging sink **1. Choose a destination** In **Platform > Log Ingest**, select **New sink**. Name the sink, then choose where Cotool should write the exported files and the prefix to use inside that bucket or container. **2. Choose or create a connection** Select the credentials Cotool should use for writes. If you already use **AWS S3 + SQS**, **GCP Pub/Sub**, or **Azure Event Hub** for log ingest, you can often reuse that cloud connection instead of creating a new one. Otherwise, create a dedicated sink connection for the destination. **3. Pick sources and output** Choose all sources or only selected sources, then choose **Normalized** or **Raw** output. The setup flow previews the example object path and a sample record before you activate the sink. **4. Run the write test** Cotool writes a small test object under the destination prefix to confirm that the connection can write to the destination. If the test fails, fix the permissions or destination details before activating the sink. **5. Activate the sink** After the write test passes, activate the sink. Newly ingested logs that match the selected sources are then mirrored to your storage automatically. ## Understand sink health Each sink shows its current delivery state: | State | What it means | | - | - | | **Waiting for logs** | No new matching logs have been ingested since the sink was created. | | **Healthy** | Cotool is delivering new matching batches successfully. | | **Retrying** | Cotool hit a temporary delivery problem and is retrying with backoff. | | **Failing** | Delivery has continued to fail and needs attention. | | **Paused** | Delivery is intentionally paused. New matching logs are held temporarily instead of being dropped immediately. | If a batch cannot be delivered before its hold window expires, Cotool records it as a **gap**. Gaps remain searchable in Cotool, but they are missing from that destination. ## What happens when you pause, edit, or delete a sink ### Pause Pausing a sink stops new writes to the destination. Matching logs are held for a limited time so they can still be delivered if you resume quickly. If they wait too long, they become gaps. ### Edit Edits apply going forward. Newly ingested logs use the new settings after you save. Batches already queued for delivery continue with the configuration they were staged with. If you change the destination or write credentials, Cotool requires a fresh write test before the sink can stay active. ### Delete Deleting a sink stops future exports and drops batches that were not yet delivered. Objects already written to your bucket or container are not deleted. ## Troubleshoot common issues * **Access denied**: confirm that the selected connection still has permission to write to the destination. * **Bucket or container not found**: verify the destination name, region, endpoint, or container path. * **Write test fails after changing settings**: rerun the test after correcting the destination or connection details. * **No files appear yet**: confirm the selected sources are actively ingesting, and remember that sinks export only logs ingested after the sink was created. ## Related guides > [card] [Connect log sources](/log-ingest/connect-sources) > > Enable and verify the sources a sink can export. > [card] [Monitor ingestion](/log-ingest/monitoring) > > Check whether the sources feeding your sink are healthy. > [card] [Search logs](/log-ingest/search) > > Validate that the data you want to export is present in Cotool Logs. > [card] [Integrations overview](/integrations/overview) > > See which integrations support managed log ingest. # Monitor Log Ingestion Source: https://docs.cotool.ai/log-ingest/monitoring Understand stream status, ingestion progress, and the data available to search. Open [Integrations > Cotool Logs](https://app.cotool.ai/platform/log-ingest) to see the Log Ingest overview. Select a source to open its integration page and inspect individual streams. ## Stream health A source's summary badge reflects its most severe stream state. Inspect the individual streams to identify which one needs attention. | Status | Who acts | What it means | | - | - | - | | Healthy | — | Collection is meeting the source's health criteria. Check event-time progress for the period you need. | | Backfilling | — | Collection is advancing but still behind, such as the initial backfill after enabling a stream or a catch-up after a gap. It finishes on its own. | | Recovering | — | A recent run did not complete cleanly (attempts erroring while retries remain, a skipped run, or a run that hit its time limit after making progress). It recovers on its own, or becomes Stalled or Failing. | | Waiting | — | Collection has not yet made its first progress, the warehouse is still being provisioned, or a push endpoint is inside its setup grace period. | | Degraded | Cotool | Logs are missing or late: a run was truncated by the provider, late-arriving events are not being re-read, push deliveries arrive but are not indexing, or the backlog is not shrinking. | | Stalled | Depends | No progress within the source's freshness window. For push sources this includes an endpoint that never received a delivery, or a provider that stopped sending; check the provider-side setup. | | Failing | Depends | A run exhausted its retries. An authentication error means reconnecting the integration; otherwise Cotool is notified. | | No access | You | The provider refuses Cotool access to the stream: the credential is missing or unusable, the tenant lacks the license a log type requires, or the consent lacks a permission the stream reads with. | Each stream's details say who needs to act and what to do. ## Notifications In [Platform > Notifications](https://app.cotool.ai/platform/notifications), the **Log ingest** tab sends a notification to the destinations you choose when a stream enters one of the states you select: **No access**, **Degraded**, **Stalled**, or **Failing**. All four are selected by default. Recovering, backfilling, and waiting streams never notify. See [Notifications](/settings/notifications) for the full settings workflow. Every notification states who needs to act. When a provider truncates a run, the notification names the time window whose events were not ingested; a later run does not re-read that window. A stream that keeps flipping in and out of a state, or keeps truncating run after run, notifies once rather than on every change; it notifies again after three hours out of that state. ## Read the timestamps **Ingested through** is the event-time boundary up to which logs have been durably ingested. **Last success** is when an ingestion run succeeded. A recent success does not necessarily mean the newest provider events are already available. Where supported, **Reconciled through** shows how far Cotool has re-read older time ranges to collect late-arriving events. It can lag behind the main ingestion boundary. **Oldest event** indicates the oldest event still retained. It does not promise that every event between that timestamp and now is present, or that every source has the same retention period. ## Inspect tables and volume The overview includes stream health, indexed event counts, and table inventory. Select a table to inspect column names, types, and comments before writing a query. Table inventory is refreshed separately from the status view. A dash or an initially missing table can mean the inventory has not measured the source yet. **Indexed (recent runs)** totals the indexed-event counts of the runs listed under Recent runs. That list holds only the most recent runs, so this is not a count for a fixed time window. ## Troubleshoot missing events 1. Confirm the required stream is enabled and its credentials have the necessary permissions. 2. For push sources, verify that the provider is sending to the current Cotool endpoint. 3. Inspect **Last run**, including errors, skipped reasons, or truncation. A truncated run means the provider capped pagination before the window was drained. 4. Compare the ingestion and reconciliation boundaries with the event time you are looking for. 5. In [Log Search](https://app.cotool.ai/platform/logs), confirm the table, timestamp column, and query filters. If collection continues to fail, provide support with the source, stream, relevant timestamps, and displayed error. Do not include ingest tokens. [Back to Cotool Log Ingest](/log-ingest/overview) # Cotool Log Ingest Source: https://docs.cotool.ai/log-ingest/overview Collect security logs, inspect ingestion health, and search your data in Cotool. Cotool Log Ingest is the data collection layer of Cotool's SIEM. It brings logs from supported integrations into Cotool Logs so you can search events, run detections against them, and optionally mirror newly ingested data into storage you control. ## From source to investigation 1. Connect an integration in [Integrations](https://app.cotool.ai/platform/integrations) and enable the log streams you need. 2. Check that those streams are ingesting successfully. 3. Explore the resulting tables in [Log Search](https://app.cotool.ai/platform/logs). 4. Use the [Detections Platform](https://app.cotool.ai/detections/overview) to evaluate activity on a schedule and create alerts for triage. Connecting an integration and enabling log ingestion are separate actions. A connected tool can be available to agents without its logs being collected into Cotool Logs. ## Where to start Open [Integrations](https://app.cotool.ai/platform/integrations), then select a source to configure its **Log Ingest** settings. Open the [Cotool Logs](https://app.cotool.ai/platform/log-ingest) card in the integrations catalog to view ingestion health across sources. Use [Log Search](https://app.cotool.ai/platform/logs) in the main navigation to query collected events. Available streams and setup requirements vary by integration. Some sources are polled through an API; others require you to configure delivery from the provider to a Cotool endpoint. Use the setup instructions shown on the integration page for your source. If you want Cotool to proactively notify your team when ingestion health changes, configure shared destinations in [Settings > Notifications](/settings/notifications). > [card] [Connect log sources](/log-ingest/connect-sources) > > Enable streams and verify your first ingestion. > [card] [Monitor ingestion](/log-ingest/monitoring) > > Interpret stream health, freshness, and table inventory. > [card] [Export logs](/log-ingest/exporting) > > Mirror newly ingested logs into your own object storage. > [card] [Search logs](/log-ingest/search) > > Inspect schemas and query collected events. > [card] [Detections Platform](/detections-platform/overview) > > Turn source data into scheduled detections and alerts. # Search Logs Source: https://docs.cotool.ai/log-ingest/search Explore collected tables and run queries in Log Search. Open [Log Search](https://app.cotool.ai/platform/logs) from the main navigation, or use the **Log Search** button on the [Log Ingest overview](https://app.cotool.ai/platform/log-ingest). ## Explore and query 1. Find a table in the tables sidebar. 2. Expand it to inspect its columns and types. 3. Insert a starter query from the table, then adjust the fields and filters. 4. Select **Run** and inspect the results or query error. Cotool Logs uses ClickHouse SQL. Use the actual table and column names shown in your workspace. Include a time filter when investigating a specific period, and use SQL `LIMIT` to keep exploratory results manageable. An empty result is not proof that the activity did not happen. Verify that the relevant stream is enabled, that ingestion has reached the event time, and that your filters match the source's schema. See [Monitor Log Ingestion](/log-ingest/monitoring). ## Reuse a query **History** lets you return to queries run in your browser. This history is stored locally in the browser; it is not a shared query library. Use the share-link control to copy a link containing the query text. Review the SQL before sharing it, especially if you included sensitive values. The link shares the query, not a frozen copy of the results. ## Move from investigation to detection Once you understand the relevant events and fields, use the [Detections Platform](/detections-platform/overview) to build repeatable logic. Include the data source, time window, suspicious condition, and known benign exceptions when describing the detection you want. [Back to Cotool Log Ingest](/log-ingest/overview) # Connect an App Source: https://docs.cotool.ai/mcp/connect-clients Add the Cotool MCP server to Claude, ChatGPT, Cursor, VS Code, Codex, or another MCP client Every client uses your region's server URL. Use the one that matches where you sign in to Cotool, or copy it from **Settings → MCP**: | Region | You sign in at | Server URL | | - | - | - | | US | [app.cotool.ai](https://app.cotool.ai) | `https://app.cotool.ai/api/mcp` | | EU | [eu.cotool.ai](https://eu.cotool.ai) | `https://eu.cotool.ai/api/mcp` | The commands and config on this page have a tab for each region. A connection made with the wrong region's URL signs in to the wrong Cotool and won't find your account. You add the URL once in the app's settings. When the app first connects, a browser window opens to Cotool. Sign in with your normal Cotool login, check which account and organization the app will act as, and select **Connect**. There is no API key to create or paste. > [!NOTE] > > Every app can connect unless an admin has turned the MCP server off. If the > consent screen says MCP is off, ask an admin. See [Turn the MCP server > off](/mcp/overview#turn-the-mcp-server-off). ## Claude > [tab] Desktop or web > > 1. In the Claude app or on [claude.ai](https://claude.ai), open **Customize → Connectors**, select **Add**, then **Custom → Web**. > 2. Name it `Cotool` and paste your region's server URL. > 3. Select **Continue** through setup, then sign in to Cotool. > > One connector covers Chat, Cowork, and Code, in the app and on the web. > [tab] Claude Code (terminal) > > Add the server: > > ```bash US theme={null} > claude mcp add --transport http --scope user cotool https://app.cotool.ai/api/mcp > ``` > > ```bash EU theme={null} > claude mcp add --transport http --scope user cotool https://eu.cotool.ai/api/mcp > ``` > > In Claude Code, run `/mcp`, pick `cotool`, and sign in to Cotool. > > If you signed in to Claude Code with your Claude account, a connector added in the Claude app already works here. ## ChatGPT > [tab] Chat and Work > > 1. In the ChatGPT app, open the **Customize** tab in the left rail and select **Plugins**. > 2. Select **Add** at the top right, then **Add custom MCP server**. > 3. Name it `Cotool`, paste your region's server URL, and sign in to Cotool. > > On [chatgpt.com](https://chatgpt.com), open **Plugins**, select **+**, then **Add custom MCP server**. > [tab] Codex > > In the ChatGPT app, follow the same steps as Chat and Work: **Customize → Plugins → Add → Add custom MCP server**, name it `Cotool`, and paste your region's server URL. > > The Codex CLI and IDE extension share this setup. > [tab] Codex CLI > > Add the server and sign in: > > ```bash US theme={null} > codex mcp add cotool --url https://app.cotool.ai/api/mcp > codex mcp login cotool > ``` > > ```bash EU theme={null} > codex mcp add cotool --url https://eu.cotool.ai/api/mcp > codex mcp login cotool > ``` > > Codex in the ChatGPT app shares this setup. ## Cursor Add the server to `~/.cursor/mcp.json`: ```json US theme={null} { "mcpServers": { "Cotool": { "url": "https://app.cotool.ai/api/mcp" } } } ``` ```json EU theme={null} { "mcpServers": { "Cotool": { "url": "https://eu.cotool.ai/api/mcp" } } } ``` Then open **Cursor Settings → MCPs**. Cotool shows under **Needs Attention**; select **Authenticate** and sign in to Cotool. > [!TIP] > > Use the global `~/.cursor/mcp.json` rather than a project's > `.cursor/mcp.json`, so the connection follows you across projects and isn't > committed to a repository. ## VS Code Add the server: ```bash US theme={null} code --add-mcp '{"name":"cotool","type":"http","url":"https://app.cotool.ai/api/mcp"}' ``` ```bash EU theme={null} code --add-mcp '{"name":"cotool","type":"http","url":"https://eu.cotool.ai/api/mcp"}' ``` Then start `cotool` from the **MCP: List Servers** command and sign in to Cotool. ## Other MCP clients and custom agents Add your region's server URL (`https://app.cotool.ai/api/mcp` or `https://eu.cotool.ai/api/mcp`) as a remote MCP server using the Streamable HTTP transport with OAuth. The client must support: * OAuth 2.1 with PKCE * Dynamic client registration, or a client ID metadata document * Discovery from the server URL, through the `/.well-known/oauth-protected-resource` and `/.well-known/oauth-authorization-server` metadata Most current MCP SDKs handle all of this when you give them the server URL. Access tokens last one hour and refresh automatically; a refresh token that has already been used disconnects the app, and you sign in again. ## Troubleshooting * **Sign-in doesn't recognize your account.** Check the app uses your region's URL: `eu.cotool.ai` if you sign in to Cotool at eu.cotool.ai, `app.cotool.ai` otherwise. Remove the server from the app and add it again with the right URL. * **The consent screen says MCP is turned off.** An admin needs to turn on **Allow apps to connect** in **Settings → MCP**. * **The consent screen asks you to switch back to your own organization.** You're viewing another organization in Cotool. Switch back to your own, then connect again. * **The app stopped working.** It may have been disconnected in **Settings → MCP**, or the MCP server was turned off. Reconnect it from the app's MCP settings. * **A tool is missing.** Tools for features that are off for your organization, such as Detections or Log Ingest, aren't listed. # MCP Server Source: https://docs.cotool.ai/mcp/overview Use Cotool from ChatGPT, Claude, Cursor, Codex, VS Code, or your own agents Cotool runs a remote [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server. Connect it to an AI app and that app can work with your agents, alerts, detections, logs, and integrations, acting as you and with your permissions. There are no API keys. You add one URL to your app, sign in with your normal Cotool login, and approve the connection. ## Server URL The server URL depends on your region. Copy it from **Settings → MCP** in Cotool, or use the one that matches where you sign in: | Region | You sign in at | Server URL | | - | - | - | | US | [app.cotool.ai](https://app.cotool.ai) | `https://app.cotool.ai/api/mcp` | | EU | [eu.cotool.ai](https://eu.cotool.ai) | `https://eu.cotool.ai/api/mcp` | Add it to your app's MCP or connector settings, not to a chat message. See [Connect an app](/mcp/connect-clients) for the steps in each client. ## Turn the MCP server off The MCP server is on for every organization. Admins can turn it off in [Settings → MCP](https://app.cotool.ai/settings/mcp) ([eu.cotool.ai/settings/mcp](https://eu.cotool.ai/settings/mcp) for EU organizations) with **Allow apps to connect**. Turning it off takes effect immediately, including for apps that are already connected. Admins can also disconnect any connected app from the same page. ## What a connected app can do An app acts as the person who connected it. It can do what that person can do in the Cotool web app and nothing more: the same role, permissions, and organization. | Area | What the app can do | | - | - | | Search | Search the Cotool docs and your agents, alerts, detections, and integrations | | Agents | List, read, create, update, and run agents, and read agent runs | | Alerts | Search and read alerts and their timelines, change status and severity, add comments | | Detections | List and read detections, change schedules, and start tuning runs | | Logs | List log tables and run log queries | | Integrations | List integrations, read setup guides, and save non-secret connection settings | Tools for features that are off for your organization, such as Detections or Log Ingest, aren't available. Apps can add library detections, which publishes the library's code and enables its schedule. They can't directly publish edits to detection code, approve or reject tuning proposals, or delete anything. ## Secrets stay out of chat An app never sends or stores integration secrets such as API keys, client secrets, or passwords. * When an integration needs a secret, the app gives you a link instead. The link opens the integration's connect form in Cotool, prefilled with the non-secret values, and you enter the secret there. * If an app sends a secret anyway, Cotool rejects it without storing it. Rotate that secret, because it has passed through the app's chat history. ## Manage connections The **Connections** table in **Settings → MCP** lists every connected app, who connected it, and when it was last used. Admins see the whole organization; everyone else sees their own connections. Select **Disconnect** to revoke an app's access immediately. Connecting it again requires signing in. ## Audit log Every tool call is recorded in the [audit log](/settings/audit-logs) as `user.calledMcpTool`. Changes an app makes, such as updating an alert, show as made by the user through that app, and the Audit Logs page can filter by app type. Connecting and disconnecting apps and changing MCP settings are recorded too. See the [MCP events](/settings/audit-log-events) in the event reference. # Audit Event Reference Source: https://docs.cotool.ai/settings/audit-log-events Every event type the Cotool audit log can record This page lists every audit-log event type the platform can emit, regardless of whether it has appeared in your organization's logs yet. This catalog is also available programmatically via the [Get audit-log event catalog](https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-event-catalog) API endpoint. Note that the [Get audit-log filter options](https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-filter-options) endpoint is different: it returns only the values that already appear in your organization's audit logs, for populating filter dropdowns. ## User events Events performed directly by a user (actor: `user`). | Event | Description | | - | - | | `user.login` | A user signed in. | | `user.logout` | A user signed out. | | `user.create` | A new user account was created. | | `user.update` | A user account was updated. | | `user.updatedSamlSettings` | A user changed the organization's SAML SSO settings. | | `user.updatedScimSettings` | A user changed the organization's SCIM provisioning settings. | | `user.updatedSessionSettings` | A user changed the organization's session length setting. | | `user.enrolledTool` | A user connected (authenticated) a tool integration. | | `user.updatedIngestCredentials` | A user added or replaced a log-ingest credential for a tool integration. | | `user.createdChat` | A user started a new chat. | | `user.sentChatMessage` | A user sent a message in a chat. | | `user.createdAgent` | A user created an agent. | | `user.updatedAgent` | A user updated an agent's configuration or operational settings. | | `user.deletedAgent` | A user deleted an agent. | | `user.pausedAgent` | A user paused an agent. | | `user.resumedAgent` | A user resumed an agent. | | `user.createdAgentTrigger` | A user created an agent trigger. | | `user.enabledAgentTrigger` | A user enabled an agent trigger. | | `user.disabledAgentTrigger` | A user disabled an agent trigger. | | `user.updatedAgentTrigger` | A user updated an agent trigger. | | `user.updatedAgentSettings` | A user turned Hunt or agent evaluation on or off. | | `user.deletedAgentTrigger` | A user deleted an agent trigger. | | `user.triggeredAgent` | A user manually triggered an agent run. | | `user.resentRunDelivery` | A user resent a failed output delivery or notification from an agent run. | | `user.confirmedChatToolUse` | A user approved a tool call requested in a chat. | | `user.rejectedChatToolUse` | A user rejected a tool call requested in a chat. | | `user.createdCustomModel` | A user created a custom model configuration. | | `user.updatedCustomModel` | A user updated a custom model configuration. | | `user.deletedCustomModel` | A user deleted a custom model configuration. | | `user.deletedUser` | A user deleted another user from the organization. | | `user.updatedGroupPermissions` | A user changed the permissions assigned to a role. | | `user.startedAgentInstruction` | A user started an agent-instruction feedback session. | | `user.submittedAgentInstructionFeedback` | A user submitted feedback in an agent-instruction session. | | `user.generatedAgentInstructionDiff` | A user generated proposed instruction changes from feedback. | | `user.appliedAgentInstructions` | A user applied proposed instruction changes to an agent. | | `chat.shared` | A user shared a chat. | | `chat.unshared` | A user unshared a chat. | | `user.changedIngestSource` | A user created, updated, removed, paused, or resumed a log source. | | `user.changedLogSink` | A user created, edited, tested, paused, resumed, or removed a logging sink that exports logs to customer storage. | | `user.updatedSandboxEgress` | A user changed the organization sandbox network policy. | | `user.updatedAgentSandboxEgress` | A user customized an agent's sandbox network policy or reset it to the organization policy. | | `user.updatedAlertStatus` | A user changed an alert's status (for example escalated, closed, or dismissed it). | | `user.updatedAlertSeverity` | A user changed an alert's severity. | | `user.rejectedAlertFeedbackQuestion` | A user marked a suggested explanation for escalated alerts as not true. | | `user.updatedUserRole` | A user changed another user's role. | | `user.createdApiKey` | A user created an API key. | | `user.revokedApiKey` | A user revoked an API key. | | `user.createdRole` | A user created a role. | | `user.updatedRole` | A user updated a role's name or description. | | `user.deletedRole` | A user deleted a role. | | `user.createdInvite` | A user invited someone to the organization. | | `user.canceledInvite` | A user canceled a pending invite. | | `user.resentInvite` | A user resent a pending invite. | | `user.disconnectedTool` | A user disconnected a tool or CLI integration and removed its credentials. | | `user.enabledTool` | A user enabled a tool or CLI integration. | | `user.disabledTool` | A user disabled a tool or CLI integration. | | `user.createdCustomTool` | A user created a custom MCP tool. | | `user.updatedCustomTool` | A user updated a custom MCP tool. | | `user.deletedCustomTool` | A user deleted a custom MCP tool. | | `user.connectedMcpApp` | A user connected an app, such as ChatGPT, Claude, or Cursor, to Cotool through the MCP server. | | `user.disconnectedMcpApp` | A user disconnected an app from Cotool, revoking its access. | | `user.reusedMcpToken` | An app sent a token that was already used, which can mean the token was stolen. Cotool disconnected the app. | | `user.updatedMcpSettings` | A user turned the MCP server on or off or changed which apps may connect. | | `user.calledMcpTool` | An app connected to the MCP server ran a Cotool tool on behalf of a user. | | `user.updatedToolAppConfig` | A user created or changed an integration app configuration (GitHub App, Slack app, or Jira service account). | | `user.deletedToolAppConfig` | A user removed an integration app configuration or GitHub installation. | | `user.updatedIngestSettings` | A user turned log-ingest streams on or off for a tool integration. | ## Agent events Events emitted by autonomous agent runs (actor: `agent`). | Event | Description | | - | - | | `agent.createdChat` | An agent run created a new chat. | | `agent.runStarted` | An agent run started (via UI, API, cron, webhook, job, tool, or detection). | | `agent.invokedTool` | An agent invoked a tool during a run. | | `agent.runCompleted` | An agent run completed (successfully or with an error). | ## Chat events Events emitted during interactive chats (actor: `chat`). | Event | Description | | - | - | | `chat.runCompleted` | A chat turn completed (successfully or with an error). | | `chat.invokedTool` | A tool was invoked during a chat. | ## Detection events Events emitted by published code detections (actor: `detection`). | Event | Description | | - | - | | `detection.invokedTool` | A published code detection invoked a tool during an execution. | ## SCIM events Changes pushed by your identity provider through SCIM provisioning (actor: `scim`). No Cotool user performs these, so the entry has no user or IP address; the affected user is recorded in `data.targetUserId`. | Event | Description | | - | - | | `scim.createdUser` | The SCIM identity provider provisioned a user. | | `scim.updatedUser` | The SCIM identity provider updated a user's attributes. | | `scim.deactivatedUser` | The SCIM identity provider deactivated a user. | | `scim.deletedUser` | The SCIM identity provider deleted a user. | # Audit Logs Source: https://docs.cotool.ai/settings/audit-logs Track all activity with comprehensive audit logging Comprehensive audit trail for security and monitoring. ## What's Logged * All agent executions * Tool calls and parameters * User actions (create, edit, delete agents) * Integration authentication * API calls * Configuration changes ## Viewing Logs View your audit logs at [app.cotool.ai/audit-logs](https://app.cotool.ai/audit-logs). Filter by: * Date range * User * Action type * Agent * Resource ## Event Reference A complete list of every event type the audit log can record is available on the [Audit Event Reference](/settings/audit-log-events) page, or programmatically via the [event catalog API endpoint](https://docs.cotool.ai/api-reference/audit-logs/get-audit-log-event-catalog). ## Export Audit logs are exportable via API for SIEM integration and external analysis. View more here: [audit logs api](https://docs.cotool.ai/api-reference/audit-logs/list-audit-logs). # Managing Roles & Users Source: https://docs.cotool.ai/settings/managing-roles How to create custom roles, assign permissions, and manage user access This guide walks you through creating custom roles, managing user assignments, and troubleshooting common permission issues. > [!NOTE] > > You need the `setting.perms.manage` permission to create or edit roles. By > default, only Super Admins have this permission. ## Assigning Roles to Users > [accordion] Demo > > ![Accessing Roles](https://mintcdn.com/cotool-bcb49c92/aLqDLxBukZPWioDb/assets/assign-role.gif?s=3dc3649c8fbb54c6f15876faa6ef5ac0) **1. Go to Users Tab** Navigate to **Settings > Accounts** and click the **Users** tab **2. Find the User** Locate the user you want to update in the table. You can use the **Filter by Role** dropdown to narrow down the list if you have many users. **3. Change Role** Click the **Role** dropdown in the user's row and select the new role from the list. All available roles (both system and custom) will appear here. **4. Confirm** The change is applied immediately—no need to click "Save". The user's access updates in real-time (they may need to refresh their browser if currently logged in). > [!WARNING] > > **Protection for Super Admins**: You cannot change the last Super Admin's > role. Every organization must have at least one Super Admin at all times. To > change the last Super Admin's role, first promote another user to Super > Admin. ## Creating a Custom Role > [!TIP] > > **New to permissions?** Check out the [Permission Validation > Examples](#permission-validation-examples) section below to understand how > prerequisite permissions work and see common validation scenarios before you > start. > [accordion] Demo > > ![Creating Roles](https://mintcdn.com/cotool-bcb49c92/aLqDLxBukZPWioDb/assets/creating-role.gif?s=b4361f73f67014487cca307596ba349d) **1. Click 'New Role'** In the **Roles** tab, click **+ New Role** **2. Name and Describe** * **Name**: Short, descriptive name (e.g., "Security Analysts", "Tier 1 Operators") - **Description**: Explain who this role is for and what they can do **3. Add Permissions** Click **+ Add Permission** to add each permission: 1. **Select Action** * Choose what can be done (e.g., "Read Agents") 2. **Select Scope** - Choose "all" or "specific" (if available) 3. **Select Resource** - If "specific", choose which resource (e.g., which agent or tool) 4. Click **Add** Repeat for each permission needed. **4. Review Validation** As you add permissions, Cotool validates them in real-time: - **Yellow warnings** appear for missing prerequisite permissions - Click **Quick Fix** to automatically add missing permissions - The **Save Role** button is disabled until all validation issues are resolved **5. Save** Once validation passes, click **Save Role** > [!TIP] > > **Quick Start**: If you're creating a role similar to an existing one, > consider cloning a role instead. ## Inviting New Users > [!NOTE] > > You need the `setting.users.invite` permission to invite users. Without it, > the **Invite user** button doesn't appear. **1. Open Accounts** Navigate to **Settings > Accounts** **2. Click 'Invite user'** Click **Invite user** at the top of the page **3. Enter Email and Role** * **Email address**: The user's email address - **Role**: Which role to assign them (defaults to your role) > [!NOTE] > > If you don't have the `setting.perms.manage` permission, you can > only invite users to your own role. You can't invite anyone to a > role that has permissions you don't have. **4. Send Invite** Click **Send invite**. Cotool emails the user an invitation link and shows you the same link to copy. If the email couldn't be sent, share the link with the user directly or click **Resend email**. **5. Track Invite Status** View pending invites in the **Invites** tab. You can **Resend** or **Cancel invite** for any pending invite. ## Viewing Role Permissions To see what permissions a role has: **1. Find the Role** In the **Roles** tab, find the role you want to inspect **2. Click 'View'** Click the **View** button (eye icon) **3. Review Permissions** A modal opens showing: - All permissions grouped by category (agent, tool, setting, etc.) - Scope for each permission (all vs specific) - Specific resource names if applicable ## Troubleshooting Permission Issues > [accordion] User can't see an agent > > **Check**: > > 1. Does their role have `agent.read` for that agent (or all agents)? > 2. Does their role have `tool.read` for all tools that agent uses? > 3. Did someone in their role create that agent? (If yes, they should have automatic access) > > **Fix**: Add `agent.read` and the required `tool.read` permissions to their role. > [accordion] User can see an agent they shouldn't have access to > > **This is likely expected behavior!** > > When any user in a role creates an agent, all other users in that same role automatically get `agent.read`, `agent.execute`, and `agent.edit` permissions for that specific agent. > > **Example**: If "Alice" (Security Operator role) creates the "Phishing Triage" agent, all other Security Operators automatically gain access to that agent—even if their role doesn't have "all agents" permissions. > > **Fix**: Create a separate custom role with different permissions for users who shouldn't share agent access. > [accordion] User can't execute an agent > > **Check**: > > 1. Does their role have `agent.execute` for that agent? > 2. Does their role have `agent.read` for that agent? > 3. Does their role have `tool.use` for all tools that agent uses? > > **Fix**: Add `agent.execute`, `agent.read`, and the required `tool.use` permissions. > [accordion] User can't access settings > > **Check**: > > 1. Which setting are they trying to access? > 2. Does their role have the corresponding `setting.*` permission? > > **Fix**: Settings permissions are powerful. Consider if this user should really have access, or if you should assign them to a Super Admin role. > [accordion] Can't save role due to validation errors > > **Symptom**: Yellow warning boxes appear showing missing permissions. > > **Fix**: > > 1. Read the error message - it tells you which permissions are missing > 2. Click **Quick Fix** to automatically add them > 3. Or manually add the missing permissions using **+ Add Permission** > > Common causes: > > * Added `agent.execute` without `agent.read` > * Added `agent.read` for an agent without tool permissions for its tools > * Added `tool.use` without `tool.read` > [accordion] Can't delete a user's role > > **Symptom**: System prevents changing or removing a user's role. > > **Cause**: They are the last Super Admin in your organization. > > **Fix**: Promote another user to Super Admin first, then you can change this user's role. ## Common Custom Role Templates Here are some common custom role configurations: ### Agent Runner **Use case**: Users who need to execute agents in chat but not create or edit them. ``` Permissions: - agent.read (all) - agent.execute (all) - tool.read (all) - tool.use (all) - chat.manage (all) - insight.read (all) ``` ### Agent Builder **Use case**: Users who need to create and edit agents but not manage org settings. ``` Permissions: - agent.create (all) - agent.read (all) - agent.execute (all) - agent.edit (all) - tool.read (all) - tool.use (all) - chat.manage (all) - insight.read (all) ``` ### Limited Scope Role **Use case**: Users who need to only access specific agents (e.g., only the Phishing Triage agent). ``` Permissions: - agent.read (specific: phishing-triage-agent) - agent.execute (specific: phishing-triage-agent) - tool.read (specific: email) - tool.read (specific: virustotal) - tool.use (specific: email) - tool.use (specific: virustotal) - chat.manage (all) ``` ### All Agents Except Some **Use case**: Users who should work with every agent, including new ones, but not a few sensitive agents. When adding an agent permission, choose **all agents except...** as the scope, then pick the agents to exclude. ``` Permissions: - agent.read (all except: incident-response-agent) - agent.execute (all except: incident-response-agent) - tool.read (all) - tool.use (all) - cli.read (all) - cli.use (all) - chat.manage (all) ``` ## Best Practices > [!NOTE] > > **Start with Built-in Roles** - The Super Admin and Analyst roles cover most > use cases. Only create custom roles when you need fine-grained control. > [!NOTE] > > **Use Cloning** - Instead of building roles from scratch, clone an existing > role and modify it. This reduces validation errors. > [!NOTE] > > **Test Before Rollout** - After creating a custom role, assign it to a test > user (or yourself) and verify they can access what they need before > assigning to multiple users. > [!NOTE] > > **Document Custom Roles** - Use the description field to explain who should > be assigned to each custom role and why. > [!NOTE] > > **Review Regularly** - Periodically audit your custom roles. Remove roles > that are no longer needed and update permissions as your org's needs change. > [!WARNING] > > **Be Careful with Settings Permissions** - Permissions like > `setting.perms.manage` and `setting.users.delete` are powerful. Only grant > these to trusted users. ## Audit Trail All role and permission changes are logged in the **Audit Logs** (if you have `setting.auditLog.read` permission): * Role creation/deletion * Permission changes (what was added/removed) * User role assignments * Who made each change and when Use audit logs to track who has access to what over time. # Notifications Source: https://docs.cotool.ai/settings/notifications Configure organization-wide notification destinations and defaults Use **Settings > Notifications** to decide where Cotool sends important operational updates for your organization. This page controls shared notification defaults for alert escalations, log-ingest health, agent failures, and, when enabled in your workspace, detection tuning. Notification destinations are shared across your organization. A destination you create here can be reused in other notification settings and anywhere else Cotool asks for an output destination. ## Open the page Go to [Settings > Notifications](https://app.cotool.ai/platform/notifications). The page is organized into tabs. Each tab lets you enable or disable a notification type and choose one or more destinations. ## Manage destinations Each tab uses the same destination picker: 1. Turn the notification type on. 2. Open **Destinations**. 3. Select one or more existing destinations. 4. Or choose **New Destination** to create one while staying on the page. 5. Save your changes. Depending on which integrations are connected in your workspace, destinations can include Slack, Microsoft Teams, webhooks, PagerDuty, Linear, or Tines. > [!NOTE] > > Destination availability depends on your connected integrations. For > example, Slack destinations require the Slack integration to be connected, > and PagerDuty destinations require PagerDuty to be connected. ## Alerts tab The **Alerts** tab controls notifications for escalated alerts. When enabled, Cotool sends a notification each time an alert moves into **Escalated** status, whether that escalation came from a response agent or a person. You can also set a **Minimum severity** so lower-severity escalations do not notify. Use this tab when you want an on-call channel, incident system, or downstream workflow to hear about alerts that need higher-attention review. Related guide: [Alert Routing](/alerts/routing) ## Log ingest tab The **Log ingest** tab controls notifications for managed log-ingest health changes. You can choose which stream states notify: * **No access** - the provider is refusing access and you need to fix the source-side configuration or credentials * **Degraded** - logs are missing, late, or not catching up as expected * **Stalled** - the stream is not making progress within its freshness window * **Failing** - a run exhausted its retries and will not recover on its own Backfilling, recovering, and waiting streams never notify because they are expected or self-healing states. AWS S3/SQS and GCP Pub/Sub sources report through the same states: quarantined records and an aging queue backlog read **Degraded**, a full quarantine reads **Failing**, and denied reads read **No access**. The stream's status on the Log Ingest page links to the source's **Failures** tab. Use this tab when you want the right team to know when a source stops delivering trustworthy data. Related guide: [Monitor Log Ingestion](/log-ingest/monitoring) ## Agent failures tab The **Agent failures** tab sets the default destinations for: * terminal run failures * failed acceptance criteria * critical issues detected during evaluation * runs whose evaluation score falls below the **Minimum evaluation score** These are organization defaults. Individual agents can still override their own failure-notification settings, including the minimum evaluation score. ### Minimum evaluation score Every evaluated run gets a score from 0 to 100. Set **Minimum evaluation score** to notify when a run scores below that threshold, even if it met its acceptance criteria and reported no critical issue. A run that scores exactly the threshold does not notify. Choose **Off** to notify only on failures, failed criteria, and critical issues. This threshold is the organization default. An agent whose **Failure notifications** are set to **Organization default** uses it. To give one agent a different threshold, open the agent, set **Failure notifications** to **Custom**, and choose its own **Minimum evaluation score**. A custom agent uses only its own threshold, and **Off** turns score notifications off for that agent. A low score that comes with failed criteria or a critical issue is sent as one notification that includes the score. A run that already sent a terminal-failure notification to a destination does not send that destination a second notification for its score. Use this tab to make sure broken or off-track agent runs reach the people or systems that need to investigate them. Related guide: [Acceptance Criteria](/improving-agents/acceptance-criteria) ## Detection tuning tab If detection autotuning is enabled in your workspace, the **Detection tuning** tab controls notifications when Cotool automatically applies a tuning proposal and publishes a new detection version. This tab only covers **auto-applied** tuning changes. Review-only proposals still wait for a person to approve or reject them. Use this tab when detection owners want visibility into automatic noise-reduction changes without watching the detections workspace continuously. Related guide: [Operate and Tune Detections](/detections-platform/operations#review-tuning-proposals) ## Best practices * Send different notification types to different destinations when different teams own the response. * Start with a small set of destinations to avoid duplicate noise across channels. * For log-ingest health, notify only on the states your team actively responds to. * Review shared destinations before deleting or repointing them, since other notification flows may reuse them. ## Related documentation > [card] [Monitor log ingestion](/log-ingest/monitoring) > > Understand the health states used by log-ingest notifications. > [card] [Alert routing](/alerts/routing) > > Learn how alerts are created, assigned, and escalated. > [card] [Acceptance criteria](/improving-agents/acceptance-criteria) > > Configure per-agent evaluation checks and failure handling. > [card] [Operate and tune detections](/detections-platform/operations) > > Review detection schedules, hits, and tuning proposals. # Roles & Permissions Overview Source: https://docs.cotool.ai/settings/roles-permissions-overview Understanding role-based access control in Cotool Cotool uses **Role-Based Access Control (RBAC)** to manage what users can do within your organization. Every user is assigned exactly one role, and that role determines their permissions across agents, tools, settings, and more. ## Definitions > [accordion] Role > > A **role** is a named collection of permissions that can be assigned to > users. Each user in your organization has exactly one role. > **Examples**: "Super Admin", "Analyst", "Security Operators", "Read-Only > Users" Roles can be: - **System roles** (built-in, cannot be modified): > Super Admin, Analyst - **Custom roles** (created by your organization, > fully customizable) > [accordion] Permission > > A **permission** grants the ability to perform a specific action on > resources. Every permission has two parts: 1. **Action**: What can be > done (e.g., `agent.read`, `tool.use`, `setting.perms.manage`) 2. > **Resource Scope**: Which resources it applies to (all resources or a > specific resource) **Example**: `agent.execute` with "all" scope = can > execute all agents **Example**: `tool.read` with specific scope for > "jira" = can only read Jira tool configuration > [accordion] Resource > > A **resource** is an entity in Cotool that can be protected by > permissions: - **Agents** (AI workflows) - **Tools** (integrations like > Jira, Splunk, SentinelOne) - **Settings** (organizational configuration) > > * **Insights** (dashboards and metrics) - **Chats** (the chat interface) > [accordion] Action > > An **action** is the specific operation being performed, following the > pattern `resource.verb`: - `agent.read` - View agent details - > `agent.execute` - Run an agent - `tool.use` - Use a tool in agents or > chat - `setting.perms.manage` - Modify roles and permissions > [accordion] Scope > > **Scope** determines which resources a permission applies to: - **All > scope**: Permission applies to all resources of that type - Example: > `agent.read` (all) = read all agents - **Specific scope**: Permission > applies to one specific resource by ID - Example: `agent.read` > (specific: "alert-triage") = read only the Alert Triage agent Not all > permissions support specific scope (e.g., `agent.create` is always > "all"). ## How RBAC Works **1. Role Creation** Your organization can use **built-in system roles** (Super Admin, Analyst) or create **custom roles** with specific permissions. Custom roles let you bundle permissions to match job functions—for example, a "Security Operators" role with access to security agents and specific tools. **2. Role Assignment** Each user in your organization is assigned to exactly **one role**. Every user must have a role. When you invite or update a user, you choose their role, which immediately determines what they can access. **3. Access Control** When a user attempts any action, Cotool checks their role's permissions in real-time: Does the role have the required permission? Does it apply to this resource? Are all prerequisite permissions present? If all checks pass, the action proceeds. ## Permission Categories Permissions are organized into several categories: > [accordion] Agent Permissions > > Control access to AI agents: > > * **agent.create** - Create new agents > * **agent.read** - View agent configurations and prior executions > * **agent.execute** - Run agents in chat or via triggers > * **agent.edit** - Modify existing agents > > These can be scoped to all agents or specific agents. > > > [!NOTE] > > > > **Automatic Permission Sharing**: When a user creates an agent, all other users in their role automatically receive `agent.read`, `agent.execute`, and `agent.edit` permissions for that specific agent—even if the role doesn't have these permissions for "all agents". This enables team collaboration within roles. > [accordion] Tool Permissions > > Control access to integrations and tools: > > * **tool.read** - View tool configurations > * **tool.use** - Use tools (required for agents to call them) > * **tool.manage** - Connect/disconnect integrations, manage auth > > These can be scoped to all tools or specific tool types. > [accordion] Chat Permissions > > Control chat access: > > * **chat.manage** - Access the chat interface > > Applies to all chats (no specific scoping). > [accordion] Alert Permissions > > Control alert triage access: > > * **alert.triage** - Comment on alerts and change alert status > * **alert.manage** - Start response-agent triage and manage alert routing > Starting response-agent triage also requires `agent.execute` for the selected response agent. Reading alerts is based on `agent.read` access to the related origin or triage agents. > [accordion] Insight Permissions > > Control access to analytics: > > * **insight.read** - View dashboards and metrics > > Applies to all insights (no specific scoping). > [accordion] Billing Permissions > > Control access to your organization's platform usage and cost data: > > * **billing.read** - View platform usage, spend, and invoices, and export usage reports > > Applies organization-wide (no specific scoping). Only the Super Admin built-in role has it by default. Add it to a custom role to give access to others, such as a finance contact. > [accordion] Settings Permissions > > Control access to organizational settings: > > * **setting.perms.manage** - Create/edit roles and permissions > * **setting.users.invite** - Invite new users > * **setting.users.update** - Change user roles > * **setting.users.delete** - Remove users > * **setting.apiKey.manage** - Create/revoke API keys > * **setting.auth.manage** - Configure SSO and authentication > * **setting.customModel.manage** - Add custom LLM models > * **setting.auditLog.read** - View audit logs > > All settings permissions apply organization-wide (no specific scoping). ## Permission Scoping: All vs Specific Many permissions support two types of scoping: > [tab] All Scope > > Grants permission to perform an action on **all** resources of that > type. **Example**: `agent.read` with "all" scope means the user can read > every agent in the organization. This is simpler to manage and is > appropriate when users need broad access. > [tab] Specific Scope > > Grants permission to perform an action on **one specific** resource. > **Example**: `agent.execute` with specific scope for agent ID "abc-123" > means the user can only execute that one agent. Use this for > fine-grained access control when you want to limit users to specific > agents or tools. > [tab] All Except Scope > > Any permission that supports specific scope can also apply to > **everything except** the resources you list. **Example**: `agent.edit` > with "all agents except Phishing Triage" lets users edit every agent, > including agents created later, but not Phishing Triage, and `tool.use` > with "all tools except Slack" lets users use every tool but Slack. Each > permission uses one scope: all, specific resources, or a single "all > except" list. Like "all" scope, agent permissions that use it need tool > and CLI permissions for all tools and CLIs. > [!NOTE] > > Not all permissions support specific scoping. For example, `agent.create` > always applies to all agents (you can't limit someone to "only create agent > X"). ## Built-in Roles Cotool provides two system roles that cannot be modified: > [tab] Super Admin > > **Full system access** - Super Admins can do everything. **Permissions > include:** - All agent permissions (create, read, execute, edit) - All > tool permissions (read, use, manage) - All settings permissions (manage > users, roles, auth, API keys) - Read insights and audit logs - Manage > chats > > > [!WARNING] > > > > Every organization **must have at least one Super Admin** at all > > times. You cannot delete the last Super Admin or change their role. > [tab] Analyst > > **Read and execute agents and tools** - Analysts can use Cotool but > cannot modify configuration. **Permissions include:** - Read, execute, > and edit agents - Read and use tools - Read insights - Manage chats > **Cannot do:** - Create new agents - Manage tool configurations - Modify > settings (users, roles, integrations) - Read audit logs ## Critical Rules > [!WARNING] > > **One Role Per User** - Each user must be assigned to exactly one role. > Users cannot have multiple roles or no role. > [!WARNING] > > **At Least One Super Admin** - Your organization must always have at least > one user with the Super Admin role. The system prevents you from removing or > demoting the last Super Admin. > [!WARNING] > > **Permission Hierarchies** - Some permissions require others. For example: - > `agent.execute` requires `agent.read` - `agent.edit` requires both > `agent.read` and `agent.execute` - `tool.use` requires `tool.read` - > `tool.manage` requires both `tool.read` and `tool.use` ## Next Steps > [card] [Managing Roles](/settings/managing-roles) > > Learn how to create custom roles, assign permissions, and manage users # SSO Source: https://docs.cotool.ai/settings/sso Single Sign-On configuration for enterprise authentication Cotool supports SAML SSO for enterprise authentication and configurable SCIM setup for identity-provider user provisioning. To configure SAML SSO or SCIM provisioning, visit [app.cotool.ai/settings/saml](https://app.cotool.ai/settings/saml). For identity-provider administrators, use the public [SAML and SCIM IdP setup guide](/integrations/identity/saml-scim). It includes the SAML ACS fields, SCIM base URL format, supported SCIM operations, and Okta configuration notes.