diff --git a/app-catalog/services/linkwarden/manifest.yaml b/app-catalog/services/linkwarden/manifest.yaml index 2cbab7022..7d0433c57 100644 --- a/app-catalog/services/linkwarden/manifest.yaml +++ b/app-catalog/services/linkwarden/manifest.yaml @@ -19,9 +19,8 @@ install: - data:/data/data ports: [3000] env: - NEXTAUTH_SECRET: "changeme" + NEXTAUTH_SECRET: "{secret_key}" NEXTAUTH_URL: "http://localhost:3000" - DATABASE_URL: "postgresql://postgres:postgres@localhost:5432/linkwarden" lifecycle: health_check: "curl -sf http://localhost:3000" diff --git a/changelog.d/tsk-oqpbvn-merge-attribution-flake.md b/changelog.d/tsk-oqpbvn-merge-attribution-flake.md new file mode 100644 index 000000000..31d85c89d --- /dev/null +++ b/changelog.d/tsk-oqpbvn-merge-attribution-flake.md @@ -0,0 +1,3 @@ +### Tests + +- Fixed a CI flake in `tests/test_merge_attribution.py`: two assertions checked that an excluded PR number ("41") was a bare substring of `result.stdout`, but the fixture commit shas are generated at runtime, so a sha for the in-scope PR could coincidentally contain "41" and fail the assertion for a reason unrelated to the actual reconciliation logic. Both now assert on the exact `"#41"` PR-reference token the checker prints, which cannot collide with a hex sha substring. diff --git a/changelog.d/tsk-saz74u-linkwarden-manifest-static-secret.md b/changelog.d/tsk-saz74u-linkwarden-manifest-static-secret.md new file mode 100644 index 000000000..472db5e60 --- /dev/null +++ b/changelog.d/tsk-saz74u-linkwarden-manifest-static-secret.md @@ -0,0 +1,3 @@ +### Fixed + +- Linkwarden manifest: replaced static `NEXTAUTH_SECRET: "changeme"` with `{secret_key}` placeholder per-install; removed `DATABASE_URL` since no Postgres companion service is started in single-container installs \ No newline at end of file diff --git a/tests/test_installers.py b/tests/test_installers.py index df2e52506..3ed8bbb70 100644 --- a/tests/test_installers.py +++ b/tests/test_installers.py @@ -313,3 +313,40 @@ def test_docker_installer_searxng_host_port_not_8080(self, tmp_path): host_side, _, container_side = port_mappings[0].partition(":") assert int(host_side) == host_port assert int(container_side) == 8080 + + + + + +@pytest.mark.asyncio +async def test_manifests_have_no_changeme_secrets(tmp_path): + """RED: assert no manifest env value equals "changeme" and every + *_SECRET env uses a placeholder (e.g. {secret_key}).""" + from pathlib import Path + import yaml + + services_dir = Path("app-catalog") / "services" + manifests = sorted(services_dir.rglob("manifest.yaml")) + has_issue = False + for manifest_path in manifests: + data = yaml.safe_load(manifest_path.read_text()) + if data.get("type") != "service": + continue + env = data.get("install", {}).get("env") or {} + for key, value in env.items(): + if value == "changeme": + has_issue = True + print( + f"FAIL: {manifest_path}: {key}='changeme' " + f"in {manifest_path}" + ) + if key.endswith("_SECRET") and "{secret_key}" not in str(value): + has_issue = True + print( + f"FAIL: {manifest_path}: {key}={value!r} " + f"missing placeholder in {manifest_path}" + ) + assert not has_issue, ( + "Manifest audit: some manifests have static secrets or " + "changeme values" + )