"Caller does not have permission" trying to create custom token with Firebase Admin SDK
C

1

25

Error

When calling admin.auth().createCustomToken() I am getting the following error:

Error: The caller does not have permission; Please refer to https://firebase.google.com/docs/auth/admin/create-custom-tokens for more details on how to use and troubleshoot this feature.

The provided documentation leads me to believe that the service account I am initializing the Firebase Admin SDK with does not have sufficient permissions. I don't believe this to be the case, so I want to ask and see if I've missed anything.

Configuration

Firebase Admin SDK is initialized in the backend like so:

admin.initializeApp({
  serviceAccountId: '[email protected]'
});

Technically the value is referenced from an env var, but I have confirmed this value to be correct.

The service account being used has the following roles:

roles/firebase.sdkAdminServiceAgent
roles/iam.serviceAccountTokenCreator

Per the documentation, the required permission for creating custom tokens is iam.serviceAccounts.signBlob. This permission is part of the iam.serviceAccountTokenCreator role as per this output:

❯ gcloud beta iam roles describe roles/iam.serviceAccountTokenCreator
description: Impersonate service accounts (create OAuth2 access tokens, sign blobs
  or JWTs, etc).
etag: AA==
includedPermissions:
- iam.serviceAccounts.get
- iam.serviceAccounts.getAccessToken
- iam.serviceAccounts.getOpenIdToken
- iam.serviceAccounts.implicitDelegation
- iam.serviceAccounts.list
- iam.serviceAccounts.signBlob
- iam.serviceAccounts.signJwt
- resourcemanager.projects.get
- resourcemanager.projects.list
name: roles/iam.serviceAccountTokenCreator
stage: GA
title: Service Account Token Creator

Lastly, the code in question that is erroring out is as follows:

try {
  const loginToken = await admin.auth().createCustomToken(uid);
  return response(200).json({ loginToken });
} catch (err) {
  ...
}

The uid comes from signing in a user via a GoogleUser credential - the provided uid is confirmed to be accurate, and this flow works locally when referencing a JSON key file for the same service account.

Server is running on GKE, in case it could be a cluster permission error.

Any help would be greatly appreciated!

EDIT - RESOLVED Hiranya's answer did the trick - the K8s deployment had been configured with a service account whose original intent was only to enable Cloud SQL Proxy. Giving this service account the serviceAccountTokenCreator role solved the issue.

Cahoot answered 12/8, 2020 at 22:35 Comment(0)
F
51

You need to make sure the service account that the SDK is authorized with (not the one specified as serviceAccountId) has the token creator role. This is the service account auto-discovered by Google Application Default Credentials. In case of Cloud Functions this is the service account named {project-name}@appspot.gserviceaccount.com. You need to figure out the equivalent service account for GKE and grant it the token creator role.

Florentinoflorenza answered 13/8, 2020 at 1:38 Comment(7)
For me, it only worked when I started try adding the "Service Account Token Creator" role for each one of the members. It seams to did work after adding to myself (the owner)Tbar
@AlissonNunes that also worked for me! Thanks a bunchGraphitize
So it turns out that GCP doesn't propagate role changes immediately and can take up to a few minutes for the new permissions to be in effect. If you don't immediately see the {project-name}@appspot.gserviceaccount.com account with Service Account Token Creator working, try waiting several minutes and trying again. (removed prior comment)Sivas
Tried adding the Service Account Token Creator role to the app role as described above and it did not work, but adding the role to the Owner account worked for me as well.Fortieth
confirmed it works with @AlissonNunes note. Thanks!Insubstantial
@bsplosion's suggestion of adding the role to the default App Engine service account fixed this for me. I noticed this error only occurred on deployed Cloud Functions and not when emulated, and I realised I was using a difference service account for local development.Conchita
For completeness, you can add it from console.cloud.google.com/iam-admin/iam?project=YOUR_PROJECT_IDBuettner

© 2022 - 2024 — McMap. All rights reserved.