Skip to content

chore: codify unversioned prod signup-lock security trigger#1343

Merged
suisuss merged 2 commits into
stagingfrom
feat/TECH-11-reconcile-prod-security-triggers
May 22, 2026
Merged

chore: codify unversioned prod signup-lock security trigger#1343
suisuss merged 2 commits into
stagingfrom
feat/TECH-11-reconcile-prod-security-triggers

Conversation

@suisuss
Copy link
Copy Markdown

@suisuss suisuss commented May 22, 2026

Summary

  • Adds drizzle migration 0084 that creates the existing prod trigger block_user_signup_security_2026_05_21 on users plus its plpgsql function.
  • Migration matches the live prod DDL bit-for-bit. pg_get_triggerdef and pg_get_functiondef output identical to prod after applying locally.
  • No behavior change in prod. Idempotent via DROP TRIGGER IF EXISTS and CREATE OR REPLACE FUNCTION.

Why

The trigger was installed directly on the prod DB during incident response (2026-05-21) and was never committed. A clean rebuild from migrations (CI, ephemeral env, disaster recovery) would silently lose this protection. A broader scan of prod (all schemas) confirms this is the only remaining unversioned trigger or function. Migrations 0082 and 0083 already covered the other two triggers from the same incident; the file content hashes there match the prod ledger rows exactly, so those are fully reconciled.

Not in this PR

The trigger currently blocks every non-employee signup with errcode 42501 and message Signup paused (security incident 2026-05-21). Contact security team. This PR is codification only and does not address the customer-lockout side effect. A follow-up should either retire the trigger (once app-layer signup gating is confirmed sufficient) or convert it to a non-blocking audit signal.

Test plan

  • Apply locally on a fresh DB; resulting trigger and function DDL match prod capture
  • Re-apply against a DB that already has the trigger; idempotent (no errors, no notices)
  • INSERT with non-employee email rejected with the expected message and 42501
  • INSERT with employee email (@keeperhub.com) accepted
  • Reviewer: dry-run pnpm db:migrate against staging before merge to confirm drizzle picks up the new journal entry cleanly

Notes

  • 0084_snapshot.json is a verbatim copy of 0083_snapshot.json since the schema did not change (same pattern 0081 -> 0082 -> 0083 already follows: same id / prevId across all three).
  • Journal when is 1779409707320 (2026-05-22), monotonically newer than 0083's 1779383340528. If an intermediate migration lands first, bump this value before merge.

The block_user_signup_security_2026_05_21 trigger was installed live on
prod during incident response and has no committed migration. A fresh DB
rebuilt from migrations would silently lose this protection.

This migration codifies the trigger and its function exactly as they
exist in prod (verified via pg_get_triggerdef and pg_get_functiondef
against prod). DROP TRIGGER IF EXISTS plus CREATE OR REPLACE FUNCTION
make it a no-op when re-applied to a DB that already has the trigger.

This is codification only. The lockout currently blocks all non-employee
signups and should be retired or converted to a non-blocking audit
signal in a follow-up, once app-layer signup gating is confirmed.
Migration 0084 (also in this branch) restores the signup-block trigger
that rejects any INSERT on users whose email is not under
techops.services or keeperhub.com. Existing test fixtures and dev seed
scripts use various non-routable domains (@test.local, @example.com,
@keeperhub.test, @localhost, @keeperhub.local) that would all fail the
trigger after merge.

Updated 7 sites across 4 vitest e2e tests and 2 seed scripts to use
@techops.services, matching the convention already in
tests/e2e/playwright/utils/seed.ts. Local-parts are preserved so test
intent stays readable.

Also added a SEED_EMAIL constraint note to seed-user.ts so anyone
overriding via env knows about the trigger allowlist.
@suisuss suisuss merged commit f754dc3 into staging May 22, 2026
41 checks passed
@suisuss suisuss deleted the feat/TECH-11-reconcile-prod-security-triggers branch May 22, 2026 01:46
@github-actions
Copy link
Copy Markdown

🧹 PR Environment Cleaned Up

The PR environment has been successfully deleted.

Deleted Resources:

  • Namespace: pr-1343
  • All Helm releases (Keeperhub, Scheduler, Event services)
  • PostgreSQL Database (including data)
  • LocalStack, Redis
  • All associated secrets and configs

All resources have been cleaned up and will no longer incur costs.

@github-actions
Copy link
Copy Markdown

ℹ️ No PR Environment to Clean Up

No PR environment was found for this PR. This is expected if:

  • The PR never had the deploy-pr-environment label
  • The environment was already cleaned up
  • The deployment never completed successfully

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