mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-15 18:15:53 +00:00
Finished adding support for service account JSON auth method for GCP secret manager integration
This commit is contained in:
@@ -46,6 +46,14 @@ interface ExchangeCodeAzureResponse {
|
||||
id_token: string;
|
||||
}
|
||||
|
||||
interface ExchangeCodeGCPResponse {
|
||||
access_token: string;
|
||||
expires_in: number;
|
||||
refresh_token: string;
|
||||
scope: string;
|
||||
token_type: string;
|
||||
}
|
||||
|
||||
interface ExchangeCodeHerokuResponse {
|
||||
token_type: string;
|
||||
access_token: string;
|
||||
@@ -174,7 +182,7 @@ const exchangeCode = async ({
|
||||
const exchangeCodeGCP = async ({ code }: { code: string }) => {
|
||||
const accessExpiresAt = new Date();
|
||||
|
||||
const res: ExchangeCodeAzureResponse = (
|
||||
const res: ExchangeCodeGCPResponse = (
|
||||
await standardRequest.post(
|
||||
INTEGRATION_GCP_TOKEN_URL,
|
||||
new URLSearchParams({
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import { standardRequest } from "../config/request";
|
||||
import { IIntegrationAuth } from "../models";
|
||||
import {
|
||||
@@ -6,6 +7,9 @@ import {
|
||||
INTEGRATION_BITBUCKET_TOKEN_URL,
|
||||
INTEGRATION_GITLAB,
|
||||
INTEGRATION_HEROKU,
|
||||
INTEGRATION_GCP_SECRET_MANAGER,
|
||||
INTEGRATION_GCP_TOKEN_URL,
|
||||
INTEGRATION_GCP_CLOUD_PLATFORM_SCOPE
|
||||
} from "../variables";
|
||||
import {
|
||||
INTEGRATION_AZURE_TOKEN_URL,
|
||||
@@ -21,6 +25,8 @@ import {
|
||||
getClientSecretBitBucket,
|
||||
getClientSecretGitLab,
|
||||
getClientSecretHeroku,
|
||||
getClientIdGCPSecretManager,
|
||||
getClientSecretGCPSecretManager,
|
||||
getSiteURL,
|
||||
} from "../config";
|
||||
|
||||
@@ -59,6 +65,19 @@ interface RefreshTokenBitBucketResponse {
|
||||
state: string;
|
||||
}
|
||||
|
||||
interface ServiceAccountAccessTokenGCPSecretManagerResponse {
|
||||
access_token: string;
|
||||
expires_in: number;
|
||||
token_type: string;
|
||||
}
|
||||
|
||||
interface RefreshTokenGCPSecretManagerResponse {
|
||||
access_token: string;
|
||||
expires_in: number;
|
||||
scope: string;
|
||||
token_type: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return new access token by exchanging refresh token [refreshToken] for integration
|
||||
* named [integration]
|
||||
@@ -101,18 +120,23 @@ const exchangeRefresh = async ({
|
||||
refreshToken,
|
||||
});
|
||||
break;
|
||||
case INTEGRATION_GCP_SECRET_MANAGER:
|
||||
tokenDetails = await exchangeRefreshGCPSecretManager({
|
||||
integrationAuth,
|
||||
refreshToken,
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw new Error("Failed to exchange token for incompatible integration");
|
||||
}
|
||||
|
||||
if (
|
||||
tokenDetails?.accessToken &&
|
||||
tokenDetails?.refreshToken &&
|
||||
tokenDetails?.accessExpiresAt
|
||||
tokenDetails.accessToken &&
|
||||
tokenDetails.refreshToken &&
|
||||
tokenDetails.accessExpiresAt
|
||||
) {
|
||||
await IntegrationService.setIntegrationAuthAccess({
|
||||
integrationAuthId: integrationAuth._id.toString(),
|
||||
accessId: null,
|
||||
accessToken: tokenDetails.accessToken,
|
||||
accessExpiresAt: tokenDetails.accessExpiresAt,
|
||||
});
|
||||
@@ -278,4 +302,76 @@ const exchangeRefreshBitBucket = async ({
|
||||
};
|
||||
};
|
||||
|
||||
export { exchangeRefresh };
|
||||
/**
|
||||
* Return new access token by exchanging refresh token [refreshToken] for the
|
||||
* GCP Secret Manager integration
|
||||
* @param {Object} obj
|
||||
* @param {String} obj.refreshToken - refresh token to use to get new access token for GCP Secret Manager
|
||||
* @returns
|
||||
*/
|
||||
const exchangeRefreshGCPSecretManager = async ({
|
||||
integrationAuth,
|
||||
refreshToken,
|
||||
}: {
|
||||
integrationAuth: IIntegrationAuth;
|
||||
refreshToken: string;
|
||||
}) => {
|
||||
const accessExpiresAt = new Date();
|
||||
|
||||
if (integrationAuth.metadata?.authMethod === "serviceAccount") {
|
||||
const serviceAccount = JSON.parse(refreshToken);
|
||||
|
||||
const payload = {
|
||||
iss: serviceAccount.client_email,
|
||||
aud: serviceAccount.token_uri,
|
||||
scope: INTEGRATION_GCP_CLOUD_PLATFORM_SCOPE,
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: Math.floor(Date.now() / 1000) + 3600,
|
||||
};
|
||||
|
||||
const token = jwt.sign(payload, serviceAccount.private_key, { algorithm: 'RS256' });
|
||||
|
||||
const { data }: { data: ServiceAccountAccessTokenGCPSecretManagerResponse } = await standardRequest.post(
|
||||
INTEGRATION_GCP_TOKEN_URL,
|
||||
new URLSearchParams({
|
||||
grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',
|
||||
assertion: token
|
||||
}).toString(),
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + data.expires_in);
|
||||
|
||||
return {
|
||||
accessToken: data.access_token,
|
||||
refreshToken,
|
||||
accessExpiresAt
|
||||
};
|
||||
}
|
||||
|
||||
const { data }: { data: RefreshTokenGCPSecretManagerResponse } = (
|
||||
await standardRequest.post(
|
||||
INTEGRATION_GCP_TOKEN_URL,
|
||||
new URLSearchParams({
|
||||
client_id: await getClientIdGCPSecretManager(),
|
||||
client_secret: await getClientSecretGCPSecretManager(),
|
||||
refresh_token: refreshToken,
|
||||
grant_type: "refresh_token",
|
||||
} as any)
|
||||
)
|
||||
);
|
||||
|
||||
accessExpiresAt.setSeconds(accessExpiresAt.getSeconds() + data.expires_in);
|
||||
|
||||
return {
|
||||
accessToken: data.access_token,
|
||||
refreshToken,
|
||||
accessExpiresAt,
|
||||
};
|
||||
};
|
||||
|
||||
export { exchangeRefresh };
|
||||
@@ -1,3 +1,4 @@
|
||||
import jwt from "jsonwebtoken";
|
||||
import {
|
||||
CreateSecretCommand,
|
||||
GetSecretValueCommand,
|
||||
@@ -28,6 +29,8 @@ import {
|
||||
INTEGRATION_FLYIO_API_URL,
|
||||
INTEGRATION_GCP_SECRET_MANAGER,
|
||||
INTEGRATION_GCP_SECRET_MANAGER_URL,
|
||||
INTEGRATION_GCP_TOKEN_URL,
|
||||
INTEGRATION_GCP_CLOUD_PLATFORM_SCOPE,
|
||||
INTEGRATION_GITHUB,
|
||||
INTEGRATION_GITLAB,
|
||||
INTEGRATION_GITLAB_API_URL,
|
||||
|
||||
Reference in New Issue
Block a user