instruction() and missing() from codepathfinder.container_matchers. They do not use flows(), calls(), QueryType, or PropagationPresets. Boolean combinators use all_of / any_of / none_of (not And / Or / Not).from codepathfinder.container_decorators import dockerfile_rule
from codepathfinder.container_matchers import instruction, missing
from codepathfinder.container_combinators import all_of, any_of, none_of # optionalDeclares a rule scoped to Dockerfile (and Dockerfile.* variants). The decorator automatically sets file_pattern="Dockerfile*" in metadata.
@dockerfile_rule(
id="DOCKER-SEC-001", # required
name="",
severity="MEDIUM", # CRITICAL | HIGH | MEDIUM | LOW | INFO
category="security",
cwe="",
cve="",
tags="",
message="",
)
def my_rule():
return instruction(type="FROM", image_tag="latest")@dockerfile_rule does not accept an owasp parameter (unlike @go_rule and @python_rule). Putting owasp="..." will raise a TypeError.Matches a Dockerfile instruction by type and optional property constraints. Only non-None parameters are applied, so you can compose matches as narrowly as needed.
from codepathfinder.container_matchers import instruction
# Base image using the :latest tag
instruction(type="FROM", image_tag="latest")
# FROM without a pinned digest
instruction(type="FROM", missing_digest=True)
# ARG with password-ish name
instruction(type="ARG", arg_name_regex=r"(?i).*password.*")
# EXPOSE with invalid port
instruction(type="EXPOSE", port_greater_than=65535)
instruction(type="EXPOSE", port_less_than=1)
# USER = root
instruction(type="USER", user_name="root")
# HEALTHCHECK too aggressive
instruction(type="HEALTHCHECK", healthcheck_interval_less_than="10s")typerequiredbase_imageimage_tagimage_tag_regexmissing_digestuser_nameuser_name_regexportport_less_thanport_greater_thanprotocolarg_namearg_name_regexcopy_fromchownmissing_flaghealthcheck_interval_less_thanhealthcheck_timeout_greater_thanhealthcheck_retries_greater_thanlabel_keylabel_value_regexcommand_formworkdir_not_absolutesignal_not_incontainsnot_containsregexnot_regexvalidateFull signature in codepathfinder/container_matchers.py:24-136.
Matches when a required instruction is not present in the Dockerfile. Most useful for enforcing hardening baselines (USER, HEALTHCHECK, LABEL metadata).
from codepathfinder.container_matchers import missing
missing(instruction="USER") # container would run as root
missing(instruction="HEALTHCHECK") # no healthcheck defined
missing(instruction="LABEL", label_key="maintainer") # specific label is absentinstructionrequiredlabel_keymissing() (from codepathfinder.container_matchers) with qualifier missing() (from codepathfinder.qualifiers). Same name, different module, different purpose.Boolean combinators for container rules. Import from codepathfinder.container_combinators.
from codepathfinder.container_combinators import all_of, any_of, none_of
# Any invalid port range
any_of(
instruction(type="EXPOSE", port_less_than=1),
instruction(type="EXPOSE", port_greater_than=65535),
)
# All hardening requirements met (matches if any are missing; combine with negation)
all_of(
instruction(type="USER", user_name_regex=r"^(?!root$).*"),
instruction(type="HEALTHCHECK"),
)
# None of the risky patterns
none_of(
instruction(type="RUN", contains="sudo"),
instruction(type="RUN", contains="curl | sh"),
)Real rule from the registry (DOCKER-SEC-001). Detects Dockerfiles that don't pin a non-root user.
from codepathfinder.container_decorators import dockerfile_rule
from codepathfinder.container_matchers import missing
@dockerfile_rule(
id="DOCKER-SEC-001",
name="Container Running as Root - Missing USER",
severity="HIGH",
cwe="CWE-250",
category="security",
tags="docker,dockerfile,container,security,privilege-escalation,root,user,best-practice,hardening,principle-of-least-privilege",
message=(
"Dockerfile does not specify USER instruction. Container will run as root by default, "
"which increases the attack surface if the container is compromised."
)
)
def missing_user_instruction():
"""Detects Dockerfiles that do not specify a USER instruction."""
return missing(instruction="USER")