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.

coding agent · 02:14
agent › write src/billing/webhooks.ts · done 1.8s agent › write src/api/users.ts · done 2.1s agent › tests 312 pass · commit 43 of 43
minutes later
deploy prod release v2.114 live · 41s
then the scan runs
Misconfigs-2026-07-27.csvread-only
CRITKSP10038 · Access + secret key exist for the root accountopen
CRITKSP25113 · Security group allows all ports from internetopen
CRITKSP25116 · IAM policy allows unrestricted iam:PassRoleopen
HIGHKSP25120 · Internet ingress to sensitive ports · sg-████open
row 1 of 627assigned to: you
recreated from a real scan export — one AWS account, 627 rows, resources redacted

The problem

What machine speed does to security

1

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.

agent run · 7 repos · 36h elapsedSample — recreated from the run described
  1. 00:00run starts — 7 repos queued, zero humans in the loop
  2. ~09:00iteration ~160 · commit 11 of 43
  3. ~18:00iteration ~320 · commit 22 of 43
  4. ~27:00iteration ~480 · commit 33 of 43
  5. 36:00iteration 638 · commit 43 of 43 — run ends
An agent loop refactored Kloudle itself across 7 repos in 36 hours: 638 iterations, 43 commits, zero humans.
“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
2

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.

3

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
4

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
5

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.

In buildSample — illustrative

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

BUCKET-A · WAIVEDBUCKET-B · CRITICAL

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.

Security Ledger · № A-042Sample — demo tenant

S3 Public Access Block disabled

check KSP10010 · AWS·S3 · s3://demo-assets-prod

stages01 Observed 2026-07-28 → 07 Verified 2026-07-30
decisionallow-scoped-fix · scope: this bucket only
statusresolved · re-scan PASS
Read a real check ↓
Same check, two answers, both on the record — show the evidenceSample — demo tenant
2026-07-28 · scanFAIL
// public-access-block.json
{
  "BlockPublicAcls":       false,
  "IgnorePublicAcls":      false,
  "BlockPublicPolicy":     false,
  "RestrictPublicBuckets": false
}
2026-07-30 · re-scanPASS
// 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

ScannerWhat it coversChecksStatus
Cloud configurationAWS, GCP, Azure, Kubernetes, DigitalOcean2,082 — all readable SQLLive
Apps & APIsDeployed web apps, client-side bundles, APIs, WebSockets, DNS, authorization boundaries243Live
MCP serversMCP servers and client/server configurations48Live
Supply chainKnown npm and PyPI compromises in hosts, manifests, environments, caches2 sweepsLive
OAuth / OIDCAuthorization servers, relying parties, resource servers16In 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

scan · 2026-08-01 · account ████████Sample — recreated from the engine’s real event strings
  1. 02:00:00Z
    scan started

    on schedule · snapshot runner

  2. 02:00:03Z
    credentials verified

    against the live provider · pulled from your secrets manager

  3. 02:00:05Z
    creating tasks

    split into parallel per-service tasks

  4. 02:00:09Z
    tasks created
  5. 02:00:10Z
    scanning

    assets enumerated · raw snapshots stored

  6. 02:07:41Z
    scan completed

    every expected snapshot confirmed written

  7. 02:07:43Z
    evaluating

    full catalog against the snapshot

  8. 02:09:58Z
    generating reports
  9. 02:10:46Z
    report generated

    PDF · JSON ↓

out the other end · PDF + JSON
executive-summary.pdf detailed-findings.pdf asset-inventory.json compliance.pdf audit.pdf
templates: SOC2ISO27001HIPAAPCI-DSS

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

check: KSP10011 · severity: CRITICAL · resource: s3_bucket · language: SQL

-- 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;
The check body above is printed byte-identical to the file that ships; 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.

Your perimeter
Your secrets manager
cloud credentials live here — never in code, config, or logs
Kloudle scanner
one binary on your VM · snapshot-based · on demand or scheduled · no Kubernetes required
Postgres you administer
snapshots · findings · pass/fail history · every ledger entry — join your own logs against its stable resource URIs

Nothing crosses out. retention: your policy · access: your call

Your perimeter · a SaaS CSPM
Your cloud
your security data, collected —
Vendor's cloud
their database · their retention policy · their access

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:

curl https://mcp.kloudle.dev/ {"name":"kloudle-cloud-security-scanner","version":"1.0.0","tools":["search","get"],"binaries":7,"payment":{"enabled":false,"free_tier":"50/day per IP"}} curl mcp.kloudle.dev/mcp -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search","arguments":{"query":"s3"}}}' {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"[\n {\n \"name\": \"k5e-aws-s3\",\n \"description\": \"S3 bucket security scanner — encryption, public access, versioning, logging, lifecycle\",\n \"checks\": 5,\n \"severities\": {\n \"critical\": 1,\n \"high\": 1,\n \"medium\": 2,\n \"low\": 1\n },\n \"tags\": [\n \"s3\",\n \"storage\",\n \"encryption\",\n \"public-access\"\n ]\n }\n]"}]}}

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