-
-
Save lox/8bff5607c3e713c92a03a631796ab3f3 to your computer and use it in GitHub Desktop.
A workaround for service account impersonation at runtime in firebase-admin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { GoogleAuth } from 'google-auth-library' | |
import fs from 'fs' | |
import path from 'path' | |
const GCLOUD_CREDENTIAL_SUFFIX = 'gcloud/application_default_credentials.json' | |
const GCLOUD_CREDENTIAL_PATH = path.resolve(`${process.env.HOME}/.config`, GCLOUD_CREDENTIAL_SUFFIX) | |
/** | |
* A credential provider for Firebase Admin SDK that uses google-auth-library | |
*/ | |
class GoogleAuthCredential { | |
/** | |
* @param credentials | |
*/ | |
constructor(credentials) { | |
this.credentials = credentials | |
} | |
/** | |
* Gets the access token for the credential. | |
* @returns {Promise<{access_token: string, expires_in: number}>}} | |
*/ | |
async getAccessToken() { | |
const auth = new GoogleAuth({ | |
credentials: this.credentials, | |
scopes: ['https://www.googleapis.com/auth/cloud-platform'], | |
}) | |
const client = await auth.getClient() | |
const res = await client.getAccessToken() | |
return { | |
access_token: res.token, | |
expires_in: new Date().getTime() / 1000 + res.res?.data?.expires_in, | |
} | |
} | |
} | |
/** | |
* @param {string} serviceAccount | |
* @returns {import('firebase-admin').credential.Credential} | |
*/ | |
export function impersonateServiceAccount(serviceAccount) { | |
const sourceCreds = JSON.parse(fs.readFileSync(GCLOUD_CREDENTIAL_PATH, 'utf-8')) | |
if (sourceCreds.type !== 'authorized_user') { | |
throw new Error('Expected source credentials to be authorized_user') | |
} | |
return new GoogleAuthCredential({ | |
delegates: [], | |
service_account_impersonation_url: `https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/${serviceAccount}:generateAccessToken`, | |
source_credentials: sourceCreds, | |
type: 'impersonated_service_account', | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I just checked and "expires_in" does not exist on res.data, all that exists are
expireTime
andaccessToken
.A more correct gist might be: https://gist.github.com/k2wanko/289f5cf231ca80da099c7414dceb465d