Skip to content

fix(security): harden production configuration and GitHub trust boundaries - #12

Merged
ashishsinghbora merged 1 commit into
mainfrom
fix/production-security-hardening
Oct 30, 2026
Merged

ashishsinghbora merged 1 commit into
mainfrom
fix/production-security-hardening

Conversation

@ashishsinghbora

Copy link
Copy Markdown
Contributor

Summary

Hardens production environment configuration and locks down GitHub trust boundaries to ensure only verified TechNexusOrg organization repositories (Organization ID 333899669) can participate in the contribution and verifiable credential lifecycle.

Changes

  • Production Environment Hardening (src/lib/env.ts):
    • Validates all environment variables with fail-closed rules for production runtime.
    • Rejects known development placeholders for AUTH_SECRET, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET, and GITHUB_WEBHOOK_SECRET.
    • Enforces mandatory PostgreSQL DATABASE_URL in production.
    • Introduces INTERNAL_SERVICE_SECRET dedicated to background/sync service authorization.
    • Introduces safeCompare using crypto.timingSafeEqual to eliminate timing attack vectors.
  • Production Database Fail-Closed Safeguard (src/lib/db/index.ts):
    • Rejects silent fallback to PGlite when NODE_ENV=production. Throws a fatal, clear configuration error if PostgreSQL connection fails or URL is invalid.
  • GitHub Repository Trust Boundary (src/lib/github/issues.ts, src/lib/projects/approval.ts, src/lib/github/webhooks.ts):
    • Restricts issue synchronization and webhook ingestion strictly to repositories verified against live GitHub API belonging to TechNexusOrg (ID 333899669).
    • Schema extension: added immutable github_repo_id and github_owner_id to the projects table with indexes.
    • Requires explicit maintainer review and approval before newly discovered repositories become eligible for contributions or credentials.
    • Rejects unapproved or external repositories during approval, webhook handling, and issue synchronization.
  • Webhook Security Hardening (src/app/api/webhooks/github/route.ts):
    • Requires mandatory X-GitHub-Delivery header for pipeline events to preserve delivery idempotency and audit logs.
  • Service Bearer Authentication (src/app/api/sync/issues/route.ts):
    • Switched from AUTH_SECRET to dedicated INTERNAL_SERVICE_SECRET with constant-time equality check.
    • Added origin/CSRF validation for browser session cookie requests.
  • Database Migration:
    • Added drizzle/0005_project_trust_boundary.sql for github_repo_id and github_owner_id columns and indexes.
    • Updated drizzle/meta/_journal.json.
  • Automated Tests:
    • Expanded src/lib/env.test.ts to cover production fail-closed rules, placeholder rejection, and safeCompare.
    • Added src/lib/projects/approval.test.ts to test repository trust boundaries and approval rejection.
    • Expanded src/lib/github/webhooks.test.ts to test spoofed owner IDs.

Architecture

Enforces least-privilege trust boundaries at ingress points (webhooks, API sync, and admin approval). Separates user session secret (AUTH_SECRET) from internal service automation secret (INTERNAL_SERVICE_SECRET).

Security Considerations

  • Prevents malicious external repositories from registering as official projects.
  • Prevents forged webhook events from injecting illegitimate contributions or claiming credentials.
  • Protects secret verification from timing attacks.
  • Disallows local PGlite fallback in production, preventing data loss or unintended local file storage.

Database Migrations

  • Migration file: drizzle/0005_project_trust_boundary.sql
  • Rollback: ALTER TABLE projects DROP COLUMN github_repo_id, DROP COLUMN github_owner_id;

Testing

  • npm run lint: passed with 0 errors, 0 warnings.
  • npm run typecheck: passed with 0 errors.
  • npm test: 80 passed across 18 test files (including new security tests).
  • npm run build: production build completed successfully (19 static/dynamic routes).

Deployment Considerations

Ensure production environment contains:

  • Strong, random AUTH_SECRET (min 32 chars).
  • Strong, random INTERNAL_SERVICE_SECRET (min 32 chars).
  • Valid PostgreSQL connection URL for DATABASE_URL.
  • Real GitHub OAuth Client ID & Secret.

Related Issues

Fixes #11

Copilot AI balanced review requested due to automatic review settings October 30, 2026 01:35
@ashishsinghbora ashishsinghbora added priority: critical Critical priority issue security Security and trust boundaries backend Backend API & services database Database schema, migrations & queries testing Automated tests and QA labels Oct 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has insufficient remaining quota.

An organization owner can choose the repository organization as the billing source for reviews requested by members with a paid Copilot license. Learn about Copilot code review billing.

@ashishsinghbora
ashishsinghbora merged commit eff0aca into main Oct 30, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend Backend API & services database Database schema, migrations & queries priority: critical Critical priority issue security Security and trust boundaries testing Automated tests and QA

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(security): harden production configuration and GitHub trust boundaries

2 participants