AI Infrastructure (IaC)

The IaC pass analyzes repository files — Kubernetes manifests (including CRDs), docker-compose files and Dockerfiles — for the AI infrastructure they would produce. Every detection is validated; a value that cannot be verified from the file is either dropped (likely false positive) or reported with vulnetix:ai/confidence-gap = true and a vulnetix:ai/gap-reason stating exactly what could not be verified and why. Nothing is ever guessed.

Generated from the catalog. To add or refine a rule, edit internal/aibom/catalog/infrastructure.json and run just gen-aibom.

Runtimes detected by container image

Image patterns are matched against the image name (registry + repository, tag/digest split off). The version is reported only when the tag is semver-shaped; otherwise the raw tag is preserved and the component carries a confidence gap.

RuntimeCategoryImage patterns
Chainlitagent^chainlit/chainlit$
Flowiseagent^flowiseai/flowise$
Haystackagent^deepset/haystack$, ^deepset/hayhooks$
Langflowagent^langflowai/langflow$
LlamaIndexagent^llamaindex/[\w.-]+$
Open WebUIagent^ghcr\.io/open-webui/open-webui$
LM Evaluation Harnessevaluation^eleutherai/lm-eval(uation-harness)?$
Ragasevaluation^ragas/[\w.-]+$
TruLensevaluation^trulens/[\w.-]+$
LMDeployinference^openmmlab/lmdeploy$
LiteLLM Proxyinference^ghcr\.io/berriai/litellm$
LocalAIinference^localai/localai$, ^quay\.io/go-skynet/local-ai$
NVIDIA NIMinference^nvcr\.io/nim/[\w.-]+/[\w.-]+$
Ollamainference^ollama/ollama$
Rayinference^rayproject/ray(-ml)?$
SGLanginference^lmsysorg/sglang$
Text Embeddings Inferenceinference^ghcr\.io/huggingface/text-embeddings-inference$
Text Generation Inferenceinference^huggingface/text-generation-inference$, ^ghcr\.io/huggingface/text-generation-inference$
Triton Inference Serverinference^nvcr\.io/nvidia/tritonserver$
llama.cpp serverinference^ghcr\.io/ggml-org/llama\.cpp$, ^ghcr\.io/ggerganov/llama\.cpp$
llm-dinference^ghcr\.io/llm-d/[\w.-]+$
vLLMinference^vllm/[\w.-]+$, ^ghcr\.io/vllm-project/[\w.-]+$
Axolotltraining^axolotlai/axolotl$, ^winglian/axolotl$
Hugging Face Acceleratetraining^huggingface/accelerate(-[\w.-]+)?$
JAXtraining^ghcr\.io/google/jax$, ^ghcr\.io/nvidia/jax$
PyTorchtraining^pytorch/pytorch$, ^nvcr\.io/nvidia/pytorch$
Chromavector-database^chromadb/chroma$, ^ghcr\.io/chroma-core/chroma$
Milvusvector-database^milvusdb/milvus$
Qdrantvector-database^qdrant/qdrant$
Weaviatevector-database^semitechnologies/weaviate$, ^cr\.weaviate\.io/semitechnologies/weaviate$
pgvectorvector-database^pgvector/pgvector$, ^ankane/pgvector$

Custom resources (CRDs)

KindAPI group prefixCategoryDeclared fields extracted
InferenceServiceserving.kserve.io/inferencespec.predictor.model.storageUri, spec.predictor.model.modelFormat.name, spec.predictor.model.modelFormat.version, spec.predictor.model.runtime, spec.predictor.serviceAccountName
PyTorchJobkubeflow.org/trainingpod templates (embedded)
TFJobkubeflow.org/trainingpod templates (embedded)
RayJobray.io/trainingpod templates (embedded)
RayServiceray.io/inferencepod templates (embedded)
RayClusterray.io/trainingpod templates (embedded)

Model identity signals

  • Environment values: HF_MODEL_ID, MODEL_NAME, MODEL_ID, OLLAMA_MODEL (a valueFrom secret/configMap reference is never resolved — it produces a confidence gap instead)
  • Container args/command flags: --model, --model-id, --model_id, --model-path, --model-repository, --model-name, --served-model-name (both --flag value and --flag=value)
  • Declared annotations: prefixes vulnetix.com/model., model.k8saibom.dev/
  • Volume mounts (model artifacts): path-boundary prefixes /models, /model, /weights, /checkpoints, /hf_cache/models matches /models/x but never /models-shared
  • Dataset volumes (training workloads only): names dataset, datasets, training-data, mount prefixes /data

Workload environment-name signals

Only the variable name is matched — values are never read.

Env varFrameworkCategory
AUTOGEN_USE_DOCKERAutoGenagent
CREWAI_TELEMETRY_OPT_OUTCrewAIagent
DSPY_CACHEDIRDSPyagent
HAYSTACK_TELEMETRY_ENABLEDHaystackagent
LANGCHAIN_API_KEYLangChainagent
LANGCHAIN_TRACING_V2LangChainagent
LANGSMITH_API_KEYLangChainagent
LLAMA_CLOUD_API_KEYLlamaIndexagent
MLFLOW_TRACKING_URIMLflowtraining
WANDB_API_KEYWeights & Biasestraining
WANDB_PROJECTWeights & Biasestraining

Remote AI API dependencies (e.g. OPENAI_API_KEY, ANTHROPIC_API_KEY) declared on workload containers are surfaced through the same provider-service catalog as the local environment pass.

GPU / accelerator signals

Resource keys: nvidia.com/gpu, amd.com/gpu, google.com/tpu, habana.ai/gaudi, intel.com/gpu, plus node selectors mentioning accelerator.

Terraform / OpenTofu signals

Matched by resource type (regex over .tf/.tofu content — resource names and variables are never interpreted). An attribute gate additionally requires a pattern inside the resource block, so e.g. a ComputerVision cognitive account never matches the Azure OpenAI signal.

SignalProviderCategoryResource patternAttribute gate
Google Vertex AIGoogle Cloudmanaged-ai^google_vertex_ai_
Amazon BedrockAWSmanaged-ai^aws_bedrock
Amazon SageMakerAWSmanaged-ai^aws_sagemaker_
Azure OpenAI ServiceMicrosoft Azuremanaged-ai^azurerm_cognitive_account$kind\s*=\s*"OpenAI"
Azure AI ServicesMicrosoft Azuremanaged-ai^azurerm_ai_services$
GKE GPU node poolGoogle Cloudaccelerator^google_container_node_pool$guest_accelerator
AWS GPU instanceAWSaccelerator`^aws_(instancelaunch_template)$`
Azure GPU VMMicrosoft Azureaccelerator`^azurerm_(linuxwindows)_virtual_machine(_scale_set)?$`

Model files on disk

Weight files present in the repository (.gguf, .safetensors, .onnx) are reported as verified data components — the artifact literally exists. .pt is deliberately excluded (too many non-model uses).

Known false negatives

Detection is deliberately allowlist-driven — a missed detection is preferred over a wrong one. The following are not detected, by design:

  • Images mirrored to private or organisation-local registries (the official-registry patterns will not match a mirror).
  • Helm values that are still templated ({{ .Values.image }}) — structural parsing skips them; the narrow regex fallback reports what it finds with an explicit confidence gap.
  • Models fetched at runtime (entrypoint scripts, init downloads) that leave no declared trace in the manifest.
  • Model identities passed through ConfigMaps or Secrets — references are never resolved.
  • Bare /data mounts on workloads with no training signal (not assumed to be datasets).

Absence of a finding is therefore not verified absence of AI infrastructure.