Security & Permissions.

Security is enforced at every layer — edge, API, database, and agent.

Edge authentication

Firebase JWTs are verified on every request at the Cloudflare edge before any business logic runs. Invalid or expired tokens return 401. The Firebase project ID (theintern007) is hardcoded in the verification logic.

Database-level authorization

Every Drizzle query includes a .where(eq(table.userId, authenticatedUserId)) clause. There is no admin bypass in the API layer — even internal routes scope queries to the requesting user. Cross-user data access is architecturally impossible via the API.

Secrets never in code

All credentials are stored as Cloudflare Workers Secrets (wrangler secret put). They are available as c.env.SECRET_NAME at runtime but never logged, never returned in responses, and never committed to the repository. The .dev.vars file (local development only) is in .gitignore.

CORS policy

The backend currently uses origin: "*" for CORS. This is intentional for the development phase — the API is authenticated via JWT so CORS is not a security boundary. For production hardening, restrict origin to your Cloudflare Pages domain.

Input validation

All route handlers validate required fields and return 400 with descriptive errors for missing or malformed input. JSON parsing errors are caught and return structured error responses. No raw error messages from the database or AI provider are exposed to clients.