EresusSecurity

Container and OCI Image Rules

Detects risky container image configuration, secrets in layers, and unpinned base images.

Definition

The OCI rule family turns findings on this surface into actionable records with rule ID, severity, CWE, OWASP LLM mapping, owner, release decision, and retest command.

AI workloads frequently ship as containers with GPU runtimes, notebooks, and model-serving APIs. Image hygiene controls production blast radius.

Canonical help URL

Supported inputs

  • Dockerfile
  • OCI manifest
  • container image tar
  • SBOM

Typical attack scenarios

  • An API key remains in an old image layer.
  • A notebook image runs as root with host-mounted model directories.
  • A mutable base image changes under the same tag.

Detection logic

Sentinel ties OCI evidence to reproducible signals such as file path, metadata, opcode, AST node, manifest field, dependency, or archive entry. The same signal should disappear when the finding is closed.

Triage

Do not read OCI findings as scanner noise. Verify the evidence first, map the finding to a severity-based release decision, and then produce closure evidence with the same Sentinel command.

Operational checklist
  • Source: where did the file, manifest, prompt, archive, or dependency come from?
  • Impact: code execution, data leakage, supply chain, or resource consumption?
  • Control: allowlist, hash, sandbox, egress policy, or secret rotation?
  • Evidence: does the same rule category return clean after the fix?

Remediation

Remediation should change the risk boundary, not merely silence the finding: remove executable formats, pin source or hash, narrow tool permissions, rotate secrets, or add runtime sandboxing.

CI policy

sentinel-policy.yml
category: OCI
fail_on:
  - CRITICAL
  - HIGH
ticket_on:
  - MEDIUM
retest: "sentinel scan ./project/"

Rule index

Rule IDSeverityTitleCWEFix Hint
OCI-ROOT-USERMEDIUMContainer Runs as RootCWE-250Set a non-root USER in the image.
OCI-SECRET-IN-LAYERCRITICALSecret in Container LayerCWE-798Never bake credentials into images.
OCI-UNPINNED-BASEMEDIUMUnpinned Base ImageCWE-494Use immutable OCI digests for base images.

OCI-ROOT-USERContainer Runs as Root

MEDIUM
Rule IDOCI-ROOT-USER
CategoryOCI
SeverityMEDIUM
CWECWE-250
OWASP LLMLLM03 — Supply Chain
FP RiskMEDIUM
OwnerPlatform, DevOps, and dependency owner
Release decisionAssign an owner, fix within the sprint, and attach the retest command to the issue.

Description

Detects OCI images or Dockerfiles that run model services as root without an explicit exception.

Why it matters

AI workloads frequently ship as containers with GPU runtimes, notebooks, and model-serving APIs. Image hygiene controls production blast radius.

When it fires

Sentinel fires this rule in the OCI category when it sees missing user instruction, user root, or image config user value 0.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

Missing USER instruction, USER root, or image config user value 0.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is medium. Verify source, expected use, and owner first; add an allowlist if needed, but do not remove evidence from the report.

Triage

Operational checklist
  • Owner: Platform, DevOps, and dependency owner.
  • Decision: Assign an owner, fix within the sprint, and attach the retest command to the issue.
  • Evidence: Missing USER instruction, USER root, or image config user value 0.
  • Closure: sentinel scan ./project/ must return clean output.

How to fix

Run inference services as a non-root user and limit filesystem permissions.

CLI

sentinel scan ./project/

Policy example

sentinel-policy.yml
rules:
  OCI-ROOT-USER:
    owner: "Platform, DevOps, and dependency owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel scan ./project/"

Expected output

OCI-ROOT-USER MEDIUM
Container Runs as Root
Set a non-root USER in the image.

Example

Bad
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER root
Good
FROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret manager

Related rules

OCI-SECRET-IN-LAYERSecret in Container Layer

CRITICAL
Rule IDOCI-SECRET-IN-LAYER
CategoryOCI
SeverityCRITICAL
CWECWE-798
OWASP LLMLLM02 — Sensitive Information Disclosure, LLM03 — Supply Chain
FP RiskLOW
OwnerPlatform, DevOps, and dependency owner
Release decisionBlock release; do not promote the artifact or code path until it is isolated.

Description

Flags credentials, tokens, or private keys embedded in image layers, build args, or environment instructions.

Why it matters

AI workloads frequently ship as containers with GPU runtimes, notebooks, and model-serving APIs. Image hygiene controls production blast radius.

When it fires

Sentinel fires this rule in the OCI category when it sees secret scanner match in layer diff, image config, dockerfile env, or history metadata.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

Secret scanner match in layer diff, image config, Dockerfile ENV, or history metadata.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is low. If evidence points directly to a file, opcode, secret pattern, path, or manifest field, treat it as real and require closure evidence.

Triage

Operational checklist
  • Owner: Platform, DevOps, and dependency owner.
  • Decision: Block release; do not promote the artifact or code path until it is isolated.
  • Evidence: Secret scanner match in layer diff, image config, Dockerfile ENV, or history metadata.
  • Closure: sentinel scan ./project/ must return clean output.

How to fix

Rotate the exposed credential, rebuild from a clean base, and move secrets to a runtime secret manager.

CLI

sentinel scan ./project/

Policy example

sentinel-policy.yml
rules:
  OCI-SECRET-IN-LAYER:
    owner: "Platform, DevOps, and dependency owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel scan ./project/"

Expected output

OCI-SECRET-IN-LAYER CRITICAL
Secret in Container Layer
Never bake credentials into images.

Example

Bad
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER root
Good
FROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret manager

Related rules

OCI-UNPINNED-BASEUnpinned Base Image

MEDIUM
Rule IDOCI-UNPINNED-BASE
CategoryOCI
SeverityMEDIUM
CWECWE-494
OWASP LLMLLM03 — Supply Chain
FP RiskMEDIUM
OwnerPlatform, DevOps, and dependency owner
Release decisionAssign an owner, fix within the sprint, and attach the retest command to the issue.

Description

Reports base images referenced by mutable tags without digest pinning.

Why it matters

AI workloads frequently ship as containers with GPU runtimes, notebooks, and model-serving APIs. Image hygiene controls production blast radius.

When it fires

Sentinel fires this rule in the OCI category when it sees from image:latest or from image:tag without @sha256 digest.. The finding should be reported with reproducible evidence such as file name, metadata, opcode, AST node, or manifest field.

Evidence format

FROM image:latest or FROM image:tag without @sha256 digest.

Expected evidence

The report should include the affected file or manifest path, observed signal, rule ID, severity, owner, and retest command required for closure.

False-positive notes

False-positive probability is medium. Verify source, expected use, and owner first; add an allowlist if needed, but do not remove evidence from the report.

Triage

Operational checklist
  • Owner: Platform, DevOps, and dependency owner.
  • Decision: Assign an owner, fix within the sprint, and attach the retest command to the issue.
  • Evidence: FROM image:latest or FROM image:tag without @sha256 digest.
  • Closure: sentinel scan ./project/ must return clean output.

How to fix

Pin base images by digest and update them through controlled dependency review.

CLI

sentinel scan ./project/

Policy example

sentinel-policy.yml
rules:
  OCI-UNPINNED-BASE:
    owner: "Platform, DevOps, and dependency owner"
    fail_on: ["CRITICAL", "HIGH"]
    retest: "sentinel scan ./project/"

Expected output

OCI-UNPINNED-BASE MEDIUM
Unpinned Base Image
Use immutable OCI digests for base images.

Example

Bad
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER root
Good
FROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret manager

Related rules

References