Container and OCI Image Rules
Detects risky container image configuration, secrets in layers, and unpinned base images.
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.
Supported inputs
DockerfileOCI manifestcontainer image tarSBOM
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.
- 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
category: OCI
fail_on:
- CRITICAL
- HIGH
ticket_on:
- MEDIUM
retest: "sentinel scan ./project/"Rule index
| Rule ID | Severity | Title | CWE | Fix Hint |
|---|---|---|---|---|
| OCI-ROOT-USER | MEDIUM | Container Runs as Root | CWE-250 | Set a non-root USER in the image. |
| OCI-SECRET-IN-LAYER | CRITICAL | Secret in Container Layer | CWE-798 | Never bake credentials into images. |
| OCI-UNPINNED-BASE | MEDIUM | Unpinned Base Image | CWE-494 | Use immutable OCI digests for base images. |
OCI-ROOT-USER — Container Runs as Root
MEDIUM| Rule ID | OCI-ROOT-USER |
|---|---|
| Category | OCI |
| Severity | MEDIUM |
| CWE | CWE-250 |
| OWASP LLM | LLM03 — Supply Chain |
| FP Risk | MEDIUM |
| Owner | Platform, DevOps, and dependency owner |
| Release decision | Assign 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
- 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
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
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER rootFROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret managerRelated rules
- OCI-SECRET-IN-LAYER: Secret in Container Layer
- OCI-UNPINNED-BASE: Unpinned Base Image
OCI-SECRET-IN-LAYER — Secret in Container Layer
CRITICAL| Rule ID | OCI-SECRET-IN-LAYER |
|---|---|
| Category | OCI |
| Severity | CRITICAL |
| CWE | CWE-798 |
| OWASP LLM | LLM02 — Sensitive Information Disclosure, LLM03 — Supply Chain |
| FP Risk | LOW |
| Owner | Platform, DevOps, and dependency owner |
| Release decision | Block 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
- 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
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
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER rootFROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret managerRelated rules
- OCI-ROOT-USER: Container Runs as Root
- OCI-UNPINNED-BASE: Unpinned Base Image
OCI-UNPINNED-BASE — Unpinned Base Image
MEDIUM| Rule ID | OCI-UNPINNED-BASE |
|---|---|
| Category | OCI |
| Severity | MEDIUM |
| CWE | CWE-494 |
| OWASP LLM | LLM03 — Supply Chain |
| FP Risk | MEDIUM |
| Owner | Platform, DevOps, and dependency owner |
| Release decision | Assign 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
- 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
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
FROM python:latest
ENV OPENAI_API_KEY=sk-live-example
USER rootFROM python:3.12-slim@sha256:...
USER 10001
# secrets injected by runtime secret managerRelated rules
- OCI-ROOT-USER: Container Runs as Root
- OCI-SECRET-IN-LAYER: Secret in Container Layer