Dependency security maintenance¶
COLEMAN audits the complete committed uv.lock, including development,
documentation, notebook, release, telemetry, ClickHouse and MCP extras, plus packages
that only install on another operating system. The base installation remains
independent of optional tools.
The lock file pins distribution versions and hashes. An advisory audit answers whether those versions have known reported vulnerabilities at the time of the query. A clean result does not prove that software has no undisclosed defects or that every possible deployment is secure.
Reproduce the audit¶
From a checkout with Python 3.14 and uv:
python scripts/audit_lock.py > /tmp/coleman-audit-requirements.txt
uv sync --frozen --only-group security --no-build --no-install-project
uv run --frozen --no-sync pip-audit \
--strict --no-deps --disable-pip \
--requirement /tmp/coleman-audit-requirements.txt \
--format json --output /tmp/coleman-audit.json
The generated pins are advisory lookup input, not installation requirements.
The script reads every registry entry rather than filtering for the current
platform. It skips only COLEMAN's root editable entry; an unknown package source
fails with an actionable error instead of escaping the audit. No project
dependency is installed or executed by this lookup. Install from the hashed
uv.lock with uv sync --frozen as usual.
The Locked dependency security audit GitHub workflow runs on dependency PRs,
main dependency updates, weekly and on manual dispatch. It retains the queried
pins and JSON results as workflow artifacts. Known vulnerabilities, advisory
collection failures and unsupported sources fail the job; there is no blanket
ignore list. Advisory services require network access. Unit tests cover the
inventory and fail-closed source handling offline.
Updating dependencies¶
- Inspect open Dependabot PRs and alerts, including aliases and affected version ranges. Counts from different advisory services may differ or contain aliases.
- Update vulnerable transitive packages in the lock. If a direct pin prevents a patched transitive version, update the direct package after checking its compatibility and release notes.
- Re-run the complete audit, native CI tests, installed-package examples, strict documentation and the repository quality gates. Notebook/documentation/server extras need checks too; they are not exempt because the base API is offline.
- Merge reviewed corrections before closing superseded bump PRs. Confirm GitHub's alert state after its dependency graph refreshes. Explain any actual blocker; do not dismiss an alert merely to reduce a counter.
October 2026 maintenance baseline¶
The pre-update GitHub inventory contained 106 open Dependabot alerts: 2 critical,
58 high, 42 medium and 4 low, all attached to uv.lock. The initial pip-audit
export reported 166 vulnerability occurrences in 17 packages; aliases and
platform/extra representations mean this is not a second count of unique GitHub
alerts.
The update refreshes affected registry packages, including GitPython, Pillow, Starlette, AnyIO, Authlib, Bleach, Cryptography, IDNA, Mistune, MkDocs Material, nbconvert, PyMdown Extensions, SoupSieve, Tornado, urllib3 and virtualenv. Zensical and Marimo direct pins also advance so their supported transitive dependency ranges admit patched versions. Native numerical dependencies are not upgraded without a compatibility or security reason.
The all-platform lock audit is the authoritative reproducible check for this maintenance change; its output is attached to the PR and retained in CI. Future advisories may change the result and require another update.
Workflow and documentation boundaries¶
The same review inventories code-scanning findings separately from dependency advisories. The October baseline additionally contained 33 SonarCloud alerts, mostly about installation in GitHub workflows, plus a documentation path warning.
CI pins the setup action and uv version, verifies the Linux archive checksum, installs registry dependencies from the frozen lock with source builds disabled, and installs the reviewed local project with the locked build backend. This explicit local editable build is separate from third-party source distribution builds; it retains normal development imports. Release/build/audit tools are also locked. CI checks run without silently synchronizing another dependency set.
Linux CI and DevContainers have a wheel-only installation path. On macOS, the existing Watchdog 6.0.0 documentation dependency has no wheel: local full-extra setup may need its hash-pinned source build. The Linux preflight must not be presented as proof of wheel availability on every platform.
The documentation generator refuses symlink sources and output, checks resolved source containment, reads the checked path, and atomically replaces complete output. Tests demonstrate that outside files remain untouched and interruption preserves the previous complete file. This protects normal repository generation; it is not an isolation boundary against an adversary concurrently rewriting the filesystem with the process's own permissions.
flowchart LR
Lock[All locked registry packages] --> Audit[Known advisory gate]
Sources[Workflow and filesystem findings] --> Review[Verify and fix findings]
Audit --> Checks[Tests, install, docs and local review]
Review --> Checks
Checks --> Merge[Reviewed security correction on main]
Merge --> Refresh[Refresh GitHub security findings]
Release distribution inventory¶
With Syft 1.42.3 installed on PATH, the release SBOM catalogs the wheel's distribution metadata, requires the expected COLEMAN version, and binds the root to the complete wheel's SHA-256. The package identifier is bound explicitly to this GitHub repository; inferred PyPI coordinates and guessed CPEs are removed because the PyPI name belongs to another project. It does not claim that unbundled dependencies are installed in the wheel. The complete lock advisory audit above covers those version pins separately.
The command accepts no arguments: it reads its checkout's package version and
uses the corresponding wheel and SBOM under that checkout's dist/.
The helper reads only the fixed METADATA member; it does not extract archive paths
or execute package code. Empty/mismatched inventories fail before publication.
Host file metadata is excluded, so local extraction paths do not become public
components. Tool timestamps/serial numbers remain observations. Output replaces
atomically after validation; a failed tool or interrupted write retains prior bytes.