compose-lint
Security-focused linter for Docker Compose files. Catches dangerous misconfigurations before they reach production — and auto-fixes the unambiguous ones, dry-run first. Grounded in OWASP and the CIS Docker Benchmark.
Static-analysis checks for docker-compose.yml and compose.yaml, covering privileged containers, unpinned images, host-network sharing, sensitive bind mounts, hard-coded credentials, and more. Full rule documentation lives at tmatens.github.io/compose-lint (the same pages --explain prints offline).
In a scan of 5,417 public Docker Compose files on GitHub, 91% of those that parse had at least one security finding. Nearly all skip basic capability restrictions, 49% run images without a pinned digest, and 64% bind ports to all interfaces. compose-lint catches these in CI before they ship. Read the full State of Docker Compose Security report →
What it catches:
- Privilege flaws —
privileged: true, missingcap_drop,no-new-privilegesnot set, root user, host namespace sharing - Network exposure — wildcard port binds,
network_mode: host - Supply-chain — unpinned images, missing digest pins
- Filesystem and credential leaks — Docker socket mounts, sensitive host paths, plaintext credentials in
environment:
Use it if you ship Compose to production, want defense in depth in a homelab, or want a fast pre-merge gate on infrastructure-as-code. Fits the same niche as Hadolint, the Dockerfile linter and dclint, the Compose schema linter: zero-config, opinionated, fast, and grounded in the OWASP Docker Security Cheat Sheet and CIS Docker Benchmark.
Installation
pip
pip install compose-lint
Or run it ad hoc without installing anything:
uvx compose-lint docker-compose.yml # or: pipx run compose-lint docker-compose.yml
That resolves the newest release at install time. For a reproducible install (CI, production tooling), pin the version and install the dependency set from the repo's hash-pinned lockfile, which release automation keeps current:
pip install --require-hashes -r requirements.lock # dependencies, hash-pinned
pip install --no-deps compose-lint==X.Y.Z # the tool, version-pinned
Docker — composelint/compose-lint
docker run --rm -v "$(pwd):/src" composelint/compose-lint
The Docker image is distroless, multi-arch, and runs nonroot — see Security posture below for SLSA, Sigstore, and OpenVEX details.
Running with full hardening
Want to dogfood compose-lint's own rules against the container that runs it? See the hardening guide for the fully-hardened docker run invocation, the flag-to-rule mapping, and digest-pinning instructions.
Quick Start
Run without arguments to auto-detect compose.yml, compose.yaml, docker-compose.yml, or docker-compose.yaml in the current directory:
compose-lint
Or pass files explicitly:
compose-lint docker-compose.yml docker-compose.prod.yml
Preview the auto-fixable findings as a unified diff, then apply them — reading the ⚠ behavior-changing labels first (see Fixing findings):
compose-lint fix # dry-run diff, writes nothing
compose-lint fix --apply # write the fixes in place
Don't recognize a rule ID in the output? --explain prints the full rule doc — what it catches, why it matters, the fix, and the OWASP/CIS reference — without leaving the terminal:
compose-lint --explain CL-0005
Docker equivalent:
docker run --rm -v "$(pwd):/src" composelint/compose-lint docker-compose.prod.yml
Compose compatibility
compose-lint targets the Compose Specification used by Compose v2 and v3. Compose v1 files (services declared at the top level) are skipped with a stderr note rather than failing the run — Docker retired Compose v1 in 2023. Structural fragments (files containing only volumes: / networks: / configs: / secrets: / x-* keys, typically merged via -f overlay.yml) are skipped for the same reason, as is compose-lint's own .compose-lint.yml config if a glob happens to sweep it in. Genuinely unrecognised shapes still exit 2.
Python 3.10+ is required for the pip install path; the Docker image is self-contained.
Example Output
Given this docker-compose.yml:
services:
traefik:
image: traefik:v3.0@sha256:aaaabbbbccccddddeeeeffff00001111222233334444555566667777888899990
read_only: true
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
mem_limit: 256m
cpus: 0.5
volumes:
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "8080:80"
db:
image: postgres:16@sha256:bbbbccccddddeeeeffff000011112222333344445555666677778888999900001
read_only: true
cap_drop: [ALL]
security_opt: [no-new-privileges:true]
mem_limit: 1g
cpus: 1.0
environment:
POSTGRES_PASSWORD: hunter2
volumes:
- pgdata:/var/lib/postgresql/data
tmpfs:
- /tmp
- /run
volumes:
pgdata:
and this .compose-lint.yml (suppressing CL-0001 for traefik with a tracked reason):
rules:
CL-0001:
exclude_services:
traefik: "SEC-1234 approved — socket proxy planned for 2026-Q3"
running compose-lint docker-compose.yml produces:
files: docker-compose.yml · config: .compose-lint.yml · fail-on: high
docker-compose.yml
service: traefik (line 10)
line severity rule message
10 SUPPRESSED CL-0001 Docker runtime socket mounted via '/var/run/docker.sock:/var/run/docker.sock'. This gives the container full control over the Docker runtime — equivalent to root on the host.
reason: SEC-1234 approved — socket proxy planned for 2026-Q3
12 MEDIUM CL-0005 Port '8080:80' is bound to all interfaces. Docker bypasses host firewalls (UFW/firewalld), potentially exposing this port to the public internet.
12 │ - "8080:80"
│ ───────
fix: Bind to localhost: 127.0.0.1:8080:80
If public access is needed, use a reverse proxy with TLS.
ref: https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-5a-be-careful-when-mapping-container-ports-to-the-host-with-firewalls-like-ufw
service: db (line 22)
line severity rule message
22 HIGH CL-0020 Service has credential-shaped env key 'POSTGRES_PASSWORD' with a literal value. Env vars are exposed via `docker inspect`, `/proc/<pid>/environ`, `docker compose config`, process listings, and CI logs — any process or operator with daemon access can read them.
22 │ POSTGRES_PASSWORD: hunter2
│ ─────────────────
fix: Move 'POSTGRES_PASSWORD' to Compose's `secrets:` primitive. If the image supports the `*_FILE` convention (Postgres, MySQL, MariaDB, MinIO, etc.), set `POSTGRES_PASSWORD_FILE: /run/secrets/<name>` and declare the secret under the top-level `secrets:` block sourced from a gitignored file or `external: true`. Otherwise, have the entrypoint read the secret file at startup and export the value into the workload's environment.
ref: https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html#rule-12-utilize-docker-secrets-for-sensitive-data-management
docker-compose.yml: 1 high, 1 medium · 1 suppressed (not counted)
✗ FAIL · 1 finding at or above high
Exit code is 1 (one finding at or above the default --fail-on high threshold). Suppressed findings are shown for auditability but do not count toward the threshold. Findings are grouped by service and ordered highest-severity first within each service; the fix block and reference URL print only once per rule id per file — pass -v / --verbose to repeat them on every finding, or -q / --quiet for one compact line per finding.
How it compares
| Tool | Compose security rules | Auto-fix | Scope | Zero config |
|---|---|---|---|---|
| compose-lint | Yes | Yes — dry-run diff first | Docker Compose | Yes |
| KICS | Yes | Yes (remediate command) |
Broad IaC (Terraform, K8s, Compose, ...) | No |
| Hadolint | No — Dockerfile only | No | Dockerfile | Yes |
| dclint | Yes — schema/structure only | Style/formatting only | Docker Compose | Yes |
| Trivy | No — image/CVE + IaC misconfig scanning, no dedicated Compose ruleset | No | Dockerfiles, images, IaC | Yes |
| Checkov | No — no dedicated Compose ruleset | No | Broad IaC (Terraform, K8s, ...) | No |
Competitor capabilities verified July 2026.
If you need broad IaC coverage across Terraform, Kubernetes, and more, KICS covers Docker Compose and is worth evaluating. If you want a lightweight, focused tool with zero config and actionable fix guidance for Compose files specifically, this is it.
Not in scope: compose-lint does not validate Compose schema, scan images for CVEs, or lint Dockerfiles. Pair it with dclint for schema/structure, Hadolint for Dockerfiles, and Trivy for image CVEs.
Rules
| ID | Severity | Description | OWASP | CIS |
|---|---|---|---|---|
| CL-0001 | CRITICAL | Host control socket exposed | Rule #1 | 5.32 |
| CL-0002 | CRITICAL | Privileged mode enabled | Rule #3 | 5.5 |
| CL-0003 | MEDIUM | Privilege escalation not blocked | Rule #4 | 5.26 |
| CL-0004 | MEDIUM | Image not pinned to version | Rule #13 | 5.28 |
| CL-0005 | MEDIUM | Ports bound to all interfaces | Rule #5a | 5.14 |
| CL-0006 | MEDIUM | No capability restrictions | Rule #3 | 5.4 |
| CL-0007 | LOW | Filesystem not read-only | Rule #8 | 5.13 |
| CL-0008 | HIGH | Host network mode | Rule #5 | 5.10 |
| CL-0009 | HIGH | Security profile disabled | Rule #6 | 5.2, 5.3, 5.22 |
| CL-0010 | HIGH | Host namespace sharing | Rule #3 | 5.16, 5.17, 5.21, 5.31 |
| CL-0011 | HIGH | Strong host-adjacent capability added | Rule #3 | 5.4 |
| CL-0013 | HIGH | Sensitive host path exposed | Rule #8 | 5.6 |
| CL-0014 | LOW | Logging driver disabled | — | — |
| CL-0016 | CRITICAL | Dangerous host device exposed | — | 5.18 |
| CL-0017 | LOW | Shared mount propagation | — | 5.20 |
| CL-0018 | MEDIUM | Explicit root user | Rule #2 | — |
| CL-0019 | MEDIUM | Image tag without digest | Rule #13 | — |
| CL-0020 | HIGH | Credential-shaped env key with literal value | Rule #12 | — |
| CL-0021 | HIGH | Credential embedded in connection-string env value | Rule #12 | — |
| CL-0022 | LOW | tmpfs mount re-enables exec/suid/dev | Rule #8 | — |
| CL-0024 | CRITICAL | Host-code-execution capability added | Rule #3 | 5.4 |
| CL-0025 | CRITICAL | Root-equivalent host path mounted writable | Rule #8 | 5.6 |
| CL-0026 | MEDIUM | No resource limits (memory/CPU) | Rule #7 | 5.10, 5.11 |
| CL-0027 | MEDIUM | Bounded-grant capability added | Rule #3 | 5.4 |
| CL-0028 | HIGH | Host-reaching capability added | Rule #3 | 5.4 |
| CL-0030 | HIGH | Host-disclosure capability added | Rule #3 | 5.4 |
| CL-0029 | HIGH | Host-availability capability added | Rule #3 | 5.4 |
Severity Levels
Findings are rated LOW, MEDIUM, HIGH, or CRITICAL. Each rule's severity is derived from a two-axis matrix — the attacker precondition the misconfiguration creates, and the impact scope it reaches — under a stated attacker baseline and a stated Docker posture. See docs/severity.md for the full scoring matrix, the derivation of every rule, and the override mechanism.
Configuration
Create .compose-lint.yml to disable rules, exclude specific services, or adjust severity:
rules:
CL-0001:
enabled: false
reason: "SEC-1234 — approved 2026-07-01"
CL-0003:
exclude_services:
minecraft: "entrypoint switches users via su-exec"
CL-0005:
severity: medium
Disabled and excluded findings still appear marked SUPPRESSED with the reason flowing to JSON's suppression_reason and SARIF's justification (recognized by GitHub Code Scanning) — they do not affect exit code. Pass --skip-suppressed to hide them. A severity: override is reported too, as (severity overridden from …) in text and severity_overridden_from / properties.severityOverriddenFrom in JSON and SARIF, so a re-graded finding is distinguishable from one the rule declared at that level.
See docs/configuration.md for per-service exclusion semantics, precedence rules, and the full output-format mapping.
CLI Reference
compose-lint [check] [OPTIONS] [FILE ...] Lint files (default; bare invocation works)
compose-lint fix [OPTIONS] [FILE ...] Auto-remediate auto-fixable findings
compose-lint init [OPTIONS] FILE Generate a starter .compose-lint.yml
check options:
--format {text,json,sarif} Output format (default: text)
--fail-on {low,medium,high,critical}
Minimum severity to trigger exit 1 (default: high)
-v, --verbose Repeat the fix block and reference on every finding (text mode)
-q, --quiet One line per finding — no fix, reference, or excerpt (text mode)
--skip-suppressed Hide suppressed findings from output
--allow-partial-coverage Grade a file whose `include:` / cross-file `extends:`
could not be resolved, instead of failing (exit 2)
--no-merge-overrides Lint each file alone instead of merging the
`compose.override.yml` Compose merges beside it
--no-env Ignore a `.env` sitting beside the Compose file,
which Compose reads for COMPOSE_FILE and for
`${VAR}` values
--config PATH Path to config file (default: .compose-lint.yml)
--strict-config Treat config diagnostics (unknown rule id or key) as errors, not warnings
--explain CL-XXXX Print the full documentation for a single rule
--version Show version and exit
fix options:
--apply Write fixes in place (default: print a dry-run diff)
--only CL-XXXX Restrict fixes to the named rule(s); repeatable
--no-merge-overrides Fix each file alone instead of merging the
`compose.override.yml` Compose merges beside it
--no-env Ignore a `.env` sitting beside the Compose file
--config PATH Path to config file (suppressions are honored)
--strict-config Treat config diagnostics (unknown rule id or key) as errors, not warnings
init options:
-o, --output PATH Where to write the config (default: .compose-lint.yml)
--force Overwrite an existing config file
Fixing findings
compose-lint fix auto-remediates the findings whose edit is mechanically
unambiguous — one correct value, in one place, with no collateral change to
the rest of the file: adding read_only: true or no-new-privileges:true,
binding a published port to 127.0.0.1, restoring a disabled logging driver
or seccomp profile, and similar. It is dry-run by default: it
prints a unified diff and writes nothing.
Auto-fixable does not mean harmless. The guarantee is about the edit, not the outcome.
fixwill not corrupt your file, reflow it, or guess at a value it cannot derive — but it will happily change how your stack behaves.read_only: truebreaks a container that writes to its root filesystem; rebinding a published port to127.0.0.1cuts off every client outside the host. Those edits are still offered, because withholding them would hide a real finding. Instead each one is labelled⚠ behavior-changingin the diff with the specific breakage named:⚠ behavior-changing · CL-0007: read_only: true breaks the container if it writes to its root filesystem; declare writable paths via tmpfs/volumes first.Read those lines before you
--apply, and roll the result out to a staging stack before production. Treatfixas a patch author, not an approver.
compose-lint fix docker-compose.yml # preview the diff, write nothing
compose-lint fix --apply docker-compose.yml # write the fixes in place
compose-lint fix --only CL-0007 --apply . # restrict to one rule
- Dry-run by default;
--applywrites in place via an atomic swap that preserves the file's permission bits — an interrupted write never corrupts the Compose file. - Only mechanically unambiguous fixes are applied. Findings whose remediation is context-dependent (e.g. CL-0006 capability lists, CL-0001 socket mounts) are reported as needing manual review, never auto-edited — the tool refuses rather than guess at a value only you can choose.
- Behavior-changing edits are labelled, not withheld. Every edit that alters
runtime behavior emits a
⚠ behavior-changingline naming what breaks, on the dry-run and on--apply, so the warning reaches you on whichever path you took. The label is the mitigation; there is no severity gate that quietly drops risky fixes. - Suppressed findings are never touched —
.compose-lint.ymldisables and per-service excludes are honored. - Refuses rather than risk a wrong rewrite. Files using YAML anchors, merge keys, or
${VAR}interpolation in the affected region are skipped rather than risk a wrong rewrite, and every apply is re-parsed and re-linted before it is written — anything that wouldn't round-trip clean is refused with the diff surfaced for diagnosis. - Diff is data, status is human. The diff goes to stdout; progress and
warnings go to stderr, so
compose-lint fix file.yml > changes.diffcaptures exactly the patch.
Structured fixes also ride in SARIF output: compose-lint check --format sarif
populates fixes[].artifactChanges, which GitHub Code Scanning renders as an
inline suggested change on the pull request.
Generating a starter config
compose-lint init turns a file's current findings into a .compose-lint.yml
you then triage, so you don't have to hand-author suppressions from the schema:
compose-lint init docker-compose.yml # writes ./.compose-lint.yml
compose-lint init docker-compose.yml -o ci.yml # write somewhere else
compose-lint init docker-compose.yml --force # overwrite an existing config
Each finding becomes a per-service exclude_services entry with a placeholder
reason — never a global enabled: false, so a service you add later still trips
the rule instead of being silently uncovered. It refuses to overwrite an
existing config without --force, writes nothing for a clean file, and sends
status to stderr. Replace each TODO reason with a real justification or delete
the entry and fix the issue. See
docs/configuration.md
for the full behavior.
Versioning & stability
compose-lint follows Semantic Versioning. From 1.0, the CLI, exit codes, config schema, and JSON/SARIF output are stable. New and tightened rules ship in MINOR releases, so pin a version or use --fail-on if you need deterministic CI. See docs/compatibility.md for the full stability promise and deprecation policy.
Color is on when stdout is a terminal. Set NO_COLOR to disable it (even on a
terminal) or FORCE_COLOR to force it through a pipe — e.g. into less -R or a
CI log that renders ANSI.
Exit Codes
| Code | Meaning |
|---|---|
| 0 | No findings at or above the --fail-on threshold |
| 1 | One or more findings at or above the --fail-on threshold |
| 2 | compose-lint couldn't run, or couldn't see the whole stack (invalid args, file not found, invalid Compose file, a rule crashed, or a coverage gap — see below) |
Overlays are merged. docker compose up loads a compose.override.yml sitting beside the base file and merges it, with no flag and no opt-in, so the merged pair is what actually runs. compose-lint grades that pair: the run header names both documents, findings report the file their evidence is written in, and the exit code is unaffected because merging is coverage achieved, not a gap (ADR-025). --no-merge-overrides grades the base alone. fix edits only findings written in the file it is fixing; anything from the overlay is left for manual review.
A sibling .env is read, because Compose reads it. docker compose loads a .env from the Compose file's own directory and uses it for two things, and compose-lint follows both (ADR-026):
COMPOSE_FILEchooses the documents. It replaces discovery and suppresses the automatic override merge, so a project configured that way is graded as the file set Compose actually loads. For a file you name on the command line, a.envcan only add documents, never drop the one you asked for.${VAR}resolves to what the.envsupplies.volumes: ["${MOUNT}:/data"]withMOUNT=/var/run/docker.sockis a control-socket mount, and is now graded as one. A supplied value beats a written default, matching Compose; a name the.envdoes not define stays unresolved rather than guessed.
Two deliberate limits. Values under environment: are never resolved from a .env — that is where secrets live, the only rules reading them grade sensitivity rather than deployment, and resolving there would make CL-0021 flag the very pattern its own fix text recommends. And references inside the .env are not expanded from your shell, so nothing about the machine running the lint reaches a finding.
The run header names the .env it read, so two machines that read different ones produce a visible difference rather than a mystery. --no-env ignores it entirely. The ambient shell environment is out of scope: a COMPOSE_FILE exported in a session and never written down would make the same checkout lint differently depending on who ran the command.
Coverage gaps. Beyond that overlay, compose-lint follows no references out of a file, so include: and cross-file extends: {file: ...} leave part of the stack unlinted. Reporting a pass over a partial view is the one failure mode a merge gate cannot have, so a gap is an error: exit 2, a JSON errors[] entry, and a SARIF toolExecutionNotifications record. Lint the merged output (docker compose config) to cover everything, or pass --allow-partial-coverage to accept the gap and grade what is visible.
The default threshold is high — medium and low findings don't fail CI unless you opt in:
compose-lint --fail-on low docker-compose.yml # fail on everything
compose-lint --fail-on critical docker-compose.yml # only critical
CI Integration
GitHub Actions
The easiest path — runs compose-lint and uploads findings to GitHub Code Scanning. Pinned to immutable SHAs for reproducible CI; Renovate keeps the pins current:
# .github/workflows/lint.yml
name: Compose Lint
on: [push, pull_request]
permissions: {}
jobs:
compose-lint:
runs-on: ubuntu-latest
permissions:
contents: read # checkout
security-events: write # upload the SARIF to Code Scanning
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: tmatens/compose-lint@50d147004984f929e0b5fd74eaa776d832601cea # v0.21.0
with:
sarif-file: results.sarif
The permissions: blocks are part of the recipe, not decoration. Without them the
job inherits the repository default, which on many repositories is still
read-write for every scope — so a linting job that needs only contents: read
and security-events: write runs holding a token that can push code and edit
releases. Denying everything at the workflow level and granting the two scopes
the job actually uses keeps a compromised dependency in this job from reaching
anything else.
Drop security-events: write if you are not uploading SARIF. To write the
SARIF file without the Code Scanning upload — for example to attach it as a
build artifact instead — set upload-sarif: "false" alongside sarif-file
(and drop the scope).
Or install from PyPI directly:
- uses: actions/setup-python@v6
with:
python-version: "3.13"
- run: pip install compose-lint
- run: compose-lint docker-compose.yml
Forgejo Actions
Forgejo Actions runs GitHub-Actions-compatible workflows via act_runner, with two practical differences: cross-instance action refs need full URLs (https://code.forgejo.org/...), and JS actions like checkout need node inside the job container (act#107) — container: jobs run fine, but a node-less Python image fails at checkout, so install via apt + pip on the default image instead:
# .forgejo/workflows/validate.yml
name: Validate
on:
pull_request:
branches: [main]
workflow_dispatch:
jobs:
compose-lint:
runs-on: docker
steps:
- uses: https://code.forgejo.org/actions/checkout@v4
- name: Install compose-lint
run: |
apt-get update -qq
apt-get install -yqq --no-install-recommends python3-pip
pip3 install --break-system-packages --no-cache-dir compose-lint==0.22.0
- name: Run compose-lint
run: compose-lint --fail-on high
Forgejo has no SARIF UI today — --format sarif still produces a valid document, but there's no security-tab equivalent to render it. Verified on Forgejo 16.0.2, runner 13.0.0 — this exact snippet is executed against a live Forgejo weekly by the forgejo-smoke workflow, which fails if this line and the versions it ran on disagree.
SARIF output
compose-lint --format sarif docker-compose.yml > results.sarif
Pre-commit
# .pre-commit-config.yaml
repos:
- repo: https://github.com/tmatens/compose-lint
rev: v0.22.0
hooks:
- id: compose-lint
The hook ships args: [--]. pre-commit builds the command as entry + args + filenames, so that trailing -- is what stops a repository path from being read as an option — a directory named --config=cfgdir holding a compose.yml otherwise arrives as --config=cfgdir/compose.yml and installs an attacker-authored policy for the run. Setting args: replaces that default, so keep -- last if you pass flags:
- id: compose-lint
args: [--fail-on, low, --]
Security posture
compose-lint is built to be safe to depend on:
- Runtime image: distroless Python on Debian, multi-arch (
linux/amd64+linux/arm64), nonroot UID 65532, no shell or package manager at runtime. See ADR-009. - Supply chain: every release ships SLSA build provenance and Sigstore attestations. Published to PyPI via Trusted Publishers (OIDC) — no manual
twine upload, no long-lived API tokens. - Vulnerability transparency: each release ships an OpenVEX document declaring known pip CVEs
not_affectedwith justificationvulnerable_code_not_present— pip code is stripped from the runtime venv and only.dist-infometadata is retained for SCA scanner attribution. - External audit: tracked on OpenSSF Scorecard and OpenSSF Best Practices Baseline 2; CodeQL runs on every PR, ClusterFuzzLite fuzzes code-touching PRs, and Docker Scout scans the published image daily.
- Reporting vulnerabilities: see SECURITY.md.
Contributing
See CONTRIBUTING.md for development setup and how to add rules.
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file compose_lint-0.22.0.tar.gz.
File metadata
- Download URL: compose_lint-0.22.0.tar.gz
- Upload date:
- Size: 2.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0ec2dd77003bc96ab0ff1676be0562150f6194e72f105ba67a6539f57e4afebc
|
|
| MD5 |
f0b88f89a79eba66ae18fb2455f56b0a
|
|
| BLAKE2b-256 |
9a51022fd7f9eafbbee8acb9f19c2f56139a6f7b81a6f551c0f76527235bf93d
|
Provenance
The following attestation bundles were made for compose_lint-0.22.0.tar.gz:
Publisher:
publish.yml on tmatens/compose-lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
compose_lint-0.22.0.tar.gz -
Subject digest:
0ec2dd77003bc96ab0ff1676be0562150f6194e72f105ba67a6539f57e4afebc - Sigstore transparency entry: 2556453204
- Sigstore integration time:
-
Permalink:
tmatens/compose-lint@811ef6b379dbc78d048fcedaf976205705d4a7c3 -
Branch / Tag:
refs/tags/v0.22.0 - Owner: https://github.com/tmatens
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@811ef6b379dbc78d048fcedaf976205705d4a7c3 -
Trigger Event:
push
-
Statement type:
File details
Details for the file compose_lint-0.22.0-py3-none-any.whl.
File metadata
- Download URL: compose_lint-0.22.0-py3-none-any.whl
- Upload date:
- Size: 290.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed17235e88449be9ce7db3c4f49d9f171360c2b5dab28f544577b9a563d578af
|
|
| MD5 |
4bf84ad93bd9d974d319f32bf732fe00
|
|
| BLAKE2b-256 |
da35a1cbc8eab80fba75db0aed1868b1a5ef2559a41600173c3f1438bcfd8033
|
Provenance
The following attestation bundles were made for compose_lint-0.22.0-py3-none-any.whl:
Publisher:
publish.yml on tmatens/compose-lint
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
compose_lint-0.22.0-py3-none-any.whl -
Subject digest:
ed17235e88449be9ce7db3c4f49d9f171360c2b5dab28f544577b9a563d578af - Sigstore transparency entry: 2556453253
- Sigstore integration time:
-
Permalink:
tmatens/compose-lint@811ef6b379dbc78d048fcedaf976205705d4a7c3 -
Branch / Tag:
refs/tags/v0.22.0 - Owner: https://github.com/tmatens
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@811ef6b379dbc78d048fcedaf976205705d4a7c3 -
Trigger Event:
push
-
Statement type: