Overview
Verifieddit uses Clerk for authentication. Clerk handles user sign-up/sign-in, session management, and JWT verification. There are separate production and testing instances.
Instances
Production Instance
- Frontend key:
pk_live_*(baked into Vite build viaVITE_CLERK_PUBLISHABLE_KEY) - Custom domain:
clerk.verifieddit.com - Dashboard: https://dashboard.clerk.com (select production instance)
Testing Instance
- Frontend key:
pk_test_*(baked into testing build) - Domain: Default Clerk domain (no custom domain for testing)
- Dashboard: https://dashboard.clerk.com (select testing instance)
Key Management
Production vs Test Keys
| Key Type | Production | Testing |
|---|---|---|
| Publishable Key | pk_live_* | pk_test_* |
| Secret Key | pass verifieddit/clerk/secret-key | pass verifieddit/clerk/test-secret-key |
Critical: The publishable key is baked into the Vite build at compile time. Changing the key requires:
- Update
VITE_CLERK_PUBLISHABLE_KEYinflake.nix - Recompute the FOD hash (since the build output changes)
- Rebuild and redeploy
Where Keys Are Used
| Component | Key Source | Key Type |
|---|---|---|
| Vite app (frontend) | flake.nix build var | Publishable key |
| Badges Worker | Worker secret | Secret key |
| Stripe Backend | Pulumi secret | Secret key |
| Testing Worker | Worker secret (test) | Test secret key |
Custom Domain Setup
DNS Records Required (5 total)
See Cloudflare DNS SOP for the full DNS setup procedure.
clerk.verifieddit.comCNAME ->frontend-api.clerk.servicesaccounts.verifieddit.comCNAME ->accounts.clerk.servicesclk._domainkey.verifieddit.comCNAME ->dkim1.<instance-id>.clerk.servicesclk2._domainkey.verifieddit.comCNAME ->dkim2.<instance-id>.clerk.servicesclkmail.verifieddit.comCNAME ->mail1.<instance-id>.clerk.services
Critical: Proxy Setting
All Clerk DNS records MUST have proxied: false in Cloudflare. Clerk needs direct access to provision SSL certificates. If records are proxied:
- SSL certificate provisioning fails
- Clerk shows “DNS verification pending”
- Users cannot sign in via the custom domain
SSL Certificate Provisioning
After DNS records are created:
- Clerk begins verification (automatic)
- SSL certificate provisioning takes up to 24 hours
- Check status in Clerk Dashboard > Domains
- Once verified, Clerk serves auth pages from the custom domain
GitHub OAuth Setup
To enable “Sign in with GitHub” on Clerk:
Create GitHub OAuth App:
- Go to https://github.com/settings/developers
- Create new OAuth App
- Homepage URL:
https://verifieddit.com - Authorization callback URL:
https://clerk.verifieddit.com/v1/oauth_callback(or the Clerk-provided callback URL)
Add to Clerk:
- Clerk Dashboard > User & Authentication > Social connections
- Enable GitHub
- Enter Client ID and Client Secret from the GitHub OAuth App
Verify: Sign in flow should show “Continue with GitHub” option
User Migration Between Instances
When migrating users from one Clerk instance to another (e.g., testing to production):
Export Users
| |
Create Users in Target Instance
| |
D1 Data Migration
After migrating users in Clerk, update the D1 database:
| |
CSP Configuration
The Content Security Policy must include Clerk domains:
connect-src 'self' https://*.clerk.com https://clerk-telemetry.com;
script-src 'self' https://*.clerk.com;
frame-src 'self' https://*.clerk.com;
Known issue: clerk-telemetry.com must be explicitly listed in CSP or telemetry requests will be blocked, causing console errors.
Troubleshooting
- “Guest mode only”: The Clerk publishable key is missing from the build. Check
VITE_CLERK_PUBLISHABLE_KEYinflake.nix. This is preflight check #13. - SSL certificate not provisioning: Ensure all 5 DNS records have
proxied: false. Check withdig clerk.verifieddit.com– it should resolve directly to Clerk, not Cloudflare. - CSP errors in console: Add
clerk-telemetry.comto CSP connect-src. - User not found after migration: Verify the Clerk user ID matches between the old and new instances. D1 references are by
clerk_id. - OAuth callback error: Verify the callback URL in the GitHub OAuth App matches exactly what Clerk expects.