code-quality analyzes untrusted repository content with tools that may execute consumer configuration. Review the image, setup commands, configuration files, and image overrides as part of the repository's trust boundary.
- dependency-cruiser configuration and import-linter imports can execute consumer code inside the container.
- A reusable-workflow
setupcommand, such ascomposer install, executes consumer code inside the job container. - Knip runs with configuration-executing plugins disabled, but other supported tools can still load repository configuration where their operation requires it.
- Local launcher containers bind-mount the current repository at
/workread-write.
- The image runs as its non-root
nodeuser by default. - On Linux, the launcher passes
--user <uid>:<gid>so files written into the mounted repository remain owned by the invoking user. - GitHub container jobs run as root because GitHub Actions owns the mounted workspace; the reusable workflow sets
options: --user root.
- Tool subprocesses receive an allow-list plus constant and invocation-specific values, not the complete parent environment.
- The npm launcher forwards
CI,GITHUB_ACTIONS,NO_COLOR, andFORCE_COLORinto the analysis container. - When host stdout is a TTY and neither
NO_COLORnorFORCE_COLORis set, the launcher injectsFORCE_COLOR=1; it invokesdocker runwithout-t, so container stdout is never a TTY. - The Docker client inherits the launcher's full environment because the launcher does not replace it when spawning Docker;
DOCKER_HOSTandDOCKER_CONTEXTare the security-relevant variables. - Treat a remote Docker daemon selected by those variables as part of the same trust boundary.
- The reusable workflow fixes the registry and repository to
ghcr.io/runroom/code-quality; callers can set onlyimage-tag. - The workflow validates check IDs as lowercase space-separated values and validates coverage artifact names before use.
- Launcher X.Y.Z normally selects the tag
ghcr.io/runroom/code-quality:vX.Y.Z. CODE_QUALITY_IMAGEreplaces the launcher's entire image reference and is validated only for syntactic shape, not publisher or contents; the accepted shape includes digest references such asghcr.io/runroom/code-quality@sha256:<digest>.- Set
CODE_QUALITY_IMAGEonly to a trusted image because that image receives a read-write repository mount. - The default launcher image uses a tag rather than a digest;
CODE_QUALITY_IMAGEcan select a digest.
- Consumer paths must be repository-relative and reject option-like values, colons, absolute paths, empty or
.paths, and parent-directory traversal. - An explicitly configured architecture rules file must exist.
- A coverage path must be repository-relative.
- Coverage resolution follows real paths and requires the resulting path to remain inside the repository, preventing symlink escape.
- Coverage input must be a regular file and no larger than 256 MiB.
- Missing, unreadable, or malformed Istanbul maps fail rather than silently changing measured results.
- A path that matches no repository file emits a notice and leaves advisory CRAP estimated.
- The v1 image pins all documented top-level tools.
- Global npm packages' transitive dependencies and Python packages are pinned only at the top level.
- Composer dependencies are fully locked.
- Downloaded phars are pinned and checksum-verified.
- These are accepted v1 limits; a tool-version change is a reviewed policy change, not an automatic baseline update.