How It Works
Here is what happens when an agent triggers the approval workflow:Agent wants to perform an action
Your agent decides it needs to take an action — for example, deleting a
file, sending a mass message, or modifying a configuration setting.
Comis classifies the action
Every action is automatically classified as read (safe), mutate
(modifying), or destructive (irreversible). 178 actions across 21
categories have specific classifications built in. Any action that is not
registered defaults to “destructive” — Comis fails closed.
Confirmation is checked
If the action’s classification requires confirmation (destructive actions
do by default), the request enters the approval workflow. The confirmation
policy determines which classifications require human approval.
Execution pauses
The agent stops and waits. The pending request surfaces in three places:
- The web dashboard at
/security(real-time list with one-click Approve / Deny buttons) - The JSON-RPC API via
approvals.listandapprovals.resolvemethods - Channel DM to the operator (when the agent runs on a chat channel and the operator is reachable there)
Dual-Cache Behavior
The approval gate keeps two short-lived caches so repeated identical requests do not flood operators. Both caches are keyed by(agentId, actionType, target), so a request for file.delete /tmp/a is distinct from
file.delete /tmp/b.
| Cache | Default TTL | Behavior |
|---|---|---|
| Denial cache | 60 seconds (approvals.denialCacheTtlMs) | A fresh request that you just denied is auto-denied without paging you again. After the TTL expires, the next request pages you normally. |
| Approval cache | 30 seconds (approvals.batchApprovalTtlMs) | A fresh request that you just approved is auto-approved so a retried agent step does not pause. Set to 0 to disable batching entirely. |
file.delete /var/log/old.log while you are looking at the first
one, your single Approve resolves all 5.
The pending approval state serializes/restores on daemon restart, so an
in-flight approval survives a pm2 restart.
Worked Example: Deleting a Build Artifact
Walk through what happens when a coding agent namedcode-assistant decides
to delete a stale build artifact.
The agent issues a tool call
code-assistant calls file.delete with path: ~/.comis/workspace-code-assistant/build/old.tar.gz.Action classifier marks it destructive
classifyAction("file.delete") returns "destructive". The
requireForDestructive: true policy triggers an approval request.The gate publishes the request
The
ApprovalGate checks both caches; neither has a hit, so it creates
a pending entry, emits an approval:requested event, and parks the tool
call on a Promise. The agent’s tool loop is now blocked.You see it on the dashboard
The web dashboard’s Security view shows:
Pending approval — agentcode-assistantwants to runfile.deleteonbuild/old.tar.gz. Approve / Deny (4:58 left).
You click Approve
The dashboard calls
approvals.resolve with approved: true. The gate
writes the entry to the approval cache (30s TTL), emits an
approval:resolved event, and unblocks the tool call. The agent
receives the file-delete result and continues.A retry within 30 seconds is auto-approved
If
code-assistant decides 10 seconds later to also delete
build/old.tar.gz (e.g., because it raced against a sibling agent),
the gate finds the cache hit and auto-approves — you do not see a
second prompt.Two Systems Working Together
Comis has two related but distinct configuration areas for action control. Understanding the difference prevents confusion when setting up your approval workflow.Action Confirmation (the Policy Layer)
Action confirmation determines which actions need confirmation based on their classification. This is the policy layer — it decides what triggers the approval process.~/.comis/config.yaml
requireForDestructive: true) but sensitive/mutate actions do not (requireForSensitive: false). You
can adjust this to match your risk tolerance.
The autoApprove list lets you exempt specific actions from confirmation even
if their classification would normally require it. This is useful for actions
that are technically destructive but routine in your workflow.
Approval Workflow (the Execution Layer)
The approval workflow controls how the approval process works — including rules, timeouts, and trust levels. This is the execution layer that handles the actual approval requests.~/.comis/config.yaml
Action Classifications
Every action in Comis is classified into one of three levels. This classification drives the entire confirmation and approval system.| Classification | Meaning | Examples |
|---|---|---|
| Read | Safe, no side effects | Viewing files, reading memory, checking status |
| Mutate | Modifies something, reversible | Sending messages, writing files, updating settings |
| Destructive | Irreversible or high-impact | Deleting files, dropping data, bulk operations |
Approval Modes
The approval workflow supports three modes that control how requests are handled.- auto (default) — The system decides based on action classification and confirmation settings. Most actions proceed automatically; only flagged actions pause for approval. This is the recommended mode for most setups.
- require — Always require human approval regardless of classification. Use this for high-security environments where every action must be reviewed.
- deny — Always deny the action. Useful for permanently blocking certain operations that should never be allowed, such as file deletion in a read-only deployment.
~/.comis/config.yaml
Using the Dashboard
Pending approvals appear in the Security dashboard. You can see the action details, the requesting agent, and the context for the request. Approve or deny with a single click. The dashboard shows a real-time list of all pending approval requests across all your agents, with the most recent requests at the top. Expired requests (those that timed out) are marked as auto-denied.Configuration Reference
| Setting | Default | Description |
|---|---|---|
security.actionConfirmation.requireForDestructive | true | Require confirmation for destructive actions |
security.actionConfirmation.requireForSensitive | false | Require confirmation for sensitive/mutate actions |
security.actionConfirmation.autoApprove | [] | Actions that bypass confirmation |
approvals.enabled | false | Enable the approval workflow |
approvals.defaultMode | auto | Default approval mode (auto, require, deny) |
approvals.defaultTimeoutMs | 300000 | Timeout in milliseconds (5 minutes, auto-deny) |
approvals.denialCacheTtlMs | 60000 | Auto-deny window for repeats of a denied request (60s) |
approvals.batchApprovalTtlMs | 30000 | Auto-approve window for repeats of an approved request (30s, 0 disables) |
The
approvals.enabled default is false. You need to explicitly enable the
approval workflow to start receiving approval requests. Without it, action
confirmation still classifies actions, but no human-in-the-loop step occurs.Related
Defense in Depth
How approvals fit into the security layers
Hardening
Complete security hardening checklist
Security Dashboard
Manage approvals in the web UI
Action Classifier Reference
Complete action registry
