diff --git a/backend/src/db/migrations/20240507153350_identity-gcp-iam-auth.ts b/backend/src/db/migrations/20240507213008_identity-gcp-iam-auth.ts
similarity index 100%
rename from backend/src/db/migrations/20240507153350_identity-gcp-iam-auth.ts
rename to backend/src/db/migrations/20240507213008_identity-gcp-iam-auth.ts
diff --git a/backend/src/server/routes/v1/identity-gcp-iam-auth-router.ts b/backend/src/server/routes/v1/identity-gcp-iam-auth-router.ts
index e38767b0e..4a0032c02 100644
--- a/backend/src/server/routes/v1/identity-gcp-iam-auth-router.ts
+++ b/backend/src/server/routes/v1/identity-gcp-iam-auth-router.ts
@@ -6,6 +6,7 @@ import { readLimit, writeLimit } from "@app/server/config/rateLimiter";
import { verifyAuth } from "@app/server/plugins/auth/verify-auth";
import { AuthMode } from "@app/services/auth/auth-type";
import { TIdentityTrustedIp } from "@app/services/identity/identity-types";
+import { validateGcpIamAuthField } from "@app/services/identity-gcp-iam-auth/identity-gcp-iam-auth-validators";
export const registerIdentityGcpIamAuthRouter = async (server: FastifyZodProvider) => {
server.route({
@@ -73,8 +74,8 @@ export const registerIdentityGcpIamAuthRouter = async (server: FastifyZodProvide
identityId: z.string().trim()
}),
body: z.object({
- allowedServiceAccounts: z.string(), // TODO: better validation
- allowedProjects: z.string(), // TODO: better validation
+ allowedServiceAccounts: validateGcpIamAuthField,
+ allowedProjects: validateGcpIamAuthField,
accessTokenTrustedIps: z
.object({
ipAddress: z.string().trim()
diff --git a/backend/src/services/identity-gcp-iam-auth/identity-gcp-iam-auth-validators.ts b/backend/src/services/identity-gcp-iam-auth/identity-gcp-iam-auth-validators.ts
new file mode 100644
index 000000000..a581ba9cc
--- /dev/null
+++ b/backend/src/services/identity-gcp-iam-auth/identity-gcp-iam-auth-validators.ts
@@ -0,0 +1,14 @@
+import { z } from "zod";
+
+export const validateGcpIamAuthField = z
+ .string()
+ .trim()
+ .default("")
+ .transform((data) => {
+ if (data === "") return "";
+ // Trim each ID and join with ', ' to ensure formatting
+ return data
+ .split(",")
+ .map((id) => id.trim())
+ .join(", ");
+ });
diff --git a/docs/documentation/platform/identities/gcp-iam-auth.mdx b/docs/documentation/platform/identities/gcp-iam-auth.mdx
index 3d046c2e8..cf46e36b0 100644
--- a/docs/documentation/platform/identities/gcp-iam-auth.mdx
+++ b/docs/documentation/platform/identities/gcp-iam-auth.mdx
@@ -45,8 +45,7 @@ access the Infisical API using the GCP IAM authentication method.
Once you've created an identity, you'll be prompted to configure the authentication method for it. Here, select **GCP IAM Auth**.
- TODO: add image
- {/*  */}
+ 
Here's some more guidance on each field:
diff --git a/docs/documentation/platform/identities/machine-identities.mdx b/docs/documentation/platform/identities/machine-identities.mdx
index 9168cb230..e4b93053c 100644
--- a/docs/documentation/platform/identities/machine-identities.mdx
+++ b/docs/documentation/platform/identities/machine-identities.mdx
@@ -7,7 +7,7 @@ description: "Learn how to use Machine Identities to programmatically interact w
An Infisical machine identity is an entity that represents a workload or application that require access to various resources in Infisical. This is conceptually similar to an IAM user in AWS or service account in Google Cloud Platform (GCP).
-Each identity must authenticate using a supported authentication method like [Universal Auth](/documentation/platform/identities/universal-auth) or [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth) to get back a short-lived access token to be used in subsequent requests.
+Each identity must authenticate with the Infisical API using a supported authentication method like [Universal Auth](/documentation/platform/identities/universal-auth), [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth), or [GCP IAM Auth](/documentation/platform/identities/gcp-iam-auth) to get back a short-lived access token to be used in subsequent requests.

@@ -21,7 +21,7 @@ Key Features:
A typical workflow for using identities consists of four steps:
1. Creating the identity with a name and [role](/documentation/platform/role-based-access-controls) in Organization Access Control > Machine Identities.
- This step also involves configuring an authentication method for it such as [Universal Auth](/documentation/platform/identities/universal-auth) or [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth).
+ This step also involves configuring an authentication method for it.
2. Adding the identity to the project(s) you want it to have access to.
3. Authenticating the identity with the Infisical API based on the configured authentication method on it and receiving a short-lived access token back.
4. Authenticating subsequent requests with the Infisical API using the short-lived access token.
@@ -39,6 +39,7 @@ To interact with various resources in Infisical, Machine Identities are able to
- [Universal Auth](/documentation/platform/identities/universal-auth): A platform-agnostic authentication method that can be configured on an identity suitable to authenticate from any platform/environment.
- [AWS IAM Auth](/documentation/platform/identities/aws-iam-auth): An AWS-native authentication method for IAM principals like EC2 instances or Lambda functions to authenticate with Infisical.
+- [GCP IAM Auth](/documentation/platform/identities/gcp-iam-auth): A GCP-native authentication method for IAM service accounts to authenticate with Infisical.
## FAQ
diff --git a/docs/images/platform/identities/identities-org-create-gcp-iam-auth-method.png b/docs/images/platform/identities/identities-org-create-gcp-iam-auth-method.png
new file mode 100644
index 000000000..67d906851
Binary files /dev/null and b/docs/images/platform/identities/identities-org-create-gcp-iam-auth-method.png differ
diff --git a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx
index 2cd4cc334..ca62bd617 100644
--- a/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx
+++ b/frontend/src/views/Org/MembersPage/components/OrgIdentityTab/components/IdentitySection/IdentityAuthMethodModal.tsx
@@ -15,6 +15,7 @@ import { IdentityAuthMethod } from "@app/hooks/api/identities";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { IdentityAwsIamAuthForm } from "./IdentityAwsIamAuthForm";
+import { IdentityGcpIamAuthForm } from "./IdentityGcpIamAuthForm";
import { IdentityUniversalAuthForm } from "./IdentityUniversalAuthForm";
type Props = {
@@ -28,7 +29,8 @@ type Props = {
const identityAuthMethods = [
{ label: "Universal Auth", value: IdentityAuthMethod.UNIVERSAL_AUTH },
- { label: "AWS IAM Auth", value: IdentityAuthMethod.AWS_IAM_AUTH }
+ { label: "AWS IAM Auth", value: IdentityAuthMethod.AWS_IAM_AUTH },
+ { label: "GCP Auth", value: IdentityAuthMethod.GCP_IAM_AUTH }
];
const schema = yup
@@ -75,6 +77,15 @@ export const IdentityAuthMethodModal = ({ popUp, handlePopUpOpen, handlePopUpTog
/>
);
}
+ case IdentityAuthMethod.GCP_IAM_AUTH: {
+ return (
+
+ );
+ }
case IdentityAuthMethod.UNIVERSAL_AUTH: {
return (
(
-
+
)}
/>