rules

package
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package rules provides the built-in lint rules bundled with decolint. See linter.Rule for the interface they implement.

To add a new rule, implement linter.Rule in a new file in this package and register it in RegisterRules.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RegisterRules

func RegisterRules(l *linter.Linter, platforms []linter.Platform, overrides map[string]linter.Severity) error

RegisterRules registers the built-in rules whose target platform matches platforms on l, in a deterministic order, at their default severities, unless overrides contains an entry for a rule's ID, in which case that severity is used instead. A rule whose effective severity is Off is not registered on l at all.

A rule is registered if it declares no target platforms (applies to all platforms), or if any of the platforms it targets is in platforms. If platforms is empty, only rules with no target platforms are registered.

RegisterRules returns an error if overrides contains a key that does not match any built-in rule ID. An override for a rule that exists but is filtered out by platforms is not an error: overriding a platform-scoped rule that hasn't been enabled is a legitimate no-op, not a typo.

Types

type CodespacesNoBindMount

type CodespacesNoBindMount struct{}

CodespacesNoBindMount reports "mounts" entries that use the "bind" mount type. The Dev Container spec allows bind mounts, but GitHub Codespaces silently ignores them, except for a mount whose source is the Docker socket, so other bind mounts have no effect there.

func (CodespacesNoBindMount) Check

Check implements linter.Rule.

func (CodespacesNoBindMount) Description

func (CodespacesNoBindMount) Description() string

Description implements linter.Rule.

func (CodespacesNoBindMount) FileTypes

func (CodespacesNoBindMount) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (CodespacesNoBindMount) ID

ID implements linter.Rule.

func (CodespacesNoBindMount) Paths

func (CodespacesNoBindMount) Paths() []string

Paths implements linter.Rule.

func (CodespacesNoBindMount) Platforms

func (CodespacesNoBindMount) Platforms() []linter.Platform

Platforms implements linter.Rule.

type CodespacesNoHostPortFormat

type CodespacesNoHostPortFormat struct{}

CodespacesNoHostPortFormat reports "forwardPorts" entries and "portsAttributes" keys written in "host:port" format. The Dev Container spec allows that format, but GitHub Codespaces only supports a bare port number in either property.

func (CodespacesNoHostPortFormat) Check

Check implements linter.Rule.

func (CodespacesNoHostPortFormat) Description

func (CodespacesNoHostPortFormat) Description() string

Description implements linter.Rule.

func (CodespacesNoHostPortFormat) FileTypes

FileTypes implements linter.Rule.

func (CodespacesNoHostPortFormat) ID

ID implements linter.Rule.

func (CodespacesNoHostPortFormat) Paths

Paths implements linter.Rule.

func (CodespacesNoHostPortFormat) Platforms

Platforms implements linter.Rule.

type IDDirMismatch

type IDDirMismatch struct{}

IDDirMismatch reports a Feature's or Template's "id" property when it does not match the name of the directory containing its metadata file, per the Dev Container Features/Templates convention.

func (IDDirMismatch) Check

func (r IDDirMismatch) Check(ctx *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (IDDirMismatch) Description

func (IDDirMismatch) Description() string

Description implements linter.Rule.

func (IDDirMismatch) FileTypes

func (IDDirMismatch) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (IDDirMismatch) ID

func (IDDirMismatch) ID() string

ID implements linter.Rule.

func (IDDirMismatch) Paths

func (IDDirMismatch) Paths() []string

Paths implements linter.Rule.

func (IDDirMismatch) Platforms

func (IDDirMismatch) Platforms() []linter.Platform

Platforms implements linter.Rule.

type InvalidSemver

type InvalidSemver struct{}

InvalidSemver reports a Feature's or Template's "version" property when its value is not a valid semantic version, per the Dev Container Features/Templates specification, which requires "version" to follow the semver.org format.

func (InvalidSemver) Check

func (r InvalidSemver) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (InvalidSemver) Description

func (InvalidSemver) Description() string

Description implements linter.Rule.

func (InvalidSemver) FileTypes

func (InvalidSemver) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (InvalidSemver) ID

func (InvalidSemver) ID() string

ID implements linter.Rule.

func (InvalidSemver) Paths

func (InvalidSemver) Paths() []string

Paths implements linter.Rule.

func (InvalidSemver) Platforms

func (InvalidSemver) Platforms() []linter.Platform

Platforms implements linter.Rule.

type MissingBuildDockerfile

type MissingBuildDockerfile struct{}

MissingBuildDockerfile reports a devcontainer.json "build" object that does not set "dockerfile", leaving no way to know which Dockerfile to build.

func (MissingBuildDockerfile) Check

Check implements linter.Rule.

func (MissingBuildDockerfile) Description

func (MissingBuildDockerfile) Description() string

Description implements linter.Rule.

func (MissingBuildDockerfile) FileTypes

func (MissingBuildDockerfile) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (MissingBuildDockerfile) ID

ID implements linter.Rule.

func (MissingBuildDockerfile) Paths

func (MissingBuildDockerfile) Paths() []string

Paths implements linter.Rule.

func (MissingBuildDockerfile) Platforms

func (MissingBuildDockerfile) Platforms() []linter.Platform

Platforms implements linter.Rule.

type MissingComposeService

type MissingComposeService struct{}

MissingComposeService reports a devcontainer.json that sets "dockerComposeFile" without also setting "service", leaving the tool no way to know which compose service to attach to.

func (MissingComposeService) Check

Check implements linter.Rule.

func (MissingComposeService) Description

func (MissingComposeService) Description() string

Description implements linter.Rule.

func (MissingComposeService) FileTypes

func (MissingComposeService) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (MissingComposeService) ID

ID implements linter.Rule.

func (MissingComposeService) Paths

func (MissingComposeService) Paths() []string

Paths implements linter.Rule.

func (MissingComposeService) Platforms

func (MissingComposeService) Platforms() []linter.Platform

Platforms implements linter.Rule.

type MissingContainerDef

type MissingContainerDef struct{}

MissingContainerDef reports a devcontainer.json that defines none of "image", "build", or "dockerComposeFile", leaving no way to build a container.

func (MissingContainerDef) Check

Check implements linter.Rule.

func (MissingContainerDef) Description

func (MissingContainerDef) Description() string

Description implements linter.Rule.

func (MissingContainerDef) FileTypes

func (MissingContainerDef) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (MissingContainerDef) ID

ID implements linter.Rule.

func (MissingContainerDef) Paths

func (MissingContainerDef) Paths() []string

Paths implements linter.Rule.

func (MissingContainerDef) Platforms

func (MissingContainerDef) Platforms() []linter.Platform

Platforms implements linter.Rule.

type MissingRequiredProps

type MissingRequiredProps struct{}

MissingRequiredProps reports a Feature's or Template's metadata when it is missing a required property ("id", "version", or "name").

func (MissingRequiredProps) Check

Check implements linter.Rule.

func (MissingRequiredProps) Description

func (MissingRequiredProps) Description() string

Description implements linter.Rule.

func (MissingRequiredProps) FileTypes

func (MissingRequiredProps) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (MissingRequiredProps) ID

ID implements linter.Rule.

func (MissingRequiredProps) Paths

func (MissingRequiredProps) Paths() []string

Paths implements linter.Rule.

func (MissingRequiredProps) Platforms

func (MissingRequiredProps) Platforms() []linter.Platform

Platforms implements linter.Rule.

type MissingWorkspaceMountFolder

type MissingWorkspaceMountFolder struct{}

MissingWorkspaceMountFolder reports a devcontainer.json that uses "image" or "build" and sets only one of "workspaceMount" or "workspaceFolder", leaving the tool unable to tell where the overridden mount lands inside the container.

func (MissingWorkspaceMountFolder) Check

Check implements linter.Rule.

func (MissingWorkspaceMountFolder) Description

func (MissingWorkspaceMountFolder) Description() string

Description implements linter.Rule.

func (MissingWorkspaceMountFolder) FileTypes

FileTypes implements linter.Rule.

func (MissingWorkspaceMountFolder) ID

ID implements linter.Rule.

func (MissingWorkspaceMountFolder) Paths

Paths implements linter.Rule.

func (MissingWorkspaceMountFolder) Platforms

Platforms implements linter.Rule.

type NoAppPort

type NoAppPort struct{}

NoAppPort reports the legacy "appPort" property. It only supports statically publishing ports at container-creation time; "forwardPorts" is the modern replacement and forwards ports dynamically without requiring the container to be recreated.

func (NoAppPort) Check

func (r NoAppPort) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoAppPort) Description

func (NoAppPort) Description() string

Description implements linter.Rule.

func (NoAppPort) FileTypes

func (NoAppPort) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoAppPort) ID

func (NoAppPort) ID() string

ID implements linter.Rule.

func (NoAppPort) Paths

func (NoAppPort) Paths() []string

Paths implements linter.Rule.

func (NoAppPort) Platforms

func (NoAppPort) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoCapAddAll

type NoCapAddAll struct{}

NoCapAddAll reports a devcontainer.json or devcontainer-feature.json that grants every Linux capability to the container, either via an "ALL" entry in the "capAdd" property or, in a devcontainer.json, a "--cap-add=ALL" entry in "runArgs". Granting all capabilities gives the container far more privilege than most workloads need, which is a significant security risk.

func (NoCapAddAll) Check

func (r NoCapAddAll) Check(ctx *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoCapAddAll) Description

func (NoCapAddAll) Description() string

Description implements linter.Rule.

func (NoCapAddAll) FileTypes

func (NoCapAddAll) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoCapAddAll) ID

func (NoCapAddAll) ID() string

ID implements linter.Rule.

func (NoCapAddAll) Paths

func (NoCapAddAll) Paths() []string

Paths implements linter.Rule.

func (NoCapAddAll) Platforms

func (NoCapAddAll) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoDockerSocketMount

type NoDockerSocketMount struct{}

NoDockerSocketMount reports a devcontainer.json that bind-mounts the host's Docker daemon socket into the container, either via a "mounts" entry or a "-v"/"--volume"/"--mount" entry in "runArgs". Anything with access to the socket can control the host's Docker daemon, which is effectively root-equivalent access to the host.

func (NoDockerSocketMount) Check

Check implements linter.Rule.

func (NoDockerSocketMount) Description

func (NoDockerSocketMount) Description() string

Description implements linter.Rule.

func (NoDockerSocketMount) FileTypes

func (NoDockerSocketMount) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoDockerSocketMount) ID

ID implements linter.Rule.

func (NoDockerSocketMount) Paths

func (NoDockerSocketMount) Paths() []string

Paths implements linter.Rule.

func (NoDockerSocketMount) Platforms

func (NoDockerSocketMount) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoImageLatest

type NoImageLatest struct{}

NoImageLatest reports the "image" property when it references a container image without an explicit tag or with the "latest" tag. Such references are not reproducible: the image they resolve to changes over time.

func (NoImageLatest) Check

func (r NoImageLatest) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoImageLatest) Description

func (NoImageLatest) Description() string

Description implements linter.Rule.

func (NoImageLatest) FileTypes

func (NoImageLatest) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoImageLatest) ID

func (NoImageLatest) ID() string

ID implements linter.Rule.

func (NoImageLatest) Paths

func (NoImageLatest) Paths() []string

Paths implements linter.Rule.

func (NoImageLatest) Platforms

func (NoImageLatest) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoPrivilegedContainer

type NoPrivilegedContainer struct{}

NoPrivilegedContainer reports a devcontainer.json or devcontainer-feature.json that runs the container in privileged mode, either via the "privileged" property or, in a devcontainer.json, a "--privileged" entry in "runArgs". Privileged mode disables the container's isolation from the host, which is a significant security risk.

func (NoPrivilegedContainer) Check

func (r NoPrivilegedContainer) Check(ctx *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoPrivilegedContainer) Description

func (NoPrivilegedContainer) Description() string

Description implements linter.Rule.

func (NoPrivilegedContainer) FileTypes

func (NoPrivilegedContainer) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoPrivilegedContainer) ID

ID implements linter.Rule.

func (NoPrivilegedContainer) Paths

func (NoPrivilegedContainer) Paths() []string

Paths implements linter.Rule.

func (NoPrivilegedContainer) Platforms

func (NoPrivilegedContainer) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoSeccompOverride

type NoSeccompOverride struct{}

NoSeccompOverride reports a devcontainer.json or devcontainer-feature.json that overrides the container runtime's default seccomp profile, either via the "securityOpt" property or, in a devcontainer.json, a "--security-opt seccomp=..." entry in "runArgs". Unlike NoSeccompUnconfined, which only flags disabling seccomp entirely, this rule flags any override, including a custom profile, since it replaces the runtime's vetted default. It is off by default because many projects legitimately ship a custom profile.

func (NoSeccompOverride) Check

func (r NoSeccompOverride) Check(ctx *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoSeccompOverride) Description

func (NoSeccompOverride) Description() string

Description implements linter.Rule.

func (NoSeccompOverride) FileTypes

func (NoSeccompOverride) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoSeccompOverride) ID

ID implements linter.Rule.

func (NoSeccompOverride) Paths

func (NoSeccompOverride) Paths() []string

Paths implements linter.Rule.

func (NoSeccompOverride) Platforms

func (NoSeccompOverride) Platforms() []linter.Platform

Platforms implements linter.Rule.

type NoSeccompUnconfined

type NoSeccompUnconfined struct{}

NoSeccompUnconfined reports a devcontainer.json or devcontainer-feature.json that disables seccomp confinement, either via the "securityOpt" property or, in a devcontainer.json, a "--security-opt seccomp=unconfined" entry in "runArgs". Running unconfined removes a key layer of kernel-level syscall filtering that isolates the container from the host.

func (NoSeccompUnconfined) Check

func (r NoSeccompUnconfined) Check(ctx *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (NoSeccompUnconfined) Description

func (NoSeccompUnconfined) Description() string

Description implements linter.Rule.

func (NoSeccompUnconfined) FileTypes

func (NoSeccompUnconfined) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (NoSeccompUnconfined) ID

ID implements linter.Rule.

func (NoSeccompUnconfined) Paths

func (NoSeccompUnconfined) Paths() []string

Paths implements linter.Rule.

func (NoSeccompUnconfined) Platforms

func (NoSeccompUnconfined) Platforms() []linter.Platform

Platforms implements linter.Rule.

type PinExtensionVersion

type PinExtensionVersion struct{}

PinExtensionVersion reports a "customizations.vscode.extensions" entry that does not pin an explicit version (e.g. "publisher.name@1.2.3"). Without a pinned version, the VS Code Dev Containers extension and GitHub Codespaces always install the latest published version, which is not reproducible.

func (PinExtensionVersion) Check

Check implements linter.Rule.

func (PinExtensionVersion) Description

func (PinExtensionVersion) Description() string

Description implements linter.Rule.

func (PinExtensionVersion) FileTypes

func (PinExtensionVersion) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (PinExtensionVersion) ID

ID implements linter.Rule.

func (PinExtensionVersion) Paths

func (PinExtensionVersion) Paths() []string

Paths implements linter.Rule.

func (PinExtensionVersion) Platforms

func (PinExtensionVersion) Platforms() []linter.Platform

Platforms implements linter.Rule.

type PinFeatureVersion

type PinFeatureVersion struct{}

PinFeatureVersion reports a "features" entry whose key references an OCI Feature without an explicit version tag or with the "latest" tag. Such references are not reproducible: the Feature they resolve to changes over time. Local path Features (e.g. "./my-feature") and direct tarball URIs (e.g. "https://.../devcontainer-feature.tgz") have no version tag to pin and are not checked.

func (PinFeatureVersion) Check

func (r PinFeatureVersion) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (PinFeatureVersion) Description

func (PinFeatureVersion) Description() string

Description implements linter.Rule.

func (PinFeatureVersion) FileTypes

func (PinFeatureVersion) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (PinFeatureVersion) ID

ID implements linter.Rule.

func (PinFeatureVersion) Paths

func (PinFeatureVersion) Paths() []string

Paths implements linter.Rule.

func (PinFeatureVersion) Platforms

func (PinFeatureVersion) Platforms() []linter.Platform

Platforms implements linter.Rule.

type PinImageDigest

type PinImageDigest struct{}

PinImageDigest reports the "image" property when it references a container image without a content digest (e.g. "ubuntu@sha256:..."). Unlike NoImageLatest, which only flags a missing or "latest" tag, this rule flags any reference that isn't pinned by digest, since even a fixed tag can later be reassigned to point at a different image. It is off by default because digest-pinning every image is a heavier requirement than most projects want.

func (PinImageDigest) Check

func (r PinImageDigest) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (PinImageDigest) Description

func (PinImageDigest) Description() string

Description implements linter.Rule.

func (PinImageDigest) FileTypes

func (PinImageDigest) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (PinImageDigest) ID

func (PinImageDigest) ID() string

ID implements linter.Rule.

func (PinImageDigest) Paths

func (PinImageDigest) Paths() []string

Paths implements linter.Rule.

func (PinImageDigest) Platforms

func (PinImageDigest) Platforms() []linter.Platform

Platforms implements linter.Rule.

type RequireCapDropAll

type RequireCapDropAll struct{}

RequireCapDropAll reports a devcontainer.json that does not drop all Linux capabilities, either via an "ALL" entry in the "capDrop" property or a "--cap-drop=ALL" entry in "runArgs". Dropping every capability and adding back only what's needed (e.g. via "capAdd") follows the principle of least privilege. It is off by default because most configs don't set it and enabling it by default would be noisy.

func (RequireCapDropAll) Check

func (r RequireCapDropAll) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (RequireCapDropAll) Description

func (RequireCapDropAll) Description() string

Description implements linter.Rule.

func (RequireCapDropAll) FileTypes

func (RequireCapDropAll) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (RequireCapDropAll) ID

ID implements linter.Rule.

func (RequireCapDropAll) Paths

func (RequireCapDropAll) Paths() []string

Paths implements linter.Rule.

func (RequireCapDropAll) Platforms

func (RequireCapDropAll) Platforms() []linter.Platform

Platforms implements linter.Rule.

type RequireNoNewPrivileges

type RequireNoNewPrivileges struct{}

RequireNoNewPrivileges reports a devcontainer.json that does not set "no-new-privileges", either via the "securityOpt" property or a "--security-opt no-new-privileges..." entry in "runArgs". Without it, processes in the container can gain additional privileges through setuid/setgid binaries. It is off by default because most configs don't set it and enabling it by default would be noisy.

func (RequireNoNewPrivileges) Check

Check implements linter.Rule.

func (RequireNoNewPrivileges) Description

func (RequireNoNewPrivileges) Description() string

Description implements linter.Rule.

func (RequireNoNewPrivileges) FileTypes

func (RequireNoNewPrivileges) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (RequireNoNewPrivileges) ID

ID implements linter.Rule.

func (RequireNoNewPrivileges) Paths

func (RequireNoNewPrivileges) Paths() []string

Paths implements linter.Rule.

func (RequireNoNewPrivileges) Platforms

func (RequireNoNewPrivileges) Platforms() []linter.Platform

Platforms implements linter.Rule.

type RequireNonRoot

type RequireNonRoot struct{}

RequireNonRoot reports a devcontainer.json that does not clearly configure a non-root user. Per the devcontainer.json spec, "remoteUser" is the user any lifecycle script and remote editor/IDE server or terminal session runs as, defaulting to "containerUser" (and, ultimately, the image's own default user) when unset. Both properties are therefore consulted: "remoteUser" is checked first, falling back to "containerUser" only when "remoteUser" is unset. It is off by default because most configs don't set either property and enabling it by default would be noisy.

func (RequireNonRoot) Check

func (r RequireNonRoot) Check(_ *linter.Context, node *linter.Node) []linter.Finding

Check implements linter.Rule.

func (RequireNonRoot) Description

func (RequireNonRoot) Description() string

Description implements linter.Rule.

func (RequireNonRoot) FileTypes

func (RequireNonRoot) FileTypes() []linter.FileType

FileTypes implements linter.Rule.

func (RequireNonRoot) ID

func (RequireNonRoot) ID() string

ID implements linter.Rule.

func (RequireNonRoot) Paths

func (RequireNonRoot) Paths() []string

Paths implements linter.Rule.

func (RequireNonRoot) Platforms

func (RequireNonRoot) Platforms() []linter.Platform

Platforms implements linter.Rule.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL