<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Grumpy Sage</title>
    <description>The latest articles on DEV Community by Grumpy Sage (@grumpysage).</description>
    <link>https://dev.to/grumpysage</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3924029%2F833bdb60-b1d0-4613-89f9-725cf91ae3f3.png</url>
      <title>DEV Community: Grumpy Sage</title>
      <link>https://dev.to/grumpysage</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/grumpysage"/>
    <language>en</language>
    <item>
      <title>Why I Stopped Letting Claude Shell Out for Security Scans</title>
      <dc:creator>Grumpy Sage</dc:creator>
      <pubDate>Mon, 11 May 2026 04:44:53 +0000</pubDate>
      <link>https://dev.to/grumpysage/why-i-stopped-letting-claude-shell-out-for-security-scans-o7d</link>
      <guid>https://dev.to/grumpysage/why-i-stopped-letting-claude-shell-out-for-security-scans-o7d</guid>
      <description>&lt;p&gt;A founder I know spent last Tuesday night debugging what he thought was a Claude bug. He'd wired up Claude Code to his repo with the default shell tool, asked it to "scan this codebase for secrets and SQL injection," and watched it confidently produce a clean report. Zero findings. He shipped to staging. Twelve hours later his Datadog alert fired on a Postgres error trace that exposed a hardcoded service account key in a config file Claude had supposedly scanned.&lt;/p&gt;

&lt;p&gt;He called me at 11pm. We screen-shared. The problem was almost funny once we saw it. Claude had run &lt;code&gt;cyscan&lt;/code&gt; — correctly, with the right flags — against the wrong directory. It had &lt;code&gt;cd&lt;/code&gt;'d into a subfolder earlier in the conversation to read a file, never &lt;code&gt;cd&lt;/code&gt;'d back, and then run the scan from there. The scan completed in 400ms because there were six files in scope. Claude wrote up a confident summary of those six files, called it a codebase audit, and moved on.&lt;/p&gt;

&lt;p&gt;That's not a Claude failure. That's a tool design failure. Shell is a terrible interface for a security scanner when the caller is a probabilistic agent with no model of working directory state, no schema for what "done" looks like, and no way to know if the tool it just invoked actually understood the request. The whole exchange was vibes. The agent produced confident output because shell tools produce stdout and stdout looks like an answer.&lt;/p&gt;

&lt;p&gt;I've been building Cybrium for two years now, and the single most important architectural decision we made in the last six months was to stop telling people to invoke our scanners via shell. Today everything routes through an MCP server. Ten tools. Typed inputs. Structured outputs. No working directory drift. Let me explain why this matters and what we learned along the way.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thesis
&lt;/h2&gt;

&lt;p&gt;If your agent talks to security tooling over a shell, you've built a system where the agent's confidence is decoupled from the scanner's actual coverage. MCP fixes this by making the contract between agent and tool explicit, machine-checkable, and inspectable after the fact. This isn't a UX upgrade. It's the difference between a security pipeline you can audit and one you cannot.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "default shell tool" actually gives you
&lt;/h2&gt;

&lt;p&gt;When Claude Code, Cursor, or any agent runs &lt;code&gt;cyscan --path . --format json&lt;/code&gt; through a bash tool, here's what's actually happening. The agent constructs a string. The string goes to a shell. The shell maintains its own state — working directory, environment variables, prior exit codes — that the agent only partially observes. The scanner runs, writes to stdout, maybe also stderr, exits with a code, and the agent reads it all back as a single blob of text that it then has to parse.&lt;/p&gt;

&lt;p&gt;Every step there is a place where things break in ways the agent can't see.&lt;/p&gt;

&lt;p&gt;The agent doesn't know if &lt;code&gt;cyscan&lt;/code&gt; was the binary it thought it was, or some alias, or a different version on PATH. It doesn't know if the path it passed was a symlink, was expanded by the shell glob, or got truncated. It doesn't know if stderr contained warnings that materially change the meaning of stdout. It doesn't know if the exit code maps to "clean scan" or "scanner crashed after partial run." It just sees text.&lt;/p&gt;

&lt;p&gt;And here's the part that haunts me as someone shipping a security product: the agent doesn't know how many rules ran. If &lt;code&gt;cyscan&lt;/code&gt; ran 1,815 rules across 75+ languages on a 200-engineer monorepo, that's one outcome. If it ran 12 rules because it only found two file types in the subdirectory it was actually pointed at, that's a completely different outcome. Stdout looks similar in both cases — a JSON array of findings, possibly empty. The agent summarizes "no findings." The CISO sleeps poorly.&lt;/p&gt;

&lt;p&gt;Shell tools optimize for human flexibility. Humans cross-reference, notice anomalies, get suspicious when a scan finishes too fast. Agents don't, at least not reliably, and certainly not under pressure when they're four turns deep in a conversation about something else.&lt;/p&gt;

&lt;h2&gt;
  
  
  What MCP changes structurally
&lt;/h2&gt;

&lt;p&gt;Model Context Protocol is, at its core, a typed RPC layer between agents and tools. That sounds dry. The implications are not.&lt;/p&gt;

&lt;p&gt;When Claude calls &lt;code&gt;cyscan_repository&lt;/code&gt; through our MCP server, it isn't writing a shell string. It's calling a function with a typed schema. The schema declares that &lt;code&gt;path&lt;/code&gt; is required, that it must be an absolute path, that &lt;code&gt;language_filter&lt;/code&gt; is an optional enum, that &lt;code&gt;rule_packs&lt;/code&gt; defaults to "all 1,815." The MCP server validates the call before our scanner ever runs. If the agent forgets a required arg, the call fails with a structured error the agent can actually reason about — not a bash error that says "missing argument" in some format the agent has to text-match against.&lt;/p&gt;

&lt;p&gt;The response is structured too. Not stdout. A JSON object with fixed fields: &lt;code&gt;scan_id&lt;/code&gt;, &lt;code&gt;files_scanned&lt;/code&gt;, &lt;code&gt;rules_executed&lt;/code&gt;, &lt;code&gt;findings&lt;/code&gt;, &lt;code&gt;coverage_metadata&lt;/code&gt;, &lt;code&gt;duration_ms&lt;/code&gt;. The agent doesn't have to parse anything. It just reads &lt;code&gt;files_scanned&lt;/code&gt;. If that number is 6 when the repo has 4,000 files, the agent has a fighting chance of noticing, because &lt;code&gt;files_scanned&lt;/code&gt; is a first-class field that the agent's system prompt can be told to check.&lt;/p&gt;

&lt;p&gt;This is what I mean by making the contract machine-checkable. With shell, "did the scan actually scan the thing" is a vibes question. With MCP, it's a field.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ten tools and why ten
&lt;/h2&gt;

&lt;p&gt;Our MCP server exposes exactly ten tools right now. I get asked sometimes why so few — surely a security platform has more surface area than that. The answer is that ten is the result of a lot of arguing about granularity.&lt;/p&gt;

&lt;p&gt;Too few tools and each tool becomes a god-function with twenty parameters and the agent has to learn a sub-language to drive it. Too many tools and the agent's context window fills with tool descriptions before it's done a single useful thing. Ten was where we landed after watching agents actually use the server for three months.&lt;/p&gt;

&lt;p&gt;The tools split roughly into three families. Code and repo scanning lives in &lt;code&gt;cyscan&lt;/code&gt;-backed tools that handle static analysis across 75+ languages. AI-specific scanning lives in &lt;code&gt;cyradar&lt;/code&gt;-backed tools that probe local inference endpoints — Ollama, vLLM, TGI, LocalAI, Triton, LM Studio, llama.cpp — for the kinds of misconfigurations that don't show up in any conventional vuln scanner. Web and API fuzzing lives in &lt;code&gt;cyweb&lt;/code&gt;-backed tools that drive our 22 fuzz categories with 95% template-conversion fidelity against upstream community signatures.&lt;/p&gt;

&lt;p&gt;Each tool does one thing. The agent composes them. That composition is where the real power lives, and it's also what shell tools fundamentally can't do, because shell composition happens through pipes and string parsing instead of through structured data the agent actually understands.&lt;/p&gt;

&lt;h2&gt;
  
  
  A concrete example
&lt;/h2&gt;

&lt;p&gt;Here's the kind of workflow that's trivial with MCP and miserable with shell. Suppose I want my agent to do a full security pass on a new microservice: scan the source for vulns and secrets, then if any of the findings touch an AI inference path, probe the running inference endpoint for those specific issues, then if any of the findings touch an HTTP route, fuzz that route with relevant templates.&lt;/p&gt;

&lt;p&gt;With shell, this is a small program. The agent has to invoke &lt;code&gt;cyscan&lt;/code&gt;, parse the output, build a follow-up command, invoke that, parse, build another. Every parsing step is a place where the agent can hallucinate field names, miss findings, or get tripped up by formatting changes between versions. I've seen agents miss findings because they expected &lt;code&gt;severity&lt;/code&gt; and got &lt;code&gt;risk_level&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With MCP, here's roughly what it looks like from the agent's side:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. call cyscan_repository(path=/repo/order-service)
   -&amp;gt; returns findings[] with structured types
2. for findings where category == "ai_inference":
     call cyradar_probe(endpoint=finding.endpoint, checks=["prompt_injection","model_extraction"])
3. for findings where category == "http_route":
     call cyweb_fuzz(target=finding.url, template_packs=relevant_packs)
4. call generate_report(scan_ids=[...])
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent doesn't write parsing code. It doesn't construct strings. It calls functions on objects. When &lt;code&gt;cyradar_probe&lt;/code&gt; finds a prompt injection vector against a llama.cpp endpoint, that finding is a typed object with a CVE-style identifier, a severity, a remediation hint, and a pointer back to the originating &lt;code&gt;cyscan&lt;/code&gt; finding. The lineage is preserved. The audit trail is automatic.&lt;/p&gt;

&lt;p&gt;You can build something similar with shell. People do. It involves jq, bash heredocs, and a lot of prayer. It is not robust to scanner version updates, scanner output changes, or agent context drift across turns. I have watched these pipelines work flawlessly for two weeks and then silently start dropping findings because someone added a field to the JSON output and the jq filter didn't match anymore. Nobody noticed for a month.&lt;/p&gt;

&lt;h2&gt;
  
  
  The state problem
&lt;/h2&gt;

&lt;p&gt;This is the one I care about most, and it's the one that bit the founder I mentioned at the top. Shell sessions have state. Agents have an imperfect model of that state.&lt;/p&gt;

&lt;p&gt;Working directory is the obvious one but it's not the only one. There's environment variables, which the agent often sets early in a conversation and then forgets about. There's PATH ordering, which can change which binary gets executed. There's shell history affecting tab completion if the agent uses it. There's locale settings affecting how filenames with non-ASCII characters get handled. There's &lt;code&gt;umask&lt;/code&gt; affecting permissions on output files. Every one of these is a state surface the agent has to track or risk getting wrong.&lt;/p&gt;

&lt;p&gt;MCP tools are stateless by default in the way the protocol is designed. Each call is a self-contained, fully-specified invocation. If you want state — say, a long-running scan whose results you want to retrieve later — that state is explicit and addressable. Our &lt;code&gt;scan_id&lt;/code&gt; is a first-class thing. The agent passes it in, gets the same results back, can hand it to another tool. There's no "where am I in the filesystem" question because the filesystem isn't part of the protocol. Paths are arguments. Arguments are typed. The scanner resolves them against a known, fixed base.&lt;/p&gt;

&lt;p&gt;This eliminates a whole class of failure mode that I genuinely believe is responsible for most agent-driven security incidents I've seen in the last year. Not zero-days. Not novel attacks. Agents scanning the wrong directory and confidently reporting clean.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one server and not ten CLI wrappers
&lt;/h2&gt;

&lt;p&gt;I get the architectural question a lot: why does Cybrium ship one MCP server that exposes scanners, instead of three separate MCP servers wrapping &lt;code&gt;cyscan&lt;/code&gt;, &lt;code&gt;cyradar&lt;/code&gt;, and &lt;code&gt;cyweb&lt;/code&gt;? Why couple them?&lt;/p&gt;

&lt;p&gt;Because the findings need to talk to each other. A &lt;code&gt;cyscan&lt;/code&gt; SAST finding about an unsafe deserialization in an LLM-output handler is interesting on its own. It becomes urgent when &lt;code&gt;cyradar&lt;/code&gt; finds that the upstream inference endpoint accepts prompts from untrusted users. It becomes a P0 when &lt;code&gt;cyweb&lt;/code&gt; confirms that the HTTP route exposing that handler is reachable without auth. None of those tools, in isolation, can tell you you have a critical incident chain. The MCP server holds the cross-tool context that makes correlation possible.&lt;/p&gt;

&lt;p&gt;You could rebuild this on top of three separate MCP servers if you put a coordinator agent in front of them. People will try. I've tried. The coordinator agent has to know the semantics of findings from each scanner well enough to correlate them, which means baking scanner-specific knowledge into the agent's prompts, which means every scanner version bump becomes a prompt-engineering exercise. We did this. It was bad. Centralizing the correlation in the MCP server itself — where it can be versioned, tested, and updated alongside the scanners — is the better factoring.&lt;/p&gt;

&lt;p&gt;The same logic, by the way, is why I don't believe in "bring your own scanner" MCP servers as a long-term architecture. Generic shells over arbitrary security tools sound great in a slide deck. In practice, the semantic gap between tools is where all the value lives, and a generic shell can't bridge it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The recomposition
&lt;/h2&gt;

&lt;p&gt;What's actually happening across the security tooling industry right now is a quiet recomposition. For fifteen years, the unit of integration was the CLI. You wrote a scanner that emitted SARIF or some custom JSON, and CI systems plumbed it together with bash. That worked when the orchestrator was a human writing YAML.&lt;/p&gt;

&lt;p&gt;The orchestrator now is an agent. The agent doesn't write YAML. The agent makes decisions turn-by-turn based on what it just saw. The unit of integration for that world is not CLI output. It's a typed protocol that lets the agent reason about tools the same way a human reasons about a library. MCP is the first credible attempt at that protocol, and the products that win the next five years of security tooling will be the ones that ship native MCP surfaces, not the ones that bolt an MCP wrapper around their existing CLI as an afterthought.&lt;/p&gt;

&lt;p&gt;The reason this is recomposition and not just integration is that once you have MCP-native tooling, the right unit of work changes. You stop thinking about "the scan" as a CI step and start thinking about "the security question" as an agent conversation. What did this PR change that touches PII? Did any of those changes introduce new attack surface that wasn't there yesterday? Are the inference endpoints we just deployed exposed to the same prompt injection that bit us last quarter? Those questions don't have YAML-shaped answers. They have agent-shaped answers, and they need tools the agent can actually drive.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do tomorrow if I were you
&lt;/h2&gt;

&lt;p&gt;If you're using Claude Code or any agentic dev tool with shell access to security scanners right now, I'd do two things this week. Try our MCP server end-to-end on a real repo. The setup is one config block in your MCP client. Compare the findings count against whatever you're getting via shell. I would bet money you find a delta, and I'd bet that delta is in the direction of "MCP found things shell missed because shell was scanning the wrong scope."&lt;/p&gt;

&lt;p&gt;The second thing: audit one of your agent conversations from last week. Pick a security-related one. Read the transcript. Count the number of places the agent made an assumption about shell state that it had no way to verify. Then ask yourself how many of those assumptions would still be assumptions if the tool had a typed schema.&lt;/p&gt;

&lt;p&gt;You can pull the MCP server from &lt;code&gt;cybrium.ai/mcp&lt;/code&gt;. The ten tools are documented there. Source for &lt;code&gt;cyscan&lt;/code&gt;, &lt;code&gt;cyradar&lt;/code&gt;, and &lt;code&gt;cyweb&lt;/code&gt; lives in the same place. If you want to talk through your setup — especially if you're running local inference at scale and worrying about what your agents are actually seeing when they scan it — find me at &lt;code&gt;anand@cybrium.ai&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devsecops</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Four Pillars, One Platform: How Cybrium Unifies Code, Cloud, AI, and GRC</title>
      <dc:creator>Grumpy Sage</dc:creator>
      <pubDate>Mon, 11 May 2026 04:05:22 +0000</pubDate>
      <link>https://dev.to/grumpysage/four-pillars-one-platform-how-cybrium-unifies-code-cloud-ai-and-grc-jff</link>
      <guid>https://dev.to/grumpysage/four-pillars-one-platform-how-cybrium-unifies-code-cloud-ai-and-grc-jff</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31vdp0w0pjq4vrlerzly.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F31vdp0w0pjq4vrlerzly.png" alt="Cybrium — four pillars, one platform: Code, Cloud, AI, GRC" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A friend of mine runs security at a 200-engineer SaaS company. Last winter she got paged at 2 a.m. for an exposed S3 bucket. Customer PII. The bucket had been flagged by their cloud scanner three weeks earlier. The ticket sat in a Jira board owned by the platform team, who had been waiting on an IAM change from the cloud team, who needed sign-off from compliance, who were busy preparing for their SOC 2 audit. By the time the breach was contained, the marketing email had already gone out announcing their new Series B.&lt;/p&gt;

&lt;p&gt;She told me later that the part that haunted her was not the breach. It was that the finding had existed. The scanner had done its job. The system around the scanner had not.&lt;/p&gt;

&lt;p&gt;I keep coming back to that story because it explains almost every modern breach I have seen. The signal exists. The fix is known. The owners are identifiable. But the four pieces of the puzzle — code, cloud, AI, and governance — live in four separate tools owned by four separate teams, each pretending the others do not exist. The breach is the gap between them.&lt;/p&gt;

&lt;p&gt;This is the case I want to make: those four pieces should be one product. Not four products that talk to each other through APIs. One product, one asset graph, one workflow. I am going to use &lt;a href="https://cybrium.ai" rel="noopener noreferrer"&gt;Cybrium&lt;/a&gt; as the worked example because it is what my team builds, but the architectural argument generalises.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the four pillars actually are
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funlooxdc27es0bny31hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Funlooxdc27es0bny31hr.png" alt="Cybrium covers all four security pillars: Code, Cloud, AI, GRC" width="800" height="420"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I keep these labels short because everyone in security uses them but rarely defines them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code&lt;/strong&gt; is everything that happens before a deploy. SAST, SCA, secrets in repos, infrastructure-as-code, container images, Kubernetes manifests. The unit of work is a pull request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Cloud&lt;/strong&gt; is everything that happens after the deploy. Posture in AWS / Azure / GCP, identity, drift, runtime config. The unit of work is a resource.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI&lt;/strong&gt; is the new pillar that nobody had three years ago. Who is running what model, where, with what data, calling which tools, exposed how. The unit of work is an asset that did not exist in the old asset taxonomy.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GRC&lt;/strong&gt; is the layer that turns all of the above into auditable evidence. Frameworks, controls, risk register, trust center. The unit of work is a control.&lt;/p&gt;

&lt;p&gt;Now look at the market. Snyk does code very well and reaches into cloud weakly. Wiz does cloud very well and barely touches code. The AI security startups each take one slice — runtime guardrails, prompt injection scanning, model inventory — and assume someone else is doing the other three pillars. Vanta and Drata collect evidence from everything and generate nothing.&lt;/p&gt;

&lt;p&gt;This is a feature map, not a strategy. The customer pays for four tools and assumes glue code will make them coherent. It does not. It never does.&lt;/p&gt;




&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;I will start with code because it is the best-understood pillar and that makes the gap between best-in-class and standard practice the most visible.&lt;/p&gt;

&lt;p&gt;Most SAST tools produce a number that I think of as the friendship-ending number. The CI pipeline says "we found 10,000 issues in your repo this morning," and the developer either ignores it forever or quits Slack. Neither is the response you want.&lt;/p&gt;

&lt;p&gt;The fix is reachability. A CVE in a transitive dependency only matters if your code actually reaches it at runtime. Most don't. If you can rank findings by whether a real call path touches them, the friendship-ending 10,000 collapses to something like 12. Twelve is a number a human can act on.&lt;/p&gt;

&lt;p&gt;In Cybrium the code engine is a Rust binary called &lt;code&gt;cyscan&lt;/code&gt;. It runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SAST across 75-plus languages with 1,815 hand-curated rules&lt;/li&gt;
&lt;li&gt;SCA with reachability — only CVEs your code can actually reach&lt;/li&gt;
&lt;li&gt;Secrets detection (entropy + format + context)&lt;/li&gt;
&lt;li&gt;IaC: Terraform, CloudFormation, Bicep, Pulumi, plus Kubernetes manifests&lt;/li&gt;
&lt;li&gt;Span-based autofix, so the scanner does not just point at the problem; it produces a code edit you can apply or open as a PR&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can run it locally without ever signing up for anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;cybrium-ai/cli/cyscan
cyscan &lt;span class="nb"&gt;.&lt;/span&gt;
cyscan supply &lt;span class="nb"&gt;.&lt;/span&gt;                   &lt;span class="c"&gt;# SCA with reachability&lt;/span&gt;
cyscan fix &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--apply&lt;/span&gt;              &lt;span class="c"&gt;# write the autofixes&lt;/span&gt;
cyscan &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt; sarif &lt;span class="nt"&gt;--output&lt;/span&gt; cyscan.sarif
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SARIF output drops straight into GitHub Code Scanning or any CI that reads SARIF. For web apps where SAST is not enough, the companion binary is &lt;code&gt;cyweb&lt;/code&gt; — same Rust core, but DAST: spider, headless-Chrome AJAX spider, fuzzer, template engine, OAST callbacks for blind SSRF and RCE detection. It replaced ZAP/Nikto/Nuclei in our pipeline and the conversion rate on upstream templates is around 95 percent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Cloud
&lt;/h2&gt;

&lt;p&gt;Cloud is where the market is most fragmented because every cloud has its own posture-management API surface and most vendors specialise in one.&lt;/p&gt;

&lt;p&gt;We cover AWS, Azure, and GCP plus M365 and Active Directory under a single connector. The customer adds a cloud account once with a least-privilege read role, and the platform produces CSPM, ISPM (identity posture), ASPM (the wiring from repos to deployed services to cloud resources), container scanning via image-registry hooks, full Kubernetes scanning with the seven phases CIS calls out, and an M365 baseline that includes the DMARC/SPF/DKIM check from &lt;code&gt;cymail&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What makes a cloud security tool useful versus useful-looking is the fix. Cybrium generates a Terraform pull request for every cloud finding. Behind a feature gate, there is a direct-apply mode for low-blast-radius changes. The developer sees the same shape of work whether the finding came from code or cloud — a PR, a diff, a CI pipeline running. They do not have to context-switch into a separate UI to fix a cloud problem versus a code problem.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI
&lt;/h2&gt;

&lt;p&gt;This is the pillar I think most vendors are getting wrong, and the one that explains why I think the next two years in this market will be a recomposition.&lt;/p&gt;

&lt;p&gt;Almost every "AI security" company you can name right now sells a runtime gateway. A proxy between your developer and the model. That is one slice of one problem. It is the slice that demos well — you can stand in front of an audience and watch a prompt-injection attempt get blocked in real time. But it does not answer the question that actually keeps CISOs awake: "what AI is running in my company that I do not know about?"&lt;/p&gt;

&lt;p&gt;You cannot govern what you cannot see. Cybrium's AI inventory has five channels:&lt;/p&gt;

&lt;p&gt;The first is an &lt;strong&gt;active probe&lt;/strong&gt;. A Rust binary called &lt;code&gt;cyradar&lt;/code&gt; sweeps network ranges and identifies self-hosted inference servers: Ollama, vLLM, TGI, LocalAI, Triton, LM Studio, llama.cpp, OpenAI-compatible endpoints. It fingerprints each match against a YAML signature catalogue. We ship the catalogue versioned; new model servers are a config update, not a code release.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;cloud API&lt;/strong&gt;. We ingest Bedrock usage from AWS billing, Azure OpenAI from the Azure activity log, Vertex AI from GCP audit logs. Whatever model invocations are going through the sanctioned cloud accounts, we see.&lt;/p&gt;

&lt;p&gt;The third is &lt;strong&gt;endpoint&lt;/strong&gt;. A host-posture agent called &lt;code&gt;cydevice&lt;/code&gt; runs on machines outside MDM coverage and reports which AI CLIs are installed (&lt;code&gt;ollama&lt;/code&gt;, the OpenAI CLI, &lt;code&gt;claude&lt;/code&gt;), which IDE extensions are active (Copilot, Continue, Cline, Cursor's local model use), which desktop apps are running (LM Studio, Anything LLM), and which model files are on disk (GGUF, safetensors, ONNX). This is the channel that catches shadow AI on developer laptops.&lt;/p&gt;

&lt;p&gt;The fourth is &lt;strong&gt;traffic&lt;/strong&gt; inspection — passive observation of egress to flag cloud-API calls to AI providers that did not go through SSO.&lt;/p&gt;

&lt;p&gt;The fifth is &lt;strong&gt;SCM/SAST&lt;/strong&gt;. The &lt;code&gt;cyscan&lt;/code&gt; engine recognises imports of langchain, llama-index, transformers, the anthropic SDK, the openai SDK, and surfaces them as AI usage. If you have an LLM call in your code, we know about it from the repo before it ever hits production.&lt;/p&gt;

&lt;p&gt;All five channels write into the same &lt;code&gt;AIAsset&lt;/code&gt; row in the platform. The AI governance team can run a single query — "show me every AI surface in the company" — and get the union across channels. Policy then layers on top: no inference servers in &lt;code&gt;corp/&lt;/code&gt; subnet without TLS, no Bedrock model invocation without a &lt;code&gt;sanctioned&lt;/code&gt; tag, no production code path that takes LLM output and pipes it into a tool call without sanitisation.&lt;/p&gt;

&lt;p&gt;The prompt-injection point is worth dwelling on for a second. We do not have a separate scanner for it. The same &lt;code&gt;cyscan&lt;/code&gt; engine that does SAST recognises the patterns: unsanitised LLM output flowing into a tool-call argument, hidden-character-aware string handling, RAG ingestion that does not strip control characters from untrusted documents. The AI pillar is not a separate product. It is a set of new questions asked by engines we already had.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;cybrium-ai/cli/cyradar
cyradar discover &lt;span class="nt"&gt;--targets&lt;/span&gt; 10.0.0.0/24    &lt;span class="c"&gt;# find AI servers on the LAN&lt;/span&gt;
cyradar local-scan                         &lt;span class="c"&gt;# inventory local AI tooling&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For AI coding agents that should reach into the platform directly, we ship an MCP server — &lt;code&gt;@cybrium-ai/mcp-server&lt;/code&gt; on npm — with ten tools. Claude Desktop, Cursor, Windsurf, Cline can call any of them by name. I will come back to this in a minute.&lt;/p&gt;




&lt;h2&gt;
  
  
  GRC
&lt;/h2&gt;

&lt;p&gt;Most security platforms wave their hands here. The GRC team gets handed a CSV export and told to "make the audit work."&lt;/p&gt;

&lt;p&gt;A serious GRC implementation has three components that have to be wired into the other three pillars, not bolted on after.&lt;/p&gt;

&lt;p&gt;The first is &lt;strong&gt;framework mapping&lt;/strong&gt;. Every finding from code, cloud, and AI must map to a control in SOC 2, ISO 27001, HIPAA, PCI, EU AI Act, NIST AI RMF, and whatever industry-specific frameworks apply. Without this mapping, a finding is operational noise; with it, the same finding becomes audit evidence. We do the mapping at rule-authoring time — every &lt;code&gt;cyscan&lt;/code&gt; rule and every cloud check carries the relevant control IDs.&lt;/p&gt;

&lt;p&gt;The second is &lt;strong&gt;evidence collection&lt;/strong&gt;. When an auditor asks "show me that control CC6.1 is enforced," the answer cannot be a screenshot. It has to be a query that runs against the live asset graph and returns a count, a list, and a timestamped attestation. The compliance engine in the platform does this nightly, automatically, against the same asset graph the other pillars write into.&lt;/p&gt;

&lt;p&gt;The third is &lt;strong&gt;the Trust Center&lt;/strong&gt;. Your customers' procurement teams are asking the same security-questionnaire questions of every vendor. A Trust Center that exposes your controls publicly — with continuous, auto-collected evidence — cuts months off the sales cycle. Ours is at &lt;a href="https://trust.cybrium.ai" rel="noopener noreferrer"&gt;https://trust.cybrium.ai&lt;/a&gt; and updates from the same store as everything else.&lt;/p&gt;

&lt;p&gt;We also ship a vCISO module — engagements, risk register, policy library, treatment tracking — for teams that do not have a full-time CISO but need to look like they do for a Series B raise. The risk register is keyed on the same asset graph, so a risk row is always traceable to specific findings and specific controls. Not narrative text in a Word document.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why one platform, not four
&lt;/h2&gt;

&lt;p&gt;If the only argument for unification were "fewer dashboards," you could ignore it. The actual argument is structural, and it lives in three properties that one asset graph makes possible.&lt;/p&gt;

&lt;p&gt;A finding in one pillar becomes an enforcement signal for another. A reachable CVE in code creates a deployment-gate policy in cloud. A new AI inference server discovered on the LAN auto-creates a risk row in the GRC register. An auditor's evidence query pulls from the live posture, not a copy of it from last Tuesday.&lt;/p&gt;

&lt;p&gt;A fix in one pillar resolves the corresponding finding in the others. Close an IAM mis-scoping in cloud, the related SOC 2 finding in GRC closes automatically. The compliance team stops chasing the cloud team for evidence.&lt;/p&gt;

&lt;p&gt;Coverage gaps become visible. "What is not covered" becomes a query. Three repos have full code coverage, twelve have partial. Two clouds are scanned, one is not. The AI inventory has four channels but the fifth is unconfigured. You can see the holes before someone else finds them.&lt;/p&gt;

&lt;p&gt;These three properties cannot be retrofitted by integration. Every API integration between four point tools is a translation layer that loses data and a workflow boundary that delays the response. The only architecturally clean approach is to start with one asset graph and build outward from there.&lt;/p&gt;




&lt;h2&gt;
  
  
  The new buyer is an AI agent
&lt;/h2&gt;

&lt;p&gt;There is one more reason this matters now that I want to end on, because I think most security vendors have not internalised it yet.&lt;/p&gt;

&lt;p&gt;A year ago, when a developer needed a security tool, they searched Stack Overflow, asked a colleague, or read a blog post. Today, increasingly, the developer asks Claude or Cursor. The agent reads the project state, parses the question, and picks a tool. The agent does not see ads. It does not have a procurement team. It reads documentation.&lt;/p&gt;

&lt;p&gt;This is going to recompose the market. The vendors who ship coherent, AI-agent-readable tooling — with intent-mapped documentation, clean MCP integrations, READMEs that describe when to use the tool versus when to use something else — will absorb workloads that used to be spread across a long tail of point tools. The vendors who write press releases about "AI-powered security" and hope the AI does not look too closely will lose their seat at the table.&lt;/p&gt;

&lt;p&gt;We have made our bet on the first model. The CLIs are open source and Apache-2.0. The MCP server is published on npm. The VS Code extension is on the Marketplace (&lt;code&gt;cybrium-ai.cybrium&lt;/code&gt;). Every public repo has an &lt;code&gt;AGENTS.md&lt;/code&gt; that tells an AI coding agent when to invoke which tool. The website has an &lt;code&gt;llms.txt&lt;/code&gt; at the root that explains the same thing to any agent fetching the domain for the first time. The OpenAPI schema is public. The Trust Center is public.&lt;/p&gt;

&lt;p&gt;If you are building anything that touches code, cloud, AI, or compliance, you can start with the pieces you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Code: &lt;a href="https://github.com/cybrium-ai/cyscan" rel="noopener noreferrer"&gt;https://github.com/cybrium-ai/cyscan&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Cloud: &lt;a href="https://app.cybrium.ai" rel="noopener noreferrer"&gt;https://app.cybrium.ai&lt;/a&gt; (14-day trial)&lt;/li&gt;
&lt;li&gt;AI inventory: &lt;a href="https://github.com/cybrium-ai/cyradar" rel="noopener noreferrer"&gt;https://github.com/cybrium-ai/cyradar&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;MCP for agents: &lt;code&gt;npm install -g @cybrium-ai/mcp-server&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Trust Center: &lt;a href="https://trust.cybrium.ai" rel="noopener noreferrer"&gt;https://trust.cybrium.ai&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Docs: &lt;a href="https://docs.cybrium.ai" rel="noopener noreferrer"&gt;https://docs.cybrium.ai&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The four pillars are not optional anymore. The breach my friend stayed up for came from a gap between them. The question for every security team this year is whether they want one platform that closes those gaps or four that hold them open.&lt;/p&gt;

&lt;p&gt;We have made our choice. If you want to talk through yours, find me at &lt;code&gt;hello@cybrium.ai&lt;/code&gt;.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devsecops</category>
      <category>governance</category>
    </item>
  </channel>
</rss>
