Skip to content

fix: prune secret versions labelled firebase-managed=functions - #11067

Open
IzaakGough wants to merge 7 commits into
mainfrom
@invertase/fix-issue-11066
Open

IzaakGough wants to merge 7 commits into
mainfrom
@invertase/fix-issue-11066

Conversation

@IzaakGough

@IzaakGough IzaakGough commented Sep 10, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #11066.

  • Match managed secrets with isFunctionsManaged. pruneSecrets filtered on labels.firebase-managed=true, but labels() has written functions since 13.6.1, so the query matched nothing and neither command destroyed anything. Listing without a label filter and selecting client-side keeps one definition of "managed" and still matches older secrets.
  • Only enabled versions are candidates. Disabled versions are a recoverable rollback and are left to functions:secrets:destroy.
  • secrets:set only destroys the versions the updated functions were bound to. Anything else unused is left to secrets:prune, which lists what it will remove before asking.
  • secrets:prune requires --force when non-interactive rather than destroying on the prompt default, and counts every deployed function as a consumer, not only Firebase-deployed ones.
  • Both commands abort if a region was unreachable, since a missing function would otherwise read as unused, and report destroy failures per version instead of stopping at the first.

Live tested against a real project: prunes the orphaned firebase-managed=functions version main misses, still matches the older true label, skips disabled versions, refuses --non-interactive without --force, and destroys only the version a redeployed function moved off. The unreachable-region guard, the every-function-counts change and partial destroy failures are unit tested only.

pruneSecrets queried labels.firebase-managed=true, but secrets created
since 13.6.1 are labelled firebase-managed=functions, so the query
returned nothing and both functions:secrets:set and
functions:secrets:prune reported success over an empty list.

List without a label filter and select with isFunctionsManaged, which
already accepts both values and excludes App Hosting secrets.

@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 updates the secret pruning logic to support both firebase-managed=true and firebase-managed=functions labels by fetching all secrets and filtering them client-side. The reviewer suggests optimizing this by performing parallel, server-side filtered API requests for both labels to avoid performance issues in large GCP projects, and updating the unit tests accordingly.

Comment thread src/functions/secrets.ts
Comment thread src/functions/secrets.spec.ts
Pruning stale versions lists and destroys secret versions, which the
command did not declare. The calls were unreachable while pruneSecrets
returned nothing, so a caller on a custom role would have failed with a
raw 403 partway through instead of the upfront permission check.
@IzaakGough
IzaakGough marked this pull request as ready for review September 10, 2026 11:31
…ailures

Disabled versions are a user's recoverable rollback, so pruneSecrets now
queries state: ENABLED. destroySecretVersions runs every destroy and
reports which ones failed instead of aborting on the first rejection.
Both commands abort if any region was unreachable, since a missing
function would otherwise read as an unused version. prune counts every
deployed function as a consumer and refuses to run non-interactively
without --force. set only destroys the versions the updated functions
were bound to, leaving the rest to prune. Both report failures per
version.
@cabljac
cabljac self-requested a review September 24, 2026 16:07

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

functions:secrets:set and :prune never destroy anything: pruneSecrets filters firebase-managed=true, but labels() writes firebase-managed=functions

2 participants