Last active
August 5, 2024 09:27
-
-
Save danbars/d39bad619db29669cebccf464d9e66e5 to your computer and use it in GitHub Desktop.
Generate Google access token for service-account in Cloudflare workers environment
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
/** | |
You can use the code below in Cloudfalre worker environment to generate a Google access token | |
for a service-account. | |
Run this code in a worker cron so you always have a fresh token in your KV that can be used by other workers. | |
The generated token here will be valid for 3600 seconds, but you can change that in your code. | |
The code assumes that you have a KV mapped to 'PROPERTIES' in you wrangler.toml file | |
You must create a service-user and assign to it the roles that you need in google console. | |
Then take the JSON that you get and paste it below | |
This code also assumes that you have your private key mapped to a variable `PRIVATE_KEY` | |
Note that currently `wrangler secret put PRIVATE_KEY` will not be able to save private keys because they are too long. | |
Instead, use Cloudflare dashboard UI to save this as an environemnt variable for your worker | |
**/ | |
import jwt from 'jsonwebtoken'; | |
/* global PRIVATE_KEY, PROPERTIES */ | |
const ServiceAccountJson = { | |
"type": "service_account", | |
"project_id": "project-id", | |
"private_key_id": "92c482736826384a88", | |
"private_key": PRIVATE_KEY, | |
"client_email": "[email protected]", | |
"client_id": "87263847628736478", | |
"auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
"token_uri": "https://oauth2.googleapis.com/token", | |
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/service-account-user%40project-id.iam.gserviceaccount.com" | |
} | |
addEventListener('scheduled', event => { | |
event.waitUntil(handleScheduled()) | |
}) | |
//store it under whatever key that you want. | |
//Use the permission scope that you need for your access token | |
async function handleScheduled() { | |
await generateKey(ServiceAccountJson, 'GOOGLE_FIRESTORE_ACCESS_TOKEN', 'https://firestore.googleapis.com/') | |
} | |
async function generateKey(serviceAccount, property, aud) { | |
const now = new Date() | |
const NOW = Math.floor( now.getTime() / 1000); | |
const token = jwt.sign({ | |
iss: serviceAccount.client_email, | |
sub: serviceAccount.client_email, | |
aud, | |
iat: NOW, | |
exp: NOW + 3600 | |
}, | |
serviceAccount.private_key, | |
{ | |
algorithm: 'RS256', | |
keyid: serviceAccount.private_key_id | |
}); | |
//store token in KV | |
await PROPERTIES.put(property, token) | |
console.log('generated token', property) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Since this code was written I actually moved to
@tsndr/cloudflare-worker-jwt
which seems to be well maintained and works really well for me in Cloudflare workers environment