<?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: Varun Poojari</title>
    <description>The latest articles on DEV Community by Varun Poojari (@varun_poojari).</description>
    <link>https://dev.to/varun_poojari</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4159640%2F962b1dd5-dc1d-42e0-b297-1b72a9225c39.jpg</url>
      <title>DEV Community: Varun Poojari</title>
      <link>https://dev.to/varun_poojari</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/varun_poojari"/>
    <language>en</language>
    <item>
      <title>What does an AI security review actually cost? I measured it per run</title>
      <dc:creator>Varun Poojari</dc:creator>
      <pubDate>Sat, 03 Oct 2026 11:37:16 +0000</pubDate>
      <link>https://dev.to/varun_poojari/what-does-an-ai-security-review-actually-cost-i-measured-it-per-run-4f2n</link>
      <guid>https://dev.to/varun_poojari/what-does-an-ai-security-review-actually-cost-i-measured-it-per-run-4f2n</guid>
      <description>&lt;p&gt;Everyone asks whether AI agents can find security bugs. Fewer people ask the question a team lead asks five minutes later: &lt;strong&gt;what does it cost each time we run it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'm an intern at RakFort in Dublin, and for the last few weeks my job has been testing the cost tracking in &lt;a href="https://github.com/secfoo-com/secfoo" rel="noopener noreferrer"&gt;secfoo&lt;/a&gt;, an open-source (MIT) CLI that gives AI coding agents a fixed security brief and a fixed report format. This post is what I found, including the parts that are not finished.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with "just ask the agent"
&lt;/h2&gt;

&lt;p&gt;You can point Claude Code, Cursor or Codex at a repo and ask for a security review. You will get something useful. You will not get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the same structure twice, so you cannot compare runs&lt;/li&gt;
&lt;li&gt;a record of what the run cost&lt;/li&gt;
&lt;li&gt;a way to stop a CI job that is burning money&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;secfoo handles the first with what it calls skills (structured briefs such as &lt;code&gt;sast&lt;/code&gt;, &lt;code&gt;threat-modeling&lt;/code&gt; and &lt;code&gt;secret-scanning&lt;/code&gt;). The second and third are what I tested.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;I used a deliberately small target: a 30-line Flask app with one SQL injection, where &lt;code&gt;get_user()&lt;/code&gt; builds its query by joining strings. Small on purpose, so I could check the report by hand.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="s2"&gt;"secfoo[api]"&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;...
secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; sast &lt;span class="nt"&gt;--agent&lt;/span&gt; api &lt;span class="nt"&gt;--target&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--project-name&lt;/span&gt; demo &lt;span class="nt"&gt;--app-id&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;api&lt;/code&gt; agent calls a model API directly, so you do not need an agent CLI installed. The last two flags skip the interactive prompts, which matters in scripts.&lt;/p&gt;

&lt;p&gt;Here is the real output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ secfoo run --skill sast --agent api --target . --project-name demo --app-id ""
  success — SAST — Static Code Analysis
                                              Assessment results
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━┳━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Skill                       ┃ Status  ┃ Duration ┃ Findings (C/H/M/L) ┃   Cost ┃ Run ID                               ┃
┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━╇━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
│ SAST — Static Code Analysis │ success │ 11.2s    │ 0/1/0/0            │ &amp;lt;$0.01 │ 888f222e-7228-4b2b-b306-78db7a17d499 │
└─────────────────────────────┴─────────┴──────────┴────────────────────┴────────┴──────────────────────────────────────┘
AI spend for this run: &amp;lt;$0.01
Run secfoo serve to view full reports in your browser.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What one run cost
&lt;/h2&gt;

&lt;p&gt;The scan finished in &lt;strong&gt;11.2 seconds&lt;/strong&gt; and reported &lt;strong&gt;one finding: the SQL injection in &lt;code&gt;get_user()&lt;/code&gt;&lt;/strong&gt;, which is the right answer for this app.&lt;/p&gt;

&lt;p&gt;It used &lt;strong&gt;2,183 input tokens and 981 output tokens&lt;/strong&gt;, 3,164 in total. secfoo printed the spend for the run as &lt;strong&gt;under one cent&lt;/strong&gt;. It shows &lt;code&gt;&amp;lt;$0.01&lt;/code&gt; rather than rounding down to zero, which I liked: a zero would suggest the run was free.&lt;/p&gt;

&lt;p&gt;In my earlier testing, a repeat scan of an unchanged repo used exactly the same input tokens. That is expected today: nothing is cached between runs yet, so the second scan costs the same as the first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Same kind of target, different agent
&lt;/h2&gt;

&lt;p&gt;Earlier I ran a similar small app through Codex instead of the &lt;code&gt;api&lt;/code&gt; agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; sast &lt;span class="nt"&gt;--agent&lt;/span&gt; codex &lt;span class="nt"&gt;--target&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;--project-name&lt;/span&gt; demo &lt;span class="nt"&gt;--app-id&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It finished in 27.5 seconds and also found the injection. Two things were different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost shows as &lt;code&gt;-&lt;/code&gt;, not &lt;code&gt;$0.00&lt;/code&gt;.&lt;/strong&gt; Codex runs on a subscription login, so there is no per-run price to record. A dash is the right answer. A zero would be a lie.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tokens were much higher.&lt;/strong&gt; Codex's own log reported 15,201 tokens for the run, roughly five times the &lt;code&gt;api&lt;/code&gt; agent, because an agent CLI explores the repo with tools instead of receiving one prepared prompt.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That second point is the most useful thing I learned. The agent you pick can change the token count by a multiple, on a small target, for the same finding.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seeing spend across runs
&lt;/h2&gt;

&lt;p&gt;Per-run numbers are nice. The summary is what a team would actually use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secfoo cost
secfoo cost &lt;span class="nt"&gt;--by&lt;/span&gt; skill &lt;span class="nt"&gt;--since&lt;/span&gt; 2026-09-01
secfoo cost &lt;span class="nt"&gt;--by&lt;/span&gt; agent &lt;span class="nt"&gt;--project&lt;/span&gt; demo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can group by agent, skill or project. The same numbers appear in the local dashboard (&lt;code&gt;secfoo serve&lt;/code&gt;), and in my tests the dashboard total matched the CLI total for the same runs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ secfoo cost --by agent --project demo
                   AI spend by agent
┏━━━━━━━┳━━━━━━┳━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┳━━━━━━━━┓
┃ Agent ┃ Runs ┃ Input tokens ┃ Output tokens ┃   Cost ┃
┡━━━━━━━╇━━━━━━╇━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━╇━━━━━━━━┩
│ api   │    2 │        2,183 │           981 │ &amp;lt;$0.01 │
├───────┼──────┼──────────────┼───────────────┼────────┤
│ Total │    2 │        2,183 │           981 │ &amp;lt;$0.01 │
└───────┴──────┴──────────────┴───────────────┴────────┘
1 run(s) have no cost recorded -- their agent doesn't report it (cursor, agy), or they ran before cost tracking existed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That table shows two runs, not one. My first attempt failed because I pasted my API key with a character missing. secfoo still counted it as a run and told me that one run had no cost recorded. I did not plan that, but it is a fair picture of how it behaves when something goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Making cost a CI gate
&lt;/h2&gt;

&lt;p&gt;This is the part I think matters most for real pipelines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; sast &lt;span class="nt"&gt;--agent&lt;/span&gt; api &lt;span class="nt"&gt;--target&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fail-on&lt;/span&gt; high &lt;span class="nt"&gt;--max-cost&lt;/span&gt; 2.00 &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; secfoo-result.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exit code tells CI what happened: &lt;code&gt;0&lt;/code&gt; means the run succeeded and no gate tripped, &lt;code&gt;1&lt;/code&gt; means a run failed or timed out, and &lt;code&gt;2&lt;/code&gt; means the run succeeded but a finding or the cost crossed your threshold. A security scan that can fail a build for being too expensive is not something I had seen before.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is not there yet
&lt;/h2&gt;

&lt;p&gt;I was testing, so I was looking for gaps. The honest list:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cost coverage depends on the agent.&lt;/strong&gt; API-key runs give you tokens and cost. Subscription-based agent CLIs often give you neither, and you see a dash.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex tokens are not recorded yet.&lt;/strong&gt; Codex prints its total, but secfoo does not pick it up today. There is an open item for it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Failed runs are counted as runs.&lt;/strong&gt; They show up in the totals with no cost recorded, as my mistyped key showed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Severity can differ between the CLI and the dashboard.&lt;/strong&gt; In my run the CLI table counted the finding as High, and the dashboard labelled the same finding Critical. It is a known issue.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;--since&lt;/code&gt; compares against UTC.&lt;/strong&gt; If you run scans late at night in another timezone, the cut-off may not be where you expect.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No savings on repeat scans yet.&lt;/strong&gt; Reusing results for unchanged code is planned, not shipped.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I would tell a team
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Start with the &lt;code&gt;api&lt;/code&gt; agent on one repo, so you get real token and cost numbers from day one.&lt;/li&gt;
&lt;li&gt;Run the same repo through the agent your developers already use, and compare the reports side by side.&lt;/li&gt;
&lt;li&gt;Put &lt;code&gt;--max-cost&lt;/code&gt; in CI before you put the scan on every pull request.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;secfoo
secfoo run &lt;span class="nt"&gt;--skill&lt;/span&gt; sast &lt;span class="nt"&gt;--agent&lt;/span&gt; claude
secfoo serve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The repo is here: &lt;strong&gt;&lt;a href="https://github.com/secfoo-com/secfoo" rel="noopener noreferrer"&gt;https://github.com/secfoo-com/secfoo&lt;/a&gt;&lt;/strong&gt;. If it is useful to you, a star helps a small open-source project a lot, and issues telling us where the output is wrong help even more.&lt;/p&gt;

&lt;p&gt;We are also part of the team organising a secfoo hackathon in Dublin in mid-November. If you would like to take part, or to help as a moderator, leave a comment and I will get back to you.&lt;/p&gt;

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