Kai Ole Hartwig
10 min read
Low
By

AI-BOM, ML-BOM and ISO/IEC 27090: Which model is actually running in your cluster?

Imagine you're in an audit, standing in front of your GPU cluster. A vLLM pod is running in the inference namespace. The image is signed and scanned, and the SBOM sits in the registry.

Then comes the question: Which model does this pod actually load? Where do the weights come from? Who changed them last?

Suddenly the room goes quiet. You know the image down to the last library. You don't know the 40 GB of weights pulled from a bucket.

ISO/IEC 27090 was published on 14 October 2026. Time to stop treating AI-BOMs as compliance folklore.

01 — The blind spot of the SBOM

A classic SBOM describes code and packages. I showed why that matters using libssh2 and CVE-2026-7598.

An AI workload, however, is more than its container. The actual logic lives in artifacts no package manager knows about:

If any of these is tampered with, your image scanner sees nothing. The image hasn't changed. Data poisoning, a swapped model or a backdoored adapter stay invisible.

This is supply chain security, just one layer deeper. An AI-BOM describes exactly that layer.

02 — AI-BOM and ML-BOM compared

AI-BOM is the umbrella term, ML-BOM is CycloneDX's name for it. Both mean the same thing: a machine-readable inventory of all AI components of a system, including their relationships.

CycloneDX ML-BOMSPDX 3.0 AI profile
StatusPart of CycloneDX 1.7 (ECMA-424), AI/ML schema for 2.0 in progressAI profile, combinable with the software profile
ModelComponent machine-learning-model with modelCardAI package with dedicated fields
DatasetsComponent type dataDataset profile
StrengthFits existing SBOM and vulnerability pipelinesProvenance, licensing, relationship graph

My recommendation: If your pipeline already speaks CycloneDX, stick with it. The ML-BOM is then just another component type in the same document, not a parallel process.

What has to be in it

03 — ISO/IEC 27090 as guidance

ISO/IEC 27090:2026 comes from JTC 1/SC 27, the same committee behind ISO 27001. On 56 pages it describes how to detect and mitigate AI-specific threats across the life cycle.

This is where the AI-BOM comes in. You can't detect a threat to an asset you don't know exists. The AI-BOM is to 27090 what the asset register is to 27001.

The AI Act asks for the same inventory. What that means in practice is in my EU AI Act checklist. How one piece of evidence serves several standards is shown in Grundschutz++ as code, part 7.

The standard has only been available for a few days. Which chapters cover inventory and supply chain in detail is best checked in the text itself. To get started, the core idea is enough: inventory first, then assess.

04 — Models as OCI artifacts in the cluster

The biggest lever in the cluster is simple. Stop pulling weights from a bucket with an init container. Push them to your registry as OCI artifacts, just like your images.

I've been doing this for TYPO3 code for a while. The idea is in TYPO3 as a signed OCI artifact, the implementation in the field note on code as an image volume. It works the same way for models:

apiVersion: v1
kind: Pod
metadata:
  name: llm-inference
spec:
  containers:
    - name: server
      image: registry.example.com/ai/vllm@sha256:<image-digest>
      args: ["--model=/models"]
      volumeMounts:
        - name: model
          mountPath: /models
          readOnly: true
  volumes:
    - name: model
      image:
        reference: registry.example.com/models/my-llm@sha256:<model-digest>
        pullPolicy: IfNotPresent

 

The pod spec now contains two digests: runtime and model. Anything with a digest can be signed, attested and checked at admission.

05 — Warning signs in the AI-BOM

An AI-BOM only becomes a tool once you can read it. Three levels help with the decision.

Blockers

Review

Normal

Important: The AI-BOM only contains what the generator finds. Add a scanner such as ModelScan or picklescan that looks inside the files. Blockers become hard rules, review cases become warnings with documented exceptions.

06 — The AI-BOM as a gate in GitLab CI

An AI-BOM as a PDF in the wiki protects nothing. It has to be created in the pipeline, checked there and enforced in the cluster. You know the pattern from Grundschutz part 3 on the signed artifact and the CVE gate from part 4.

  1. Generate: Create the AI-BOM from the repository and model metadata.
  2. Validate: Check the schema. Broken BOMs fail the build.
  3. Check policy: Enforce hash, license and allowed formats.
  4. Attest: Attach the AI-BOM as a signed attestation to the model and image digests.
  5. Admission: Only admit what carries a valid attestation in the cluster.
stages: [aibom, verify, attest]

variables:
  MODEL_REF: registry.example.com/models/my-llm
  IMAGE_REF: registry.example.com/ai/vllm
  # MODEL_DIGEST and IMAGE_DIGEST come from the build/push jobs

aibom:generate:
  stage: aibom
  image: ghcr.io/cyclonedx/cdxgen:latest   # in production: pin by digest
  script:
    - cdxgen -t ai --spec-version 1.7 -o aibom.cdx.json .
  artifacts:
    paths: [aibom.cdx.json]

aibom:validate:
  stage: verify
  image: cyclonedx/cyclonedx-cli:latest   # in production: pin by digest
  script:
    - cyclonedx validate --input-file aibom.cdx.json --fail-on-errors

aibom:policy:
  stage: verify
  image: alpine:3
  before_script:
    - apk add --no-cache jq
  script:
    # Every model needs a hash and a license, otherwise the build fails
    - |
      jq -e '
        [.components[]? | select(.type == "machine-learning-model")] as $m
        | ($m | length) > 0
          and all($m[]; (.hashes // [] | length) > 0
                    and (.licenses // [] | length) > 0)
      ' aibom.cdx.json

aibom:attest:
  stage: attest
  image: cgr.dev/chainguard/cosign:latest   # in production: pin by digest
  id_tokens:
    SIGSTORE_ID_TOKEN:
      aud: sigstore
  script:
    - cosign attest --yes --type cyclonedx --predicate aibom.cdx.json "$MODEL_REF@$MODEL_DIGEST"
    - cosign attest --yes --type cyclonedx --predicate aibom.cdx.json "$IMAGE_REF@$IMAGE_DIGEST"

 

Three things you shouldn't skip

And a valid signature alone doesn't prove clean content. I wrote about why after Mini Shai-Hulud. The attestation tells you who created the AI-BOM. Whether its content is acceptable is up to your policy.

07 — Admission with Kyverno

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: require-aibom
spec:
  validationFailureAction: Enforce
  webhookTimeoutSeconds: 30
  rules:
    - name: verify-aibom-attestation
      match:
        any:
          - resources:
              kinds: [Pod]
      verifyImages:
        - imageReferences:
            - "registry.example.com/ai/*"
          attestations:
            - type: cyclonedx.org/bom
              attestors:
                - entries:
                    - keyless:
                        subject: "https://gitlab.example.com/ai/inference//.gitlab-ci.yml@refs/heads/main"
                        issuer: "https://gitlab.example.com"
              conditions:
                - all:
                    - key: "{{ components[?type=='machine-learning-model'] | length(@) }}"
                      operator: GreaterThan
                      value: 0
    - name: model-volumes-by-digest
      match:
        any:
          - resources:
              kinds: [Pod]
      validate:
        message: "Models only from the approved registry and only by digest."
        pattern:
          spec:
            =(volumes):
              - =(image):
                  reference: "registry.example.com/models/*@sha256:*"

 

The first rule checks the AI-BOM attestation on the runtime image. The second makes sure models only come from your registry and only by digest.

A note from practice: Test whether verifyImages in your Kyverno version also covers image volumes. If it doesn't, verify the model artifact's signature additionally in the pipeline or with a rule of your own.

08 — The takeaway

Back to the audit. You no longer answer the question about the model with silence. You have a digest, a signed AI-BOM and a policy that would have rejected anything else.

ISO/IEC 27090 tells you which threats to take seriously. The AI-BOM tells you where they can strike. Your pipeline makes sure neither ends up in a spreadsheet.

Start small: one model, one registry, one policy. Once that runs, the rest is legwork.

How do you inventory the models in your cluster today? Or is it still the bucket with the init container for you too?

09 — Sources

Frequently asked questions

Isn't a signature on the model enough?+

No. A signature proves who approved something. Whether a pickle model with foreign code is underneath only becomes clear once you check the content.

Can I get certified against ISO/IEC 27090?+

No. The standard is guidance. It extends an ISMS based on ISO 27001 with AI-specific threats.

CycloneDX or SPDX?+

Use the format your pipeline already speaks. With CycloneDX, the ML-BOM stays one more component type in the same document. SPDX plays to its strengths on licensing and provenance.

Do I need an AI-BOM if I only use a model through an API?+

Yes, just a leaner one. The external service goes into the BOM as a service, with provider, model version and data flow. The weights aren't yours, but the dependency is.

Do you know which models are running in your cluster?

I look at how models get into your Kubernetes environment: what is loaded unchecked today, what an AI-BOM for your workloads looks like, and how to anchor it as a gate in pipeline and admission.

Book a call →

About the author

Photo of Kai Ole Hartwig.

Kai Ole Hartwig

Freelance DevSecOps consultant · OnlyOle Consulting

Programming since 2002 – self-taught, set up my own business with KO-Web in 2012. Over 100 projects, with a focus on security, performance, automation and quality. Today freelance: DevSecOps consulting, training and software development.