Problem
Paperscout handles Slack OAuth tokens and PostgreSQL connection strings in a deployed 24/7 service, but has no dependency lockfile. Running pip install -e . or building the Docker image pulls the latest compatible version of all five runtime dependencies at install time. The Dockerfile uses pip install . without --require-hashes or a constraints file, so the image's dependency graph is not reproducible across builds. A compromised or behavioral-breaking update to any dependency (especially pydantic-settings, which controls credential parsing) reaches the production build without review. Dependabot and CodeQL provide detection but not prevention.
Acceptance Criteria
Implementation Notes
pip-tools is the lightest-weight option: add pip-tools to dev dependencies, run pip-compile --generate-hashes pyproject.toml -o requirements.txt, update the Dockerfile RUN pip install line to use -r requirements.txt. Alternatively, adopt uv which is gaining traction in the Python ecosystem. The key constraint is that pyproject.toml continues to be the source of truth for dependency specifications, with the lockfile as a derived artifact. The Dependabot configuration in .github/dependabot.yml should continue to work alongside the lockfile.
References
- Eval finding: Test 37 (Security Posture / lockfile), cluster Sustainability
- Related files:
pyproject.toml, Dockerfile, .github/dependabot.yml, CONTRIBUTING.md
Problem
Paperscout handles Slack OAuth tokens and PostgreSQL connection strings in a deployed 24/7 service, but has no dependency lockfile. Running
pip install -e .or building the Docker image pulls the latest compatible version of all five runtime dependencies at install time. TheDockerfileusespip install .without--require-hashesor a constraints file, so the image's dependency graph is not reproducible across builds. A compromised or behavioral-breaking update to any dependency (especiallypydantic-settings, which controls credential parsing) reaches the production build without review. Dependabot and CodeQL provide detection but not prevention.Acceptance Criteria
pip-compile(pip-tools) generatingrequirements.txtwith pinned versions and hashes, oruv lockgeneratinguv.lockDockerfileto install from the lockfile with--require-hashes(pip-tools) or equivalent hash verificationpyproject.toml(e.g.,pip-compile --checkoruv lock --check)CONTRIBUTING.md: how to add/update a dependency and regenerate the lockfileImplementation Notes
pip-toolsis the lightest-weight option: addpip-toolsto dev dependencies, runpip-compile --generate-hashes pyproject.toml -o requirements.txt, update the DockerfileRUN pip installline to use-r requirements.txt. Alternatively, adoptuvwhich is gaining traction in the Python ecosystem. The key constraint is thatpyproject.tomlcontinues to be the source of truth for dependency specifications, with the lockfile as a derived artifact. The Dependabot configuration in.github/dependabot.ymlshould continue to work alongside the lockfile.References
pyproject.toml,Dockerfile,.github/dependabot.yml,CONTRIBUTING.md