<?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: Micky Irons</title>
    <description>The latest articles on DEV Community by Micky Irons (@mickai).</description>
    <link>https://dev.to/mickai</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%2F3909620%2F836c63c8-56bd-4f81-b44c-5d3968713336.jpeg</url>
      <title>DEV Community: Micky Irons</title>
      <link>https://dev.to/mickai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mickai"/>
    <language>en</language>
    <item>
      <title>What Replaces Live Patching When Software Can't Phone Home</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:08:06 +0000</pubDate>
      <link>https://dev.to/mickai/what-replaces-live-patching-when-software-cant-phone-home-fkj</link>
      <guid>https://dev.to/mickai/what-replaces-live-patching-when-software-cant-phone-home-fkj</guid>
      <description>&lt;p&gt;Here's a question that only shows up once you've actually tried to ship something that runs permanently disconnected: if your software never talks to the internet again after the day it's installed, what replaces your vulnerability feed?&lt;/p&gt;

&lt;p&gt;Most of the dependency tooling I've used assumes a live connection. A registry you can query at 3am when a CVE drops, a scheduled dependency audit, an auto-patch pipeline that pushes a fix to production before most users have noticed anything happened. All of that is a safety net that catches problems after the fact. Take the network away properly (not 'usually connected but pretending otherwise') and that net disappears. Whatever ships in the build is what runs, often for months, with nothing watching it from the outside.&lt;/p&gt;

&lt;h2&gt;
  
  
  Front-loading trust instead of maintaining it
&lt;/h2&gt;

&lt;p&gt;The practical effect is that disconnected software has to front-load almost all of its supply-chain trust decisions, rather than spreading them across the life of the deployment. In a connected system you can afford to be a bit loose about what gets pulled into a build, because continuous scanning and a patch pipeline sit behind you as a correction mechanism. Offline, there is no correction mechanism. So the question stops being 'how fast can I react' and becomes 'how sure am I before I ship'.&lt;/p&gt;

&lt;h2&gt;
  
  
  Allow-listing dependencies before they're a problem
&lt;/h2&gt;

&lt;p&gt;The pattern I've settled on is to turn dependency management from a detection problem into an admission problem. Instead of pulling in whatever the package manager resolves and scanning the result afterwards, you maintain an explicit allow-list of exactly which packages, at which versions, with which hashes, are permitted to enter a build at all. A new dependency doesn't get scanned after the fact, it gets reviewed and added to the manifest before CI will even fetch it. It's a small shift in wording, deny unless approved rather than allow unless flagged, but it changes what a dependency bump actually looks like: a reviewed, auditable diff to a manifest file, not a background process nobody reads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;allowlist&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_yaml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;deps.allowlist.yaml&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;lockfile&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;parse_lockfile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;package-lock.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;pkg&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;lockfile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;packages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;allowlist&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; not in allow-list, needs review before it can ship&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; version drift: allowed &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;, got &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;version&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;sha256&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tarball&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="nf"&gt;fail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; hash mismatch: possible tampering or a silent republish upstream&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nf"&gt;build&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That check is deliberately boring. It doesn't need a threat feed or anything clever, just a manifest, a lockfile and a hash comparison. The interesting work happens earlier, when a human decides whether a new dependency goes into that manifest in the first place, and on what schedule anyone revisits the ones already there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The SBOM is the record, not the paperwork
&lt;/h2&gt;

&lt;p&gt;Generating a software bill of materials, CycloneDX or SPDX, either works, gets talked about as a compliance exercise you produce because a customer's procurement team asked for one. For disconnected software it's closer to the only audit trail you will ever have. There's no live inventory service to query later. When a new CVE surfaces for a library you bundled eight months ago, the SBOM from that specific release is the only quick way to know which of your shipped versions actually contain it. I generate it directly from the same lockfile and allow-list manifest that CI already checks, so there's no separate process that can quietly drift from what actually got built. Diffing SBOMs between two releases is also just genuinely useful on its own: it tells you exactly what changed, dependency by dependency, which is a far more honest release note than 'various fixes and improvements'.&lt;/p&gt;

&lt;h2&gt;
  
  
  Signed installers instead of a live update check
&lt;/h2&gt;

&lt;p&gt;The other half of a connected system's trust model is usually 'only accept updates signed and pushed from my own servers'. You can keep the signing, you just lose the pushing. What I ended up with for SIOS, the platform I build at Mickai, is a release signed with a key kept well away from any build machine, with the public key distributed out of band so it can be checked independently of the installer itself. The verification step is simple and happens once, by whoever is doing the install, often onto a machine with no outbound network path at all.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;installer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release-4.2.bin&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;signature&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;read_file&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release-4.2.bin.sig&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;pubkey&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;load_pubkey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release-pubkey.pem&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="nf"&gt;verify_signature&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;installer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;pubkey&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="nf"&gt;abort&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;signature verification failed: do not install this binary&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's a manual step rather than an automatic one, and that's the point of it. In a disconnected environment, the moment of installation is the only point where the operator and the software are both present and able to check each other.&lt;/p&gt;

&lt;h2&gt;
  
  
  The honest tradeoff
&lt;/h2&gt;

&lt;p&gt;None of this is free, and it's worth being straightforward about the cost rather than only talking up the upside. The whole model above is a deliberate trade: you give up continuous, hours-scale patching in exchange for a system that never calls home. A critical CVE in a dependency on your allow-list can, on a connected system, be patched and auto-pushed in under a day. Here, the same fix has to go through review, a rebuild, a fresh SBOM and re-signing, then physical distribution to machines that might be air-gapped or simply hard to reach. That can easily stretch to weeks, not hours. That's a real security cost, not a rounding error, and anyone running or recommending this kind of architecture should say so plainly rather than only advertising the parts that sound good.&lt;/p&gt;

&lt;p&gt;It also doesn't remove the need for a human to keep watching upstream security advisories for whatever's on the allow-list. The list isn't a one-time decision, it needs revisiting on a schedule by someone whose job includes checking whether anything on it has picked up a disclosed vulnerability since the last review. Skip that and the allow-list quietly stops meaning anything, it just becomes a static file nobody interrogates. The honest version of this setup needs a fast lane too: a shorter, security-only rebuild and re-sign path that skips whatever isn't essential, so when something genuinely urgent turns up, the gap between disclosure and a distributable fix is measured in days rather than whatever your normal release cadence happens to be.&lt;/p&gt;

&lt;p&gt;I'd genuinely like to know how other people running disconnected or air-gapped systems handle that gap between a CVE landing and a signed fix actually reaching a box. Is there a sane middle ground between fully offline and continuously patched, something that doesn't just quietly reintroduce the live connection you were trying to remove in the first place? Or is a slower, more deliberate update cadence simply the price of the offline guarantee, full stop?&lt;/p&gt;

</description>
      <category>security</category>
      <category>architecture</category>
      <category>devops</category>
      <category>programming</category>
    </item>
    <item>
      <title>A Release Gate Isn't a Checklist</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:07:30 +0000</pubDate>
      <link>https://dev.to/mickai/a-release-gate-isnt-a-checklist-5bmm</link>
      <guid>https://dev.to/mickai/a-release-gate-isnt-a-checklist-5bmm</guid>
      <description>&lt;p&gt;A few months back I had a release candidate sitting in front of me with a green CI pipeline, coverage numbers that would make most teams happy, and a changelog nobody could argue with. By every metric my pipeline tracked, it was ready to ship. It also bundled a dependency whose licence terms didn't actually permit the deployment model we were planning for that release. Nothing in the test suite caught that, because the test suite was never built to catch it.&lt;/p&gt;

&lt;p&gt;That's the gap I want to talk about. Not 'write more tests', but what 'ready to release' actually has to mean once you're shipping into a regulated or high-stakes environment, where a mistake isn't a bug ticket, it's a breach, a legal exposure, or a regulator asking why nobody signed off on something. 'Tests pass' is necessary. It is nowhere near sufficient, and treating it as the whole answer is how teams end up with incidents that have nothing to do with code quality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why one green checkmark isn't a release decision
&lt;/h2&gt;

&lt;p&gt;CI answers one question: does the code do what I told it to do. That's a different question from is this safe to run on someone else's infrastructure, can a new user actually operate it without causing damage, did we actually have the right to ship this dependency, and is there a named human who is accountable if this goes wrong. Those are four separate questions, answered by four different kinds of expertise, and almost none of them compress into an automated assertion.&lt;/p&gt;

&lt;p&gt;The usual failure mode is picking one of two bad options. Option one: try to encode everything into the pipeline, which mostly doesn't work because licence provenance and governance sign off aren't the kind of thing a unit test can evaluate. Option two: let engineering green light stand in for the whole decision, and quietly hope the security review, the UX pass and the legal check happened somewhere upstream. On a small team under deadline pressure, 'somewhere upstream' is usually nowhere at all.&lt;/p&gt;

&lt;h2&gt;
  
  
  A gate per concern, not a meeting per concern
&lt;/h2&gt;

&lt;p&gt;The pattern that's worked for me is to treat a release as gated on several independent, named checks, each with its own owner and its own falsifiable criteria, rather than one holistic 'is this good' judgement call. On the systems I've built at Mickai, that's six gates: engineering readiness (does it work, is it reversible, what's the rollback plan), UX readiness (can the intended user actually use this without a support ticket), security and sovereignty review (what's the attack surface, and for anything running on someone else's premises, does data actually stay where the contract says it stays), IP and licensing provenance (do I actually have the rights to ship every component in this build, including anything pulled in transitively), governance sign off (has an accountable person actually looked at this and said yes, with their name attached), and a controls and audit gate (can I reconstruct, after the fact, exactly what shipped, who approved it, and why).&lt;/p&gt;

&lt;p&gt;None of those six gates is new as a concept. What matters is making them structurally equal and independently blocking, so that a green pipeline literally cannot ship a release on its own. The simplest way I've found to do that is a gate manifest that sits alongside the release candidate, checked by the release job before anything is allowed to deploy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# release-gate.yaml, checked by CI before the deploy job is allowed to run
&lt;/span&gt;&lt;span class="n"&gt;release&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;v2.14.0&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;span class="n"&gt;gates&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="n"&gt;engineering&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lead-eng&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ci-run-8841&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;ux&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;design-lead&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;usability-notes-v214.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;security_sovereignty&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;security-lead&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;threat-model-v214.pdf&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;ip_provenance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;legal-eng-liaison&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dependency-licence-scan-8841.json&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;governance&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;release-board&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;governance-minutes-2026-10-14.md&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;audit_controls&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;owner&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;compliance&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;pass&lt;/span&gt;
    &lt;span class="n"&gt;evidence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;control-mapping-v214.xlsx&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;can_release&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gate&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;manifest&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;gates&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;gate&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;status&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;pass&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;blocked on &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; (owner: &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;gate&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;owner&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;gate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;evidence&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s"&gt; has no evidence attached, treat as fail&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;all gates green&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The three ways this turns into theatre
&lt;/h2&gt;

&lt;p&gt;The first time I set something like this up, it immediately started failing in predictable ways, and they're worth naming because they're what makes a gate framework fake rather than real.&lt;/p&gt;

&lt;p&gt;Rubber stamping is the big one. A gate that's just a boolean someone clicks true on becomes a formality within about three releases. The fix is requiring an evidence reference for every gate, not just a status, so 'pass' means 'here is the artefact that justifies this', not 'someone with the right job title didn't object'. The pseudocode above fails closed if evidence is missing, which sounds pedantic until you notice how often that's exactly where the shortcut happens.&lt;/p&gt;

&lt;p&gt;Gate sprawl is the opposite failure. If every release needs all six gates fully re-run regardless of size, releasing becomes a quarterly event and people start batching changes to avoid the overhead, which defeats the entire point of shipping safely and often. The fix is proportionality: classify the change by blast radius first, and let a genuinely low risk patch skip the governance and audit gates by policy, not by someone deciding on the day that it probably doesn't matter.&lt;/p&gt;

&lt;p&gt;The third is the single point of failure. One named owner per gate is good for accountability and bad for availability, the gate owner goes on leave and the release sits blocked for two weeks. A named deputy and a time boxed response window, with an explicit escalation path rather than a silent bypass, is what keeps the gate meaningful instead of becoming the reason nothing ships.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this got concrete for me
&lt;/h2&gt;

&lt;p&gt;Building a sovereign, on-premise AI platform makes two of these gates stop being abstract fairly quickly. The security and sovereignty gate is the one that actually caught a real problem: an assumption baked into how a service handled data residency broke the moment it ran air gapped rather than connected, something no amount of unit testing in my normal CI environment was ever going to surface, because the test environment itself had network access the production environment deliberately didn't. The IP and provenance gate caught a dependency whose redistribution terms were fine for a hosted SaaS model and not fine for something I was licensing for a customer to run entirely inside their own infrastructure. Neither of those is a code quality problem. Both would have shipped past any pipeline built only to check that the code does what it claims to do.&lt;/p&gt;

&lt;p&gt;I'd genuinely like to know how other teams handle this at smaller scale, where six distinct named owners isn't realistic and you've maybe got two or three people wearing all these hats between them. Do you collapse several gates into one reviewer with a structured checklist, run them as sequential annotations on a single document instead of separate sign offs, or something else entirely? I suspect the six concerns stay the same regardless of team size, it's the ownership structure around them that has to flex, and I haven't settled on a version of that for a three person team that I'd fully trust yet.&lt;/p&gt;

</description>
      <category>releaseengineering</category>
      <category>devops</category>
      <category>security</category>
      <category>compliance</category>
    </item>
    <item>
      <title>Classify Before You Embed: The Access Control Problem RAG Pipelines Skip</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:06:54 +0000</pubDate>
      <link>https://dev.to/mickai/classify-before-you-embed-the-access-control-problem-rag-pipelines-skip-4ifk</link>
      <guid>https://dev.to/mickai/classify-before-you-embed-the-access-control-problem-rag-pipelines-skip-4ifk</guid>
      <description>&lt;p&gt;Most teams building retrieval-augmented systems over an organisation's archive treat data preparation as a parsing problem: get the PDFs and emails into text, chunk it, embed it, done. I've made that mistake myself, early on, and the system worked fine in every demo. It broke in production, three months in, when a support chatbot surfaced a severance negotiation memo in response to a completely unrelated question about expense policy. Nobody had done anything wrong. The retrieval pipeline did exactly what it was built to do: find the chunk most semantically similar to the query. The problem was that nothing in the pipeline knew that chunk was anything other than ordinary text.&lt;/p&gt;

&lt;p&gt;That's the bit that gets missed when people frame this as a compliance exercise. Treating it as a checklist you run once to satisfy an auditor misses the point. It is an access control design problem, and if you get the sequencing wrong, you end up with a retrieval layer that holds more privilege than any single human user is meant to have, with nothing stopping that privilege leaking into a response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why broad retrieval access is a confused deputy, not a convenience
&lt;/h2&gt;

&lt;p&gt;When you point an embedding pipeline at a file share, a SharePoint site, or an email archive, the pipeline runs under a service account. That account usually has read access to everything in scope, because that's the easiest way to get it working. The model sitting on top of the retriever doesn't have its own identity. It inherits whatever the retriever can see. So the moment end users start querying that system, you've built a confused deputy: an agent with high privilege acting on behalf of a requester with lower privilege, with no check in between.&lt;/p&gt;

&lt;p&gt;This failure mode is concrete and specific. It isn't "the model might say something wrong." It's: a junior employee's benign question gets answered using the contents of a document they were never granted read access to in the source system, because the vector index flattened every document into one undifferentiated pool, and the only gate left is whether a chunk looks semantically relevant. Semantic relevance and authorisation are unrelated properties. Treating the first as a proxy for the second is where this goes wrong.&lt;/p&gt;

&lt;h2&gt;
  
  
  Start with assessment, not ingestion
&lt;/h2&gt;

&lt;p&gt;Before anything gets parsed, I want an inventory: what repositories exist, who owns each one, what access control already governs it in its source system (file share ACLs, SharePoint permissions, mailbox ownership), and roughly what's in it. This sounds slow. It's the only point in the process where you can catch, for example, an HR share that holds years of disciplinary records sitting next to the induction handbook, before both get flattened into the same chunk store.&lt;/p&gt;

&lt;h2&gt;
  
  
  Digitisation needs to carry provenance forward, not just extract text
&lt;/h2&gt;

&lt;p&gt;OCR and format conversion (Word, PDF, scanned paper, old database exports) is the part everyone budgets time for. What usually gets skipped is making sure the pipeline preserves where each piece of text came from: source system, original path, original ACL where one exists, and a reference back to the source object, not just the extracted string. Throw that away at digitisation time and you have no way to reconstruct it later. You'd be re-deriving sensitivity from content alone, which is a much weaker signal than the access control that already existed in the source system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Classify at the chunk level, because documents aren't uniformly sensitive
&lt;/h2&gt;

&lt;p&gt;A tier taxonomy (public, internal, restricted, confidential) is the easy part to decide on. The harder part is applying it below the document level. A long board pack usually has a public-facing strategy summary and a confidential remuneration annex in the same file. Tag the whole document confidential and you've blocked legitimate use of the public section. Tag it internal because that's the average and you've exposed the annex. Tag at chunk granularity instead, in the same pass that splits the document for embedding, so the sensitivity tag and the chunk boundary get decided together, by whoever or whatever is doing the splitting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"chunk_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"doc-4471-chunk-12"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_system"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sharepoint://hr-archive"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"source_path"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/Board/2024/Remuneration_Annex.docx"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sensitivity_tier"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"confidential"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"compartment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hr"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"exec"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"inherited_acl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"hr-leadership"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"board"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"classified_by"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"pipeline-v2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"classified_at"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2026-03-11T09:02:00Z"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Enforce permissioning at retrieval time, not at the prompt
&lt;/h2&gt;

&lt;p&gt;The tags are inert unless something checks them before a chunk reaches the model's context window. I've seen teams try to solve this by instructing the model in its system prompt not to repeat confidential information. That doesn't hold up, because by the time the chunk is in context, the model has already read it, and a different phrasing of the question can get it to paraphrase rather than quote. The filter needs to sit between the vector search and context assembly, and it needs to be a hard filter, not a suggestion to the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;retrieve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;candidates&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;embed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;candidates&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nf"&gt;tier_rank&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sensitivity_tier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;clearance_rank&lt;/span&gt;
        &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compartment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;compartments&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="n"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;[:&lt;/span&gt;&lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note what that function requires: every candidate chunk has to carry sensitivity_tier and compartment as queryable metadata, which only exists because classification happened before indexing, not after. If you index everything first and plan to add permissions later, you're not adding a feature. You're re-running the entire classification and re-indexing pass over whatever has accumulated in the meantime, under time pressure, probably after an incident rather than before one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this actually lands
&lt;/h2&gt;

&lt;p&gt;This is ordinary compartmentalisation thinking that's existed in information security for decades, applied to a retrieval mechanism that happens to be very good at finding things you didn't mean to expose. I've done this properly on a production system, and the part that took the longest wasn't the classification taxonomy, it was getting chunk-level metadata to survive every transformation a document goes through before it reaches an index. The only genuinely new wrinkle semantic search introduces is that relevant and accessible start to feel like the same property when they aren't, and that's exactly where the failure mode above lives.&lt;/p&gt;

&lt;p&gt;I haven't found a clean answer for one part of this: tier inheritance when a chunk gets reused across derived documents, summaries, translations, re-exports, that sort of thing. The sensitivity of the source is clear enough. What the derived version should inherit is less obvious. Has anyone settled on a pattern for propagating sensitivity metadata through a document that's been transformed rather than simply copied?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>architecture</category>
      <category>rag</category>
    </item>
    <item>
      <title>Why row-level isolation isn't enough when multiple departments share one AI server</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:06:19 +0000</pubDate>
      <link>https://dev.to/mickai/why-row-level-isolation-isnt-enough-when-multiple-departments-share-one-ai-server-4nhk</link>
      <guid>https://dev.to/mickai/why-row-level-isolation-isnt-enough-when-multiple-departments-share-one-ai-server-4nhk</guid>
      <description>&lt;p&gt;I keep running into the same conversation with people building internal AI tools for organisations that have more than one department: HR, finance, engineering, legal, whatever the split is. Everyone wants one server. Buying a separate GPU box per department is expensive, and most departments don't come close to using a full GPU's throughput for most of the working day. So the instinct is reasonable: share the hardware, share the model, and keep each department's data apart with a tenant_id column and a WHERE clause.&lt;/p&gt;

&lt;p&gt;That instinct is where most of the trouble starts. A tenant_id column is access control. It is not isolation. Those are different guarantees, and conflating them is how an HR salary review ends up summarised into a finance dashboard, or a legal team's privileged documents get pulled into an engineering support bot's answer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Namespaces are the actual boundary
&lt;/h2&gt;

&lt;p&gt;Access control answers "is this request allowed to see this row." Isolation answers "can this data physically end up somewhere it shouldn't, regardless of whether a check was written correctly." On a shared server you need both, and they live in different places.&lt;/p&gt;

&lt;p&gt;In practice that means treating each department as its own namespace at every layer the data touches, not just the database table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Storage: separate buckets or volume prefixes per department, not one bucket with a folder convention everyone is trusted to respect.&lt;/li&gt;
&lt;li&gt;Vector indexes: a separate index or namespace per department for retrieval, not one shared index with a metadata filter bolted onto every query.&lt;/li&gt;
&lt;li&gt;Model context: no shared conversation or prompt cache keyed only by a session ID, especially if session IDs can collide or be guessed across tenants.&lt;/li&gt;
&lt;li&gt;Credentials: a separate service identity per department with its own scoped key, not one shared service account that fans out to several departments relying on row filters to decide what it's "supposed" to return.&lt;/li&gt;
&lt;li&gt;Logging and audit trails: per-namespace logs, so a department's own compliance team can prove what left their boundary without trusting your application code to have tagged everything correctly after the fact.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is exotic. It's the same multi-tenancy discipline you'd apply to any SaaS product. The difference on an internal, on-premise deployment is that people often skip it, because "it's all one organisation" feels like it lowers the stakes. It doesn't. Internal departments routinely have stricter mutual confidentiality requirements, HR and legal data about an ongoing dispute, finance data ahead of results, than a SaaS vendor typically owes its external customers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why row isolation alone breaks: a concrete example
&lt;/h2&gt;

&lt;p&gt;Here's a failure mode I've seen play out almost exactly like this. A shared vector database holds embeddings for every department's documents, filtered at query time by tenant_id in application code. It works fine for the main chat interface, because every query path there remembers to filter.&lt;/p&gt;

&lt;p&gt;Then someone builds a second feature: a nightly job that re-embeds documents after a model upgrade, or a debugging tool that lets an admin "search everything" to diagnose a bad retrieval result, or a caching layer that stores the top results for a popular query to save latency. None of those is the main chat interface. Each one is a reasonable thing to build on its own. And each one is a separate, independent place where someone has to remember to apply the same filter, correctly, forever, as the codebase changes under them.&lt;/p&gt;

&lt;p&gt;Eventually one of them doesn't. The debugging tool surfaces a chunk of finance data on an HR analyst's screen while they're chasing an unrelated bug. The cache key doesn't include tenant_id, so two departments asking a similarly worded question get served each other's cached result, source chunks included. Nothing throws an error. No log line flags it. The data just quietly crosses a boundary that only ever existed as a convention in application code, never as a structural property of the system. That's the core weakness of database-level isolation on its own: its strength equals the weakest query path that ever touches the data, including ones that don't exist yet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a structural fix looks like
&lt;/h2&gt;

&lt;p&gt;The shape of the fix is to move the isolation boundary out of query logic and into the object being queried, so no code path, present or future, can bypass it by accident:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Fragile: isolation depends on every caller remembering a filter
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&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="n"&gt;r&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;results&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tenant_id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;# a new caller (cache warmer, admin tool, batch job) that forgets this
&lt;/span&gt;    &lt;span class="c1"&gt;# line compiles fine, runs fine, and silently leaks data across tenants
&lt;/span&gt;
&lt;span class="c1"&gt;# Structural: isolation is a property of the object, not the query
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_tenant_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;vector_db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get_namespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;# distinct index, distinct keys
&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;search_documents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_tenant_index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tenant_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;similarity_search&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query_vector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;top_k&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# there's no "forgot the filter" failure mode here, because the
&lt;/span&gt;    &lt;span class="c1"&gt;# connection object has no way to see another tenant's namespace at all
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Physical separation vs shared infrastructure: the real tradeoffs
&lt;/h2&gt;

&lt;p&gt;Once you accept that correct isolation takes real engineering effort, full physical separation starts to look tempting again: give every department its own server, and the failure I just described becomes structurally impossible, because there's no shared database for a bad query to reach in the first place.&lt;/p&gt;

&lt;p&gt;Full physical separation has real advantages. It's the easiest architecture to explain to a compliance team or an auditor, because the boundary is a locked server room door rather than a line of code. A bug or an outage in one department's stack can't touch another's. And if one department genuinely needs air-gapped handling, classified government data is the obvious example, physical separation stops being a tradeoff and becomes the requirement, full stop.&lt;/p&gt;

&lt;p&gt;But full physical separation has a cost people underestimate until they're paying it monthly. A GPU sized for one department's peak load sits mostly idle the rest of the time, and you pay for that idle capacity once for every department that gets its own box. You're also multiplying operational load: a model deployment to patch per department, a monitoring and alerting setup per department, a place a model upgrade can quietly go wrong, times however many departments you have, instead of once.&lt;/p&gt;

&lt;p&gt;Shared infrastructure with strict, structural isolation (separate namespaces, separate containers or process-level sandboxing, separate encryption keys per department, all enforced at the object level rather than the query level) gets you most of the security properties of physical separation while sharing the expensive, often-idle GPU across departments whose peak usage rarely lines up at the same moment. The honest cost is that it's harder to build correctly and harder to verify from the outside. A shared host OS or hypervisor compromise is a shared blast radius in a way that physically separate boxes never are, no matter how good your namespace discipline is above that layer.&lt;/p&gt;

&lt;p&gt;The working rule I've settled on when building this kind of thing: structural isolation, not row filters, by default on shared hardware, with full physical separation reserved specifically for workloads that carry an actual regulatory or classification requirement for it, rather than deployed as a default reaction to "this data feels sensitive."&lt;/p&gt;

&lt;p&gt;I'd be genuinely interested to hear where other people draw that line in practice. At what point does structurally isolated shared hardware stop being good enough for you, and what's actually pushed you to pay for full physical separation rather than just isolating harder on the box you've already got?&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>security</category>
      <category>multitenancy</category>
      <category>onpremise</category>
    </item>
    <item>
      <title>Routing one request across many small models: what the demo doesn't show you</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:05:49 +0000</pubDate>
      <link>https://dev.to/mickai/routing-one-request-across-many-small-models-what-the-demo-doesnt-show-you-c46</link>
      <guid>https://dev.to/mickai/routing-one-request-across-many-small-models-what-the-demo-doesnt-show-you-c46</guid>
      <description>&lt;p&gt;Everyone shows the same demo. A request comes in, it hits a router, the router picks a small specialist model instead of a giant generalist one, and the slide moves on to the next bullet point about cost savings. I spent most of this year living in the part the demo skips: the arbitration layer that has to decide, for every request, which specialist (if any) is even allowed to touch it, and how the pieces of a multi-step request get stitched back together afterwards.&lt;/p&gt;

&lt;p&gt;A single big generalist model doesn't need any of this. It has one context window, one set of weights, and whatever access you've already granted it. The moment you split the work across several smaller, narrower models, you've created a coordination problem that didn't exist before. That problem, not the models themselves, is where most of the engineering effort actually goes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Arbitration is a permissions question before it's a quality question
&lt;/h2&gt;

&lt;p&gt;The instinct when you first build a router is to treat it like a classifier: look at the request, work out its intent, pick the model that's best at that intent. That's backwards. The first question has to be which models are even permitted to see this particular input and take this particular action, and only then do you ask which of the permitted ones is best.&lt;/p&gt;

&lt;p&gt;I keep these as two separate checks for a reason. A contract clause extractor might be the best tool in the building for parsing a lease, but if the request includes a field tagged as personal data and that specialist's permission set doesn't cover personal data, it never gets to compete on quality. It's excluded before ranking starts, not after. With three specialists you can eyeball the permission matrix by hand. With thirty, the exclusion check has to be a first-class step in the pipeline, not something a prompt gently asks the model to respect. A generalist model that already has broad access skips this problem entirely, which is exactly why it's harder to audit what it actually used that access for on any given request.&lt;/p&gt;

&lt;h2&gt;
  
  
  A single request is rarely a single task
&lt;/h2&gt;

&lt;p&gt;Once you accept that requests get split across specialists, you notice most real requests were never one task to begin with. 'Summarize this contract, flag anything that needs legal review, and draft a holding reply' is three jobs with a dependency order: the flagging step needs the summary, the drafting step needs to know what got flagged. That's a small directed acyclic graph, not a single function call.&lt;/p&gt;

&lt;p&gt;I don't author these graphs by hand per request type. The arbitration layer builds the DAG dynamically: the incoming request gets decomposed into sub-tasks, each sub-task declares what it needs as input and what permissions it requires, and the graph only commits to an execution order once every node has a specialist it's actually allowed to run. One of the specialists I run as part of SIOS, the platform I've been building, does nothing but contract clause extraction, nothing else, and that narrowness is deliberate. If clause language in a particular jurisdiction changes, I retrain or replace that one node and nothing else in the graph has to move.&lt;/p&gt;

&lt;h2&gt;
  
  
  What the interface actually looks like
&lt;/h2&gt;

&lt;p&gt;Stripped down to the part that matters, the arbitration interface is smaller than people expect. Roughly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;Specialist&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;          &lt;span class="c1"&gt;// e.g. "clause-extraction", "pii-redaction", "drafting"&lt;/span&gt;
  &lt;span class="nx"&gt;permissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;   &lt;span class="c1"&gt;// data classes / actions this model may touch&lt;/span&gt;
  &lt;span class="nx"&gt;costTier&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;low&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;medium&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;high&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;SubTask&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;dependsOn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;        &lt;span class="c1"&gt;// ids of upstream nodes this needs output from&lt;/span&gt;
  &lt;span class="nx"&gt;requiredPermissions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;ArbitrationResult&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;subTaskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Specialist&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;     &lt;span class="c1"&gt;// passed the permission check&lt;/span&gt;
  &lt;span class="nx"&gt;chosen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Specialist&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;
  &lt;span class="nx"&gt;reason&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;chosen&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no_eligible_specialist&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;generalist_fallback&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;arbitrate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SubTask&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Specialist&lt;/span&gt;&lt;span class="p"&gt;[]):&lt;/span&gt; &lt;span class="nx"&gt;ArbitrationResult&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;eligible&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;requiredPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;every&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;p&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&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="nx"&gt;p&lt;/span&gt;&lt;span class="p"&gt;))&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="nx"&gt;eligible&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;===&lt;/span&gt; &lt;span class="mi"&gt;0&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="na"&gt;subTaskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&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="nx"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;chosen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;no_eligible_specialist&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ranked&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;eligible&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;domain&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;intent&lt;/span&gt;&lt;span class="p"&gt;)&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="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;costWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;costTier&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nf"&gt;costWeight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;costTier&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="na"&gt;subTaskId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;task&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="nx"&gt;eligible&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;chosen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ranked&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;null&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;ranked&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&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;chosen&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;generalist_fallback&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The detail worth noticing is the order of operations inside arbitrate(). Permission filtering happens first and narrows the field before any quality ranking runs. Flip that order, rank everything by quality first and check permissions second, and you'll eventually ship a request where the 'best' model got chosen before anyone checked whether it should have seen the input at all. I've seen that bug in an early version of this, and it's the kind of thing that only shows up once you've got enough specialists that the top-ranked one isn't always the permitted one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The tradeoff nobody puts in the demo
&lt;/h2&gt;

&lt;p&gt;The case for many small specialists is real. Each one is narrow enough to audit properly, you can point at a specific model and say exactly what data classes it's allowed near. Each one is independently updatable, a regulatory change in one domain means retraining one node, not re-evaluating a monolith's behavior across every domain it touches. And you can run the cheap model for the common case and only wake the expensive one when the router decides the task actually needs it.&lt;/p&gt;

&lt;p&gt;None of that is free. Every hop between specialists is a network call, a permission check, and a schema translation between what one model outputs and what the next one expects as input. Say each hop costs somewhere on the order of 100 to 200 milliseconds once you include the arbitration check, a four-node DAG can easily spend close to a second just coordinating, before any model has done its actual work. A single generalist model never pays that coordination tax because it never had to hand off to anyone. You're trading a hard-to-audit black box for several auditable ones, plus a new black box sitting in front of them (the router and arbitration layer itself), which now needs its own logging, its own test suite, and its own failure modes worked out.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still unresolved
&lt;/h2&gt;

&lt;p&gt;The part I haven't settled is where the arbitration log should live so it's actually useful during an audit without turning into its own compliance burden. Logging every permission check at every node gives you full traceability and a volume of logs nobody will ever read end to end. Logging only at the branch points is cheaper but means you're trusting the bits in between. If you've built anything with a routing layer in front of multiple models, I'd like to know which way you landed and why.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>llm</category>
      <category>systemdesign</category>
    </item>
    <item>
      <title>The Real Crossover Point Between On-Premise and Cloud Inference</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 20:05:46 +0000</pubDate>
      <link>https://dev.to/mickai/the-real-crossover-point-between-on-premise-and-cloud-inference-ki6</link>
      <guid>https://dev.to/mickai/the-real-crossover-point-between-on-premise-and-cloud-inference-ki6</guid>
      <description>&lt;p&gt;Every few months someone posts a confident take on whether running your own AI inference hardware beats paying a cloud API, and both the 'on-premise is obviously cheaper' camp and the 'cloud always wins' camp are making the same mistake. They are compressing a five-variable optimisation problem into a one-line opinion. I have had to build this calculation properly more than once, for actual purchasing decisions with real money attached. The honest answer takes a formula with five inputs, and those inputs change the answer completely depending on your traffic pattern.&lt;/p&gt;

&lt;p&gt;The shortcut most people take is comparing a GPU's purchase price directly to a cloud bill and calling it done. That shortcut skips the variable that matters most of all, which is how much of that hardware's capacity you are actually using once you have bought it. Everything below follows from that one point.&lt;/p&gt;

&lt;h2&gt;
  
  
  The five variables that actually decide it
&lt;/h2&gt;

&lt;p&gt;Hardware amortisation period. The capital cost of a GPU server is not a one-off number, it is a monthly cost that depends entirely on how long you plan to run the thing before it is replaced or written off. Assume an 18-month amortisation window instead of a 48-month one and your monthly hardware cost roughly triples. This single assumption moves most on-premise versus cloud arguments more than any other variable in the spreadsheet, and it is the one people state least explicitly when they want to win an argument online.&lt;/p&gt;

&lt;p&gt;Power draw. Not the GPU's rated TDP on the spec sheet, the actual measured draw at your real utilisation, plus cooling, plus the rest of the chassis (CPU, memory, networking, storage). A multi-GPU box sitting mostly idle still pulls a surprising fraction of its peak draw. Price electricity off peak TDP and you will get a number that is wrong in both directions depending on how hard the box is actually working.&lt;/p&gt;

&lt;p&gt;Utilisation rate. This is the one everyone forgets, and it is the one that quietly decides the whole argument. A GPU running at 15 per cent utilisation because you provisioned for peak traffic is not 'mostly idle for free', it is capital you have already paid for that is not earning anything. Cloud's entire pricing model is a bet that most customers run low utilisation and will happily pay a premium for elasticity instead of carrying that idle capacity themselves. If your utilisation is genuinely high and steady, that bet stops being profitable for the provider and starts being profitable for you.&lt;/p&gt;

&lt;p&gt;Request volume. This is what utilisation is actually measuring, so it earns its own line. Low, spiky volume favours cloud, because you are not stuck paying for idle hardware between bursts. High, steady volume favours on-premise, because you are finally filling the capacity you already bought.&lt;/p&gt;

&lt;p&gt;Model size. This decides how much hardware a single request needs, which decides how many requests you can push through a GPU per second, which is the denominator in every cost-per-request number you will ever calculate. A model that needs four GPUs per replica changes your fixed cost base in a completely different way to one that needs one.&lt;/p&gt;

&lt;h2&gt;
  
  
  A formula you can actually compute
&lt;/h2&gt;

&lt;p&gt;Put those five variables together and you get something you can calculate rather than argue about. It is rough, it ignores a few second-order effects such as resale value and staff time, but it gets you from vibes to a number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# illustrative structure, plug in your own measured numbers
&lt;/span&gt;
&lt;span class="n"&gt;onprem_monthly_cost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hardware_capex&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;amortisation_months&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;avg_power_kw&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;electricity_rate_per_kwh&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                     &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;fixed_ops_overhead&lt;/span&gt;

&lt;span class="n"&gt;max_throughput_per_month&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gpus_per_box&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;requests_per_gpu_per_second&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;seconds_per_month&lt;/span&gt;

&lt;span class="n"&gt;onprem_cost_per_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onprem_monthly_cost&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;actual_requests_served_per_month&lt;/span&gt;

&lt;span class="n"&gt;cloud_cost_per_request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cloud_rate_per_request&lt;/span&gt;  &lt;span class="c1"&gt;# or derive from a cloud GPU hourly rate
&lt;/span&gt;
&lt;span class="n"&gt;breakeven_requests_per_month&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;onprem_monthly_cost&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;cloud_cost_per_request&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A worked example (illustrative only, not a benchmark)
&lt;/h2&gt;

&lt;p&gt;Say you are looking at an eight-GPU server costing somewhere around 200,000 pounds, amortised over 36 months. That is roughly 5,556 pounds a month in hardware cost alone. Add power: call it 6kW average under real load including cooling overhead, at a commercial electricity rate of 0.25 pounds per kWh, which is about 1,080 pounds a month. Add a modest 2,000 pounds a month for rack space, networking and a slice of someone's time keeping it running. Total fixed cost: roughly 8,636 pounds a month, largely independent of how many requests you actually serve, up to the box's ceiling.&lt;/p&gt;

&lt;p&gt;Now say the cloud alternative costs, illustratively, 0.0015 pounds per request for a comparable model size. Plug in your own actual quote here, this is purely to show the shape of the curve, not a real price.&lt;/p&gt;

&lt;p&gt;At 1 million requests a month, your on-premise cost per request is 8,636 divided by 1,000,000, about 0.0086 pounds. The cloud option at 0.0015 pounds per request is nearly six times cheaper, because you are paying the box's full fixed cost to serve a trickle of traffic.&lt;/p&gt;

&lt;p&gt;At 50 million requests a month, the same box now costs 8,636 divided by 50,000,000, about 0.00017 pounds per request. The cloud option at that volume would cost roughly 75,000 pounds a month. The on-premise box just won by a wide margin, because you are finally using the capacity you paid for.&lt;/p&gt;

&lt;p&gt;Solve for the exact crossover and you get roughly 5.8 million requests a month, which is 8,636 divided by 0.0015. Below that, cloud is cheaper. Above it, on-premise is cheaper. Everything in this calculation depends on where your actual traffic sits relative to that one number, not on which option sounds more serious in an argument.&lt;/p&gt;

&lt;h2&gt;
  
  
  The sawtooth nobody mentions
&lt;/h2&gt;

&lt;p&gt;The crossover point above is not a smooth line in practice, it is a sawtooth. The moment your request volume exceeds one box's capacity, you do not scale smoothly, you buy a second box, and your fixed cost jumps by another 8,636 pounds a month in one step before per-request cost starts falling again as that new capacity fills up. If your growth curve crosses a capacity boundary right before a slow quarter, you can end up paying for two boxes' worth of fixed cost while only filling one and a half boxes' worth of demand. Cloud does not have this problem, it scales in whatever increment the provider sells, usually much finer than 'another entire server'. That smoothness is part of what you are actually paying the cloud premium for, and it rarely shows up as a line item in anyone's TCO spreadsheet.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this actually matters
&lt;/h2&gt;

&lt;p&gt;This is the exact spreadsheet I build with people evaluating whether to run inference on their own hardware instead of staying on a cloud API, including people looking at an on-premise deployment of what I build at Mickai. I always ask for the same two numbers first, measured request volume and utilisation, then show exactly where the crossover sits for those numbers and let the decision follow from the number rather than from an opinion. Anyone willing to answer the general question without asking for your request volume first is guessing.&lt;/p&gt;

&lt;p&gt;The variable I see people get wrong most often is utilisation, because nobody measures it honestly before they buy hardware. They estimate it optimistically, then wonder a year later why the on-premise box never paid for itself. What is the messiest fixed cost you have had to fold into a calculation like this, and has anyone else actually hit the sawtooth problem in production and had to plan a hardware purchase around it?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>infrastructure</category>
      <category>devops</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Separating 'the AI proposed this' from 'the system did this': a pattern for staged AI actions</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Tue, 20 Oct 2026 14:16:25 +0000</pubDate>
      <link>https://dev.to/mickai/separating-the-ai-proposed-this-from-the-system-did-this-a-pattern-for-staged-ai-actions-4jg6</link>
      <guid>https://dev.to/mickai/separating-the-ai-proposed-this-from-the-system-did-this-a-pattern-for-staged-ai-actions-4jg6</guid>
      <description>&lt;p&gt;I keep seeing the same failure mode in AI tooling: a model generates an action, and the same&lt;br&gt;
code path that generated it also executes it. Draft an email, send it. Suggest a database&lt;br&gt;
update, run it. There's no seam between "the model thinks this is a good idea" and "this&lt;br&gt;
actually happened."&lt;/p&gt;

&lt;p&gt;That seam matters more than it looks like it does, so here's the pattern I ended up building&lt;br&gt;
around it, and why.&lt;/p&gt;
&lt;h2&gt;
  
  
  The problem with "the model decided"
&lt;/h2&gt;

&lt;p&gt;If you've shipped an LLM-backed feature that does anything consequential, you've probably hit&lt;br&gt;
this: the model is right most of the time, wrong occasionally, and confidently wrong often&lt;br&gt;
enough to be a real problem. The usual fix is "add a human in the loop," but in practice that&lt;br&gt;
gets bolted on as a confirmation dialog in the UI, which means the authorisation logic lives&lt;br&gt;
in the frontend, not the system. Skip the dialog (a different client, a direct API call, a&lt;br&gt;
bug), and the action just runs.&lt;/p&gt;

&lt;p&gt;That's not a staged action. That's an unstaged action with a confirmation dialog in front of&lt;br&gt;
it sometimes.&lt;/p&gt;
&lt;h2&gt;
  
  
  What an actual execution boundary looks like
&lt;/h2&gt;

&lt;p&gt;The pattern I use treats "propose" and "execute" as genuinely separate operations with a hard&lt;br&gt;
boundary between them, enforced server-side, not in whatever client happens to be calling in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;propose&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;staged_action_id&lt;/span&gt;
  &lt;span class="c1"&gt;# writes an immutable record: what was proposed, by what, when&lt;/span&gt;
  &lt;span class="c1"&gt;# does NOT perform the action&lt;/span&gt;
  &lt;span class="c1"&gt;# returns an id, nothing else&lt;/span&gt;

&lt;span class="n"&gt;authorise&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;staged_action_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;actor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;bool&lt;/span&gt;
  &lt;span class="c1"&gt;# checks actor against policy for THIS action type&lt;/span&gt;
  &lt;span class="c1"&gt;# writes who approved it and when&lt;/span&gt;
  &lt;span class="c1"&gt;# independent of propose(); a different principal can call this&lt;/span&gt;

&lt;span class="n"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;staged_action_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="c1"&gt;# only runs if authorise() succeeded for this id&lt;/span&gt;
  &lt;span class="c1"&gt;# the action handler never sees a raw "do this" call,&lt;/span&gt;
  &lt;span class="c1"&gt;# only "execute this specific staged action"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Three things fall out of structuring it this way, and they're the actual point:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. The model never has execute access.&lt;/strong&gt; It calls &lt;code&gt;propose()&lt;/code&gt;. That's the entire surface&lt;br&gt;
area it has. There's no code path from "model output" to "side effect" that doesn't pass&lt;br&gt;
through &lt;code&gt;authorise()&lt;/code&gt;, because &lt;code&gt;execute()&lt;/code&gt; refuses to run anything without a valid&lt;br&gt;
authorisation record attached to that specific staged action id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. The audit record is a side effect of the architecture, not a logging statement someone&lt;br&gt;
remembered to add.&lt;/strong&gt; &lt;code&gt;propose()&lt;/code&gt;, &lt;code&gt;authorise()&lt;/code&gt; and &lt;code&gt;execute()&lt;/code&gt; each write their own&lt;br&gt;
immutable entry. You don't need a separate "make sure we log AI actions" effort, because&lt;br&gt;
there's no way to execute one without the record existing first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. You can authorise by policy, not by UI.&lt;/strong&gt; Since &lt;code&gt;authorise()&lt;/code&gt; is a real function call&lt;br&gt;
with its own identity and its own argument (which staged action, which actor), you can wire&lt;br&gt;
it to anything: a human clicking approve, an automated policy for low-risk action types, a&lt;br&gt;
second model doing a narrower risk check. The execution boundary doesn't care how&lt;br&gt;
authorisation happened, only that it did, and that it's recorded against the right id.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where this gets interesting: sealing the record
&lt;/h2&gt;

&lt;p&gt;The part above is a reasonably standard staged-command pattern, nothing novel there. Where it&lt;br&gt;
got more interesting for us is what backs the audit record once an action has run.&lt;/p&gt;

&lt;p&gt;A log table that a sufficiently privileged user can edit isn't an audit record, it's a claim.&lt;br&gt;
For environments where you actually need to prove what happened, not just assert it, we seal&lt;br&gt;
each attestation under post-quantum signatures at write time, so an entry can be&lt;br&gt;
independently verified by anyone holding the public key, without needing to trust whoever&lt;br&gt;
operates the system that wrote it. We've written that part up separately if you want the&lt;br&gt;
mechanism in detail: &lt;a href="https://doi.org/10.5281/zenodo.22143718" rel="noopener noreferrer"&gt;The Offline Attestation Record&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I'd do differently if starting over
&lt;/h2&gt;

&lt;p&gt;Two things bit us during implementation that are worth flagging if you're building something&lt;br&gt;
similar:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Don't let &lt;code&gt;propose()&lt;/code&gt; accept anything other than a closed set of action types.&lt;/strong&gt; We
initially let it accept a free-form action descriptor for flexibility. That meant
&lt;code&gt;authorise()&lt;/code&gt; had to parse and interpret arbitrary structures to apply policy, which is
exactly the kind of ambiguity you don't want between "what was approved" and "what runs."
Closed, versioned action types fixed this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;execute()&lt;/code&gt; needs its own idempotency key, separate from the staged action id.&lt;/strong&gt; A
staged action can legitimately be authorised twice if your approval flow retries, and you
do not want that to mean "run twice."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is one piece of a larger pattern we use across a sovereign, on-premise AI system (every&lt;br&gt;
studio, email, CRM, meetings, calls the same substrate rather than implementing its own&lt;br&gt;
authorisation), but the propose/authorise/execute split stands on its own in any AI system&lt;br&gt;
where "the model decided" is currently also "the model did it."&lt;/p&gt;

&lt;p&gt;Happy to go deeper on any part of this in the comments, particularly interested if anyone's&lt;br&gt;
hit different failure modes with the UI-confirmation-dialog approach I mentioned at the top.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>architecture</category>
      <category>security</category>
      <category>opensource</category>
    </item>
    <item>
      <title>ISO 42001 vs ISO 27001: Do You Need Both Standards?</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Sat, 26 Sep 2026 08:02:42 +0000</pubDate>
      <link>https://dev.to/mickai/iso-42001-vs-iso-27001-do-you-need-both-standards-g8b</link>
      <guid>https://dev.to/mickai/iso-42001-vs-iso-27001-do-you-need-both-standards-g8b</guid>
      <description>&lt;p&gt;&lt;strong&gt;Yes, if you build or use AI systems. ISO/IEC 27001 governs information security. ISO/IEC 42001 governs how an organisation manages AI, covering impact assessment, human oversight and lifecycle control. The two share a management system structure, so 27001 gives you a head start, not an exemption. Mickai supplies one part: a signed record of what the AI actually did.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do you need ISO 42001 if you already have ISO 27001?
&lt;/h2&gt;

&lt;p&gt;Yes, in almost every case where AI touches a decision that matters. &lt;a href="https://www.iso.org/standard/27001" rel="noopener noreferrer"&gt;ISO/IEC 27001&lt;/a&gt; and &lt;a href="https://www.iso.org/standard/42001" rel="noopener noreferrer"&gt;ISO/IEC 42001&lt;/a&gt; are not competing versions of the same idea. They ask different questions about different objects. 27001 asks whether you are protecting information: confidentiality, integrity, availability, and the controls that hold those in place. 42001 asks whether you are managing artificial intelligence as something your organisation is accountable for, which includes what the system is used for, who signs off on its outputs, what it could do to the people affected by it, and how you would notice if it began behaving differently from the system you approved.&lt;/p&gt;

&lt;p&gt;There is one narrow case where 27001 on its own is defensible. If no AI system sits anywhere in a process that touches a customer, a regulated decision or personal data, and you have written that boundary into your scope statement and can hold it under questioning, there is nothing to manage under 42001. In practice that boundary erodes quickly. A team connects a model into a workflow through an API, or a supplier adds an AI feature to a tool you already pay for, and the claim expires before anyone updates the document.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does each standard actually cover?
&lt;/h2&gt;

&lt;p&gt;ISO/IEC 27001 specifies the requirements for an information security management system: how you establish, operate, monitor and improve the way your organisation protects information, and how you select and justify controls against assessed risk. ISO/IEC 42001, published in 2023, does the equivalent job for an AI management system. It is written for organisations that develop AI, provide AI, or use AI built by someone else, which means it lands on buyers as well as vendors.&lt;/p&gt;

&lt;p&gt;The distinction that matters commercially is this. 27001 is largely concerned with harm to the organisation and the information it holds. 42001 pushes you to consider harm to the people and groups on the receiving end of the system. That is a category of risk most security functions have no existing method for assessing, and it is the reason a 27001 team cannot simply extend its register and declare the job done.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do the two standards overlap?
&lt;/h2&gt;

&lt;p&gt;Structurally, a great deal. Both follow the harmonised management system structure, so the outer clauses are familiar: context of the organisation, leadership, planning, support, operation, performance evaluation, improvement. If you already hold 27001 you own the machinery. A defined scope, documented management commitment, a competence and training framework, document control, an internal audit programme, management review, and corrective action that actually closes.&lt;/p&gt;

&lt;p&gt;That machinery is the expensive part to build from nothing, and you have already paid for it. The assets that reuse cleanly are the internal audit programme, the supplier assessment process, the change management route, the incident process and the management review cadence. What does not reuse is the risk content. An AI risk assessment asks about data provenance, model behaviour as inputs shift, automation bias in the people reviewing outputs, and the effect of a wrong answer on a real person. None of that appears in a confidentiality, integrity and availability register. The &lt;a href="https://www.ncsc.gov.uk/collection/machine-learning" rel="noopener noreferrer"&gt;NCSC's machine learning principles&lt;/a&gt; is worth reading next to your existing controls for the same reason: the attack surface it describes, including training data and model behaviour, is not the surface those controls were written against.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does ISO 42001 add that ISO 27001 does not?
&lt;/h2&gt;

&lt;p&gt;Four things: AI impact assessment, human oversight as a designed control, lifecycle control from data sourcing to retirement, and your position in the AI value chain. They arrive roughly in that order of trouble.&lt;/p&gt;

&lt;p&gt;First, AI impact assessment. You have to assess the consequences of the system for individuals and groups, not only the risk to your own operations, and you have to do it before deployment and again when the system changes materially.&lt;/p&gt;

&lt;p&gt;Second, human oversight as a designed control rather than a claim. Naming an accountable owner is not sufficient. You have to show where a person can intervene, what that person sees at the point of intervention, and whether the decision they take is recorded.&lt;/p&gt;

&lt;p&gt;Third, lifecycle control. Data sourcing, preparation, model development or selection, evaluation, deployment, monitoring in service, and retirement. Each stage carries expectations, and monitoring is where most organisations are thinnest, because it needs evidence produced continuously rather than a document written once.&lt;/p&gt;

&lt;p&gt;Fourth, position in the value chain. 42001 separates developing an AI system from using one built by someone else, and expects you to carry the obligations attached to your position. Most organisations occupy both positions at once in different processes, and only find out during the first internal audit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you run one integrated management system?
&lt;/h2&gt;

&lt;p&gt;Yes, and I would not run them apart. One scope statement naming both domains. One risk register with AI-specific fields added rather than a second register alongside it. One internal audit programme with the AI clauses folded into the existing schedule. One management review covering both. Auditors are used to integrated systems, and two parallel systems create their own failure mode: two sets of records that quietly disagree with each other.&lt;/p&gt;

&lt;p&gt;Two things need fixing during the merge. Your risk appetite statement, if it is written purely in security language, has nothing to say about a model that is confidently wrong while every control passes. And your supplier controls, which almost certainly ask a vendor about its security posture and certifications, probably say nothing about where a model came from, what it was trained on, when it will change underneath you, and whether you will be told when it does.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who is actually asking suppliers for ISO 42001?
&lt;/h2&gt;

&lt;p&gt;Buyers in regulated sectors, and the procurement teams supporting them. I am not going to put a figure on it, because I have not run a survey and I will not invent one. What I see in procurement conversations is a pattern rather than a statistic: the security questionnaire has grown an AI section. It asks for an AI policy, an inventory of AI systems in use, evidence of human oversight over automated decisions, and a plain statement of where processing physically happens.&lt;/p&gt;

&lt;p&gt;Certification is often not the stated requirement yet. Frequently the requirement is the evidence that certification would have forced you to produce. That distinction is worth holding onto, because it means you can begin with the inventory and the records, answer the questions in front of you, and decide about the certificate on your own timetable.&lt;/p&gt;

&lt;h2&gt;
  
  
  What evidence does an AI management system need day to day?
&lt;/h2&gt;

&lt;p&gt;Records of what the system actually did, rather than descriptions of what it is meant to do. Both standards are satisfied by evidence, and for AI the evidence hardest to produce after the fact is action level: which model version ran, on which inputs, under which configuration, and who approved the output before it had an effect on anyone.&lt;/p&gt;

&lt;p&gt;That is the part we build. The Mickai Sovereign Intelligence Operating System (SIOS) runs on hardware the customer owns, is offline capable and moves no data offsite, and every consequential action is sealed into an Open Audit Record. Each entry is signed under ML-DSA-65, the post-quantum signature scheme &lt;a href="https://csrc.nist.gov/pubs/fips/204/final" rel="noopener noreferrer"&gt;NIST published as FIPS 204&lt;/a&gt; in 2024. An auditor exports the record and verifies it offline with a public key, using tools that are not ours.&lt;/p&gt;

&lt;p&gt;That makes the record tamper-evident, which is not the same thing as tamper-proof, and I will not claim otherwise. Nothing stops a person altering a stored record. What the signature does is make an altered record fail verification, so the alteration becomes visible to whoever checks instead of invisible. For an audit, visible failure is the property you want. And because consequential actions wait for a named person to approve them, the human oversight requirement produces its own record as a by-product rather than an assertion you have to defend later.&lt;/p&gt;

&lt;p&gt;Let me be exact about scope. This is one part of the picture. Neither standard is satisfied by software. You still need the policy, the scope statement, the impact assessments, the risk treatment and the management review, and no product supplies those. SIOS is in closed beta, with one regulated company onboarding as a design partner.&lt;/p&gt;

&lt;p&gt;None of this is an argument against cloud, or against the companies building the compute layer everyone depends on. Cloud remains the right place for a large amount of non-regulated work. The assumption worth arguing with is narrower: that a regulated organisation has to rent its intelligence, send its data somewhere else, and take a vendor's word for what happened to it afterwards. ISO/IEC 42001 is the first international AI management system standard, and what it asks for is your working.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is ISO 42001 a replacement for ISO 27001?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. They cover different objects, and certification to one says nothing about the other. ISO/IEC 27001 covers information security management. ISO/IEC 42001 covers the management of AI, including impact on affected people, human oversight and lifecycle control. An organisation running AI over regulated data will usually hold both, operated as one integrated management system rather than two parallel ones.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How much of our ISO 27001 work can we reuse for ISO 42001?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most of the structure, little of the content. The shared management system clauses mean your scope, leadership commitments, competence framework, document control, internal audit programme and management review all carry over with additions. What does not carry over is the risk work. AI risk covers data provenance, model behaviour and harm to affected individuals, none of which a security risk register addresses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does ISO 42001 certification make us EU AI Act compliant?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Certification to a management system standard is evidence that you run a governed process, not a verdict on any specific legal obligation. It helps, because much of what the standard forces you to document is what a regulator would ask to see. Obligations still attach to particular systems and particular uses, so you must assess your own systems against the law that applies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do we need ISO 42001 to sell AI into the public sector?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not as a universal gate today, but the questions behind it are already in procurement packs. Buyers ask for an AI policy, an inventory of AI systems in use, evidence of human oversight over automated decisions, and where processing physically happens. If you can answer those with records instead of assurances, the certificate becomes a formality rather than a project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How long does ISO 42001 certification usually take?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It depends on your scope and how much of a 27001 system you already operate, and I will not quote a figure I cannot source. The shape is consistent: gap analysis, implementation, internal audit, then a two-stage external audit by an accredited certification body. ISO itself does not certify organisations. The constraint is usually accumulating evidence, not writing policy.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related briefings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UK AI regulation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/is-there-a-uk-ai-act-how-the-uk-regulates-ai-today-4m3p"&gt;Is There a UK AI Act? How the UK Regulates AI Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-cyber-security-code-of-practice-who-it-applies-to-39l8"&gt;AI Cyber Security Code of Practice: Who It Applies To&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/does-cyber-essentials-cover-the-ai-tools-your-staff-use-22b"&gt;Does Cyber Essentials Cover the AI Tools Your Staff Use?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ico-code-of-practice-on-ai-and-automated-decision-making-870"&gt;ICO Code of Practice on AI and Automated Decision-Making&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-for-essential-services-what-uk-regulation-requires-2599"&gt;AI for Essential Services: What UK Regulation Requires&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data protection and UK GDPR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/uk-gdpr-and-ai-does-your-data-have-to-stay-in-the-uk-1a65"&gt;UK GDPR and AI: Does Your Data Have to Stay in the UK?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/uk-data-storage-vs-ai-processing-what-is-the-difference-4gig"&gt;UK Data Storage vs AI Processing: What Is the Difference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part of a series of 60 briefings on deploying and governing AI in UK regulated organisations, archived with a DOI at &lt;a href="https://doi.org/10.5281/zenodo.22975756" rel="noopener noreferrer"&gt;10.5281/zenodo.22975756&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluating AI for a regulated organisation?&lt;/strong&gt; Mickai runs on hardware you own, offline. Consequential actions wait for a named person to approve them, and what the AI did is sealed into a signed record an auditor can check without us. Applications for the invitation-only closed beta are open. &lt;a href="https://mickai.co.uk/beta" rel="noopener noreferrer"&gt;Apply for the closed beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by Micky Irons, founder and chief executive of Mickai LTD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Defence Cyber Certification: Do Your AI Tools Count?</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Sat, 26 Sep 2026 08:02:00 +0000</pubDate>
      <link>https://dev.to/mickai/defence-cyber-certification-do-your-ai-tools-count-580f</link>
      <guid>https://dev.to/mickai/defence-cyber-certification-do-your-ai-tools-count-580f</guid>
      <description>&lt;p&gt;&lt;strong&gt;Yes, if they sit inside the certification scope. Def Stan 05-138 Issue 4 scopes your whole corporate environment, not just contract data, so AI tools count as software or cloud services under Cyber Essentials. The MOD has asked industry partners to hold DCC Level 0 by 31 December 2026. Mickai installs on hardware you already hold in scope.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Defence Cyber Certification and who needs it?
&lt;/h2&gt;

&lt;p&gt;Defence Cyber Certification is an independent audit of a supplier's cyber security against Def Stan 05-138. The MOD created it with IASME, who act as the scheme's certification authority, and it sits alongside two things that were already in place: DEFCON 658, which carries the contractual terms, and the Cyber Security Model itself.&lt;/p&gt;

&lt;p&gt;The mechanism runs in a fixed order. An MOD delivery team completes an initial risk assessment on a contract, and that assessment determines a Cyber Risk Profile numbered Level 0 to Level 3. You are given a Risk Assessment Reference number and the required level at early market engagement. You then self-assess against the Cyber Security Model requirements using a Supplier Assurance Questionnaire on the Supplier Cyber Protection Service.&lt;/p&gt;

&lt;p&gt;DCC is the independently audited version of that self-assessment. Rather than telling the MOD you meet the controls, a licensed certification body examines you and says so.&lt;/p&gt;

&lt;p&gt;One point catches people out. A DCC certificate does not currently release you from the questionnaire. The &lt;a href="https://www.gov.uk/guidance/cyber-security-model" rel="noopener noreferrer"&gt;gov.uk Cyber Security Model guidance&lt;/a&gt; states that suppliers holding a valid DCC certificate are not yet exempt from completing elements of the SAQ through the Supplier Cyber Protection Service. Budget for both.&lt;/p&gt;

&lt;p&gt;As for who needs it: anyone in the defence supply chain, prime or lower tier. Suppliers are responsible for flow-down, and DEFCON 658 contains the obligations a supplier must place on its own subcontractors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does Level 0 actually require?
&lt;/h2&gt;

&lt;p&gt;Three controls from &lt;a href="https://www.gov.uk/government/publications/cyber-security-for-defence-suppliers-def-stan-05-138-issue-4" rel="noopener noreferrer"&gt;Def Stan 05-138 Issue 4&lt;/a&gt;. Not thirty. Three.&lt;/p&gt;

&lt;p&gt;Control 0001, Cyber Essentials. The standard requires the supplier to hold Cyber Essentials certification that covers the scope required for all aspects of the contract, and to commit to maintaining it for the duration of the contract.&lt;/p&gt;

&lt;p&gt;Control 2314, ensuring personal data is processed in compliance with UK GDPR.&lt;/p&gt;

&lt;p&gt;Control 2500, resilient networks and systems. The supplier must build resilience against cyber attack and system failure into the design, implementation, operation and management of the systems supporting its business functions and protecting its data.&lt;/p&gt;

&lt;p&gt;For scale: Level 1 is 101 controls, Level 2 is 139, Level 3 is 144. Cyber Essentials Plus, control 0002, only enters at Level 2. Level 0 is genuinely a floor, and most of the work at that floor is the Cyber Essentials scope question.&lt;/p&gt;

&lt;p&gt;Which is where AI arrives.&lt;/p&gt;

&lt;h2&gt;
  
  
  When does an AI tool fall inside your certification scope?
&lt;/h2&gt;

&lt;p&gt;Nearly always, because the standard scopes your organisation rather than your contract.&lt;/p&gt;

&lt;p&gt;Clause 1.1 of Issue 4 sets the scope as the supplier's overarching corporate or enterprise environment, covering all supplier organisations, systems, processes, procedures and data necessary for the effective protection of data and functions, going beyond the protection of just the information handed to the supplier for the contracted output. Clause 1.2 says the standard is intentionally broad.&lt;/p&gt;

&lt;p&gt;People misread this consistently. They assume the test is whether the AI tool touches MOD data. Under Issue 4 that is not the test. The test is whether the tool forms part of the enterprise environment that keeps business functions running and data protected. A summarisation assistant that half your engineering team pastes into is part of that environment whether or not a single MOD document has ever passed through it.&lt;/p&gt;

&lt;p&gt;So the useful question is not whether your AI is in scope. It is whether you can describe your AI honestly inside a boundary you can defend to an assessor.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Cyber Essentials treat AI software and cloud services?
&lt;/h2&gt;

&lt;p&gt;As software, and as cloud services. There is no AI control.&lt;/p&gt;

&lt;p&gt;Worth stating plainly: the current &lt;a href="https://www.ncsc.gov.uk/files/cyber-essentials-requirements-for-it-infrastructure-v3-3.pdf" rel="noopener noreferrer"&gt;Cyber Essentials requirements for IT infrastructure, version 3.3, April 2026&lt;/a&gt;, does not mention artificial intelligence anywhere. That is not a gap to exploit. It means your AI tooling gets classified under definitions that already exist.&lt;/p&gt;

&lt;p&gt;The scheme defines software to include operating systems, commercial off-the-shelf applications, extensions, interpreters, scripts and libraries. A model running on a server you own is software on an in-scope device. Scope itself is defined as the networks, hardware and software assets, and cloud services included in the assessment.&lt;/p&gt;

&lt;p&gt;A hosted AI service meets the scheme's cloud definition: an on-demand, scalable service on shared infrastructure, reached over the internet through an account, storing or processing data for your organisation. Then comes the line that settles the argument. Cloud services cannot be excluded from scope.&lt;/p&gt;

&lt;p&gt;For cloud, the applicant organisation is always responsible for ensuring all controls are implemented, even where the provider implements some of them. Table 1 of the requirements sets out who typically implements each control. For SaaS, user access control is yours and secure configuration is shared. Where the provider implements a control on your behalf, you must show the provider has committed to it through contractual clauses or documents referenced by the contract.&lt;/p&gt;

&lt;p&gt;That last requirement is what quietly costs money. Every AI service in your estate needs a named account owner, MFA, a defensible configuration position and contract evidence for whatever the provider does on your behalf. Multiply that by the number of AI subscriptions that arrived without procurement seeing them.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the 31 December 2026 date mean for suppliers?
&lt;/h2&gt;

&lt;p&gt;It is a request from the MOD, not a statute. In a &lt;a href="https://defencedigital.blog.gov.uk/2026/05/08/one-year-of-defence-cyber-certification-building-stronger-cyber-resilience-together/" rel="noopener noreferrer"&gt;Defence Digital blog post dated 8 May 2026&lt;/a&gt;, the MOD said it has asked all industry partners to achieve Level 0 DCC certification by 31 December 2026, including obtaining Cyber Essentials for all applicable business-critical systems in scope.&lt;/p&gt;

&lt;p&gt;Treat it as a commercial date rather than a legal one. Requirements of this kind arrive through tender conditions and contract terms, so the consequence of missing it is not a fine. It is losing a bid, or becoming the lower-tier supplier a prime cannot use because its own flow-down obligation under DEFCON 658 requires it to place the requirement on you.&lt;/p&gt;

&lt;p&gt;If you are starting now, the scope conversation is the critical path, not the audit booking. Getting a certification body to agree your boundary takes longer than most people budget, and each shadow AI subscription you discover late moves that boundary again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does on-premise AI make scoping simpler?
&lt;/h2&gt;

&lt;p&gt;Structurally, yes, for one reason: there is no cloud service to scope.&lt;/p&gt;

&lt;p&gt;I build the Mickai Sovereign Intelligence Operating System, so let me be straight about what it does and does not do here. It does not certify you. Mickai holds no DCC or Cyber Essentials certificate, and no product can hand you a certification. What changes is the shape of the problem.&lt;/p&gt;

&lt;p&gt;SIOS installs on hardware you already own and already hold inside your boundary. It is &lt;a href="https://mickai.co.uk/offline-ai-assistant" rel="noopener noreferrer"&gt;offline capable, with no data egress&lt;/a&gt;. The AI capability stops being a cloud service you must scope, evidence with contractual clauses and re-evidence when a provider changes its terms. It becomes software on servers already in your asset register and already covered by your five technical controls.&lt;/p&gt;

&lt;p&gt;Two things then help on the evidence side rather than the scope side. Every consequential action is sealed in the Open Audit Record under ML-DSA-65, the post-quantum signature scheme &lt;a href="https://csrc.nist.gov/pubs/fips/204/final" rel="noopener noreferrer"&gt;NIST published as FIPS 204 in 2024&lt;/a&gt;. That record is tamper-evident, not tamper-proof. Nothing physically stops someone altering the bytes. Altering them makes verification fail, and an auditor can verify an exported record offline with a public key, using tools that are not ours. Control 2500 asks for resilience you can demonstrate, and clause 2.4 asks for a documented, implemented control with auditable evidence. A record an assessor can check without trusting me is the kind of evidence that survives an audit.&lt;/p&gt;

&lt;p&gt;Consequential actions also wait for a named person to approve them, which produces the human accountability trail that scoping documents keep asserting and estates rarely deliver.&lt;/p&gt;

&lt;p&gt;None of this is an argument against cloud. Cloud remains the right answer for a great deal of non-regulated work, and the organisations building the compute and cloud layer are doing necessary work. The narrower argument is this: for work sitting inside a Def Stan 05-138 boundary, renting your intelligence means importing a third party into that boundary and taking their word for what happened to your data. That is an assumption, not a law.&lt;/p&gt;

&lt;p&gt;SIOS is in closed beta. Fourteen of sixty-three studios are production-ready, forty-nine are in development, and one regulated company is onboarding as a design partner. The partner and its sector stay confidential. If document reading matters to you, a local OCR runtime has read scanned PDFs in controlled tests, and the SIOS extraction and ingestion integration is still being completed. More on the wider position at &lt;a href="https://mickai.co.uk/sovereign-ai" rel="noopener noreferrer"&gt;sovereign AI&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is Defence Cyber Certification mandatory?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not by law. DCC is a contractual and policy expectation rather than a legal mandate. The MOD has asked industry partners to reach Level 0 by 31 December 2026, and DEFCON 658 carries the contractual terms of the Cyber Security Model. In practice it arrives through tender conditions and prime contractor flow-down, so treat it as commercially compulsory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a cloud AI service have to sit inside our Cyber Essentials scope?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes. The Cyber Essentials requirements for IT infrastructure state that cloud services cannot be excluded from scope where your organisation's data or services are hosted on them. A hosted AI assistant, reached through an account and processing your data, meets the scheme's definition of a cloud service. You remain responsible for ensuring all five controls are implemented.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is the difference between Defence Cyber Certification and Def Stan 05-138?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Def Stan 05-138 is the standard. It defines the four Cyber Risk Profiles and the controls required at each level. DCC is the certification scheme that independently audits you against those controls, run with IASME as certification authority. The standard tells you what to do. The certificate is third-party evidence that you did it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do subcontractors need Defence Cyber Certification too?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Often, yes. Suppliers are responsible for flow-down, and DEFCON 658 contains the contractual obligations a supplier must place on its subcontractors. The level required depends on the Cyber Risk Profile assessed for the work that subcontractor actually does, so it is not automatically the level the prime holds. Ask your prime what they intend to flow down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which Defence Cyber Certification level does our contract need?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The MOD delivery team decides. An initial risk assessment produces a Cyber Risk Profile from Level 0 to Level 3, and you receive a Risk Assessment Reference number with the required level at early market engagement. Level 0 needs three Def Stan 05-138 controls. Levels 2 and 3 add Cyber Essentials Plus and substantially more.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related briefings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Procurement and defence&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/buy-ai-through-g-cloud-and-government-frameworks-guide-263n"&gt;Buy AI Through G-Cloud and Government Frameworks: Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-disclosure-in-public-sector-tenders-whats-required-3nb5"&gt;AI Disclosure in Public Sector Tenders: What's Required?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-bid-evaluation-in-public-procurement-is-it-lawful-20an"&gt;AI Bid Evaluation in Public Procurement: Is It Lawful?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-for-procurement-contract-review-is-it-allowed-1072"&gt;AI for Procurement Contract Review: Is It Allowed?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-supplier-contract-clauses-a-uk-buyers-checklist-2llh"&gt;AI Supplier Contract Clauses: A UK Buyer's Checklist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;UK AI regulation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/is-there-a-uk-ai-act-how-the-uk-regulates-ai-today-4m3p"&gt;Is There a UK AI Act? How the UK Regulates AI Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-cyber-security-code-of-practice-who-it-applies-to-39l8"&gt;AI Cyber Security Code of Practice: Who It Applies To&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part of a series of 60 briefings on deploying and governing AI in UK regulated organisations, archived with a DOI at &lt;a href="https://doi.org/10.5281/zenodo.22975756" rel="noopener noreferrer"&gt;10.5281/zenodo.22975756&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluating AI for a regulated organisation?&lt;/strong&gt; Mickai runs on hardware you own, offline. Consequential actions wait for a named person to approve them, and what the AI did is sealed into a signed record an auditor can check without us. Applications for the invitation-only closed beta are open. &lt;a href="https://mickai.co.uk/beta" rel="noopener noreferrer"&gt;Apply for the closed beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by Micky Irons, founder and chief executive of Mickai LTD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>JSP 936 for AI Suppliers: What the MOD Now Requires</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Sat, 26 Sep 2026 08:01:17 +0000</pubDate>
      <link>https://dev.to/mickai/jsp-936-for-ai-suppliers-what-the-mod-now-requires-2o8d</link>
      <guid>https://dev.to/mickai/jsp-936-for-ai-suppliers-what-the-mod-now-requires-2o8d</guid>
      <description>&lt;p&gt;&lt;strong&gt;JSP 936 Part 1 is the MOD's directive on dependable AI. It sets mandatory requirements built on five ethical principles: human-centricity, responsibility, understanding, bias and harm mitigation, and reliability. Suppliers must show governance, assurance and human accountability across the AI lifecycle. Mickai answers the evidence question with a tamper-evident record sealed before each action runs.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is JSP 936 and does it apply to suppliers?
&lt;/h2&gt;

&lt;p&gt;JSP 936 Part 1, Dependable Artificial Intelligence (AI) in Defence, is the MOD's directive on how AI-enabled capability is adopted and held to account. It is departmental policy, so strictly speaking it binds the MOD and not your company, but it reaches you through the contract. It was published on 13 November 2024 and &lt;a href="https://www.gov.uk/government/publications/jsp-936-dependable-artificial-intelligence-ai-in-defence-part-1-directive" rel="noopener noreferrer"&gt;gov.uk&lt;/a&gt; calls it the principal policy framework governing the safe and responsible adoption of AI in the MOD.&lt;/p&gt;

&lt;p&gt;That distinction matters less than bid teams hope. Policy that binds the buyer arrives at the supplier through the contract. What you will be asked for at bid stage, and again at every gate review after it, is evidence that your system can be operated in line with the directive: who is accountable, what was assured, and what actually happened. If you sit below a prime, it reaches you through flow-down. Read the clauses in your own contract rather than a summary of them, including this one.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are the five ethical principles a supplier must support?
&lt;/h2&gt;

&lt;p&gt;The directive rests on the five ethical principles the MOD set out in its 2022 policy on AI-enabled capability, &lt;em&gt;Ambitious, Safe, Responsible&lt;/em&gt;: human-centricity, responsibility, understanding, bias and harm mitigation, and reliability. They are not slogans. Each one implies a specific artefact that you either have or do not have.&lt;/p&gt;

&lt;p&gt;Human-centricity asks who is affected by the system and how their interests were weighed. Responsibility asks for a named human accountable for a given use, a person rather than a team or a function. Understanding asks whether the people operating the system can explain what it does and where it fails, which is a training and documentation problem as much as a technical one. Bias and harm mitigation asks what you tested for and what the testing found, including the results you did not want. Reliability asks for evidence that the system performs as specified under the conditions it will actually meet.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the directive require on governance and assurance?
&lt;/h2&gt;

&lt;p&gt;Governance and assurance across the AI lifecycle are the two things the directive is built around. Governance means a documented owner, defined decision rights, and a route by which a concern stops the work rather than being noted and passed along. Assurance means activity proportionate to the risk, evidenced at the time, and repeated when the system changes.&lt;/p&gt;

&lt;p&gt;In a bid this lands as three questions. Who decides this system is fit for use, by name and role. What did you do to test that judgement, and what did the testing produce. What happens when the model, the data or the threat picture changes. Be clear about what sits alongside this rather than inside it. The &lt;a href="https://www.gov.uk/guidance/cyber-security-model" rel="noopener noreferrer"&gt;Cyber Security Model&lt;/a&gt; and Def Stan 05-138 cover supplier cyber risk against a specific contract. The &lt;a href="https://www.ncsc.gov.uk/collection/machine-learning-principles" rel="noopener noreferrer"&gt;NCSC machine learning principles&lt;/a&gt; covers attack surface that conventional security review misses, including poisoned training data and adversarial input. Both matter. Neither answers the AI directive, and answering one well is not credit against the others.&lt;/p&gt;

&lt;h2&gt;
  
  
  What evidence does human accountability actually need?
&lt;/h2&gt;

&lt;p&gt;It needs a record that ties a named person to a specific action at a specific time, and that stands up when checked by someone who has no reason to trust you. That is a higher bar than most AI deployments clear, and it is where assurance conversations tend to break.&lt;/p&gt;

&lt;p&gt;Everybody can produce a policy stating that a human approves high-consequence output. Very few can produce the approval itself, in a form that cannot be quietly rewritten afterwards. Application logs are normally mutable by anyone with database access, which includes your own administrators and anyone who has taken their credentials. A log your insiders can edit is not evidence of oversight. It is a claim about oversight, stored in a place where claims can be changed. An assessor who has seen that pattern before will ask the follow-up question.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does JSP 936 expect across the AI lifecycle?
&lt;/h2&gt;

&lt;p&gt;Lifecycle means the evidence is not a single gate at delivery. Data, build, evaluation, deployment, change and retirement each carry their own record, and those records have to stay connected to each other.&lt;/p&gt;

&lt;p&gt;The chain runs like this. Where the data came from and on what licence. Which model version and which weights were live. What the evaluation of that version produced. What changed at the last update and who signed it off. The common failure is simple and expensive: an audit in month eighteen asks what the system did in month four, the model has been updated eleven times since, and nobody recorded which version produced the output under question. Binding the version to the decision at the moment the decision is made solves that. Nothing reconstructed afterwards does, and reconstruction is exactly what an assessor is trained to spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you show what an AI system actually did?
&lt;/h2&gt;

&lt;p&gt;You seal the record before the action runs, and you let somebody else verify it without your help. That is the problem the Mickai Sovereign Intelligence Operating System was built around. SIOS runs on hardware the customer owns, is offline capable, and moves no data off the estate.&lt;/p&gt;

&lt;p&gt;Every consequential action is sealed into the Open Audit Record under ML-DSA-65, the post-quantum signature scheme NIST published as &lt;a href="https://csrc.nist.gov/pubs/fips/204/final" rel="noopener noreferrer"&gt;FIPS 204&lt;/a&gt; in 2024. The order is deliberate: seal, persist, then act. A consequential action waits for a named person to approve it, and that approval is part of the sealed record rather than a note beside it.&lt;/p&gt;

&lt;p&gt;The record is tamper-evident, not tamper-proof, and the difference is the whole argument. Tamper-proof would mean the record cannot be altered, and nobody can honestly promise that about data sitting on a machine that somebody administers. Tamper-evident means alteration breaks verification: change a byte and the signature stops checking out. Delete the whole record and the absence is conspicuous rather than silent. The property rests on key custody. Protect the signing keys and it holds. Lose control of them and it does not. That is the honest shape of the property, and an assessor can test it.&lt;/p&gt;

&lt;p&gt;An auditor exports the record and verifies it offline with a public key, using tools that are not ours. That is the point of the design. Evidence you have to take my word for is not evidence. There is more detail on &lt;a href="https://mickai.co.uk/articles/what-an-auditor-can-independently-check-in-a-sealed-ai-trail" rel="noopener noreferrer"&gt;what an auditor can independently check&lt;/a&gt; and on the &lt;a href="https://mickai.co.uk/ai-audit-trail" rel="noopener noreferrer"&gt;audit trail itself&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Some practical detail, because bid teams ask. SIOS covers 63 studios, 14 of them production-ready at launch and 49 in development, with 50 specialised models. The closed beta is open, with one regulated company onboarding as a design partner. I am not naming the partner or the sector it works in. On scanned paper, which defence work generates in volume: a local OCR runtime has read scanned PDFs in controlled tests, and the extraction and ingestion integration into SIOS is still being completed. I would rather tell you that than let you assume it is finished. The underlying approach is covered by 104 filed UK patent applications carrying 2,340 claims, owned by Mickai LTD. Filed, not granted.&lt;/p&gt;

&lt;p&gt;None of this is an argument against the companies building the compute or the cloud layer. Cloud stays valuable for work that is not regulated, and most of what any organisation does is not regulated. The assumption worth arguing with is narrower: that a regulated organisation must rent its intelligence, ship its data offsite, and take a vendor's word for what happened to it. For &lt;a href="https://mickai.co.uk/sovereign-ai" rel="noopener noreferrer"&gt;sovereign AI in defence&lt;/a&gt; that assumption is the thing that fails assurance.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you work through before you bid?
&lt;/h2&gt;

&lt;p&gt;Read Part 1 yourself rather than a consultant's summary of it. Name the accountable person for each use case, as a person. Write down decision rights and the escalation route, then test that the route actually stops work. Record data provenance and licence position for training and reference data. Bind model version to output at the point of decision. Keep evaluation results, including the failures, against the version they belong to. Make approval records verifiable by a third party who does not trust your infrastructure. Keep the cyber answer and the AI answer separate, because they are separate questions. Plan for change, because the model will change and the assurance has to survive it.&lt;/p&gt;

&lt;p&gt;The suppliers who find this straightforward are the ones already keeping records they never expected to have to explain. If you cannot currently say who approved a given AI-assisted action, on what basis, at what time, and prove it to somebody who starts from the assumption that you are wrong, that is your gap. It is cheaper to close before a bid than during one. There is a longer treatment of the same problem in &lt;a href="https://mickai.co.uk/articles/the-defence-ai-assurance-gap-proving-what-an-autonomous-system-did" rel="noopener noreferrer"&gt;the defence AI assurance gap&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Does JSP 936 apply to a subcontractor?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;JSP 936 is MOD policy, so it binds the department rather than your company directly. It reaches you through the contract, and it reaches a subcontractor through flow-down clauses in the contract above yours. If you sit at tier two or three, ask the prime for the exact wording rather than assuming what applies. Read the clauses, not a summary of them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is JSP 936 the same thing as Def Stan 05-138?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. Def Stan 05-138 is the MOD's cyber security standard for defence suppliers, applied through the Cyber Security Model with a risk assessment against each contract. JSP 936 is about dependable AI: governance, ethics and assurance of AI-enabled capability across its life. You can meet the cyber standard in full and still have nothing that answers the AI directive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does JSP 936 Part 2 cover?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A JSP is normally issued in two parts: Part 1 is the directive, the mandatory policy, and Part 2 is guidance on how to meet it. Part 1 on dependable AI is the published directive. Check the gov.uk publication page for the current status of Part 2 rather than relying on somebody's description of guidance you have not read yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do we need ISO 42001 to satisfy JSP 936?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No. ISO/IEC 42001 is an AI management system standard, and certification against it is useful evidence of governance discipline, but it is not what the directive asks for and it is not a substitute for it. A certificate says your management system was audited. It does not say what your AI system did on a given Tuesday.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we prove human oversight of an AI-enabled system?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not with a policy document. You need a record naming the person who approved a specific action, what was put in front of them, when they approved it, and what the system did next, in a form somebody can check without trusting your infrastructure. If an administrator can edit that record afterwards, it is an assertion rather than evidence.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related briefings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Procurement and defence&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/buy-ai-through-g-cloud-and-government-frameworks-guide-263n"&gt;Buy AI Through G-Cloud and Government Frameworks: Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-disclosure-in-public-sector-tenders-whats-required-3nb5"&gt;AI Disclosure in Public Sector Tenders: What's Required?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-bid-evaluation-in-public-procurement-is-it-lawful-20an"&gt;AI Bid Evaluation in Public Procurement: Is It Lawful?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-for-procurement-contract-review-is-it-allowed-1072"&gt;AI for Procurement Contract Review: Is It Allowed?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-supplier-contract-clauses-a-uk-buyers-checklist-2llh"&gt;AI Supplier Contract Clauses: A UK Buyer's Checklist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;UK AI regulation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/is-there-a-uk-ai-act-how-the-uk-regulates-ai-today-4m3p"&gt;Is There a UK AI Act? How the UK Regulates AI Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-cyber-security-code-of-practice-who-it-applies-to-39l8"&gt;AI Cyber Security Code of Practice: Who It Applies To&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part of a series of 60 briefings on deploying and governing AI in UK regulated organisations, archived with a DOI at &lt;a href="https://doi.org/10.5281/zenodo.22975756" rel="noopener noreferrer"&gt;10.5281/zenodo.22975756&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluating AI for a regulated organisation?&lt;/strong&gt; Mickai runs on hardware you own, offline. Consequential actions wait for a named person to approve them, and what the AI did is sealed into a signed record an auditor can check without us. Applications for the invitation-only closed beta are open. &lt;a href="https://mickai.co.uk/beta" rel="noopener noreferrer"&gt;Apply for the closed beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by Micky Irons, founder and chief executive of Mickai LTD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>Generative AI and MOD Contract Data: What Suppliers Can Do</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Sat, 26 Sep 2026 08:00:34 +0000</pubDate>
      <link>https://dev.to/mickai/generative-ai-and-mod-contract-data-what-suppliers-can-do-3il6</link>
      <guid>https://dev.to/mickai/generative-ai-and-mod-contract-data-what-suppliers-can-do-3il6</guid>
      <description>&lt;p&gt;&lt;strong&gt;Only on infrastructure you control. MOD contract information carries confidentiality conditions such as DEFCON 531, which limit disclosure to the people who need to know. Sending it to a hosted AI service is a disclosure you cannot evidence. Mickai installs on hardware you own and runs offline, so contract data stays inside your perimeter.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What does DEFCON 531 require you to protect?
&lt;/h2&gt;

&lt;p&gt;DEFCON 531 is the MOD's standard disclosure-of-information condition, and it operates on disclosure rather than on classification. In plain terms it stops a supplier passing information the Authority has provided, or information arising from the contract, to anyone outside the people who need it to perform that contract, without the Authority's prior written agreement.&lt;/p&gt;

&lt;p&gt;That catches a great deal of ordinary material. Statements of requirement. Pricing breakdowns and rate cards. Drawings, interface documents, delivery schedules, commercial correspondence. Most of it arrives with no marking at all, which is exactly why bid teams assume it is safe to paste into a chatbot while they tidy up a response. The condition does not ask whether a document was marked. It asks who ended up holding it.&lt;/p&gt;

&lt;p&gt;DEFCONs are revised, and the edition that binds you is the one your contract schedule incorporates, so work from your own contract and your commercial officer rather than a copy someone found online. Then apply the operational test before any tool touches contract material: can you name every party that will hold, process or retain that text, and show each one sits inside the need-to-know population? If you cannot answer that, you have not cleared the tool. You have decided not to look.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does OFFICIAL-SENSITIVE material change the answer?
&lt;/h2&gt;

&lt;p&gt;It raises the consequences without changing the logic. OFFICIAL-SENSITIVE is a handling caveat applied to information at OFFICIAL where wider circulation would cause damage, so the originator has deliberately narrowed who should see it. The &lt;a href="https://www.gov.uk/government/publications/government-security-classifications" rel="noopener noreferrer"&gt;Government Security Classifications policy&lt;/a&gt; and your own security officer set the handling rules, and those rules travel with every copy you make.&lt;/p&gt;

&lt;p&gt;A copy pasted into a text box is a copy. It exists somewhere you do not administer, on storage you cannot inspect, for a period you did not set. If a security officer later asks where that document went, the honest answer is that nobody knows, and "the vendor says it was not retained" is not evidence. It is a statement from an interested party.&lt;/p&gt;

&lt;p&gt;There is a second reason to take the caveat seriously. Suppliers on MOD contracts are assessed under the &lt;a href="https://www.gov.uk/guidance/cyber-security-model" rel="noopener noreferrer"&gt;Cyber Security Model&lt;/a&gt;, which risk-assesses contracts involving MOD identifiable information and asks suppliers to self-assess their controls. Once you have declared how information is handled, an uncontrolled route to a hosted AI service quietly contradicts your own return. That is a harder conversation than the original data question.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is an enterprise AI licence enough for contract data?
&lt;/h2&gt;

&lt;p&gt;No, not on its own. An enterprise agreement changes commercial terms: retention windows, a training opt-out, a choice of processing region, an admin console, contractual promises about confidentiality. All of it useful. None of it changes the fact that the information crossed your boundary, which is the thing the contract condition turns on.&lt;/p&gt;

&lt;p&gt;The deeper problem is that the assurance is contractual rather than technical. You are relying on a third party's description of its own behaviour, with no independent way to test it. The logs sit on their side. The retention setting is a switch you were shown in a user interface. When an auditor asks what left the building, you can produce a clause, not an observation.&lt;/p&gt;

&lt;p&gt;This is not an argument against hosted services generally. Most of what a defence supplier does has nothing to do with contract information: general research, marketing, internal tooling, code that touches no MOD material. Cloud earns its place there, and the companies building that layer are doing hard work well. My argument is narrower. It is against the assumption that regulated work has to be rented, shipped offsite and taken on trust. Split the estate by data class and the question stops being ideological.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does a defensible deployment look like?
&lt;/h2&gt;

&lt;p&gt;Two properties carry it. The model runs on hardware your organisation owns, and there is no network route from that hardware to anyone else. Everything else is detail.&lt;/p&gt;

&lt;p&gt;That is what the Mickai Sovereign Intelligence Operating System does. It installs on your own machines, runs offline and sends nothing out. You can place it on a segmented network or a fully &lt;a href="https://mickai.co.uk/articles/how-to-run-ai-on-classified-networks-without-internet-access" rel="noopener noreferrer"&gt;air-gapped&lt;/a&gt; one. There are 63 studios in the system, 14 production-ready at launch and 49 in development, drawing on 50 specialised models for different kinds of work. Consequential actions do not fire on their own. They wait for a named person to approve them, so the record shows a human decision rather than an inference.&lt;/p&gt;

&lt;p&gt;One honest limit, because bid teams always ask about documents. A local OCR runtime has read scanned PDFs in controlled tests, and the extraction and ingestion integration inside SIOS is still being completed. If your first use case is dropping in a folder of scanned contract packs and asking questions of it, that work is in progress, and I would rather you heard it from me than found it in a trial.&lt;/p&gt;

&lt;p&gt;The closed beta is open, with one regulated company onboarding as a design partner.&lt;/p&gt;

&lt;h2&gt;
  
  
  How do you evidence that nothing left the building?
&lt;/h2&gt;

&lt;p&gt;With two separate kinds of evidence: network evidence and action evidence. Neither satisfies a serious reviewer on its own.&lt;/p&gt;

&lt;p&gt;The network side belongs to you. Egress rules, firewall configuration, segment design, the absence of any route out. Your infrastructure team already knows how to produce that, and it is the same evidence you would produce for any other contained system.&lt;/p&gt;

&lt;p&gt;The action side is what most deployments cannot produce. In SIOS, every consequential action is sealed in the Open Audit Record under ML-DSA-65, the post-quantum signature scheme &lt;a href="https://csrc.nist.gov/pubs/fips/204/final" rel="noopener noreferrer"&gt;NIST published as FIPS 204 in 2024&lt;/a&gt;. An auditor exports the record, takes it away and verifies it offline against a public key, using tools that are not ours. We are not in the loop at verification time, which is the point.&lt;/p&gt;

&lt;p&gt;Be precise about what that property is. It is tamper-evident, not tamper-proof. Tamper-proof would claim the record cannot be altered, and nobody can honestly promise that about bytes on a disk that someone sufficiently privileged can reach. Tamper-evident means an altered record fails verification, visibly, to a person holding only the public key. That turns a silent edit into a finding. In an assurance conversation it is the stronger position, because it does not ask anyone to trust us.&lt;/p&gt;

&lt;h2&gt;
  
  
  What should you write into your internal AI policy?
&lt;/h2&gt;

&lt;p&gt;Classify tools by where they run, not by brand, and keep the rule short enough that a bid manager at 9pm can follow it. Four lines do most of the work.&lt;/p&gt;

&lt;p&gt;First, a named list of approved tools per data class, with MOD contract information (marked or unmarked) restricted to tools running on infrastructure the company controls. Second, a standing statement that putting contract material into any other service counts as a disclosure and needs the commercial team involved before it happens, not after. Third, a route for staff to ask about an unlisted tool, answered in hours rather than weeks, because a slow policy gets bypassed and you lose visibility of what people actually use. Fourth, a flow-down obligation so subcontractors hold the same line, since a tier-two supplier's habits become your exposure.&lt;/p&gt;

&lt;p&gt;Two documents are worth reading before you write it. The NCSC's &lt;a href="https://www.ncsc.gov.uk/collection/machine-learning" rel="noopener noreferrer"&gt;Principles for the security of machine learning&lt;/a&gt; covers failure modes specific to these systems. &lt;a href="https://www.gov.uk/government/publications/jsp-936-dependable-artificial-intelligence-ai-in-defence-part-1-directive" rel="noopener noreferrer"&gt;JSP 936, Dependable Artificial Intelligence in Defence&lt;/a&gt; sets out MOD's own direction on how AI is developed and used in defence, which tells you how your customer thinks about the subject.&lt;/p&gt;

&lt;p&gt;Then name an owner. A policy with no owner is a document, not a control. If you want to see how this is assembled on hardware you own, the &lt;a href="https://mickai.co.uk/offline-ai-assistant" rel="noopener noreferrer"&gt;offline assistant&lt;/a&gt; and &lt;a href="https://mickai.co.uk/sovereign-ai" rel="noopener noreferrer"&gt;sovereign AI&lt;/a&gt; pages cover the deployment side.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Can we use a public AI chatbot to draft a defence bid?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not with MOD contract information in it. The moment a statement of requirement, a price or a drawing goes into a public service, you have disclosed it outside your need-to-know population and you cannot evidence where it went. Generic bid-writing technique is fine. Anything specific to the contract belongs on a system your organisation controls.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does the MOD have a standard contract clause on generative AI?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No condition dealing specifically with generative AI was found in the published DEFCON set at the time of writing. The duty flows from the conditions already in your contract, principally the disclosure-of-information condition and the cyber requirements assessed under the Cyber Security Model. Treat AI as one more route by which information can leave, and apply the existing rules to it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can we use AI on export-controlled technical data?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Treat that as a licensing question rather than an IT question. UK strategic export controls can cover transfers of controlled technology by electronic means, so putting such data into a service that processes it elsewhere may require authorisation. Ask your export control officer before any tool touches it. Keeping the processing on your own hardware avoids the transfer question entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What do primes ask tier-two suppliers about AI use?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Expect questions about which tools are approved, where they run, whether contract data is retained or used to train anything, who inside your business can see the outputs, and what evidence you hold. The answer that survives scrutiny is a named tool list tied to data classes, plus logs you produced yourself rather than a statement from a vendor.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does using AI on contract information need the Authority's written consent?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It depends on whether a disclosure occurs. If the tool sends contract information to a third party that holds or processes it, that is a disclosure and consent is the safe assumption. If the tool runs on hardware you own and the information never leaves your need-to-know population, no new disclosure has happened. Confirm the position with your commercial officer.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related briefings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Procurement and defence&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/buy-ai-through-g-cloud-and-government-frameworks-guide-263n"&gt;Buy AI Through G-Cloud and Government Frameworks: Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-disclosure-in-public-sector-tenders-whats-required-3nb5"&gt;AI Disclosure in Public Sector Tenders: What's Required?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-bid-evaluation-in-public-procurement-is-it-lawful-20an"&gt;AI Bid Evaluation in Public Procurement: Is It Lawful?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-for-procurement-contract-review-is-it-allowed-1072"&gt;AI for Procurement Contract Review: Is It Allowed?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-supplier-contract-clauses-a-uk-buyers-checklist-2llh"&gt;AI Supplier Contract Clauses: A UK Buyer's Checklist&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;UK AI regulation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/is-there-a-uk-ai-act-how-the-uk-regulates-ai-today-4m3p"&gt;Is There a UK AI Act? How the UK Regulates AI Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-cyber-security-code-of-practice-who-it-applies-to-39l8"&gt;AI Cyber Security Code of Practice: Who It Applies To&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part of a series of 60 briefings on deploying and governing AI in UK regulated organisations, archived with a DOI at &lt;a href="https://doi.org/10.5281/zenodo.22975756" rel="noopener noreferrer"&gt;10.5281/zenodo.22975756&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluating AI for a regulated organisation?&lt;/strong&gt; Mickai runs on hardware you own, offline. Consequential actions wait for a named person to approve them, and what the AI did is sealed into a signed record an auditor can check without us. Applications for the invitation-only closed beta are open. &lt;a href="https://mickai.co.uk/beta" rel="noopener noreferrer"&gt;Apply for the closed beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by Micky Irons, founder and chief executive of Mickai LTD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>privacy</category>
    </item>
    <item>
      <title>NIS Regulations and AI: Rules for Transport Operators</title>
      <dc:creator>Micky Irons</dc:creator>
      <pubDate>Sat, 26 Sep 2026 07:59:52 +0000</pubDate>
      <link>https://dev.to/mickai/nis-regulations-and-ai-rules-for-transport-operators-eah</link>
      <guid>https://dev.to/mickai/nis-regulations-and-ai-rules-for-transport-operators-eah</guid>
      <description>&lt;p&gt;&lt;strong&gt;Yes, where the AI system supports an essential service. The Network and Information Systems Regulations 2018 cover air, rail, water and road transport operators, and the duty attaches to the network and information systems behind the service, AI included. The Department for Transport is the competent authority. Mickai runs offline on hardware you own, adding no outward connection.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Do the NIS Regulations cover AI used by transport operators?
&lt;/h2&gt;

&lt;p&gt;Yes. The Network and Information Systems Regulations 2018 regulate services, not technologies, so an AI system sitting behind an essential service is inside the perimeter in the same way a scheduling database or a signalling network is.&lt;/p&gt;

&lt;p&gt;The phrase "artificial intelligence" does not appear in the 2018 Regulations. Some operators read that silence as permission. It is not. The duty under regulation 10 is to take appropriate and proportionate technical and organisational measures to manage the risks to the network and information systems your essential service relies on, and to prevent and minimise the impact of incidents. That is a functional test, indifferent to what the vendor calls the product.&lt;/p&gt;

&lt;p&gt;So the useful question is not whether AI is regulated. It is whether the essential service degrades when a system returns a wrong answer, a late answer, or none at all. If it does, you are already carrying a regulated dependency, whether or not anyone wrote it into a register.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which transport operators are in scope?
&lt;/h2&gt;

&lt;p&gt;Air, rail, water and road transport are all named sectors in the Regulations. In-scope operator types include airport managing bodies, air carriers, air traffic management, rail infrastructure managers and railway undertakings, port managing bodies and port facility operators, vessel traffic services, and road traffic management bodies.&lt;/p&gt;

&lt;p&gt;Scope turns on two things: the threshold requirements set out in the schedules for your subsector, and designation. Do not self-diagnose from an article, including this one. Read the Regulations for your own operator type, then confirm your status with the Department for Transport, which is the competent authority for transport.&lt;/p&gt;

&lt;p&gt;Two traps. Falling below a threshold ends your direct duty, not your obligations to the operators you supply, who pass their own security requirements down in contract. And thresholds bite on measures like traffic or passenger volume, so an operator who sat comfortably outside the regime three years ago may not sit outside it now.&lt;/p&gt;

&lt;h2&gt;
  
  
  When does an AI system become part of an essential service?
&lt;/h2&gt;

&lt;p&gt;When the service depends on it, and when a failure of that system's confidentiality, integrity, availability or authenticity would change what the service does. Both halves matter, and the second is the one most assessments skip.&lt;/p&gt;

&lt;p&gt;Consider a model that ranks asset defect reports from inspection footage and feeds maintenance prioritisation, or one that triages alarm and sensor events in a terminal operations centre so a controller sees a shortlist instead of the full alarm stream. Both are advisory on paper. Both get relied on by controllers working at pace, which makes an integrity failure that quietly downgrades the wrong events an operational failure, not an IT inconvenience.&lt;/p&gt;

&lt;p&gt;The distinction to draw is not advisory against automatic. It is whether a named person genuinely exercises judgement before the output takes effect, and whether you can show it. That is a design question you answer before procurement, not a wording question you settle afterwards.&lt;/p&gt;

&lt;p&gt;Then there is the AI you did not procure. Staff pasting operational data into a general purpose public tool creates an unmanaged system in the path of your essential service, with no asset record, no access control and no log you can hand an inspector. It is a supply chain problem that arrived without a contract.&lt;/p&gt;

&lt;h2&gt;
  
  
  How does the Cyber Assessment Framework treat AI?
&lt;/h2&gt;

&lt;p&gt;The Cyber Assessment Framework is the outcome-based tool UK regulators use to judge whether an operator is meeting its NIS duties. The current version, CAF v4.0, was published by the NCSC on 6 August 2025 with improved coverage of AI-related cyber risks throughout the framework and a new section on secure software development and maintenance.&lt;/p&gt;

&lt;p&gt;The CAF does not hand you an AI checklist. It sets objectives and contributing outcomes you assess as achieved, partially achieved or not achieved, so a model becomes ordinary work under principles you already report against. Asset management: are the model, its configuration and its reference data in your register, with an owner? Supply chain: who built it, where does inference actually execute, and who can change its behaviour without telling you? Data and system security: what leaves the boundary, and how is the runtime hardened? Security monitoring: can you reconstruct what the system was asked and what it returned on a given shift? Response and recovery: can the service run when the model is withdrawn, and have you tested that rather than assumed it?&lt;/p&gt;

&lt;p&gt;Timing is set locally. The move to CAF v4.0 is not mandated centrally: each competent authority sets its own transition expectations. Ask yours which version it will assess you against, and when.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does the Department for Transport expect from operators?
&lt;/h2&gt;

&lt;p&gt;DfT expects you to assess yourself against the framework, to hold evidence rather than assertions, and to report incidents on time. The Regulations back that with information notices, inspection powers and a penalty ceiling of £17 million, so the evidence question is not academic.&lt;/p&gt;

&lt;p&gt;One practical point catches operators out. DfT's sector implementation guidance for transport dates from 2018, while the framework underneath it has moved on more than once since. It will not tell you how your next assessment scores an AI dependency. Treat the framework version your regulator names as the operative document.&lt;/p&gt;

&lt;p&gt;On incidents, the duty under regulation 11 is to notify the competent authority without undue delay, and in any event no later than 72 hours after becoming aware of an incident having a significant impact on the continuity of the essential service. Your competent authority sets the significance thresholds for your subsector. Work out in advance how a model integrity or availability failure maps onto them, because settling that at hour 60 is not a plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Does the Cyber Security and Resilience Bill change this?
&lt;/h2&gt;

&lt;p&gt;It will change the regime, and it is not law yet. The Cyber Security and Resilience (Network and Information Systems) Bill is before Parliament and has not received Royal Assent, so nothing in it binds you today. Check its current stage on bills.parliament.uk before relying on any timetable.&lt;/p&gt;

&lt;p&gt;It amends the 2018 Regulations rather than replacing them, and transport was in scope before and stays in scope. The changes that matter to an operator buying AI sit elsewhere. The Bill brings data centres, medium and large managed service providers, and large load controllers into the regime, and it lets regulators designate critical suppliers so the most important dependencies of an essential service carry mandatory requirements directly. Reporting becomes two-stage: an initial notification within 24 hours, then a fuller report within 72. Reportability widens to incidents capable of having a significant impact, even where the impact never materialises.&lt;/p&gt;

&lt;p&gt;Read that last change against an AI deployment. A model integrity incident you caught before it altered an operational decision may still be reportable, and reporting it requires that you saw it. The logging and approval design has to exist before the duty lands. Most of the detail arrives through secondary legislation after Royal Assent, so make your AI dependencies legible now rather than wait for a commencement date.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why does running offline help an operator of essential services?
&lt;/h2&gt;

&lt;p&gt;Because it removes a class of exposure instead of managing it, and because it makes the evidence question answerable. A system with no outward connection has no egress path to monitor, no supplier-side change you did not sanction, and no third-party availability sitting between your controllers and their decisions.&lt;/p&gt;

&lt;p&gt;There is a test I ask buyers to run on anything we propose. Unplug the network for a working day. Confirm that nothing stops, and that nothing left. A supplier who cannot survive that is part of your resilience problem.&lt;/p&gt;

&lt;p&gt;Mickai's Sovereign Intelligence Operating System runs on hardware you own, is offline capable, and moves no data off your estate. There are 63 studios in the system, 14 production-ready at launch and 49 in development, with 50 specialised models behind them. Consequential actions wait for a named person to approve them, each sealed in the Open Audit Record under ML-DSA-65, the post-quantum signature scheme NIST published as FIPS 204 in 2024. An auditor exports a record and verifies it offline with a public key, using tools that are not ours.&lt;/p&gt;

&lt;p&gt;That is tamper-evident, and the difference from the word buyers usually hear matters. Nothing stops someone altering a record. Altering it makes verification fail, so the change is detectable by a third party who does not have to take our word for anything. One caveat, because inspection and survey paperwork always comes up: a local OCR runtime has read scanned PDFs in controlled tests, and extraction and ingestion integration into SIOS is still being completed.&lt;/p&gt;

&lt;p&gt;None of this makes an operator compliant. Compliance is an outcome of your governance and your assessment, and no product delivers it. What running on your own hardware does is narrow the surface you defend and shorten the distance between an inspector's question and a record you can hand over. We are not arguing against the companies building the compute and cloud layer, and cloud remains the right answer for plenty of non-regulated work. We are arguing against the assumption that a regulated operator must rent its intelligence, ship operational data offsite, and accept a supplier's account of what happened to it.&lt;/p&gt;

&lt;p&gt;The closed beta is open, and one regulated company is onboarding as a design partner.&lt;/p&gt;

&lt;h2&gt;
  
  
  Frequently asked questions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Are we an operator of essential services if we run a regional airport?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Airport managing bodies are a listed operator type, but scope depends on the threshold requirements in the Regulations for air transport and on designation. Do not assume either way from passenger numbers alone. Ask the Department for Transport to confirm your status. If you sit below the threshold, aviation security obligations and your airline and handler contracts may still impose comparable security requirements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does a cloud AI supplier fall inside our NIS scope?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Your duty covers the network and information systems your essential service relies on, including ones you do not own, so a cloud AI supplier is your supply chain risk and appears in your assessment under the supply chain principle. The supplier may not be regulated itself. You stay accountable for the service, and the Bill would add managed service providers and designated critical suppliers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do we have to report an AI failure as a NIS incident?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If it has a significant impact on the continuity of your essential service, yes, under the 72-hour notification duty. The trigger is service impact, not the technology involved, and your competent authority sets the significance thresholds. The Cyber Security and Resilience Bill would widen this to incidents capable of significant impact and add an initial notification within 24 hours.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Does NIS2 apply to UK transport operators?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;NIS2 is an EU directive and is not UK law, so UK transport operators are governed by the Network and Information Systems Regulations 2018. It can still reach you if you are established in the EU or provide in-scope services there, in which case a member state regulator is involved too. NIS2 uses the terms essential and important entities.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How do we evidence AI security to a NIS inspector?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Put the model, its configuration and its data in your asset register with a named owner. Show where inference executes and who can change behaviour. Keep a verifiable record of inputs, outputs and approvals for consequential actions. Demonstrate that the service runs without the model. Map all of it to Cyber Assessment Framework outcomes rather than writing a separate AI annex.&lt;/p&gt;




&lt;h2&gt;
  
  
  Related briefings
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;UK AI regulation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/is-there-a-uk-ai-act-how-the-uk-regulates-ai-today-4m3p"&gt;Is There a UK AI Act? How the UK Regulates AI Today&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ai-cyber-security-code-of-practice-who-it-applies-to-39l8"&gt;AI Cyber Security Code of Practice: Who It Applies To&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/does-cyber-essentials-cover-the-ai-tools-your-staff-use-22b"&gt;Does Cyber Essentials Cover the AI Tools Your Staff Use?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/ico-code-of-practice-on-ai-and-automated-decision-making-870"&gt;ICO Code of Practice on AI and Automated Decision-Making&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/iso-42001-vs-iso-27001-do-you-need-both-standards-g8b"&gt;ISO 42001 vs ISO 27001: Do You Need Both Standards?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data protection and UK GDPR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/uk-gdpr-and-ai-does-your-data-have-to-stay-in-the-uk-1a65"&gt;UK GDPR and AI: Does Your Data Have to Stay in the UK?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/mickai/uk-data-storage-vs-ai-processing-what-is-the-difference-4gig"&gt;UK Data Storage vs AI Processing: What Is the Difference&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Part of a series of 60 briefings on deploying and governing AI in UK regulated organisations, archived with a DOI at &lt;a href="https://doi.org/10.5281/zenodo.22975756" rel="noopener noreferrer"&gt;10.5281/zenodo.22975756&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Evaluating AI for a regulated organisation?&lt;/strong&gt; Mickai runs on hardware you own, offline. Consequential actions wait for a named person to approve them, and what the AI did is sealed into a signed record an auditor can check without us. Applications for the invitation-only closed beta are open. &lt;a href="https://mickai.co.uk/beta" rel="noopener noreferrer"&gt;Apply for the closed beta&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Written by Micky Irons, founder and chief executive of Mickai LTD.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>security</category>
      <category>privacy</category>
    </item>
  </channel>
</rss>
