httpHandler = $httpHandler ?: HttpHandlerFactory::build(HttpClientCache::getHttpClient()); $this->universeDomain = $universeDomain; } /** * Sign a string using the IAM signBlob API. * * Note that signing using IAM requires your service account to have the * `iam.serviceAccounts.signBlob` permission, part of the "Service Account * Token Creator" IAM role. * * @param string $email The service account email. * @param string $accessToken An access token from the service account. * @param string $stringToSign The string to be signed. * @param array $delegates [optional] A list of service account emails to * add to the delegate chain. If omitted, the value of `$email` will * be used. * @return string The signed string, base64-encoded. */ public function signBlob($email, $accessToken, $stringToSign, array $delegates = []) { $name = sprintf(self::SERVICE_ACCOUNT_NAME, $email); $apiRoot = str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE); $uri = $apiRoot . '/' . sprintf(self::SIGN_BLOB_PATH, $name); if ($delegates) { foreach ($delegates as &$delegate) { $delegate = sprintf(self::SERVICE_ACCOUNT_NAME, $delegate); } } else { $delegates = [$name]; } $body = [ 'delegates' => $delegates, 'payload' => base64_encode($stringToSign), ]; $headers = [ 'Authorization' => 'Bearer ' . $accessToken ]; $request = new Psr7\Request( 'POST', $uri, $headers, Utils::streamFor(json_encode($body)) ); $res = ($this->httpHandler)($request); $body = json_decode((string) $res->getBody(), true); return $body['signedBlob']; } /** * Sign a string using the IAM signBlob API. * * Note that signing using IAM requires your service account to have the * `iam.serviceAccounts.signBlob` permission, part of the "Service Account * Token Creator" IAM role. * * @param string $clientEmail The service account email. * @param string $targetAudience The audience for the ID token. * @param string $bearerToken The token to authenticate the IAM request. * @param array $headers [optional] Additional headers to send with the request. * * @return string The signed string, base64-encoded. */ public function generateIdToken( string $clientEmail, string $targetAudience, string $bearerToken, array $headers = [] ): string { $name = sprintf(self::SERVICE_ACCOUNT_NAME, $clientEmail); $apiRoot = str_replace('UNIVERSE_DOMAIN', $this->universeDomain, self::IAM_API_ROOT_TEMPLATE); $uri = $apiRoot . '/' . sprintf(self::GENERATE_ID_TOKEN_PATH, $name); $headers['Authorization'] = 'Bearer ' . $bearerToken; $body = [ 'audience' => $targetAudience, 'includeEmail' => true, 'useEmailAzp' => true, ]; $request = new Psr7\Request( 'POST', $uri, $headers, Utils::streamFor(json_encode($body)) ); $res = ($this->httpHandler)($request); $body = json_decode((string) $res->getBody(), true); return $body['token']; } }