/** * Shared GCP access-token helper. * * Prefers an explicit service-account key in `GOOGLE_SERVICE_ACCOUNT_KEY_B64` * (base64-encoded JSON) — this is how the Vibn app is deployed on Coolify. * Falls back to ADC for local dev and GCE. * * The same token grants every role on the underlying SA * (currently: vibn-workspace-provisioner with roles/run.admin + * roles/artifactregistry.reader + roles/dns.admin). Callers that need a * narrower scope should ask for one explicitly. */ import { GoogleAuth, JWT } from 'google-auth-library'; const CLOUD_PLATFORM = 'https://www.googleapis.com/auth/cloud-platform'; export async function getGcpAccessToken(scopes: string[] = [CLOUD_PLATFORM]): Promise { const keyB64 = process.env.GOOGLE_SERVICE_ACCOUNT_KEY_B64; if (keyB64) { const key = JSON.parse(Buffer.from(keyB64, 'base64').toString('utf-8')) as { client_email: string; private_key: string; }; const jwt = new JWT({ email: key.client_email, key: key.private_key, scopes }); const token = await jwt.getAccessToken(); if (!token.token) throw new Error('GCP auth: JWT access token was empty'); return token.token as string; } const auth = new GoogleAuth({ scopes }); const client = await auth.getClient(); const token = await client.getAccessToken(); if (!token.token) throw new Error('GCP auth: ADC access token was empty'); return token.token; } export const GCP_PROJECT_ID = process.env.GCP_PROJECT_ID ?? 'master-ai-484822';