Skip to content

fix(frameworks): re-assert SSR public invoker on deploy#10690

Open
leoortizz wants to merge 3 commits into
mainfrom
leoortizz_fix-frameworks-ssr-public-invoker
Open

fix(frameworks): re-assert SSR public invoker on deploy#10690
leoortizz wants to merge 3 commits into
mainfrom
leoortizz_fix-frameworks-ssr-public-invoker

Conversation

@leoortizz

@leoortizz leoortizz commented Jun 19, 2026

Copy link
Copy Markdown
Member

Description

Fixes #10631.

Framework SSR runs on a Cloud Run function that Hosting invokes anonymously, so its service needs allUsers as run.invoker. The generated function declares no invoker, so only the create path set it and the update path never re-applied it. When that binding gets removed out-of-band such as by an org policy, later deploys don't restore it, and hosting:channel:deploy ships a channel that 403s on all server-rendered content while reporting success.

This adds run.ensureInvokerPublic(service), called for frameworks SSR functions on deploy. It is additive: it appends allUsers, keeps any existing invoker members, and is a no-op when allUsers is already present, so it never overwrites deliberate IAM changes. It is also non-fatal: if the grant is blocked it logs a warning instead of failing the deploy. The check is scoped to frameworks codebases, so other functions are untouched.

Scenarios Tested

Ran a Next.js app with next/image and dynamic routes on a live project. I stripped allUsers and ran hosting:channel:deploy; the binding was restored automatically and server-rendered routes returned 200. I then pre-seeded a custom invoker service account, stripped allUsers, and deployed; allUsers was added back and the custom account was preserved.

The issue author suspected the preview deploys might be stripping the binding, so I checked: shipped 15.19.1 does not modify the invoker policy on live or channel deploys, which points to the loss being external rather than deploy-caused.

Added unit tests for ensureInvokerPublic covering add, additive, and no-op, and for the updateV2Function branch covering ensure, warn-on-failure, and skip for non-frameworks functions.

Sample Commands

No new commands or flags.

firebase deploy --only hosting
firebase hosting:channel:deploy preview

@leoortizz leoortizz requested review from annajowang, inlined and jamesdaniels and removed request for annajowang, inlined and jamesdaniels June 19, 2026 13:14

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces changes to ensure that frameworks-managed SSR functions remain publicly invokable by additively granting the allUsers member the Cloud Run Invoker role (roles/run.invoker). This is implemented via a new ensureInvokerPublic utility in src/gcp/run.ts and integrated into the Fabricator deployment flow. Feedback on the changes highlights a potential TypeError in src/gcp/run.ts if currentInvokerBinding.members is undefined, suggesting the use of optional chaining to safely check for the presence of allUsers.

Comment thread src/gcp/run.ts Outdated
The generated SSR function declares no invoker, so updates never
re-applied it; a binding lost out-of-band left channels 403ing. Now
each frameworks deploy re-adds allUsers additively, warning instead of
failing when blocked.

Fixes #10631
@leoortizz leoortizz force-pushed the leoortizz_fix-frameworks-ssr-public-invoker branch from 64171f1 to 25b6972 Compare June 19, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Web frameworks: hosting:channel:deploy creates broken preview channels when the SSR function lacks public invoker IAM

2 participants