Review: Add shared Postmark inbound webhook endpoint via Tailscale funnel (r2)

review-2001-2026-08-04-r2 Review

review approved

Verdict: APPROVED

Re-review of board item #2001 after refinement. All three issues from review-2001-2026-08-04 have been resolved.

Template Completeness

  • [x] Type -- Feature
  • [x] Lineage -- Standalone, follows PR #582
  • [x] Repo -- ldraney/pal-e-platform
  • [x] User Story -- As a platform operator / I want a shared webhook endpoint / So that inbound emails are reliably processed and queryable
  • [x] Context -- Detailed background on Postmark inbound config, webhook.site expiry, security (no HMAC, Basic Auth recommended), architecture decision (shared platform service, not per-app)
  • [x] File Targets -- 4 create/modify targets, 3 don't-touch targets with reasons
  • [x] Feature Flag -- none
  • [x] Acceptance Criteria -- 5 criteria
  • [x] Test Expectations -- 3 tests (manual curl, manual email, tofu plan)
  • [x] Constraints -- 6 constraints listed
  • [x] Checklist -- Standard PR/tests/no-unrelated
  • [x] Related -- References project page, arch note, PR #582

Traceability

  • [x] arch:deployment-postmark label -- arch-deployment-postmark note exists in pal-e-docs (active architecture note)
  • [x] arch note verified -- arch-deployment-postmark covers SDK/MCP deployment pattern with diagram
  • [x] story:postmark-email label -- label present on board item
  • [x] story note verified -- story-postmark-email-inbound exists (user-story note, active), linked from project-postmark-email user-stories section with key "inbound"
  • [x] Forgejo issue -- https://forgejo.tail5b443a.ts.net/ldraney/pal-e-platform/issues/583, open

File Targets

  • [x] terraform/postmark-inbound.tf (new) -- verified: file does not exist yet. Will contain k8s deployment, configmap, service, secret, and ingress as top-level resources. Correct placement outside the per-app module.
  • [x] terraform/modules/postmark/main.tf -- verified: contains postmark_server and postmark_domain resources only. Adding inbound_hook_url to postmark_server.this is a minimal change.
  • [x] terraform/modules/postmark/variables.tf -- verified: currently has server_name, domain, return_path_subdomain. Adding inbound_hook_url (string, default "") is consistent.
  • [x] terraform/main.tf -- verified: postmark_iss at line 168, postmark_landscaping at line 177. Issue correctly says to pass URL to ISS instance only; landscaping wired later.
  • [x] terraform/modules/networking/main.tf -- correctly listed as don't-touch. Funnel pattern confirmed (9 tailscale.com/funnel annotations, ingress_class_name "tailscale").
  • [x] terraform/dns.tf -- correctly listed as don't-touch.
  • [x] terraform/modules/postmark/versions.tf -- correctly listed as don't-touch. Only declares postmark provider. Kubernetes provider is at top level (versions.tf line 11-12, providers.tf line 1).

Repo Placement

OK -- issue filed on ldraney/pal-e-platform, all file targets are in that repo. Single-repo change.

Dependencies

  • PR #582 (MX record + pillar secrets) -- stated as already merged. No blocker.
  • No other board items on board-platform-playbook are related to this work or block it.
  • Tailscale operator is deployed (networking module manages it). Not a blocker.
  • Kubernetes provider is declared at root level -- no additional provider config needed.

Acceptance Criteria

  • AC1: tofu plan shows new resources as top-level + updated InboundHookUrl on ISS server -- agent-verifiable
  • AC2: webhook endpoint reachable at funnel URL, returns 200 on POST -- post-deployment validation
  • AC3: InboundHookUrl on ISS Postmark server points to funnel URL with Basic Auth -- verifiable via tofu plan output
  • AC4: inbound emails queryable via search_inbound_messages -- post-deployment validation
  • AC5: postmark module remains clean, no kubernetes provider dependency -- agent-verifiable (check versions.tf unchanged)
AC2 and AC4 are post-deployment validation criteria. Appropriate for infrastructure work.

Blast Radius

Previous issue resolved: Webhook k8s resources now live at top level in postmark-inbound.tf, not inside the per-app module. The module is instantiated twice (postmark_iss, postmark_landscaping), but only receives a new variable -- no k8s resources duplicated. Only the ISS instance gets the URL initially.
No other services reference inbound webhook patterns. No existing inbound_hook_url or postmark-inbound references found in the terraform directory.

Decomposition Assessment

  • 4 file targets (1 new, 3 modify) in 1 repo -- under threshold
  • 5 acceptance criteria -- at threshold, not over
  • Estimated agent work under 5 minutes -- straightforward k8s resource creation + variable wiring
  • No decomposition needed.

Previous Review Issues -- Resolution Status

  • Shared module blast radius -- RESOLVED: Webhook resources now live at top level in postmark-inbound.tf, not inside the per-app module. Issue body clearly states the architecture decision and the agent's don't-touch boundaries.
  • Missing kubernetes provider -- RESOLVED: Top-level resources use the already-declared kubernetes provider (versions.tf line 11-12, providers.tf line 1). Module's versions.tf is explicitly listed as don't-touch.
  • Missing story note -- RESOLVED: story-postmark-email-inbound created as user-story note in project postmark-email. Linked from project-postmark-email user-stories section with key "inbound".

Recommendation

No action needed. All previous issues resolved. Scope is solid, file targets verified, traceability complete.