From 043c04778f7bc891fedbf99d47212a0c7051b1c0 Mon Sep 17 00:00:00 2001 From: Tuan Dang Date: Tue, 16 Jul 2024 13:47:46 +0700 Subject: [PATCH] Improve native auth method unauthorized errors --- .../identity-aws-auth-service.ts | 10 ++++++++-- .../identity-gcp-auth-service.ts | 15 ++++++++++++--- .../identity-kubernetes-auth-service.ts | 15 ++++++++++++--- .../identity-oidc-auth-service.ts | 12 +++++++++--- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts index 9cb39aece0..6e303c1f7c 100644 --- a/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts +++ b/backend/src/services/identity-aws-auth/identity-aws-auth-service.ts @@ -78,7 +78,10 @@ export const identityAwsAuthServiceFactory = ({ .map((accountId) => accountId.trim()) .some((accountId) => accountId === Account); - if (!isAccountAllowed) throw new UnauthorizedError(); + if (!isAccountAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: AWS account ID not allowed." + }); } if (identityAwsAuth.allowedPrincipalArns) { @@ -94,7 +97,10 @@ export const identityAwsAuthServiceFactory = ({ return regex.test(extractPrincipalArn(Arn)); }); - if (!isArnAllowed) throw new UnauthorizedError(); + if (!isArnAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: AWS principal ARN not allowed." + }); } const identityAccessToken = await identityAwsAuthDAL.transaction(async (tx) => { diff --git a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts index edac7c132f..fdbb8490d8 100644 --- a/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts +++ b/backend/src/services/identity-gcp-auth/identity-gcp-auth-service.ts @@ -81,7 +81,10 @@ export const identityGcpAuthServiceFactory = ({ .map((serviceAccount) => serviceAccount.trim()) .some((serviceAccount) => serviceAccount === gcpIdentityDetails.email); - if (!isServiceAccountAllowed) throw new UnauthorizedError(); + if (!isServiceAccountAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: GCP service account not allowed." + }); } if (identityGcpAuth.type === "gce" && identityGcpAuth.allowedProjects && gcpIdentityDetails.computeEngineDetails) { @@ -92,7 +95,10 @@ export const identityGcpAuthServiceFactory = ({ .map((project) => project.trim()) .some((project) => project === gcpIdentityDetails.computeEngineDetails?.project_id); - if (!isProjectAllowed) throw new UnauthorizedError(); + if (!isProjectAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: GCP project not allowed." + }); } if (identityGcpAuth.type === "gce" && identityGcpAuth.allowedZones && gcpIdentityDetails.computeEngineDetails) { @@ -101,7 +107,10 @@ export const identityGcpAuthServiceFactory = ({ .map((zone) => zone.trim()) .some((zone) => zone === gcpIdentityDetails.computeEngineDetails?.zone); - if (!isZoneAllowed) throw new UnauthorizedError(); + if (!isZoneAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: GCP zone not allowed." + }); } const identityAccessToken = await identityGcpAuthDAL.transaction(async (tx) => { diff --git a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts index 820777b465..d0a1b07cf4 100644 --- a/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts +++ b/backend/src/services/identity-kubernetes-auth/identity-kubernetes-auth-service.ts @@ -139,7 +139,10 @@ export const identityKubernetesAuthServiceFactory = ({ .map((namespace) => namespace.trim()) .some((namespace) => namespace === targetNamespace); - if (!isNamespaceAllowed) throw new UnauthorizedError(); + if (!isNamespaceAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: K8s namespace not allowed." + }); } if (identityKubernetesAuth.allowedNames) { @@ -150,7 +153,10 @@ export const identityKubernetesAuthServiceFactory = ({ .map((name) => name.trim()) .some((name) => name === targetName); - if (!isNameAllowed) throw new UnauthorizedError(); + if (!isNameAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: K8s name not allowed." + }); } if (identityKubernetesAuth.allowedAudience) { @@ -159,7 +165,10 @@ export const identityKubernetesAuthServiceFactory = ({ (audience) => audience === identityKubernetesAuth.allowedAudience ); - if (!isAudienceAllowed) throw new UnauthorizedError(); + if (!isAudienceAllowed) + throw new ForbiddenRequestError({ + message: "Access denied: K8s audience not allowed." + }); } const identityAccessToken = await identityKubernetesAuthDAL.transaction(async (tx) => { diff --git a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts index c639289de8..457e930588 100644 --- a/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts +++ b/backend/src/services/identity-oidc-auth/identity-oidc-auth-service.ts @@ -124,13 +124,17 @@ export const identityOidcAuthServiceFactory = ({ if (identityOidcAuth.boundSubject) { if (tokenData.sub !== identityOidcAuth.boundSubject) { - throw new UnauthorizedError(); + throw new ForbiddenRequestError({ + message: "Access denied: OIDC subject not allowed." + }); } } if (identityOidcAuth.boundAudiences) { if (!identityOidcAuth.boundAudiences.split(", ").includes(tokenData.aud)) { - throw new UnauthorizedError(); + throw new ForbiddenRequestError({ + message: "Access denied: OIDC audience not allowed." + }); } } @@ -139,7 +143,9 @@ export const identityOidcAuthServiceFactory = ({ const claimValue = (identityOidcAuth.boundClaims as Record)[claimKey]; // handle both single and multi-valued claims if (!claimValue.split(", ").some((claimEntry) => tokenData[claimKey] === claimEntry)) { - throw new UnauthorizedError(); + throw new ForbiddenRequestError({ + message: "Access denied: OIDC claim not allowed." + }); } }); }