fix(dev-server): inject service role token for unauthenticated function calls#516
fix(dev-server): inject service role token for unauthenticated function calls#516yurynix wants to merge 10 commits into
Conversation
🚀 Package Preview Available!Install this PR's preview build with npm: npm i @base44-preview/cli@0.0.52-pr.516.c049d5ePrefer not to change any import paths? Install using npm alias so your code still imports npm i "base44@npm:@base44-preview/cli@0.0.52-pr.516.c049d5e"Or add it to your {
"dependencies": {
"base44": "npm:@base44-preview/cli@0.0.52-pr.516.c049d5e"
}
}
Preview published to npm registry — try new features instantly! |
| // unauthenticated callers (e.g. public-facing subscribe forms). | ||
| proxyReq.setHeader( | ||
| "Base44-Service-Authorization", | ||
| authorization ?? "Bearer base44-dev-service-token", |
There was a problem hiding this comment.
This is not robust enough even for dev.
authorization is user authorization. It means that in case user is logged in locally with newly created user (also locally), then overall permissions will be limited. Which is not expected for server side authorization.
I think approach should be more robust than that.
I think Base44-Service-Authorization should be actual JWT, maybe simple solution will be to create token with email like server@server.com and then in the code check if email is "server" then allow everything. something like that
There was a problem hiding this comment.
Same goes for Bearer base44-dev-service-token - this token will fail for code that relies on user being presented in JWT:
…on calls The function router only forwarded Base44-Service-Authorization when a user Authorization header was present. Public-facing functions (e.g. a subscribe form) are called without user auth, so asServiceRole threw "Service token is required" before making any HTTP request. In production, Base44 always injects the service role token when forwarding requests to functions. Mirror that behaviour in the dev server by defaulting to a synthetic dev token when no user auth header exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ated calls Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
55f4cdc to
b24046f
Compare
This reverts commit dabbb52.
Deno 2.8 exposes `Deno.serve` as a getter-only property, so the wrapper's plain `Deno.serve = ...` assignment throws `TypeError: Cannot set property serve ... which has only a getter`. The function process crashes on startup, the dev-server proxy can't reach it, and requests return 500. Override it with Object.defineProperty (writable + configurable) instead, which works on both the old writable property and the new 2.8 accessor. CI installs Deno via `setup-deno@v2` with `deno-version: v2.x`, which now floats to 2.8.1 — this is why the local-functions dev tests started failing on every PR despite no related code change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Note
Description
Makes the local dev server inject a synthetic service-role JWT on every function proxy call, so
asServiceRoleworks locally even for unauthenticated callers (e.g. public-facing subscribe forms) — matching how production Base44 forwards a privileged service token. Also teaches RLS/FLS and the entities router to recognize the service principal and bypass denied rules, extracts the JWT helpers into a sharedauth/tokens.ts, and patchesDeno.serveviaObject.definePropertyto remain compatible with Deno 2.8 (which exposesserveas a getter-only property).Related Issue
None
Type of Change
Changes Made
packages/cli/src/cli/dev/dev-server/auth/tokens.tswithcreateJwtToken,createServiceAuthorizationHeader,SERVICE_ROLE_EMAIL, andisServiceSubjecthelpers (extracted fromauth-router.ts).Base44-Service-Authorization: Bearer <service-jwt>inroutes/functions.tsproxy, regardless of caller auth.routes/entities/current-user.tsto a syntheticSERVICE_USER(is_service: true,role: "admin") without a DB lookup.checkRLSto short-circuit totrueforis_serviceusers, and fixapplyFLSto allow service users to read fields withrls.read === false(also corrects!ruletorule === undefinedto stop droppingfalse-rule fields silently).rls.delete === false.deno-runtime/main.tsto overrideDeno.serveviaObject.defineProperty(Deno 2.8 made it getter-only, so direct assignment threw).tests/cli/dev-rls.spec.ts(unit) and three new integration tests intests/cli/dev.spec.tscovering service-token injection on authenticated/unauthenticated calls and service-role RLS bypass on create/list/delete.src/cli/index.tsto satisfy Biome.Testing
npm test)Checklist
docs/(AGENTS.md) if I made architectural changesAdditional Notes
The service-role JWT is signed with the existing
LOCAL_DEV_SECRETand identified by theserver@server.comsubject — purely a local dev sentinel, not a real credential. TheapplyFLSchange from!ruletorule === undefinedis a latent correctness fix: previously, fields with an explicitrls.read: falserule were filtered out for everyone (including admins with passing record-level RLS) instead of being evaluated.🤖 Generated by Claude | 2026-06-02 12:06 UTC | c049d5e