Your code ships at machine speed. Your security decisions live in a spreadsheet.
Kloudle is a self-hosted scanner for your cloud, apps, APIs, and MCP servers — with an append-only ledger where humans and agents work the same list. Agents act inside scopes a human set, and every decision lands in a database you own.
The problem
What machine speed does to security
Code ships at machine speed now.
Teams shipping with AI push 3–4× more commits (Cloud Security Alliance), and generated code repeats the same mistakes at scale: hardcoded secrets, missing authorization, public buckets.
- 00:00run starts — 7 repos queued, zero humans in the loop
- ~09:00iteration ~160 · commit 11 of 43
- ~18:00iteration ~320 · commit 22 of 43
- ~27:00iteration ~480 · commit 33 of 43
- 36:00iteration 638 · commit 43 of 43 — run ends
“You can go very fast with AI, but you accrue technical debt at a much higher speed too.”— a code reviewer, Reddit, 2026 · via arXiv 2603.27249
And it ships onto a bigger surface.
A JavaScript frontend with real business logic. APIs behind it, on cloud infrastructure. Now MCP servers, handing tools and data to agents. Each surface has its own auth boundaries and its own scanner — and the path that matters runs across all four. Four reports land in four queues, and a human is expected to join them in their head, at four in the afternoon, on the third day of a busy week.
Security’s answer is still a spreadsheet.
The finding that ends up in your incident report is already in your backlog — sitting there today: scanned, recorded, low severity, assigned to nobody, never read. Organizations remediate about 1 in 10 open findings a month (Kenna/Cyentia); 82% carry security debt (Veracode SoSS 2026). It is a landfill. We call it posture management.
“Security team dumped another 500 ‘critical’ alerts on us today… Half of them are in containers that ran for 30 seconds during builds.”— a developer, r/devsecops, 2025
Noise kills the trust that’s left.
Severity without context cannot tell a public website bucket from a customer-data bucket, so everything arrives marked critical. What matters is whether a finding is reachable, exploitable, and consequential.
“Once people learn the scanner cries wolf, the real findings die in the same pile as the noise.”— r/devsecops, 2026
Agents could work the pile. Ungoverned, they are the next incident.
Reading the list nobody reads — chasing the path, checking the role, trying the request — is exactly what agents are good at. It is also where this gets dangerous: an eager agent left alone will close things, rewrite the evidence to match its conclusion, and do it confidently, faster than any reviewer. A wrong finding in a queue is noise. A wrong resolution is a lie nobody will check again.
“How on earth do I explain to our Security team that the best I can hope for is that I’m asking an LLM nicely to not expose users’ secrets?”— an engineering manager, Hacker News, 2025
Every profession that has to defend a decision years later solved this long ago: double-entry bookkeeping, chain of custody, the flight recorder. You do not stop people from making calls. You make the record of the call impossible to quietly revise. That is the ledger’s job.
How Kloudle solves it
Scanners that prove. A ledger that decides.
Layer 1
Scanners that prove what they find
Five scanners, one for each surface a modern product exposes — cloud, apps & APIs, MCP servers, supply chain, and auth flows. Every scanner has followed the same trajectory: from exploratory to 100% deterministic, so the same input produces the same verdict every run. Each one writes the same kind of finding: the observation, plus the configuration it observed, captured at scan time as evidence. A finding you can open and check is the difference between a report and a rumor.
On every scan, Kloudle also connects what the scanners saw — endpoints to the roles behind them, agent tools to the cloud actions they can take, packages to the credentials near them. That connected view is what lets severity come from reachability instead of from a category default: the same failing check can be waived on a public website bucket and Critical on a CDN origin a deploy role writes to.
Same finding. Opposite verdict.
Two public buckets fail the identical check. One serves a static site. One is a CDN origin with a deploy-role writer.
evidence: bucket-policy.json · acl.json · cdn-origin.json
Layer 2
A ledger where findings become decisions
A finding does not become a security issue automatically. It has to be promoted: evidence attached, severity argued from context, reason written down. Promoted issues enter an append-only ledger in your own Postgres — the application can only insert; update and delete are revoked at the database itself. When the record is append-only, you don’t argue about what happened. You read it.
Every decision is a row. Fix, waive with a reason and an expiry, or accept — signed by a person, by a policy with its version, or by an agent. Agents act only from the promoted ledger, inside a scope a human set — one resource, one change — never from raw scanner output. This is what makes agent speed safe to use: the pile gets worked at machine speed, and the boundaries stay human.
S3 Public Access Block disabled
Same check, two answers, both on the record — show the evidenceSample — demo tenant
// public-access-block.json
{
"BlockPublicAcls": false,
"IgnorePublicAcls": false,
"BlockPublicPolicy": false,
"RestrictPublicBuckets": false
}
// public-access-block.json
{
"BlockPublicAcls": true,
"IgnorePublicAcls": true,
"BlockPublicPolicy": true,
"RestrictPublicBuckets": true
}
What runs today: the four live scanners, and stages 01 Observed and 02 Proven — every finding written to your database with its evidence attached, append-only. Being built now, on that record: stages 03–05 and 07 — promotion, the human decision, and re-scan verification. Stage 06, agents applying fixes from the ledger under scoped permission, is the destination. The demo uses the same labels, stage by stage.
Features
What ships in the box
| Scanner | What it covers | Checks | Status |
|---|---|---|---|
| Cloud configuration | AWS, GCP, Azure, Kubernetes, DigitalOcean | 2,082 — all readable SQL | Live |
| Apps & APIs | Deployed web apps, client-side bundles, APIs, WebSockets, DNS, authorization boundaries | 243 | Live |
| MCP servers | MCP servers and client/server configurations | 48 | Live |
| Supply chain | Known npm and PyPI compromises in hosts, manifests, environments, caches | 2 sweeps | Live |
| OAuth / OIDC | Authorization servers, relying parties, resource servers | 16 | In development |
Evidence-attached findings Live
Every finding carries the raw config captured at scan time — checking it is a comparison, not a judgment call.
A catalog you can read Live
All 2,082 cloud checks are SQL over snapshots of your own resources — one is printed on this page, byte-identical to the file that ships.
Append-only record Live Decisions in build
Findings land in your Postgres today, append-only. The decision stages, every decision signed, are being built on that record. pg_dump is the exit either way.
Self-hosted, small footprint Live
One binary and Postgres on your VM — credentials from your secrets manager, never in code or logs.
Built for agents Live
MCP server, CLI, and binaries — your agents read the same list your engineers do.
A scan, from credentials to reports Live
-
02:00:00Z
scan started
on schedule · snapshot runner
-
02:00:03Z
credentials verified
against the live provider · pulled from your secrets manager
-
02:00:05Z
creating tasks
split into parallel per-service tasks
-
02:00:09Z
tasks created
-
02:00:10Z
scanning
assets enumerated · raw snapshots stored
-
02:07:41Z
scan completed
every expected snapshot confirmed written
-
02:07:43Z
evaluating
full catalog against the snapshot
-
02:09:58Z
generating reports
-
02:10:46Z
report generated
PDF · JSON ↓
Read a check
The catalog is made of queries you can read
The cloud catalog is 2,082 checks, and every one is a SQL query over snapshots of your own resources — no black-box detections. Here is KSP10011, “S3 bucket is public to the internet,” exactly as it ships. It joins the bucket’s ACL grants, its policy, and its Public Access Block configuration, and returns pass or fail with the reason in plain text.
checks/aws-s3/bucket-public-composite.sql
S3 bucket is public to the internet
-- checks/aws-s3/bucket-public-composite.sql -- Check: KSP10011 -- Severity: CRITICAL -- Description: S3 buckets should not be publicly accessible (composite: ACL + policy + public access block) SELECT b.arn as resource_id, SPLIT_PART(b.arn, ':::', 2) as resource_name, CASE -- Pass if all public access is blocked WHEN pab.public_access_block_configuration IS NOT NULL AND jdecode(pab.public_access_block_configuration)->>'BlockPublicAcls' = 'true' AND jdecode(pab.public_access_block_configuration)->>'BlockPublicPolicy' = 'true' AND jdecode(pab.public_access_block_configuration)->>'IgnorePublicAcls' = 'true' AND jdecode(pab.public_access_block_configuration)->>'RestrictPublicBuckets' = 'true' THEN 'pass' -- Fail if ACL grants to AllUsers WHEN acl_public.bucket_arn IS NOT NULL THEN 'fail' -- Fail if policy allows public access (wildcard principal in an Allow statement) WHEN pol.policy IS NOT NULL AND EXISTS ( SELECT 1 FROM jsonb_array_elements( CASE jsonb_typeof(jdecode(pol.policy)->'Statement') WHEN 'array' THEN jdecode(pol.policy)->'Statement' ELSE jsonb_build_array(jdecode(pol.policy)->'Statement') END ) AS stmt WHERE stmt->>'Effect' = 'Allow' AND (stmt->>'Principal' = '*' OR stmt->'Principal'->'AWS' @> '"*"'::jsonb) ) THEN 'fail' ELSE 'pass' END as status, CASE WHEN pab.public_access_block_configuration IS NOT NULL AND jdecode(pab.public_access_block_configuration)->>'BlockPublicAcls' = 'true' AND jdecode(pab.public_access_block_configuration)->>'BlockPublicPolicy' = 'true' AND jdecode(pab.public_access_block_configuration)->>'IgnorePublicAcls' = 'true' AND jdecode(pab.public_access_block_configuration)->>'RestrictPublicBuckets' = 'true' THEN 'All public access is blocked via public access block configuration' WHEN acl_public.bucket_arn IS NOT NULL THEN 'Bucket ACL grants access to AllUsers (internet) - enable public access block or remove AllUsers grants' WHEN pol.policy IS NOT NULL AND EXISTS ( SELECT 1 FROM jsonb_array_elements( CASE jsonb_typeof(jdecode(pol.policy)->'Statement') WHEN 'array' THEN jdecode(pol.policy)->'Statement' ELSE jsonb_build_array(jdecode(pol.policy)->'Statement') END ) AS stmt WHERE stmt->>'Effect' = 'Allow' AND (stmt->>'Principal' = '*' OR stmt->'Principal'->'AWS' @> '"*"'::jsonb) ) THEN 'Bucket policy allows public access (Principal: *) - restrict the policy or enable public access block' ELSE 'Bucket is not publicly accessible' END as reason FROM aws_s3_buckets b LEFT JOIN aws_s3_bucket_public_access_blocks pab ON b.arn = pab.bucket_arn LEFT JOIN ( SELECT DISTINCT bucket_arn FROM aws_s3_bucket_grants WHERE grantee_type = 'Group' AND jdecode(grantee)->>'URI' = 'http://acs.amazonaws.com/groups/global/AllUsers' ) acl_public ON b.arn = acl_public.bucket_arn LEFT JOIN aws_s3_bucket_policies pol ON b.arn = pol.bucket_arn;
jdecode() is a Kloudle engine function that decodes snapshot JSON. Every count on this page is audited against the scanner catalogs — last audit 2026-08-05. A demo opens the rest of the catalog the same way, read-only.Your database, your record
Self-hosted, so the history is yours
The scanner runs on your infrastructure: one binary and Postgres, no Kubernetes required. Credentials come from your secrets manager, are verified against the provider before anything is fetched, and are never written to code or logs.
Snapshots, findings, and ledger entries land in a database you administer, so retention is your policy and access is your call. If you ever leave, pg_dump takes the whole history with you.
Nothing crosses out. retention: your policy · access: your call
Self-hosted — the record stays in
Centralized SaaS — the record ships out
For your agents
Agents read the same list your engineers do
An MCP server, a CLI, and plain binaries ship today. If you want to inspect the interface before talking to anyone, point your agent at the public endpoint — two tools, no account, fifty calls a day free:
responses captured 2026-08-08 and 2026-08-14 — run them yourself
FAQ
Questions with checkable answers
An append-only record of what was observed, the evidence, who decided what to do, and what happened next. It keeps the history an auditor asks for, in a database you own.
The scanner, the snapshots, and the results run and stay on your infrastructure — nothing is sent to a vendor cloud. Kloudle ships 2,391 checks across five scanners; the 2,082 cloud checks are SQL you can open and argue with.
Wiz and Datadog run as SaaS: your security data is collected into their cloud, on their retention policy. Kloudle runs on your infrastructure and writes every snapshot, finding, and ledger entry to a Postgres you administer. If you leave, pg_dump takes the whole record with you.
Yes. An MCP server (Model Context Protocol — the interface AI agents use to call tools), a CLI, and binaries ship today, so your agents read the same check list your engineers do. The destination is agents remediating from the promoted ledger, inside a human-set scope, never from raw scanner output.
One binary and a Postgres on a VM you already run — the footprint of a small internal service, no Kubernetes. An upgrade is a new binary; your snapshots and record stay in your database untouched.
No, by design. Promotion requires evidence and a written reason; a decision is signed by a person or by a human-authored policy whose version is recorded; an agent’s scope is structured: this check, this resource, this action. An issue closes only when the re-scan passes, not when an agent says it’s done. These decision stages are the part being built now, to exactly this spec.
The application can only insert; update and delete are revoked at the database itself. By design the rows are hash-chained, so an edited or deleted row breaks the chain visibly with nothing but psql. Your own DBA is inside your trust boundary; the point is that tampering leaves marks.
Akash Mahajan, Kloudle’s founder, reads it and replies himself. A demo is a walk through a real scan’s output: the evidence files, the PDF and JSON reports, and the ledger. A pilot is a self-hosted install on your VM, writing to your database. One inbox, one person, no sequence.
Book a demo
A demo is a walk through a real scan’s output: the evidence files, the PDF and JSON reports, and the ledger record they feed — each stage labeled Live, In build, or Destination, the same way this page labels them. The email goes to Akash Mahajan, Kloudle’s founder (Kloudle is built inside Appsecco, his security firm — hence the appsecco.com address); he reads it and replies himself.
Book a demo — walk a real scan’s output