firebase-tools icon indicating copy to clipboard operation
firebase-tools copied to clipboard

[2nd-gen function] The request was not authenticated

Open htsuruo opened this issue 6 months ago • 5 comments

As you know, the default service account for Eventarc, which is used by 2nd generation Cloud Functions (Cloud Run functions), is automatically attached [PROJECT_NUMBER][email protected]. However, this service account is not granted the Cloud Run Invoker role (run.invoker). Therefore, Cloud Run functions via Firebase Extensions does not have permission to invoke Cloud Run functions and output following error logs as default.

The request was not authenticated. Either allow unauthenticated invocations or set the proper Authorization header. Read more at https://cloud.google.com/run/docs/securing/authenticating Additional troubleshooting documentation can be found at: https://cloud.google.com/run/docs/troubleshooting#unauthorized-client

The issue also has been reported about the latest version(0.2.4) of Stream Firestore to BigQuery, which was created by official Firebase team.

  • https://github.com/firebase/extensions/issues/2412#issuecomment-2882918366
  • https://github.com/firebase/extensions/issues/2412#issuecomment-2885988504

[REQUIRED] Environment info

firebase-tools: 14.4.0

Platform: macOS 15.4.1 (24E263)

[REQUIRED] Test case

I’m actually an extensions developer myself. You may be able to reproduce the issue by installing my extension from following pre-release link. https://console.firebase.google.com/project/_/extensions/install?ref=htsuruo/[email protected]

[REQUIRED] Steps to reproduce

  1. Create Firebase empty project
  2. Install any extensions using 2nd-gen functions
    • ex. https://console.firebase.google.com/project/_/extensions/install?ref=htsuruo/[email protected]

[REQUIRED] Expected behavior

The service agent role should add a role roles/run.invoker to execute Cloud Run functions(2nd-gen functions). Totally, the deployment process should automatically grant both:

  • roles/eventarc.eventReceiver role to the Compute Service Agent (for receiving events)
    • → already implemented
  • roles/run.invoker role to the Compute Service Agent (for invoking Cloud Run services)
    • → missing

https://github.com/firebase/firebase-tools/blob/629f211c35032a2dea3343e408858b1043143af9/src/deploy/extensions/v2FunctionHelper.ts#L10

This is consistent with how regular Firebase Functions handle v2 functions with Eventarc triggers.

And ideally, the extension tool should create new service account for the Eventarc instead of default service account the following best practice.

[REQUIRED] Actual behavior

Add the roles/eventarc.eventReceiver IAM binding policy only to [PROJECT_NUMBER][email protected]. This means Eventarc lacks permission to execute Cloud Run functions (2nd-generation functions).

htsuruo avatar May 19 '25 23:05 htsuruo

I don't set up any organization policies and allowlists about setIamPolicy.

gcloud resource-manager org-policies list --organization=[PROJECT_NUMBER] --format="json"

[
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.disableNestedVirtualization",
    "etag": "CK3cs8AGEJC6jJcB",
    "updateTime": "2025-04-26T14:31:09.316874Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.disableSerialPortAccess",
    "etag": "CK3cs8AGEIiyz5kB",
    "updateTime": "2025-04-26T14:31:09.322165Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.restrictXpnProjectLienRemoval",
    "etag": "CK3cs8AGENCWg5cB",
    "updateTime": "2025-04-26T14:31:09.316722Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.requireOsLogin",
    "etag": "CK3cs8AGEICepZcB",
    "updateTime": "2025-04-26T14:31:09.317280Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.setNewProjectDefaultToZonalDNSOnly",
    "etag": "CLrYs8AGEOilqBk=",
    "updateTime": "2025-04-26T14:22:50.053089Z"
  },
  {
    "constraint": "constraints/compute.vmExternalIpAccess",
    "etag": "CLjcs8AGELjHubID",
    "listPolicy": {
      "allValues": "DENY"
    },
    "updateTime": "2025-04-26T14:31:20.911107Z"
  },
  {
    "constraint": "constraints/essentialcontacts.allowedContactDomains",
    "etag": "CLrYs8AGELjcthA=",
    "listPolicy": {
      "allowedValues": [
        "@htsuruo.com"
      ]
    },
    "updateTime": "2025-04-26T14:22:50.034451Z"
  },
  {
    "constraint": "constraints/iam.allowedPolicyMemberDomains",
    "etag": "CLrYs8AGEKCY5xY=",
    "listPolicy": {
      "allowedValues": [
        "C02gjtp4u"
      ]
    },
    "updateTime": "2025-04-26T14:22:50.047828Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/iam.disableServiceAccountKeyUpload",
    "etag": "CLrYs8AGEKiAhRQ=",
    "updateTime": "2025-04-26T14:22:50.042025Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/iam.disableServiceAccountKeyCreation",
    "etag": "CLrYs8AGEICkvhE=",
    "updateTime": "2025-04-26T14:22:50.036672Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/iam.automaticIamGrantsForDefaultServiceAccounts",
    "etag": "CLrYs8AGEPjNlBY=",
    "updateTime": "2025-04-26T14:22:50.046475Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/sql.restrictAuthorizedNetworks",
    "etag": "CK3cs8AGEJDlzpgB",
    "updateTime": "2025-04-26T14:31:09.320058Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/sql.restrictPublicIp",
    "etag": "CK3cs8AGEOiOg5cB",
    "updateTime": "2025-04-26T14:31:09.316721Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/storage.uniformBucketLevelAccess",
    "etag": "CLrYs8AGELDp4xc=",
    "updateTime": "2025-04-26T14:22:50.049870Z"
  },
  {
    "constraint": "constraints/compute.restrictProtocolForwardingCreationForTypes",
    "etag": "CLrYs8AGENC_txI=",
    "listPolicy": {
      "allowedValues": [
        "INTERNAL"
      ]
    },
    "updateTime": "2025-04-26T14:22:50.038658Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/storage.publicAccessPrevention",
    "etag": "CLjcs8AGELjKlL4D",
    "updateTime": "2025-04-26T14:31:20.935667Z"
  },
  {
    "booleanPolicy": {
      "enforced": true
    },
    "constraint": "constraints/compute.disableVpcExternalIpv6",
    "etag": "CK3cs8AGEICU1ZYB",
    "updateTime": "2025-04-26T14:31:09.315968Z"
  }
]

htsuruo avatar May 22 '25 01:05 htsuruo

Firebase Extensions v1 Functions Implementation is Correct

For Firebase Extensions v1 Functions, the implementation properly handles the required roles/cloudfunctions.invoker role and does not suffer from the same IAM permission gaps that exist with v2 Functions.

Proper Role Assignment for v1 Functions

v1 Functions correctly set up invoker roles through the standard Firebase Functions deployment pipeline. The role assignment happens via:

  • 1 for function creation
  • 2 for function updates

Both functions properly use roles/cloudfunctions.invoker to set the appropriate IAM policies.

Integration with Fabricator

These invoker functions are called by the Fabricator during deployment:

  • 3 handles creation for various trigger types

The Fabricator ensures that HTTPS, Callable, TaskQueue, and Auth Blocking triggers all receive proper invoker permissions.

Why v1 Functions Work Correctly

The key difference is that v1 Functions use the traditional Cloud Functions v1 API and require roles/cloudfunctions.invoker, while v2 Functions run on Cloud Run and require roles/run.invoker. Since Firebase Extensions v1 functions follow the same deployment path as regular Firebase Functions, they automatically inherit the correct IAM role setup.

Conclusion

The IAM role issue identified only affects Firebase Extensions v2 functions. v1 Functions in Firebase Extensions work correctly and do not require any fixes for invoker role assignment. The problem is specifically with v2 Functions missing the roles/run.invoker role needed for Eventarc to invoke Cloud Run services.

htsuruo avatar May 22 '25 02:05 htsuruo

Hey @htsuruo! Thanks for reporting the issue.

To make sure I understand the issue, does adding the run.invoker role (manually) on the allUsers principal solve the problem?

huangjeff5 avatar May 22 '25 20:05 huangjeff5

@huangjeff5

Hi,

adding the run.invoker role (manually) on the allUsers principal solve the problem?

Yes. In my case, solved the problem.

htsuruo avatar May 23 '25 01:05 htsuruo

I see. I looked at the Extensions platform code and your suspicion is right, allUsers is added with only cloudfunctions.invoker role. We need to add run.invoker role as well. I'm going to work on a patch soon and follow up next week. Thanks for helping find this!

huangjeff5 avatar May 23 '25 14:05 huangjeff5

@htsuruo Thanks for posting your findings here. It helped me recover things after updating a number of extensions.

@huangjeff5 Is this still scheduled for a fixed?

DaJoTo avatar Jul 07 '25 22:07 DaJoTo

Hi, I fixed this issue and rolling out the fix now. Should be in production in a couple of days.

huangjeff5 avatar Jul 08 '25 20:07 huangjeff5

Hi, I fixed this issue and rolling out the fix now. Should be in production in a couple of days.

@huangjeff5 has this fix been pushed to production?

reimertz avatar Aug 06 '25 09:08 reimertz

I dont think the issue is fixed yet

shawnazhaoxy avatar Oct 16 '25 02:10 shawnazhaoxy