Use an OAuth 2.0 access token for Domain-Wide Delegation (#388)

Fixes https://github.com/google-github-actions/auth/issues/387
This commit is contained in:
Seth Vargo 2024-02-05 11:27:46 -05:00 committed by GitHub
parent 39c96a3f1d
commit b4f4057a10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 13 additions and 10 deletions

6
dist/main/index.js vendored

File diff suppressed because one or more lines are too long

View File

@ -139,7 +139,7 @@ export class IAMCredentialsClient extends Client {
method: `POST`, method: `POST`,
path: pth, path: pth,
headers: headers, headers: headers,
body: body, body: body.toString(),
}); });
try { try {
@ -149,8 +149,8 @@ export class IAMCredentialsClient extends Client {
if (statusCode < 200 || statusCode > 299) { if (statusCode < 200 || statusCode > 299) {
throw new Error(`Failed to call ${pth}: HTTP ${statusCode}: ${respBody || '[no body]'}`); throw new Error(`Failed to call ${pth}: HTTP ${statusCode}: ${respBody || '[no body]'}`);
} }
const parsed = JSON.parse(respBody) as { accessToken: string }; const parsed = JSON.parse(respBody) as { access_token: string };
return parsed.accessToken; return parsed.access_token;
} catch (err) { } catch (err) {
const msg = errorMessage(err); const msg = errorMessage(err);
throw new Error( throw new Error(

View File

@ -80,7 +80,7 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
const logger = this._logger.withNamespace(`getToken`); const logger = this._logger.withNamespace(`getToken`);
const now = new Date().getTime(); const now = new Date().getTime();
if (this.#cachedToken && this.#cachedAt && now - this.#cachedAt > 60_000) { if (this.#cachedToken && this.#cachedAt && now - this.#cachedAt < 30_000) {
logger.debug(`Using cached token`, { logger.debug(`Using cached token`, {
now: now, now: now,
cachedAt: this.#cachedAt, cachedAt: this.#cachedAt,
@ -141,7 +141,7 @@ export class WorkloadIdentityFederationClient extends Client implements AuthClie
const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${this.#serviceAccount}:signJwt`; const pth = `${this._endpoints.iamcredentials}/projects/-/serviceAccounts/${this.#serviceAccount}:signJwt`;
const headers = { const headers = {
Authorization: `Bearer ${this.getToken()}`, Authorization: `Bearer ${await this.getToken()}`,
}; };
const body = { const body = {

View File

@ -253,11 +253,14 @@ export async function run(logger: Logger) {
); );
} }
let accessToken: string;
// If a subject was provided, use the traditional OAuth 2.0 flow to // If a subject was provided, use the traditional OAuth 2.0 flow to
// perform Domain-Wide Delegation. Otherwise, use the modern IAM // perform Domain-Wide Delegation. Otherwise, use the modern IAM
// Credentials endpoints. // Credentials endpoints.
let accessToken;
if (accessTokenSubject) { if (accessTokenSubject) {
logger.debug(`Using Domain-Wide Delegation flow`);
if (accessTokenLifetime > 3600) { if (accessTokenLifetime > 3600) {
logger.info( logger.info(
`An access token subject was specified, triggering Domain-Wide ` + `An access token subject was specified, triggering Domain-Wide ` +
@ -273,10 +276,10 @@ export async function run(logger: Logger) {
accessTokenLifetime, accessTokenLifetime,
); );
const signedJWT = await client.signJWT(unsignedJWT); const signedJWT = await client.signJWT(unsignedJWT);
accessToken = accessToken =
await iamCredentialsClient.generateDomainWideDelegationAccessToken(signedJWT); await iamCredentialsClient.generateDomainWideDelegationAccessToken(signedJWT);
} else { } else {
logger.debug(`Using normal access token flow`);
accessToken = await iamCredentialsClient.generateAccessToken({ accessToken = await iamCredentialsClient.generateAccessToken({
serviceAccount, serviceAccount,
delegates, delegates,