fix(docker): adopt Azure Linux base + remove EOL packaging tools to clear S360 SCA findings#50
Merged
Merged
Conversation
…lear S360 SCA findings Swap the runtime base from python:3.11-slim to Microsoft Azure Linux 3.0 (mcr.microsoft.com/azurelinux/base/python:3.12.9-13-azl3.0.20260706), matching the amplifier-online provisioner pattern and the AzureLinux 3.0 AKS nodes this service runs on. Azure Linux is continuously patched via a fix-only feed, so a build-time `tdnf update` clears reported CRITICAL/HIGH without suppression lists. The base ships EOL Python packaging tools (pip/setuptools/wheel) that Qualys SCA (S360) flags. In-place upgrades don't clear the findings: the rpm-installed dist-info has no RECORD, so pip/uv leave the old metadata orphaned next to the new, and scanners key on the dist-info METADATA. Since this app builds with hatchling and imports none of these at runtime, remove the vulnerable OS rpms outright (and their leftover files) and reinstall only a patched setuptools (some transitive deps still import pkg_resources). Clears: - QID 5011855 (CVE-2026-6357) / 5005553 (CVE-2025-8869) — pip -> removed - QID 5007163 (CVE-2026-24049) — wheel -> removed - QID 5006986 (CVE-2026-23949) — setuptools 83.0.0 (vendored jaraco_context 6.1.0 >= 4.3.0) Notes: - Python 3.11 -> 3.12, within requires-python >= 3.11. - apt-get -> tdnf for curl/ca-certificates. Verified locally: image builds; scan surface shows only setuptools-83.0.0.dist-info (no orphaned old metadata; pip/wheel fully gone); `import context_intelligence_server.main` succeeds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…d image string The test_dockerfile_base_image() assertion was brittle — it hardcoded an exact image string (FROM python:3.11-slim) and broke whenever the base image legitimately changed for security, Python version, or platform reasons. Paul's Azure Linux base swap is a valid security-driven change that cleared four Qualys SCA findings. This commit replaces the implementation-detail test with a capability-based check: the Dockerfile's FROM line must declare a Python base at version >= 3.11 (matching requires-python). The test now parses the FROM line using regex and enforces the real contract instead of a literal string. All 25 tests in the suite now pass against both the old and new base images. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
4c119cb to
2784c95
Compare
colombod
added a commit
that referenced
this pull request
Jul 9, 2026
…al build-run-curl integration test
Replace text-match tests that break on legitimate changes (false red) and pass while the
real thing is broken (false green) with a single integration test that builds the image,
runs the container, and curls the /status endpoint — proven end-to-end locally (~82s).
The suite had ~25 brittle string-echo tests (assert "curl" in content, etc). This change:
- ADDS tests/integration/test_docker_image.py: Builds the Dockerfile, runs the container
with ALLOW_UNAUTHENTICATED=true (documented dev/test opt-out), and curls /status,
asserting a real 200 with neo4j_connected=False (soft-fail, proving the endpoint
probed). Uses existing house docker-SDK pattern (docker, httpx already dev deps),
skips cleanly when Docker unavailable, overrides 30s pytest-timeout. Auto-marks
integration, so runs in existing non-blocking integration-tests CI job — no workflow
change needed. Verified locally: passes in ~82s real build + run + curl.
- SLIMS tests/test_docker_infrastructure.py from ~25 string-echo tests to 2 that encode
real contracts and stay fast + blocking in unit job:
(1) base image must be Python >= 3.11 (requires-python floor, parsed from FROM — not
a hardcoded string); and
(2) Neo4j credentials must not be inlined in compose (security policy; auth via env_file).
Closes brittle-test anti-pattern exposed by PR #50 (Azure Linux base swap broke CI
because test hardcoded python:3.11-slim).
🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
colombod
added a commit
that referenced
this pull request
Jul 11, 2026
…st Docker-for-Neo4j workflow Remove maintained Docker artifacts from the repo (keeping ONLY the S360-compliant server Dockerfile) and rewrite documentation/setup around a local-first workflow that runs Neo4j in a documented Docker container. Removed: - docker-compose.yml, docker-compose.airgap.yml (unused Compose stack) - start.sh (Compose wrapper) - neo4j.Dockerfile (Neo4j no longer shipped as a container image) - test/airgap/ (README.md, dtu-profile.yaml, verify-airgap-apoc.sh) - tests/test_docker_compose_simplified.py, tests/test_docker_infrastructure.py, tests/test_start_sh.py (now-subjectless tests) Kept intentionally: the server Dockerfile (S360/Qualys-compliant Azure Linux base, PR #50), .dockerignore, docker-entrypoint.sh, tests/neo4j/ fixtures and the docker dev-dependency. Added: - scripts/prime-local-config.py — stdlib-only local key-priming helper that replaces the old Docker credential bootstrap (generates the API token, prints it once, stores only the sha256 digest, writes server-config.yaml with bolt://localhost:7687 and a local writable data tree). - docs/local-development.md — canonical "Running Locally" guide: Neo4j via a single documented `docker run` (NEO4J_PLUGINS auto-installs APOC + GDS, --restart unless-stopped for boot persistence), key priming, run the server, plus ask-Amplifier prompts. Changed: - README.md — removed the Docker Compose / single-container run sections and all references to deleted files; local-first is now the primary path. - docs/azure-deployment.md — rewritten into a generic, compliant "deploy via amplifier-online" guide (no as-built specifics/secrets/IPs): S360 base-image policy (PR #50), a Neo4j VM build section (capacity, APOC+GDS, persistent disk, private VNet/NSG), Key Vault secret wiring with the declarative-redeploy rule, dual-client config keyed to the Neo4j Community single-account reality, and a Neo4j-safe version-bump runbook. - docs/service-setup.md — local Neo4j guidance; removed the docker-compose Caddy HTTPS section. - docs/managing-api-keys.md — local prime-local-config.py bootstrap. - docs/remote-access-sharing.md — standalone/local host-binding + backup/restore. - docs/designs/per-user-api-keys.md — bootstrap references off deleted start.sh. - AGENTS.md — keep/remove policy and the S360 base-image compliance anchor. - amplifier-online.yaml — deployed image tag reference v6.0.0 -> v6.6.6. Validation: `pytest tests/` collects 1881 tests with no errors; scripts/prime-local-config.py passes ruff + pyright and was tested end-to-end; repo-wide grep confirms zero broken references to any deleted file. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
colombod
added a commit
that referenced
this pull request
Jul 11, 2026
…st Docker-for-Neo4j workflow Remove maintained Docker artifacts from the repo (keeping ONLY the S360-compliant server Dockerfile) and rewrite documentation/setup around a local-first workflow that runs Neo4j in a documented Docker container. Removed: - docker-compose.yml, docker-compose.airgap.yml (unused Compose stack) - start.sh (Compose wrapper) - neo4j.Dockerfile (Neo4j no longer shipped as a container image) - test/airgap/ (README.md, dtu-profile.yaml, verify-airgap-apoc.sh) - tests/test_docker_compose_simplified.py, tests/test_docker_infrastructure.py, tests/test_start_sh.py (now-subjectless tests) Kept intentionally: the server Dockerfile (S360/Qualys-compliant Azure Linux base, PR #50), .dockerignore, docker-entrypoint.sh, tests/neo4j/ fixtures and the docker dev-dependency. Added: - scripts/prime-local-config.py — stdlib-only local key-priming helper that replaces the old Docker credential bootstrap (generates the API token, prints it once, stores only the sha256 digest, writes server-config.yaml with bolt://localhost:7687 and a local writable data tree). - docs/local-development.md — canonical "Running Locally" guide: Neo4j via a single documented `docker run` (NEO4J_PLUGINS auto-installs APOC + GDS, --restart unless-stopped for boot persistence), key priming, run the server, plus ask-Amplifier prompts. Changed: - README.md — removed the Docker Compose / single-container run sections and all references to deleted files; local-first is now the primary path. - docs/azure-deployment.md — rewritten into a generic, compliant "deploy via amplifier-online" guide (no as-built specifics/secrets/IPs): S360 base-image policy (PR #50), a Neo4j VM build section (capacity, APOC+GDS, persistent disk, private VNet/NSG), Key Vault secret wiring with the declarative-redeploy rule, dual-client config keyed to the Neo4j Community single-account reality, and a Neo4j-safe version-bump runbook. - docs/service-setup.md — local Neo4j guidance; removed the docker-compose Caddy HTTPS section. - docs/managing-api-keys.md — local prime-local-config.py bootstrap. - docs/remote-access-sharing.md — standalone/local host-binding + backup/restore. - docs/designs/per-user-api-keys.md — bootstrap references off deleted start.sh. - AGENTS.md — keep/remove policy and the S360 base-image compliance anchor. - amplifier-online.yaml — deployed image tag reference v6.0.0 -> v6.6.6. Validation: `pytest tests/` collects 1881 tests with no errors; scripts/prime-local-config.py passes ruff + pyright and was tested end-to-end; repo-wide grep confirms zero broken references to any deleted file. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
colombod
added a commit
that referenced
this pull request
Jul 13, 2026
…st Docker-for-Neo4j workflow Remove maintained Docker artifacts from the repo (keeping ONLY the S360-compliant server Dockerfile) and rewrite documentation/setup around a local-first workflow that runs Neo4j in a documented Docker container. Removed: - docker-compose.yml, docker-compose.airgap.yml (unused Compose stack) - start.sh (Compose wrapper) - neo4j.Dockerfile (Neo4j no longer shipped as a container image) - test/airgap/ (README.md, dtu-profile.yaml, verify-airgap-apoc.sh) - tests/test_docker_compose_simplified.py, tests/test_docker_infrastructure.py, tests/test_start_sh.py (now-subjectless tests) Kept intentionally: the server Dockerfile (S360/Qualys-compliant Azure Linux base, PR #50), .dockerignore, docker-entrypoint.sh, tests/neo4j/ fixtures and the docker dev-dependency. Added: - scripts/prime-local-config.py — stdlib-only local key-priming helper that replaces the old Docker credential bootstrap (generates the API token, prints it once, stores only the sha256 digest, writes server-config.yaml with bolt://localhost:7687 and a local writable data tree). - docs/local-development.md — canonical "Running Locally" guide: Neo4j via a single documented `docker run` (NEO4J_PLUGINS auto-installs APOC + GDS, --restart unless-stopped for boot persistence), key priming, run the server, plus ask-Amplifier prompts. Changed: - README.md — removed the Docker Compose / single-container run sections and all references to deleted files; local-first is now the primary path. - docs/azure-deployment.md — rewritten into a generic, compliant "deploy via amplifier-online" guide (no as-built specifics/secrets/IPs): S360 base-image policy (PR #50), a Neo4j VM build section (capacity, APOC+GDS, persistent disk, private VNet/NSG), Key Vault secret wiring with the declarative-redeploy rule, dual-client config keyed to the Neo4j Community single-account reality, and a Neo4j-safe version-bump runbook. - docs/service-setup.md — local Neo4j guidance; removed the docker-compose Caddy HTTPS section. - docs/managing-api-keys.md — local prime-local-config.py bootstrap. - docs/remote-access-sharing.md — standalone/local host-binding + backup/restore. - docs/designs/per-user-api-keys.md — bootstrap references off deleted start.sh. - AGENTS.md — keep/remove policy and the S360 base-image compliance anchor. - amplifier-online.yaml — deployed image tag reference v6.0.0 -> v6.6.6. Validation: `pytest tests/` collects 1881 tests with no errors; scripts/prime-local-config.py passes ruff + pyright and was tested end-to-end; repo-wide grep confirms zero broken references to any deleted file. 🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier) Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Fixes the 4 Qualys SCA (S360) container-image findings on the
context-intelligence-serverimage, all inherited from the base image's Python packaging tools.python:3.11-slim→mcr.microsoft.com/azurelinux/base/python:3.12.9-13-azl3.0.20260706. Matches theamplifier-onlineprovisioner pattern and the AzureLinux 3.0 AKS nodes this service runs on. Azure Linux is continuously patched via a fix-only feed, so a build-timetdnf updateclears reported CRITICAL/HIGH without suppression lists.apt→tdnffor thecurl/ca-certificatesinstall.pip,setuptools,wheel) and their leftover files, then reinstalls only a patchedsetuptools.Why the removal approach
In-place upgrades (
pip install --upgrade/uv pip install) do not clear these findings: the rpm-installeddist-infohas noRECORD, so pip/uv leave the old metadata orphaned next to the new. Scanners key on thedist-infoMETADATA, so the vulnerable version keeps getting reported. This app builds with hatchling and imports none of pip/setuptools/wheel at runtime, so the cleanest durable fix is to remove the OS rpms outright. A patchedsetuptoolsis reinstalled because some transitive deps still importpkg_resources.Findings cleared
Notes
requires-python >= 3.11.setuptools-83.0.0.dist-info(no orphaned old metadata; pip/wheel fully gone);import context_intelligence_server.mainsucceeds with auth disabled.Suggested CI
uv run pytest tests/ -q