<?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: jaryn</title>
    <description>The latest articles on DEV Community by jaryn (@jaryn_123).</description>
    <link>https://dev.to/jaryn_123</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%2F1829365%2F8b3cd045-5abe-43e5-a5ef-3a0bfe77a77f.png</url>
      <title>DEV Community: jaryn</title>
      <link>https://dev.to/jaryn_123</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jaryn_123"/>
    <language>en</language>
    <item>
      <title>Audit an AI Coding CLI Before It Uploads Your Home Directory</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Mon, 13 Jul 2026 14:15:59 +0000</pubDate>
      <link>https://dev.to/jaryn_123/audit-an-ai-coding-cli-before-it-uploads-your-home-directory-3aip</link>
      <guid>https://dev.to/jaryn_123/audit-an-ai-coding-cli-before-it-uploads-your-home-directory-3aip</guid>
      <description>&lt;p&gt;Reports that a coding CLI transmitted unexpectedly broad local data are trending today. A social post is a lead, not a verdict, so the useful response is a reproducible audit.&lt;/p&gt;

&lt;p&gt;Start with a disposable VM, a canary home directory, and a proxy you control. Put unique strings in &lt;code&gt;~/Documents/canary.txt&lt;/code&gt;, &lt;code&gt;.env.test&lt;/code&gt;, Git configuration, and a fake SSH filename. Never use real secrets.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/audit-home/Documents"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'CANARY_DOC_7f31\n'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/audit-home/Documents/canary.txt"&lt;/span&gt;
&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'FAKE_TOKEN=CANARY_ENV_b921\n'&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HOME&lt;/span&gt;&lt;span class="s2"&gt;/audit-home/.env.test"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the CLI with that directory as &lt;code&gt;HOME&lt;/code&gt;, deny access to the real home directory, and capture DNS, destination host, method, content type, byte count, and request timing. If TLS inspection is permitted in your environment, search decoded request bodies for the canaries. Otherwise compare encrypted byte volume while adding one fixture at a time.&lt;/p&gt;

&lt;p&gt;Use four tests: empty prompt, prompt referencing one file, explicit repository upload, and a prompt-injection file asking the agent to read another directory. Record the exact CLI version, configuration, consent screen, and network policy.&lt;/p&gt;

&lt;p&gt;The acceptance rule should be simple: every transmitted file must be attributable to an explicit user action or a documented minimal context rule. Block unknown destinations, require a preview for bulk transfer, and keep an append-only transfer manifest with paths hashed or redacted.&lt;/p&gt;

&lt;p&gt;MonkeyCode is an open-source coding platform where this same boundary matters for workspaces and model backends. I contribute to the project; this is a tool-independent test plan, not a claim about MonkeyCode or the reported CLI incident.&lt;/p&gt;

&lt;p&gt;Do not argue from packet size alone. Publish the fixture, version, capture method, observed destinations, and limitations so others can reproduce the result without exposing personal data.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>devtools</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Threat-Model an MCP Server as a Privileged API Gateway</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Mon, 13 Jul 2026 02:41:28 +0000</pubDate>
      <link>https://dev.to/jaryn_123/threat-model-an-mcp-server-as-a-privileged-api-gateway-1mmg</link>
      <guid>https://dev.to/jaryn_123/threat-model-an-mcp-server-as-a-privileged-api-gateway-1mmg</guid>
      <description>&lt;p&gt;An MCP server is often introduced as a convenient adapter between an assistant and an API. Security-wise, it is a privileged gateway accepting model-influenced requests.&lt;/p&gt;

&lt;p&gt;The important question is not whether a tool is called &lt;code&gt;read_dashboard&lt;/code&gt; or &lt;code&gt;fix_incident&lt;/code&gt;. It is which identities, resources, side effects, and networks the implementation can reach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Inventory authority per tool
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Read scope&lt;/th&gt;
&lt;th&gt;Write scope&lt;/th&gt;
&lt;th&gt;Credential&lt;/th&gt;
&lt;th&gt;Approval&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;get_metric&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;one tenant, named metric&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;read-only service token&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;create_ticket&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;incident summary&lt;/td&gt;
&lt;td&gt;ticket system&lt;/td&gt;
&lt;td&gt;create-only token&lt;/td&gt;
&lt;td&gt;preview&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;restart_service&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;service status&lt;/td&gt;
&lt;td&gt;one deployment&lt;/td&gt;
&lt;td&gt;short-lived workload token&lt;/td&gt;
&lt;td&gt;exact-call approval&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Do not give every tool the server process's full credential. Split read and write identities, scope them to a tenant and resource class, and mint short-lived tokens near execution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Treat arguments as untrusted
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Restart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;object&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;service&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enum&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;api&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;worker&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt;
  &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;literal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;staging&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;min&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;500&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;operationId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Strict schemas reject unexpected fields. Server-side authorization must still verify the caller, tenant, current resource state, and policy version. Never turn a model-provided URL, path, shell fragment, SQL clause, or header into raw authority.&lt;/p&gt;

&lt;p&gt;For consequential calls, show a preview generated from validated arguments. Bind approval to the user, tool name, canonical arguments, policy version, resource version, and expiry. If any changes, ask again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Log evidence, not secrets
&lt;/h2&gt;

&lt;p&gt;Record request ID, actor, tool, canonical argument hash, target resource, policy decision, credential identity, result class, and timing. Redact tokens, cookies, prompts containing credentials, and raw third-party responses. Make duplicate &lt;code&gt;operationId&lt;/code&gt; calls return the original result instead of repeating a side effect.&lt;/p&gt;

&lt;p&gt;Test prompt injection in tool output, cross-tenant IDs, unknown arguments, stale approval, duplicate delivery, timeout after a successful remote write, credential revocation, and log redaction.&lt;/p&gt;

&lt;p&gt;The public &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode repository&lt;/a&gt; describes model management, AI tasks, development environments, and private deployment. MCP-style integrations may be relevant to such platforms, but this article neither claims a current MonkeyCode MCP implementation nor reports a security test of one.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I contribute to the MonkeyCode project. Product context comes from public documentation; the threat model is tool-independent.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Naming a capability as a tool does not reduce its authority. Design the gateway as though untrusted input can reach every exposed schema—because eventually it will.&lt;/p&gt;

</description>
      <category>mcp</category>
      <category>security</category>
      <category>ai</category>
      <category>api</category>
    </item>
    <item>
      <title>Stop Mass Assignment Before It Reaches Your Authorization Layer</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Sun, 12 Jul 2026 15:12:09 +0000</pubDate>
      <link>https://dev.to/jaryn_123/stop-mass-assignment-before-it-reaches-your-authorization-layer-ial</link>
      <guid>https://dev.to/jaryn_123/stop-mass-assignment-before-it-reaches-your-authorization-layer-ial</guid>
      <description>&lt;p&gt;Mass assignment is what happens when an API treats the request body as the update policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;users&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That line is convenient until a client sends &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;accountId&lt;/code&gt;, &lt;code&gt;credit&lt;/code&gt;, or &lt;code&gt;emailVerified&lt;/code&gt;. Validation alone does not answer whether this caller may change a valid field. The safer design has three separate gates: accepted fields, valid values, and authorized transitions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build a mutation contract
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;MUTATIONS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;80&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;users:write&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;timezone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;supportedValuesOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeZone&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;buildPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;patch&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rejected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

  &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;MUTATIONS&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;authorize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;rejected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;field&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;normalize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rejected&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An allowlist makes new database columns non-writable by default. Per-field authorization prevents a broad “can edit user” check from granting authority over every property. Returning rejected field names to server-side telemetry makes probing visible; do not echo sensitive values.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test forbidden fields as invariants
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;assert&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node:assert/strict&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;u1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;u1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;member&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rejected&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildPatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; Ada &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;admin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;accountId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deepEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;patch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;displayName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ada&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;assert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deepEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rejected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;accountId&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also test duplicate JSON keys at the HTTP parser boundary, nested objects, &lt;code&gt;null&lt;/code&gt;, arrays, Unicode normalization, and races where authorization changes between read and write. Apply the database update with a condition on the version or authorization-relevant state; otherwise a correct pre-check can become stale.&lt;/p&gt;

&lt;p&gt;Log the actor, target, accepted field names, rejected field names, policy version, and result. Never log bearer tokens or entire request bodies.&lt;/p&gt;

&lt;p&gt;The public &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode repository&lt;/a&gt; describes project requirements, task management, team collaboration, and private deployment. Any platform that accepts structured updates for tasks, projects, or permissions benefits from explicit mutation contracts. This example is independent and does not claim a MonkeyCode vulnerability or describe its internal API.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I contribute to the MonkeyCode project. The product context comes from its public repository; no security test of MonkeyCode is reported here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The important boundary is simple: a request body proposes data. It never defines its own authority.&lt;/p&gt;

</description>
      <category>security</category>
      <category>api</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Use SQLite STRICT Tables for Agent Control Data</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Sun, 12 Jul 2026 08:07:08 +0000</pubDate>
      <link>https://dev.to/jaryn_123/use-sqlite-strict-tables-for-agent-control-data-46gg</link>
      <guid>https://dev.to/jaryn_123/use-sqlite-strict-tables-for-agent-control-data-46gg</guid>
      <description>&lt;p&gt;An AI coding workflow may generate probabilistic output, but its authority should not be probabilistic. Task state, approval scope, repository identity, and policy version are control data. If one of those values is malformed, silently coercing it is a dangerous default.&lt;/p&gt;

&lt;p&gt;This is why the current discussion around SQLite strict tables is relevant to agent systems. At &lt;strong&gt;2026-07-12 08:00 UTC&lt;/strong&gt;, Evan Hahn's article &lt;a href="https://evanhahn.com/prefer-strict-tables-in-sqlite/" rel="noopener noreferrer"&gt;“Prefer strict tables in SQLite”&lt;/a&gt; was the highest-scoring item in the Hacker News snapshot I reviewed, with 267 points. SQLite's own &lt;a href="https://sqlite.org/stricttables.html" rel="noopener noreferrer"&gt;STRICT tables documentation&lt;/a&gt; is the source of truth for the feature.&lt;/p&gt;

&lt;p&gt;The useful lesson is narrower than “make everything strict”: put strong boundaries around the small set of records that decide what an automated tool may do.&lt;/p&gt;

&lt;h2&gt;
  
  
  A control-data schema
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;agent_task&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;task_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;repo_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;requested_by&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'queued'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'running'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'awaiting_approval'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'succeeded'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'failed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'cancelled'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;policy_version&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;approved_commit&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;approval_expires_at&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;created_at&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;STRICT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;tool_grant&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;task_id&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;REFERENCES&lt;/span&gt; &lt;span class="n"&gt;agent_task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="n"&gt;tool&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;resource_pattern&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;effect&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;effect&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'allow'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'deny'&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="n"&gt;granted_by&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;expires_at&lt;/span&gt; &lt;span class="nb"&gt;INTEGER&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;PRIMARY&lt;/span&gt; &lt;span class="k"&gt;KEY&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;resource_pattern&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;STRICT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;STRICT&lt;/code&gt; does not create a complete authorization system. It does make invalid storage less ambiguous: values must be compatible with the declared types, and SQLite reports a constraint error rather than accepting arbitrary type substitutions. &lt;code&gt;CHECK&lt;/code&gt; constraints still carry the domain rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  Validate the decision, not only the row
&lt;/h2&gt;

&lt;p&gt;Before a worker changes a repository, the application should evaluate all of these inputs together:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;th&gt;Reject when&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Is this the intended repository?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;repo_id&lt;/code&gt; does not match the checked-out remote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the approval current?&lt;/td&gt;
&lt;td&gt;expiry is in the past or absent for a privileged tool&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the code revision pinned?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;approved_commit&lt;/code&gt; differs from the worker's base commit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the policy reproducible?&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;policy_version&lt;/code&gt; cannot be loaded&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Is the transition legal?&lt;/td&gt;
&lt;td&gt;current and requested states are not an allowed edge&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A defensive transition can be one conditional statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;agent_task&lt;/span&gt;
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'running'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;updated_at&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;unixepoch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;task_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;task_id&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;state&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'queued'&lt;/span&gt;
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;policy_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="n"&gt;loaded_policy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The worker proceeds only when exactly one row changed. That turns a race or stale assumption into a visible failure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Threat model and limits
&lt;/h2&gt;

&lt;p&gt;This boundary helps with accidental type coercion, illegal states, stale approvals, and concurrent transitions. It does not stop a process that can rewrite the database file, bypass the application, steal signing credentials, or alter the policy loader. File permissions, process isolation, append-only audit export, backups, and independent review remain separate controls.&lt;/p&gt;

&lt;p&gt;Run &lt;code&gt;PRAGMA integrity_check;&lt;/code&gt; as part of recovery testing, but do not confuse integrity with authorization. A structurally valid database can still contain a maliciously granted permission.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where MonkeyCode fits
&lt;/h2&gt;

&lt;p&gt;The public &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode repository&lt;/a&gt; describes an open-source AI coding platform with AI task, development-environment, model, and project-requirement management, plus private deployment. That makes control-data boundaries relevant when evaluating a deployment. The schema above is an independent review pattern; it is not a claim about MonkeyCode's internal database design.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I contribute to the MonkeyCode project. The observations and limitations below are based on the linked repository and the test setup described in this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are evaluating the platform, ask the team in the &lt;a href="https://discord.gg/2pPmuyr4pP" rel="noopener noreferrer"&gt;MonkeyCode Discord&lt;/a&gt; how task state, approvals, and policy versions are represented in the version you plan to run. You can also ask whether free model credits are currently available and confirm eligibility and usage limits.&lt;/p&gt;

&lt;p&gt;The practical rule is simple: model output can remain flexible; the records that grant authority should fail closed.&lt;/p&gt;

</description>
      <category>sqlite</category>
      <category>security</category>
      <category>ai</category>
      <category>database</category>
    </item>
    <item>
      <title>Threat-Modeling MonkeyCode as a Self-Hosted AI Coding Platform</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Fri, 10 Jul 2026 10:06:35 +0000</pubDate>
      <link>https://dev.to/jaryn_123/threat-modeling-monkeycode-as-a-self-hosted-ai-coding-platform-kap</link>
      <guid>https://dev.to/jaryn_123/threat-modeling-monkeycode-as-a-self-hosted-ai-coding-platform-kap</guid>
      <description>&lt;p&gt;Self-hosting changes who operates an AI coding platform. It does not make the platform trusted by default.&lt;/p&gt;

&lt;p&gt;An AI development task can combine repository content, model output, shell commands, credentials, package registries, preview servers, and human approval. That is a much larger authority surface than a chat box. The useful security question is not “is it open source?” It is “which input can cause which side effect across which trust boundary?”&lt;/p&gt;

&lt;p&gt;This article uses &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode&lt;/a&gt; as a worked example because its public README describes private deployment, managed development environments, model management, AI task management, and project requirements. I reviewed the repository documentation at commit &lt;a href="https://github.com/chaitin/MonkeyCode/tree/1ac778fdba1da1b353f7f5672d2e4550801cf46d" rel="noopener noreferrer"&gt;&lt;code&gt;1ac778f&lt;/code&gt;&lt;/a&gt;. This is a design review, not a penetration test or a claim about a deployed instance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with authority, not components
&lt;/h2&gt;

&lt;p&gt;A component diagram often says where services run. A threat model must also say what they can do.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;developer browser
      |
      | identity, task text, approvals
      v
control plane ---------&amp;gt; model endpoint
      |                       ^
      | task + policy         | prompt / response
      v                       |
workspace runner ------------+
      |
      +--&amp;gt; repository credentials
      +--&amp;gt; package registries
      +--&amp;gt; build tools and shell
      +--&amp;gt; preview endpoint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact MonkeyCode implementation may divide these responsibilities differently. The diagram is an explicit review model inferred from the capabilities in the README. Replace it with the real topology before using the checklist for an approval decision.&lt;/p&gt;

&lt;p&gt;For every arrow, record four fields:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Question&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Principal&lt;/td&gt;
&lt;td&gt;Which human or service initiated the action?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Input&lt;/td&gt;
&lt;td&gt;Is the data trusted, untrusted, or generated?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authority&lt;/td&gt;
&lt;td&gt;Can the receiver read files, run commands, reach a network, or change a repository?&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Evidence&lt;/td&gt;
&lt;td&gt;Which log proves the decision and result?&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This catches a common modeling mistake: treating model output as data while quietly giving the consumer permission to execute it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five abuse cases to model first
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Repository content becomes instructions
&lt;/h3&gt;

&lt;p&gt;A README, issue, test fixture, or dependency can contain text that attempts to redirect an agent. The control is not a better system prompt. Keep authorization in deterministic policy: permitted tools, path scopes, command classes, network destinations, and approval gates.&lt;/p&gt;

&lt;p&gt;Test property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Untrusted repository text cannot expand the task's original authority.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. A workspace exposes a credential
&lt;/h3&gt;

&lt;p&gt;Credentials may enter through Git remotes, environment variables, package-manager configuration, cloud metadata, or copied logs. Prefer short-lived task credentials and mount only the secret needed for the current operation. Redaction is a backup control, not the primary boundary.&lt;/p&gt;

&lt;p&gt;Test property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;A task that prints its environment cannot recover another task's secrets.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. One task reaches another workspace
&lt;/h3&gt;

&lt;p&gt;For a team platform, process separation is not automatically tenant separation. Review filesystem namespaces, container privileges, shared caches, Docker sockets, host mounts, preview routing, and cleanup after cancellation.&lt;/p&gt;

&lt;p&gt;Test property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Knowing another task ID or path does not grant read, write, signal, or preview access.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Dependency installation becomes unrestricted egress
&lt;/h3&gt;

&lt;p&gt;Builds legitimately contact registries, but unrestricted outbound access also creates an exfiltration path. Define whether a workspace can reach the public internet, internal services, cloud metadata, and arbitrary model endpoints. Log denied destinations without logging secret-bearing URLs.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Generated code crosses into a trusted branch
&lt;/h3&gt;

&lt;p&gt;The last boundary is often Git, not the model. Protect the default branch with human review, required tests, scoped repository tokens, signed provenance where appropriate, and a patch-size or sensitive-path gate.&lt;/p&gt;

&lt;h2&gt;
  
  
  A control matrix that can fail closed
&lt;/h2&gt;

&lt;p&gt;Use a matrix like this during deployment review:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Boundary&lt;/th&gt;
&lt;th&gt;Prevent&lt;/th&gt;
&lt;th&gt;Detect&lt;/th&gt;
&lt;th&gt;Recover&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Browser → control plane&lt;/td&gt;
&lt;td&gt;SSO, MFA, role checks, CSRF protection&lt;/td&gt;
&lt;td&gt;auth and admin audit log&lt;/td&gt;
&lt;td&gt;revoke sessions and tokens&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Control plane → runner&lt;/td&gt;
&lt;td&gt;signed task identity, policy snapshot, least privilege&lt;/td&gt;
&lt;td&gt;immutable task/tool events&lt;/td&gt;
&lt;td&gt;cancel and quarantine workspace&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runner → repository&lt;/td&gt;
&lt;td&gt;short-lived scoped token, protected branches&lt;/td&gt;
&lt;td&gt;commit and push audit&lt;/td&gt;
&lt;td&gt;revoke token, revert patch&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runner → network&lt;/td&gt;
&lt;td&gt;destination policy, metadata block&lt;/td&gt;
&lt;td&gt;DNS/connection telemetry&lt;/td&gt;
&lt;td&gt;isolate runner, rotate exposed secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Task → task&lt;/td&gt;
&lt;td&gt;per-task identity and filesystem isolation&lt;/td&gt;
&lt;td&gt;cross-scope denial events&lt;/td&gt;
&lt;td&gt;destroy affected workers and caches&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runner → preview&lt;/td&gt;
&lt;td&gt;authenticated routing, safe headers, expiry&lt;/td&gt;
&lt;td&gt;access logs tied to task ID&lt;/td&gt;
&lt;td&gt;revoke route and terminate process&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;“Prevent, detect, recover” matters. A control list containing only prevention assumes the first layer never fails.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the review reproducible
&lt;/h2&gt;

&lt;p&gt;Pin the source revision and keep the evidence beside the decision:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/chaitin/MonkeyCode.git
&lt;span class="nb"&gt;cd &lt;/span&gt;MonkeyCode
git checkout 1ac778fdba1da1b353f7f5672d2e4550801cf46d

rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"privileged|docker.sock|hostNetwork|hostPath"&lt;/span&gt; &lt;span class="nb"&gt;.&lt;/span&gt;
rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"Authorization|token|secret|password"&lt;/span&gt; backend frontend
rg &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"exec|spawn|shell|command"&lt;/span&gt; backend
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These searches do not prove a vulnerability or prove safety. They create a repeatable starting set for manual tracing. For each relevant hit, document the call path, input origin, permission check, secret handling, emitted audit event, and failure behavior.&lt;/p&gt;

&lt;p&gt;Then run adversarial tests in a disposable environment:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;submit repository text that requests an unrelated command;&lt;/li&gt;
&lt;li&gt;attempt to read a sibling workspace and a host path;&lt;/li&gt;
&lt;li&gt;request cloud metadata and an unapproved network destination;&lt;/li&gt;
&lt;li&gt;print likely secret locations and inspect every log surface;&lt;/li&gt;
&lt;li&gt;cancel during clone, dependency install, build, and repository write;&lt;/li&gt;
&lt;li&gt;reuse expired task and repository credentials;&lt;/li&gt;
&lt;li&gt;request a preview URL from another authenticated user.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Record a version, topology, test identity, expected denial, actual result, and evidence location for every case. “Blocked” without a log or packet trace is not a result another reviewer can reproduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the public repository does and does not establish
&lt;/h2&gt;

&lt;p&gt;The official documentation supports that MonkeyCode is AGPL-3.0 open source and offers private deployment. That makes source review and operator control possible. It does not, by itself, establish isolation strength, a compliance outcome, or secure configuration for a particular deployment. Those conclusions require the actual topology, version, identity provider, secret flow, runner privileges, network policy, and adversarial test results.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Disclosure: I contribute to the MonkeyCode project. This threat model is based on the linked public repository and documentation, not an independent security audit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you are evaluating a self-hosted setup, join the &lt;a href="https://discord.gg/2pPmuyr4pP" rel="noopener noreferrer"&gt;MonkeyCode Discord&lt;/a&gt; to discuss the deployment model with the team. You can also ask there about currently available free model credits; confirm eligibility and usage limits before planning around them.&lt;/p&gt;

&lt;p&gt;The safest output of a threat model is not a “secure” label. It is a short list of authority claims that can be denied, observed, and retested after every meaningful deployment change.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>opensource</category>
      <category>devops</category>
    </item>
    <item>
      <title>Threat-Modeling an LLM Feature Before It Reaches Production</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Fri, 10 Jul 2026 07:11:43 +0000</pubDate>
      <link>https://dev.to/jaryn_123/what-is-a-large-language-model-a-no-hype-technical-guide-for-developers-12p2</link>
      <guid>https://dev.to/jaryn_123/what-is-a-large-language-model-a-no-hype-technical-guide-for-developers-12p2</guid>
      <description>&lt;p&gt;Adding an LLM to an application creates a new interpreter for untrusted text. That interpreter may also retrieve private data, call tools, or write to other systems. The useful security question is therefore not “Is the model safe?” but “What can data flowing through the model cause the application to do?”&lt;/p&gt;

&lt;p&gt;Here is a compact threat-modeling method for answering that question before launch.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with assets, not prompts
&lt;/h2&gt;

&lt;p&gt;List what the feature must protect. For a support assistant, the list might include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;customer messages and attachments;&lt;/li&gt;
&lt;li&gt;retrieved account records;&lt;/li&gt;
&lt;li&gt;system instructions and internal policies;&lt;/li&gt;
&lt;li&gt;tool credentials;&lt;/li&gt;
&lt;li&gt;actions such as refunds, password resets, and ticket updates;&lt;/li&gt;
&lt;li&gt;logs, traces, and evaluation datasets.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This prevents a common modeling mistake: treating prompt injection as the whole problem. Injection is one path. The asset and the reachable action determine its impact.&lt;/p&gt;

&lt;h2&gt;
  
  
  Draw the trust boundaries
&lt;/h2&gt;

&lt;p&gt;A minimal LLM feature often has more boundaries than its UI suggests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;user input
   |
   v
application API ---&amp;gt; model provider
   |                     |
   v                     v
retrieval index       generated text
   |
   v
tool executor ---&amp;gt; business systems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mark every place where data changes authority or ownership. User text is untrusted. Retrieved documents may also be untrusted if users can upload or edit them. Model output is untrusted even when the application supplied a careful system prompt. A tool response can contain hostile instructions too.&lt;/p&gt;

&lt;p&gt;That last point matters in retrieval-augmented systems: a document is data to the application, but the model may interpret it as an instruction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Write abuse cases as data flows
&lt;/h2&gt;

&lt;p&gt;Use concrete “input → interpretation → effect” statements. For example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Input path&lt;/th&gt;
&lt;th&gt;Unsafe interpretation&lt;/th&gt;
&lt;th&gt;Possible effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Uploaded PDF&lt;/td&gt;
&lt;td&gt;Text overrides the system instruction&lt;/td&gt;
&lt;td&gt;Private retrieval results appear in output&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tool argument&lt;/td&gt;
&lt;td&gt;Generated account ID is accepted as authoritative&lt;/td&gt;
&lt;td&gt;One user acts on another user’s record&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Model response&lt;/td&gt;
&lt;td&gt;Markdown link is rendered without checks&lt;/td&gt;
&lt;td&gt;Phishing or unsafe navigation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trace pipeline&lt;/td&gt;
&lt;td&gt;Full prompts are retained by default&lt;/td&gt;
&lt;td&gt;Secrets persist in logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This format is easier to turn into controls and tests than a label such as “prompt injection risk.”&lt;/p&gt;

&lt;h2&gt;
  
  
  Put authorization outside the model
&lt;/h2&gt;

&lt;p&gt;The model may propose an action; application code must decide whether it is allowed.&lt;/p&gt;

&lt;p&gt;For every tool, define:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;a narrow input schema;&lt;/li&gt;
&lt;li&gt;server-side identity and permission checks;&lt;/li&gt;
&lt;li&gt;limits on scope, amount, and frequency;&lt;/li&gt;
&lt;li&gt;a confirmation step for consequential actions;&lt;/li&gt;
&lt;li&gt;an audit record that does not expose unnecessary prompt data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do not let the model select a user identity, tenant, or authorization scope from free text. Derive those values from the authenticated session. A refund tool, for example, should receive an order ID but obtain the customer and maximum refundable amount from trusted backend state.&lt;/p&gt;

&lt;p&gt;“The system prompt says not to” is not an authorization control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Separate content from instructions
&lt;/h2&gt;

&lt;p&gt;When retrieved or uploaded text enters a prompt, delimit and label it as data. This can reduce accidental instruction mixing, but it is not a complete defense. Enforce the important boundary after generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validate structured output against a schema;&lt;/li&gt;
&lt;li&gt;allowlist tool names and argument shapes;&lt;/li&gt;
&lt;li&gt;sanitize or safely render links and markup;&lt;/li&gt;
&lt;li&gt;filter retrieval by the caller’s permissions before context reaches the model;&lt;/li&gt;
&lt;li&gt;require deterministic policy checks before side effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is to make a successful injection produce an untrusted suggestion, not an authorized action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Test properties, not magic phrases
&lt;/h2&gt;

&lt;p&gt;A useful adversarial suite varies the attack path:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;direct instructions in the user message;&lt;/li&gt;
&lt;li&gt;indirect instructions inside retrieved documents;&lt;/li&gt;
&lt;li&gt;encoded, multilingual, fragmented, or quoted instructions;&lt;/li&gt;
&lt;li&gt;attempts to cross tenants or retrieve hidden fields;&lt;/li&gt;
&lt;li&gt;malformed tool arguments and repeated tool calls;&lt;/li&gt;
&lt;li&gt;attempts to place secrets in output or telemetry.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Assertions should describe system properties: “No document outside the caller’s tenant appears,” “A tool call without server-side authorization is rejected,” or “A generated URL cannot use an unsafe scheme.” Exact output matching is usually too brittle for this layer.&lt;/p&gt;

&lt;p&gt;Run these cases whenever prompts, models, retrieval rules, or tools change. A model update is a behavior change even when the API contract stays the same.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plan containment and evidence
&lt;/h2&gt;

&lt;p&gt;Assume one control will fail. Useful containment options include read-only tools by default, per-tool rate limits, small transaction limits, short-lived credentials, human confirmation, and an immediate tool kill switch.&lt;/p&gt;

&lt;p&gt;Collect enough evidence to investigate failures: request and tool-call IDs, model and prompt versions, policy decisions, timing, and redacted error categories. Avoid treating complete prompts as harmless debug strings; they can contain personal data, credentials, and proprietary context.&lt;/p&gt;

&lt;h2&gt;
  
  
  A pre-launch review
&lt;/h2&gt;

&lt;p&gt;Before enabling the feature, the team should be able to answer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which inputs are attacker-controlled, including retrieved content?&lt;/li&gt;
&lt;li&gt;Which private assets can enter model context?&lt;/li&gt;
&lt;li&gt;Which side effects are reachable, and who authorizes each one?&lt;/li&gt;
&lt;li&gt;What validation happens after generation?&lt;/li&gt;
&lt;li&gt;What is logged, retained, and redacted?&lt;/li&gt;
&lt;li&gt;Which adversarial cases run in CI or release evaluation?&lt;/li&gt;
&lt;li&gt;How can operators disable tools without disabling the whole product?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two useful baselines are the &lt;a href="https://genai.owasp.org/llm-top-10/" rel="noopener noreferrer"&gt;OWASP Top 10 for LLM Applications&lt;/a&gt; and NIST’s &lt;a href="https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.600-1.pdf" rel="noopener noreferrer"&gt;AI 600-1 Generative AI Profile&lt;/a&gt;. They are most valuable as inputs to a system-specific review, not as checklists that certify a design.&lt;/p&gt;

&lt;p&gt;An LLM can remain probabilistic while the surrounding security boundary stays explicit. Keep authority in deterministic code, minimize what the model can reach, and test the paths where untrusted text meets privileged actions.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>llm</category>
      <category>architecture</category>
    </item>
    <item>
      <title>GPT-5.6 Passed Government Safety Review — But What Does That Actually Mean?</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Fri, 10 Jul 2026 04:17:02 +0000</pubDate>
      <link>https://dev.to/jaryn_123/gpt-56-passed-government-safety-review-but-what-does-that-actually-mean-5bhg</link>
      <guid>https://dev.to/jaryn_123/gpt-56-passed-government-safety-review-but-what-does-that-actually-mean-5bhg</guid>
      <description>&lt;p&gt;The news dropped like it was supposed to be reassuring: GPT-5.6 — OpenAI's latest model suite including Sol, Terra, and Luna — has been reviewed and approved by the U.S. government.&lt;/p&gt;

&lt;p&gt;But here's what bothers me about this.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "government approved" actually means
&lt;/h2&gt;

&lt;p&gt;When we hear "government safety review," we imagine rigorous testing. Scientists in lab coats running adversarial prompts. Red teams trying to break the model. Extensive documentation of failure modes.&lt;/p&gt;

&lt;p&gt;The reality is closer to: OpenAI submitted internal testing results, the government looked at them, and said "okay."&lt;/p&gt;

&lt;p&gt;That's not safety testing. That's a rubber stamp with extra steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Sol-Terra-Luna lineup
&lt;/h2&gt;

&lt;p&gt;The three models are designed for different use cases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sol&lt;/strong&gt;: The flagship. Largest context window, most capable reasoning. Think GPT-4 but with actual common sense improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Terra&lt;/strong&gt;: Mid-tier. Good enough for most enterprise tasks at a fraction of Sol's cost.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Luna&lt;/strong&gt;: The lightweight. Fast, cheap, designed for high-volume API calls.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On paper, this is smart product segmentation. In practice, it means OpenAI now has a model at every price point, which is great for their revenue and potentially problematic for competition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I'm skeptical
&lt;/h2&gt;

&lt;p&gt;A few things don't add up:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Speed of approval&lt;/strong&gt;: GPT-5 development started relatively recently. How thorough could the review have been?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No public methodology&lt;/strong&gt;: We don't know what tests were run, what thresholds were applied, or what edge cases were considered.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-reported data&lt;/strong&gt;: OpenAI essentially graded their own homework.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I've been using early access versions of these models for the past few weeks. Sol is genuinely impressive — it handles complex coding tasks with fewer hallucinations than GPT-4. But "fewer" isn't "none," and the gap between demo performance and production reliability is still significant.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real question nobody's asking
&lt;/h2&gt;

&lt;p&gt;Government approval creates a false sense of security. It tells enterprises "this is safe to use," which in practice means "we can deploy this without worrying."&lt;/p&gt;

&lt;p&gt;But AI safety isn't a binary. It's not safe or unsafe. It's a spectrum of behaviors across millions of possible inputs, and a single review can't cover that.&lt;/p&gt;

&lt;p&gt;What we actually need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Continuous monitoring&lt;/strong&gt; of model behavior in production&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public benchmarks&lt;/strong&gt; that anyone can run, not just the company&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adversarial testing&lt;/strong&gt; by independent researchers, not government contractors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clear liability frameworks&lt;/strong&gt; for when things go wrong&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead, we get a stamp of approval that makes everyone feel better while changing nothing about how these models actually behave.&lt;/p&gt;

&lt;h2&gt;
  
  
  What this means for developers
&lt;/h2&gt;

&lt;p&gt;If you're building with these models (and many of us are), don't let the "government approved" label change your testing strategy. You still need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run your own evaluation suites&lt;/li&gt;
&lt;li&gt;Monitor for drift and hallucinations in production&lt;/li&gt;
&lt;li&gt;Have fallback mechanisms for when the model fails&lt;/li&gt;
&lt;li&gt;Maintain human oversight on critical decisions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I've been using tools like &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode&lt;/a&gt; for code review precisely because I don't trust any single AI model to catch everything. The combination of AI assistance with human judgment and automated checks is still the most reliable approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bottom line
&lt;/h2&gt;

&lt;p&gt;Government safety review for AI models is a good idea in principle. But the current implementation is more theater than substance. It gives enterprises permission to deploy without actually ensuring safety.&lt;/p&gt;

&lt;p&gt;The models are getting better. GPT-5.6 Sol is genuinely an improvement. But "better" isn't "safe," and we should stop conflating the two.&lt;/p&gt;

&lt;p&gt;Until we have independent, continuous, adversarial testing — not one-time self-reported reviews — "government approved" is just marketing with extra credibility.&lt;/p&gt;

&lt;p&gt;What do you think? Does government approval change how you'll use these models?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>openai</category>
      <category>gpt5</category>
      <category>safety</category>
    </item>
    <item>
      <title>Discord Banned Thousands by Accident — Why AI Moderation Needs a Human in the Loop</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Thu, 09 Jul 2026 07:59:07 +0000</pubDate>
      <link>https://dev.to/jaryn_123/discord-banned-thousands-by-accident-why-ai-moderation-needs-a-human-in-the-loop-4nfb</link>
      <guid>https://dev.to/jaryn_123/discord-banned-thousands-by-accident-why-ai-moderation-needs-a-human-in-the-loop-4nfb</guid>
      <description>&lt;p&gt;Discord just admitted something that should terrify every platform operator: their AI moderation system wrongfully banned thousands of users over harmless images.&lt;/p&gt;

&lt;p&gt;The official statement was careful. They called it a "bug." But anyone who has worked in AI safety knows this is not a bug. It is a fundamental limitation of automated content moderation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The false positive problem
&lt;/h2&gt;

&lt;p&gt;AI moderation systems are trained to catch the worst content. To do that, they cast a wide net. The result: innocent posts get flagged, users get banned, and trust evaporates.&lt;/p&gt;

&lt;p&gt;I have seen this pattern across multiple platforms. The AI team sets sensitivity high to avoid missing harmful content. False positives spike. Users complain. The team lowers sensitivity. Harmful content slips through. They raise it again. It is an endless oscillation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The core issue: AI cannot understand context the way humans do.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A photo of a child at the beach might trigger nudity detection. A medical discussion could flag as graphic content. A meme with dark humor gets classified as harassment. The AI sees patterns, not meaning.&lt;/p&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%2Fimages.unsplash.com%2Fphoto-1563986768494-4dee2763ff3f%3Fw%3D600" 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%2Fimages.unsplash.com%2Fphoto-1563986768494-4dee2763ff3f%3Fw%3D600" alt="AI Moderation" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for developers
&lt;/h2&gt;

&lt;p&gt;If you are building any platform with user-generated content, you face the same problem. Roll out aggressive AI moderation, and you risk alienating your community. Go too light, and you attract toxicity.&lt;/p&gt;

&lt;p&gt;The solution is not better AI — it is better workflow.&lt;/p&gt;

&lt;p&gt;This is where tools like &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode&lt;/a&gt; come into the conversation. The platform's approach to AI-assisted work emphasizes a principle that content moderation desperately needs: &lt;strong&gt;structured human oversight integrated into automated workflows.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;MonkeyCode's architecture keeps humans in the loop. Requirements feed into AI tasks, but verification happens through human review. The AI does the heavy lifting; humans make the judgment calls.&lt;/p&gt;

&lt;p&gt;Applied to moderation, this means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI flags suspicious content for review&lt;/li&gt;
&lt;li&gt;Human moderators make final decisions&lt;/li&gt;
&lt;li&gt;The system learns from human corrections&lt;/li&gt;
&lt;li&gt;False positives decrease over time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is not revolutionary. It is common sense. But most platforms skip the human part because it is expensive.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trust equation
&lt;/h2&gt;

&lt;p&gt;Discord's incident damaged user trust. Users who were wrongfully banned spent days trying to recover their accounts. Some lost years of chat history. Others lost access to communities they helped build.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trust takes months to build and seconds to destroy.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For platforms, the lesson is clear: AI moderation is a tool, not a replacement for human judgment. The question is not whether to use AI — it is how to structure the workflow so that AI enhances human decision-making instead of replacing it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Have you experienced wrongful bans on any platform? How did you handle it? Curious to hear other stories.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>moderation</category>
      <category>trust</category>
    </item>
    <item>
      <title>GPT-5.6 Dropped Three Models at Once — And MonkeyCode Might Be the Missing Piece</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Thu, 09 Jul 2026 04:22:00 +0000</pubDate>
      <link>https://dev.to/jaryn_123/gpt-56-dropped-three-models-at-once-and-monkeycode-might-be-the-missing-piece-2oi2</link>
      <guid>https://dev.to/jaryn_123/gpt-56-dropped-three-models-at-once-and-monkeycode-might-be-the-missing-piece-2oi2</guid>
      <description>&lt;p&gt;OpenAI just shipped GPT-5.6 — Sol for the heavy lifting, Terra for volume work, and Luna for everyday use. Three models, one release, full coverage across the price-performance spectrum.&lt;/p&gt;

&lt;p&gt;The internet lost its mind for about six hours. Then the takes started rolling in: benchmarks, comparisons, and AGI-is-closer-than-ever threads.&lt;/p&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%2Fimages.unsplash.com%2Fphoto-1620712943543-bcc4688e7485%3Fw%3D600" 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%2Fimages.unsplash.com%2Fphoto-1620712943543-bcc4688e7485%3Fw%3D600" alt="AI Technology" width="600" height="750"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But here is the question nobody is asking: &lt;strong&gt;When was the last time a model upgrade actually made your code better?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sounds cynical, but think about it. We have gone from GPT-3 to GPT-4 to GPT-5, and now 5.6. Each generation is measurably smarter. Yet the day-to-day reality of writing software has not changed that much. The requirements are still vague. The bugs are still sneaky. The only difference is that we now generate bad code faster.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real bottleneck is not intelligence
&lt;/h2&gt;

&lt;p&gt;A model — any model — is fundamentally an inference engine. It does not know your project structure. It has not read your team style guide. It has zero context about the sprint you are in or the technical debt you are carrying. Every conversation starts from scratch, like onboarding an intern who forgets everything overnight.&lt;/p&gt;

&lt;p&gt;This is the gap nobody talks about. &lt;strong&gt;AI coding actual bottleneck is not model capability. It is workflow integration.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I have been tracking an open-source project called &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode&lt;/a&gt; that takes this problem seriously. Built by Chaitin, it is not trying to out-benchmark GPT or Claude. Instead, it is building the plumbing:&lt;/p&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%2Fimages.unsplash.com%2Fphoto-1555066931-4365d14bab8c%3Fw%3D600" 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%2Fimages.unsplash.com%2Fphoto-1555066931-4365d14bab8c%3Fw%3D600" alt="Coding Workflow" width="600" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud dev environments&lt;/strong&gt; — code, build, test, preview, all server-side. No local setup.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Requirement and spec management&lt;/strong&gt; — feed structured requirements directly to the AI instead of typing prompts from memory every time.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Team collaboration&lt;/strong&gt; — shared AI environments where engineering leads can manage workflows centrally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Mobile support&lt;/strong&gt; — pick up tasks from your phone. The AI keeps running when you leave your desk.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private deployment&lt;/strong&gt; — run it inside your corporate network. Data never leaves.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this sounds glamorous. But it is exactly what is missing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The industry has a pattern
&lt;/h2&gt;

&lt;p&gt;Every time a new model drops, the hype cycle spins up. Everyone gets excited for 48 hours. Then they go back to their actual workflow — which, for most people, means opening a ChatGPT tab, pasting code in, and copy-pasting the response back.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A model is an engine. A platform is a car.&lt;/strong&gt; You do not throw away the steering wheel and brakes just because you got a V12.&lt;/p&gt;

&lt;p&gt;So yes, GPT-5.6 is impressive. Sol benchmark numbers are real. But the question worth asking is not how does Sol compare to Claude. It is: &lt;strong&gt;Is your team AI workflow actually ready to use it?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That answer matters more than any leaderboard.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What is your current AI coding workflow? Are you still in chat-and-copy-paste mode, or have you built something more structured? Curious to hear what is working for others.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Agentjacking: A New Attack Targeting Claude Code and Cursor — Could Open-Source Tools Like monkeycode Help?</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Wed, 08 Jul 2026 07:25:22 +0000</pubDate>
      <link>https://dev.to/jaryn_123/agentjacking-a-new-attack-targeting-claude-code-and-cursor-could-open-source-tools-like-4mc4</link>
      <guid>https://dev.to/jaryn_123/agentjacking-a-new-attack-targeting-claude-code-and-cursor-could-open-source-tools-like-4mc4</guid>
      <description>&lt;h1&gt;
  
  
  Agentjacking: A New Attack Targeting Claude Code and Cursor — Could Open-Source Tools Like monkeycode Help?
&lt;/h1&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%2Fimages.unsplash.com%2Fphoto-1555949963-aa79dcee981c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1000%26q%3D80" 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%2Fimages.unsplash.com%2Fphoto-1555949963-aa79dcee981c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1000%26q%3D80" alt="code on screen" width="1000" height="667"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Researchers recently disclosed a new attack class called &lt;strong&gt;Agentjacking&lt;/strong&gt; that targets AI coding agents like Claude Code and Cursor. The technique, &lt;a href="https://thehackernews.com/2026/06/agentjacking-attack-tricks-ai-coding.html" rel="noopener noreferrer"&gt;reported by The Hacker News&lt;/a&gt;, exploits trust in external services connected through the Model Context Protocol (MCP).&lt;/p&gt;

&lt;h2&gt;
  
  
  How it works
&lt;/h2&gt;

&lt;p&gt;The attack works by poisoning error reports sent to services like Sentry. When the AI agent reads the fake error report, it sees markdown-injected instructions disguised as legitimate diagnostic guidance. The researchers claim an &lt;strong&gt;85% success rate&lt;/strong&gt; in getting agents to execute malicious code.&lt;/p&gt;

&lt;p&gt;What makes this especially nasty is that it bypasses traditional security controls. The agent is not being exploited through a buffer overflow or a stolen credential. It is being tricked through a channel it implicitly trusts: a third-party error-tracking service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why MCP security matters now
&lt;/h2&gt;

&lt;p&gt;MCP has become the default way for AI agents to connect to tools, databases, and APIs. That is great for capability, but it also means every connected service becomes part of the attack surface.&lt;/p&gt;

&lt;p&gt;If you are running an agent that can read GitHub issues, query your database, and deploy code, a compromise in any one of those channels is potentially a full compromise.&lt;/p&gt;

&lt;h2&gt;
  
  
  My questions for the security community
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Should MCP servers require authentication by default?&lt;/li&gt;
&lt;li&gt;How do we sandbox AI agents so that a poisoned prompt cannot exfiltrate credentials or modify production?&lt;/li&gt;
&lt;li&gt;Is the answer better prompts, better classifiers, or simply fewer permissions?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Could open-source tools change the trust model?
&lt;/h2&gt;

&lt;p&gt;This is where I think open-source platforms like &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;monkeycode&lt;/a&gt; become interesting. Because the project is AGPL-3.0 and self-hostable, teams can inspect how it connects to external tools, control the sandbox, and limit what any single agent is allowed to do. It is not a silver bullet, but it gives operators visibility that closed SaaS agents do not.&lt;/p&gt;




&lt;p&gt;Have you started thinking about MCP and agent security? What controls are you putting in place?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://thehackernews.com/2026/06/agentjacking-attack-tricks-ai-coding.html" rel="noopener noreferrer"&gt;The Hacker News — Agentjacking Attack&lt;/a&gt;, summarized via &lt;a href="https://www.crescendo.ai/news/latest-ai-news-and-updates" rel="noopener noreferrer"&gt;Crescendo AI News&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>discuss</category>
      <category>monkeycode</category>
    </item>
    <item>
      <title>OpenAI's Axios Supply Chain Compromise: Why monkeycode's Open-Source Model Matters</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Wed, 08 Jul 2026 07:14:31 +0000</pubDate>
      <link>https://dev.to/jaryn_123/openais-axios-supply-chain-compromise-why-monkeycodes-open-source-model-matters-56gg</link>
      <guid>https://dev.to/jaryn_123/openais-axios-supply-chain-compromise-why-monkeycodes-open-source-model-matters-56gg</guid>
      <description>&lt;h1&gt;
  
  
  OpenAI's Axios Supply Chain Compromise: Why monkeycode's Open-Source Model Matters
&lt;/h1&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%2Fimages.unsplash.com%2Fphoto-1555949963-aa79dcee981c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" 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%2Fimages.unsplash.com%2Fphoto-1555949963-aa79dcee981c%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="code and lock" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;OpenAI published a &lt;a href="https://openai.com/index/axios-developer-tool-compromise/" rel="noopener noreferrer"&gt;detailed incident report&lt;/a&gt; about a supply chain attack that affected its macOS app-signing workflow. A compromised version of Axios, a popular HTTP library, was executed in a GitHub Actions pipeline that had access to OpenAI's macOS certificate and notarization material.&lt;/p&gt;

&lt;p&gt;The impacted apps include ChatGPT Desktop, Codex App, Codex CLI, and Atlas. OpenAI says there is no evidence that user data was accessed or that malware was signed, but the company is treating the certificate as compromised and rotating it. Users need to update to newly signed versions by May 8.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical root cause
&lt;/h2&gt;

&lt;p&gt;OpenAI identified two misconfigurations in the affected GitHub Actions workflow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It used a floating tag for Axios instead of pinning to a specific commit hash.&lt;/li&gt;
&lt;li&gt;It did not configure &lt;code&gt;minimumReleaseAge&lt;/code&gt;, which would have delayed automatic adoption of the newly published malicious package.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;These are common mistakes. The incident is a good reminder that build pipelines are an attractive target because they sit between source code and published binaries.&lt;/p&gt;

&lt;h2&gt;
  
  
  The trust problem with closed-source desktop apps
&lt;/h2&gt;

&lt;p&gt;When you download a signed macOS app, you are trusting the entire pipeline that produced it: dependencies, CI configuration, signing keys, notarization service, and the vendor's incident response. Most of that is invisible to the user.&lt;/p&gt;

&lt;p&gt;OpenAI handled this transparently, but the fact remains: users had no way to inspect or verify the build themselves.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I am watching monkeycode
&lt;/h2&gt;

&lt;p&gt;This kind of incident is why open-source AI platforms like &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;monkeycode&lt;/a&gt; are interesting. It is an AGPL-3.0 project that can be self-hosted, meaning teams can audit the code, control the build environment, and avoid relying entirely on a vendor's certificate chain.&lt;/p&gt;

&lt;p&gt;That does not eliminate supply chain risk, but it shifts control. For teams with strict compliance requirements, that is a meaningful difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaways for security teams
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pin dependencies by commit hash in CI/CD workflows.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;minimumReleaseAge&lt;/code&gt; or similar delays for newly published packages.&lt;/li&gt;
&lt;li&gt;Monitor build pipeline access to signing material.&lt;/li&gt;
&lt;li&gt;Have a certificate revocation and rotation plan before you need it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are using OpenAI's macOS apps, update now. And if you are evaluating AI development platforms, it is worth comparing the trust models of closed SaaS products and open-source alternatives like monkeycode.&lt;/p&gt;

</description>
      <category>security</category>
      <category>ai</category>
      <category>opensource</category>
      <category>monkeycode</category>
    </item>
    <item>
      <title>Fable 5 Is Back: A Security-Focused Look at Anthropic's Safeguards and Trade-offs</title>
      <dc:creator>jaryn</dc:creator>
      <pubDate>Wed, 08 Jul 2026 06:52:34 +0000</pubDate>
      <link>https://dev.to/jaryn_123/fable-5-is-back-a-security-focused-look-at-anthropics-safeguards-and-trade-offs-2fdl</link>
      <guid>https://dev.to/jaryn_123/fable-5-is-back-a-security-focused-look-at-anthropics-safeguards-and-trade-offs-2fdl</guid>
      <description>&lt;h1&gt;
  
  
  Fable 5 Is Back: A Security-Focused Look at Anthropic's Safeguards and Trade-offs
&lt;/h1&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%2Fimages.unsplash.com%2Fphoto-1563013544-824ae1b704d3%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" 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%2Fimages.unsplash.com%2Fphoto-1563013544-824ae1b704d3%3Fauto%3Dformat%26fit%3Dcrop%26w%3D1200%26q%3D80" alt="security workspace" width="1200" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Anthropic &lt;a href="https://www.anthropic.com/news/redeploying-fable-5" rel="noopener noreferrer"&gt;redeployed Claude Fable 5 and Mythos 5&lt;/a&gt; on July 1 after a two-and-a-half week suspension. For anyone working in security or AI tooling, the post is a useful case study in how frontier model deployments can be derailed by a single bypass report.&lt;/p&gt;

&lt;h2&gt;
  
  
  The timeline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;June 9&lt;/strong&gt;: Fable 5 and Mythos 5 released.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;June 12&lt;/strong&gt;: US government export controls applied after Amazon researchers found a safeguard bypass. Anthropic suspended access globally.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;June 26&lt;/strong&gt;: Government approved Mythos 5 access for some US Glasswing partners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;June 30&lt;/strong&gt;: Export controls lifted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;July 1&lt;/strong&gt;: Fable 5 restored globally on Claude Platform, Claude.ai, Claude Code, and Claude Cowork.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bypass was not unique to Fable 5
&lt;/h2&gt;

&lt;p&gt;The Amazon report described a prompt that caused Fable 5 to identify software vulnerabilities and, in one case, produce code demonstrating how to exploit one. Anthropic's follow-up testing found that many other models could do the same thing, including Claude Opus 4.8, GPT-5.5, and Kimi K2.7. Even the exploit demonstration was reproducible across the entire model family Anthropic tested.&lt;/p&gt;

&lt;p&gt;This matters because the incident was framed around Fable 5, but the underlying behavior was not uniquely Mythos-class. The real issue was that Fable 5's safeguards let a borderline case through.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Anthropic changed
&lt;/h2&gt;

&lt;p&gt;Anthropic trained a new safety classifier targeting the specific bypass. They claim it blocks the technique in over 99% of cases. Blocked requests are redirected to Opus 4.8 with a user notification.&lt;/p&gt;

&lt;p&gt;The cost is more false positives. Fable 5 already launched with the largest safety margin Anthropic has ever used, deliberately blocking benign requests to avoid missing harmful ones. The updated classifier tightens that margin further, which means more legitimate coding and debugging requests will get blocked too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Industry implications
&lt;/h2&gt;

&lt;p&gt;The post also outlines two longer-term efforts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A shared jailbreak severity framework&lt;/strong&gt; with Amazon, Microsoft, Google, and other Glasswing partners. The goal is a common standard for judging how serious a given bypass is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deeper US government collaboration&lt;/strong&gt; on pre-release testing, information sharing, and research.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For security teams, the takeaway is that deploying frontier models is no longer just a model-evaluation problem. It is a supply-chain, policy, and incident-response problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  One open-source alternative to watch
&lt;/h2&gt;

&lt;p&gt;If your team is evaluating AI development platforms but needs something self-hostable and open-source, &lt;a href="https://github.com/chaitin/MonkeyCode" rel="noopener noreferrer"&gt;MonkeyCode&lt;/a&gt; is worth adding to the list. It is built around cloud dev environments and team workspaces, and the repo is available under AGPL-3.0. It is not a replacement for Claude, but it is a different deployment model worth understanding.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Source: &lt;a href="https://www.anthropic.com/news/redeploying-fable-5" rel="noopener noreferrer"&gt;Anthropic — Redeploying Fable 5&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>anthropic</category>
      <category>claude</category>
    </item>
  </channel>
</rss>
