Skip to content

security(infra): harden compose exposure and split pytest out of runtime deps (#185, #186, #187) - #214

Merged
parthrohit22 merged 2 commits into
Second-Origin:devfrom
parthrohit22:fix/185-186-187-infra-hardening
Jul 27, 2026
Merged

security(infra): harden compose exposure and split pytest out of runtime deps (#185, #186, #187)#214
parthrohit22 merged 2 commits into
Second-Origin:devfrom
parthrohit22:fix/185-186-187-infra-hardening

Conversation

@parthrohit22

Copy link
Copy Markdown
Collaborator

Summary

Three infrastructure-hardening fixes: (1) the Compose stack no longer binds Postgres (5432) or Redis (6379) to the host — they stay reachable only on the internal data network, reducing self-hosted attack surface (#186); (2) pytest and its test-only deps are removed from the runtime dependency lockfile and moved to a dev/test requirements file + pyproject test extra, so the container image no longer ships a test framework (#185); (3) a .gitattributes normalises line endings and keeps lockfiles/binaries handled consistently (#187).

Linked issue

Related to #185 (pytest in runtime deps), #186 (compose host port exposure), #187 (.gitattributes). Closes #185, #186, #187.

Roadmap alignment

  • Roadmap §23 workstream this advances: W6 (Trust / secure self-hosted operations) + W7 (Platform / operability).
  • §28 market-fit criterion this moves toward: "Deployment repeatability" and "Trusted output" — a self-hosted build must not expose its datastore or carry unnecessary attack surface.
  • Accepted evidence it is real: runtime requirements.txt grep-clean of pytest/iniconfig/pluggy; requirements-dev.txt carries them; docker-compose.yml re-validated as parseable YAML; backend suite 701 passed / 4 skipped.

What changed

  • docker-compose.yml: removed ports: for postgres and redis; added comments. api keeps 8000 host binding.
  • apps/backend/requirements.txt: removed pytest, iniconfig, pluggy.
  • apps/backend/requirements-dev.txt: new (-r requirements.txt + the three test deps, pinned).
  • apps/backend/pyproject.toml: pytest moved from core dependencies to [project.optional-dependencies].test.
  • .github/workflows/ci.yml: both backend install steps use requirements-dev.txt.
  • .github/workflows/release.yml: install uses apps/backend[test] extra.
  • .gitattributes: text=auto eol=lf, lockfiles/requirements as text, binaries as -text.

Acceptance criteria completed

  • Postgres/Redis no longer host-exposed in Compose.
  • pytest removed from runtime lockfile; available via dev requirements / test extra.
  • CI + release workflows updated so tests still run.
  • .gitattributes added with sensible text/binary rules.
  • Backend suite green (701 passed, 4 skipped); compose YAML valid.

Testing performed

cd apps/backend && PYTHONPATH= .venv/bin/python -m pytest   # 701 passed, 4 skipped
python3 -c "import yaml; yaml.safe_load(open('docker-compose.yml'))"   # valid
grep pytest apps/backend/requirements.txt   # (no match — clean)

Screenshots

Not applicable (infra/config change).

Security and data considerations

  • Removes two host-exposed datastore ports from the default self-hosted stack (defence-in-depth; the datastore was already on an internal: true network, but host binding undermined that).
  • Reduces container attack surface by not shipping pytest in the runtime image.
  • No secrets, credentials, or repository contents touched.

Dependencies and blocked work

None.

Scope changes or remaining work

None. The api port (8000) is intentionally still host-exposed because the application must be reachable; only the data tier was closed off.

Contributor checklist

  • This PR targets dev
  • The branch was created from an up-to-date upstream/dev
  • This PR addresses one clearly scoped issue
  • This PR advances a §23 workstream toward a §28 market-fit criterion (Roadmap alignment filled)
  • Every acceptance criterion I claim as complete is actually complete
  • Relevant tests pass
  • Documentation is updated for any user-visible change
  • No secrets, credentials, local env files, or generated artifacts are included
  • No unrelated files were changed
  • Closing syntax (Closes) is used only because the issue is fully resolved
  • Dependencies and follow-up work are linked

…ime deps

- docker-compose.yml: drop host port bindings for postgres (5432) and redis
  (6379); both stay reachable only on the internal 'data' network. The API
  (8000) remains host-exposed (issue Second-Origin#186).
- requirements.txt: remove pytest/iniconfig/pluggy from the runtime lockfile
  so the container image no longer ships a test framework (issue Second-Origin#185).
- requirements-dev.txt: new file (-r requirements.txt + pytest stack) for CI
  and local dev.
- pyproject.toml: move pytest into a [project.optional-dependencies] test
  extra so 'pip install .' is runtime-only.
- ci.yml / release.yml: install requirements-dev.txt (or [test] extra) so
  pytest is present in CI without living in the runtime image.
- .gitattributes: normalise line endings, keep lockfiles/requirements as text,
  mark binaries as binary (issue Second-Origin#187).

Tested: backend suite 701 passed / 4 skipped; compose YAML validated.
@parthrohit22
parthrohit22 force-pushed the fix/185-186-187-infra-hardening branch from dea973f to ac963ad Compare July 27, 2026 12:41
@parthrohit22
parthrohit22 merged commit 08cbacc into Second-Origin:dev Jul 27, 2026
8 checks passed
@parthrohit22
parthrohit22 deleted the fix/185-186-187-infra-hardening branch July 27, 2026 16:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(deps): move pytest out of runtime dependencies and harden the Docker image

1 participant