Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 821
dubnev Avatar asked Aug 12 '20 22:08

dubnev


People also ask

What is Admin SDK in Firebase?

The Admin SDK is a set of server libraries that lets you interact with Firebase from privileged environments to perform actions like: Read and write Realtime Database data with full admin privileges.

What is auth token in Firebase?

When a user or device successfully signs in, Firebase creates a corresponding ID token that uniquely identifies them and grants them access to several resources, such as Firebase Realtime Database and Cloud Storage. You can re-use that ID token to identify the user or device on your custom backend server.

How do I get my firestore token?

You can generate an access token by using a service account with a Google API Client Library or by following the steps in Using OAuth 2.0 for Server to Server Applications. You can also generate a token with the gcloud command-line tool and the command gcloud auth application-default print-access-token .


1 Answers

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.

like image 100
Hiranya Jayathilaka Avatar answered Sep 29 '22 07:09

Hiranya Jayathilaka