Skip to content

2026-07-08 · 7 min

Why read-only is a feature, not a limitation

Write access is how security tools become incident vectors. What we gained by refusing it — and what it cost us.

Security tools ask for remarkable things. Admin credentials. Agents on every workload. A write path into the systems they claim to protect. The industry treats this as the cost of doing business — you can't fix what you can't touch.

We think that trade is upside down, and we built kaveo to prove it.

Write access is how tools become incidents#

Count the major security incidents of the last five years where the security tooling itself was the vector. Supply-chain compromises of monitoring agents. Management consoles with remote code execution. Credential stores that became credential buffets. Every one of those products had a write path, and the write path is what turned a bug into a breach.

A tool that can only read has a different worst case. With only its read-only role deployed, which is the default, a compromised kaveo — bad build, bad dependency, bad insider — has a blast radius of a stale or falsified report. That is a bad day. It is not an incident response.

What read-only forecloses, honestly#

Keeping scans read-only costs us convenience, and pretending otherwise would violate our own copy rules. kaveo does not change your cloud on its own. By default it holds no write credentials at all: a fix is drafted, an admin approves it with a typed reason, and it runs as a dry run. If you want kaveo to apply approved fixes, you deploy a separate kaveo-remediation role and turn the executor on. kaveo assumes that role only to apply or roll back a fix an admin has approved, never during a scan. Either way, a human stays between finding and fix.

We consider that a feature too. Unattended auto-remediation moves the write path into the vendor's blast radius and takes the change record out of your process. The teams we serve — regulated, air-gapped, audited — are precisely the teams that cannot outsource that judgment.

Read-only must be provable#

A read-only promise is marketing. A read-only architecture is checkable:

  • The scanner role carries AWS-managed SecurityAudit and ViewOnlyAccess policies. Nothing custom, nothing broad. You can diff the policy we document against the policy you deployed.
  • The role trusts only kaveo's principal and requires your ExternalId, so nothing else can assume it.
  • Writes need a separate, optional role that is not deployed by default, and kaveo uses it only for a fix an admin has approved.
  • There is no outbound connection to receive a write instruction on. No control plane, no command channel. Telemetry stays in your own database, and hosted AI and integrations send nothing until you configure them.
Nothing leaves by defaultPlan of a kaveo deployment inside your perimeter. On the left, your AWS accounts: each carries the read-only role kaveo-readonly, admitted only with a matching ExternalId of at least 8 characters, with the SecurityAudit and ViewOnlyAccess managed policies and a one-hour session. A dashed slot in each account marks the separate write role, kaveo-remediation, which is not deployed by default. Read calls only run from each account's role into the kaveo stack, one Docker Compose project you operate, plus an optional local model that is not started by default. The stack's AI provider is offline by default. The stack writes observations to its evidence store, where they are append-only. Hidden lines leave the stack only through a closed gate in the perimeter, toward three opt-in destinations that stay off until configured: a hosted AI provider, which would receive prompts built from findings; Slack, Jira, webhooks, email and other alert channels; and GitHub remediation pull requests. By default the only runtime egress is sts:AssumeRole plus read-only API calls to the accounts you connect. Note 1: AWS is covered in depth; Azure, GCP, Kubernetes and GitHub have one collector and one detector each.kaveo — one Docker Compose stackYOUR PERIMETERYOUR AWS ACCOUNTSkaveo · DOCKER COMPOSEAWS accountkaveo-readonlyAWS accountkaveo-readonlyAWS accountkaveo-readonlyAWS accountkaveo-readonlykaveo-remediation · write roleNOT DEPLOYED BY DEFAULTEXTERNALID ≥ 8 CHARS · 1-HR SESSIONSecurityAudit + ViewOnlyAccess1Azure, GCP, Kubernetes, GitHub:one collector, one detector eachREAD CALLSONLYkaveo stackAI PROVIDER: OFFLINE (DEFAULT)observationsappend-onlyevidence storelocal modelOPTIONAL · NOT STARTED BY DEFAULTOPT-IN · OFF UNTIL CONFIGUREDhosted AI providerRECEIVES PROMPTSBUILT FROM FINDINGSSlack · Jira · webhooksEMAIL · ALERT CHANNELSGitHub remediation PRsNothing leaves by defaultPlan of a kaveo deployment inside your perimeter. On the left, your AWS accounts: each carries the read-only role kaveo-readonly, admitted only with a matching ExternalId of at least 8 characters, with the SecurityAudit and ViewOnlyAccess managed policies and a one-hour session. A dashed slot in each account marks the separate write role, kaveo-remediation, which is not deployed by default. Read calls only run from each account's role into the kaveo stack, one Docker Compose project you operate, plus an optional local model that is not started by default. The stack's AI provider is offline by default. The stack writes observations to its evidence store, where they are append-only. Hidden lines leave the stack only through a closed gate in the perimeter, toward three opt-in destinations that stay off until configured: a hosted AI provider, which would receive prompts built from findings; Slack, Jira, webhooks, email and other alert channels; and GitHub remediation pull requests. By default the only runtime egress is sts:AssumeRole plus read-only API calls to the accounts you connect. Note 1: AWS is covered in depth; Azure, GCP, Kubernetes and GitHub have one collector and one detector each.YOUR PERIMETERYOUR AWS ACCOUNTSkaveo · DOCKER COMPOSE1AWS accountkaveo-readonlyAWS accountkaveo-readonlyAWS accountkaveo-readonlyAWS accountkaveo-readonlykaveo-remediation · write roleNOT DEPLOYED BY DEFAULTEXTERNALID ≥ 8 CHARSSecurityAudit + ViewOnlyAccessREAD CALLS ONLYkaveo stackAI PROVIDER: OFFLINE (DEFAULT)observations · append-onlyevidence storelocal modelOPTIONAL · OFF BY DEFAULTOPT-IN · OFF UNTIL CONFIGUREDhosted AI providerRECEIVES PROMPTSBUILT FROM FINDINGSSlack · Jira · webhooksEMAIL · ALERT CHANNELSGitHub remediation PRs

When a prospect's security team reviews kaveo, we hand them the Terraform and let them read. That review meeting is the product demo.

The bet#

Our bet is that the next decade of security tooling gets judged the way the rest of the stack already is: least privilege, provable claims, smallest possible blast radius. Read-only is not what we couldn't build past. It is the constraint that makes everything else about kaveo trustworthy.