Skip to content

feat(security): consume-side hash verification in TF module#4

Merged
bhavink merged 2 commits into
mainfrom
feat/security-consume
May 5, 2026
Merged

feat(security): consume-side hash verification in TF module#4
bhavink merged 2 commits into
mainfrom
feat/security-consume

Conversation

@bhavink
Copy link
Copy Markdown
Owner

@bhavink bhavink commented May 5, 2026

Summary

Closes the loop on PR 3's publish-side hardening. The Terraform module now fetches SHA256SUMS at plan time and verifies each feed body's sha256 against the manifest via postcondition. Default on; no-op in local source_files mode (customer controls those bytes).

What changes

Module (terraform/main.tf, variables.tf)

  • New input verify_checksums (bool, default true)
  • New data "http" "checksums" — fetched once when verification is enabled, with retry + 200-status postcondition
  • Parses GNU sha256sum format (<64-hex> <filename>) into a map[filename]hash. Tolerates blank lines and # comments
  • Postcondition on data.http.feed: short-circuits when verify is off, otherwise compares sha256(self.response_body) against the manifest entry. lookup() with empty default makes "file not in manifest" a clean failure instead of a TF map-lookup error
  • Error message names the URL, expected hash, actual hash, and the fix path — pin to a known-good ref, or set verify_checksums = false if the source intentionally doesn't publish a manifest

Tests (terraform/tests/checksums.tftest.hcl)

6 new mock-based runs using override_data. No network — runs in seconds.

Behaviour Test
Hash matches → output cidrs as expected verify_passes_when_hash_matches
Hash mismatch → postcondition fires verify_fails_on_hash_mismatch
File missing from manifest → fail verify_fails_when_file_missing_from_manifest
verify_checksums = false → checksums data resource not instantiated verify_disabled_skips_fetch
Local source_files mode → checksum fetch silently suppressed verify_silently_skipped_in_local_mode
Manifest with blank lines and # comments → parsed manifest_with_blank_and_comment_lines_is_tolerated

Docs

  • terraform/README.md — inputs table includes verify_checksums; debugging table covers SHA256 mismatch and Failed to fetch SHA256SUMS with explicit fix paths; test coverage table updated
  • SECURITY.md — "stricter" recommendation now points at the shipped module behaviour; future work list pruned

Test plan

  • terraform fmt -check -recursive passes
  • terraform validate passes
  • terraform test 15/15 passing locally (was 9/9)
  • python -m pytest 39/39 passing (no regression)
  • CI runs same on this PR
  • Smoke-test from a real consumer module against live URL once merged

bhavink added 2 commits May 5, 2026 12:01
Closes the loop on PR 3's publish-side hardening. The Terraform module
now fetches SHA256SUMS at plan time and verifies each feed body's
sha256 against the manifest via postcondition. Default on; no-op in
local source_files mode (customer controls those bytes).

Module changes (terraform/main.tf, variables.tf):
- New input verify_checksums (bool, default true).
- New data "http" "checksums" — fetched once when verify is enabled.
- Parses GNU sha256sum format ("<64-hex>  <filename>") into a map,
  tolerates blank lines and # comments.
- Postcondition on data.http.feed: short-circuits when verify is off,
  otherwise compares sha256(body) against the manifest entry.
- Error message names the URL, expected hash, actual hash, and the
  fix path — pin to a known-good ref or set verify_checksums = false.

Tests (terraform/tests/checksums.tftest.hcl): 6 new mock-based runs
using override_data. No network — runs in seconds. Covers:
- Hash matches → output cidrs as expected
- Hash mismatch → fail with actionable error
- File missing from manifest → fail (lookup default empty string)
- verify_checksums = false → checksums data resource not instantiated
- Local source_files mode → checksum fetch silently suppressed
- Manifest with blank lines and # comments → parsed correctly

Total terraform tests: 15/15 (was 9/9). Python tests still 39/39.

Docs (terraform/README.md, SECURITY.md):
- README inputs table includes verify_checksums.
- Debugging table covers SHA256 mismatch and SHA256SUMS fetch failure
  with explicit fix paths.
- Test coverage table updated.
- SECURITY.md "stricter" recommendation now points at the shipped
  module behaviour rather than a planned PR. Future work list pruned.
Three-layer validation recipe — test suite (no network), manual
SHA256SUMS check (curl + shasum), end-to-end terraform plan against
the live URL. Captures the smoke-test pattern we used to prove the
checksum verification chain works, so future contributors don't
have to rediscover it.
@bhavink bhavink merged commit 708fcdf into main May 5, 2026
1 check passed
@bhavink bhavink deleted the feat/security-consume branch May 5, 2026 16:13
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.

1 participant