misc: add auth attempt metrics

This commit is contained in:
Sheen Capadngan
2025-10-30 02:05:31 +08:00
parent e40031aeb5
commit 5d83101462
16 changed files with 1701 additions and 1298 deletions
+4
View File
@@ -157,6 +157,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
metadata: userMetadata
});
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email.toLowerCase(),
"infisical.user.id": user.id,
@@ -167,9 +168,11 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
cb(null, { isUserCompleted, providerAuthToken });
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email.toLowerCase(),
"infisical.auth.method": AuthAttemptAuthMethod.SAML,
@@ -177,6 +180,7 @@ export const registerSamlRouter = async (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
logger.error(error);
cb(error as Error);
@@ -757,6 +757,7 @@ export const oidcConfigServiceFactory = ({
manageGroupMemberships: oidcCfg.manageGroupMemberships
})
.then(({ isUserCompleted, providerAuthToken, user }) => {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": claims?.email?.toLowerCase(),
"infisical.user.id": user.id,
@@ -767,10 +768,12 @@ export const oidcConfigServiceFactory = ({
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
cb(null, { isUserCompleted, providerAuthToken });
})
.catch((error) => {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": claims?.email?.toLowerCase(),
"infisical.organization.id": org.id,
@@ -780,6 +783,7 @@ export const oidcConfigServiceFactory = ({
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
cb(error);
});
+13 -1
View File
@@ -8,7 +8,19 @@ export enum AuthAttemptAuthMethod {
OIDC = "oidc",
GOOGLE = "google",
GITHUB = "github",
GITLAB = "gitlab"
GITLAB = "gitlab",
TOKEN_AUTH = "token-auth",
UNIVERSAL_AUTH = "universal-auth",
KUBERNETES_AUTH = "kubernetes-auth",
GCP_AUTH = "gcp-auth",
ALICLOUD_AUTH = "alicloud-auth",
AWS_AUTH = "aws-auth",
AZURE_AUTH = "azure-auth",
TLS_CERT_AUTH = "tls-cert-auth",
OCI_AUTH = "oci-auth",
OIDC_AUTH = "oidc-auth",
JWT_AUTH = "jwt-auth",
LDAP_AUTH = "ldap-auth"
}
export enum AuthAttemptAuthResult {
+12 -2
View File
@@ -76,6 +76,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
orgSlug
});
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.user.id": user.id,
@@ -86,10 +87,12 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
cb(null, { isUserCompleted, providerAuthToken });
} catch (error) {
logger.error(error);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.auth.method": AuthAttemptAuthMethod.GOOGLE,
@@ -97,7 +100,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
cb(error as Error, false);
}
}
@@ -144,6 +147,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
callbackPort
});
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.user.id": user.id,
@@ -154,9 +158,11 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
done(null, { isUserCompleted, providerAuthToken, externalProviderAccessToken: accessToken });
} catch (err) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.auth.method": AuthAttemptAuthMethod.GITHUB,
@@ -164,7 +170,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
logger.error(err);
done(err as Error, false);
}
@@ -204,6 +210,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
callbackPort
});
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.user.id": user.id,
@@ -214,9 +221,11 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return cb(null, { isUserCompleted, providerAuthToken });
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.auth.method": AuthAttemptAuthMethod.GITLAB,
@@ -224,6 +233,7 @@ export const registerOauthMiddlewares = (server: FastifyZodProvider) => {
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
logger.error(error);
cb(error as Error, false);
@@ -386,6 +386,8 @@ export const authLoginServiceFactory = ({
providerAuthToken?: string;
captchaToken?: string;
}) => {
const appCfg = getConfig();
try {
const usersByUsername = await userDAL.findUserEncKeyByUsername({
username: email
@@ -440,6 +442,7 @@ export const authLoginServiceFactory = ({
organizationId
});
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.organization.id": organizationId,
"infisical.user.email": email,
@@ -449,6 +452,7 @@ export const authLoginServiceFactory = ({
"client.address": ip,
"user_agent.original": userAgent
});
}
return {
tokens: {
@@ -458,6 +462,7 @@ export const authLoginServiceFactory = ({
user: userEnc
} as const;
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.user.email": email,
"infisical.auth.method": AuthAttemptAuthMethod.EMAIL,
@@ -465,6 +470,7 @@ export const authLoginServiceFactory = ({
"client.address": ip,
"user_agent.original": userAgent
});
}
throw error;
}
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AxiosError } from "axios";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
@@ -22,6 +23,7 @@ import {
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -65,6 +67,7 @@ export const identityAliCloudAuthServiceFactory = ({
orgDAL
}: TIdentityAliCloudAuthServiceFactoryDep) => {
const login = async ({ identityId, ...params }: TLoginAliCloudAuthDTO) => {
const appCfg = getConfig();
const identityAliCloudAuth = await identityAliCloudAuthDAL.findOne({ identityId });
if (!identityAliCloudAuth) {
throw new NotFoundError({
@@ -75,6 +78,9 @@ export const identityAliCloudAuthServiceFactory = ({
const identity = await identityDAL.findById(identityAliCloudAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const requestUrl = new URL("https://sts.aliyuncs.com");
for (const key of Object.keys(params)) {
@@ -121,7 +127,6 @@ export const identityAliCloudAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityAliCloudAuth.identityId,
@@ -136,12 +141,40 @@ export const identityAliCloudAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAliCloudAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.ALICLOUD_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return {
identityAliCloudAuth,
accessToken,
identityAccessToken,
identity
};
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAliCloudAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.ALICLOUD_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachAliCloudAuth = async ({
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access */
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import axios from "axios";
import RE2 from "re2";
@@ -22,6 +23,7 @@ import {
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -98,6 +100,7 @@ export const identityAwsAuthServiceFactory = ({
orgDAL
}: TIdentityAwsAuthServiceFactoryDep) => {
const login = async ({ identityId, iamHttpRequestMethod, iamRequestBody, iamRequestHeaders }: TLoginAwsAuthDTO) => {
const appCfg = getConfig();
const identityAwsAuth = await identityAwsAuthDAL.findOne({ identityId });
if (!identityAwsAuth) {
throw new NotFoundError({ message: "AWS auth method not found for identity, did you configure AWS auth?" });
@@ -106,6 +109,8 @@ export const identityAwsAuthServiceFactory = ({
const identity = await identityDAL.findById(identityAwsAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const headers: TAwsGetCallerIdentityHeaders = JSON.parse(Buffer.from(iamRequestHeaders, "base64").toString());
const body: string = Buffer.from(iamRequestBody, "base64").toString();
@@ -196,7 +201,6 @@ export const identityAwsAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const splitArn = extractPrincipalArnEntity(Arn);
const accessToken = crypto.jwt().sign(
{
@@ -226,7 +230,35 @@ export const identityAwsAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAwsAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.AWS_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityAwsAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAwsAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.AWS_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachAwsAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -18,6 +19,7 @@ import {
UnauthorizedError
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -61,6 +63,7 @@ export const identityAzureAuthServiceFactory = ({
orgDAL
}: TIdentityAzureAuthServiceFactoryDep) => {
const login = async ({ identityId, jwt: azureJwt }: TLoginAzureAuthDTO) => {
const appCfg = getConfig();
const identityAzureAuth = await identityAzureAuthDAL.findOne({ identityId });
if (!identityAzureAuth) {
throw new NotFoundError({ message: "Azure auth method not found for identity, did you configure Azure Auth?" });
@@ -69,6 +72,9 @@ export const identityAzureAuthServiceFactory = ({
const identity = await identityDAL.findById(identityAzureAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const azureIdentity = await validateAzureIdentity({
tenantId: identityAzureAuth.tenantId,
resource: identityAzureAuth.resource,
@@ -115,7 +121,6 @@ export const identityAzureAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityAzureAuth.identityId,
@@ -131,7 +136,35 @@ export const identityAzureAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAzureAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.AZURE_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityAzureAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityAzureAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.AZURE_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachAzureAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -18,6 +19,7 @@ import {
UnauthorizedError
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -59,6 +61,7 @@ export const identityGcpAuthServiceFactory = ({
orgDAL
}: TIdentityGcpAuthServiceFactoryDep) => {
const login = async ({ identityId, jwt: gcpJwt }: TLoginGcpAuthDTO) => {
const appCfg = getConfig();
const identityGcpAuth = await identityGcpAuthDAL.findOne({ identityId });
if (!identityGcpAuth) {
throw new NotFoundError({ message: "GCP auth method not found for identity, did you configure GCP auth?" });
@@ -67,6 +70,8 @@ export const identityGcpAuthServiceFactory = ({
const identity = await identityDAL.findById(identityGcpAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
let gcpIdentityDetails: TGcpIdentityDetails;
switch (identityGcpAuth.type) {
case "gce": {
@@ -102,7 +107,11 @@ export const identityGcpAuthServiceFactory = ({
});
}
if (identityGcpAuth.type === "gce" && identityGcpAuth.allowedProjects && gcpIdentityDetails.computeEngineDetails) {
if (
identityGcpAuth.type === "gce" &&
identityGcpAuth.allowedProjects &&
gcpIdentityDetails.computeEngineDetails
) {
// validate if the project that the service account belongs to is in the list of allowed projects
const isProjectAllowed = identityGcpAuth.allowedProjects
@@ -151,8 +160,6 @@ export const identityGcpAuthServiceFactory = ({
);
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityGcpAuth.identityId,
@@ -168,7 +175,35 @@ export const identityGcpAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityGcpAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.GCP_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityGcpAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityGcpAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.GCP_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachGcpAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import https from "https";
import jwt from "jsonwebtoken";
import { JwksClient } from "jwks-rsa";
@@ -21,6 +22,7 @@ import {
UnauthorizedError
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { getValueByDot } from "@app/lib/template/dot-access";
import { ActorType, AuthTokenType } from "../auth/auth-type";
@@ -67,6 +69,7 @@ export const identityJwtAuthServiceFactory = ({
orgDAL
}: TIdentityJwtAuthServiceFactoryDep) => {
const login = async ({ identityId, jwt: jwtValue }: TLoginJwtAuthDTO) => {
const appCfg = getConfig();
const identityJwtAuth = await identityJwtAuthDAL.findOne({ identityId });
if (!identityJwtAuth) {
throw new NotFoundError({ message: "JWT auth method not found for identity, did you configure JWT auth?" });
@@ -75,6 +78,8 @@ export const identityJwtAuthServiceFactory = ({
const identity = await identityDAL.findById(identityJwtAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const { decryptor: orgDataKeyDecryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
orgId: identity.orgId
@@ -228,7 +233,6 @@ export const identityJwtAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityJwtAuth.identityId,
@@ -244,7 +248,35 @@ export const identityJwtAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityJwtAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.JWT_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityJwtAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityJwtAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.JWT_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachJwtAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import axios, { AxiosError } from "axios";
import https from "https";
import RE2 from "re2";
@@ -37,6 +38,7 @@ import { GatewayHttpProxyActions, GatewayProxyProtocol, withGatewayProxy } from
import { withGatewayV2Proxy } from "@app/lib/gateway-v2/gateway-v2";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -182,6 +184,7 @@ export const identityKubernetesAuthServiceFactory = ({
};
const login = async ({ identityId, jwt: serviceAccountJwt }: TLoginKubernetesAuthDTO) => {
const appCfg = getConfig();
const identityKubernetesAuth = await identityKubernetesAuthDAL.findOne({ identityId });
if (!identityKubernetesAuth) {
throw new NotFoundError({
@@ -192,6 +195,9 @@ export const identityKubernetesAuthServiceFactory = ({
const identity = await identityDAL.findById(identityKubernetesAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
orgId: identity.orgId
@@ -242,7 +248,9 @@ export const identityKubernetesAuthServiceFactory = ({
kind: "TokenReview",
spec: {
token: serviceAccountJwt,
...(identityKubernetesAuth.allowedAudience ? { audiences: [identityKubernetesAuth.allowedAudience] } : {})
...(identityKubernetesAuth.allowedAudience
? { audiences: [identityKubernetesAuth.allowedAudience] }
: {})
}
},
{
@@ -295,7 +303,9 @@ export const identityKubernetesAuthServiceFactory = ({
kind: "TokenReview",
spec: {
token: serviceAccountJwt,
...(identityKubernetesAuth.allowedAudience ? { audiences: [identityKubernetesAuth.allowedAudience] } : {})
...(identityKubernetesAuth.allowedAudience
? { audiences: [identityKubernetesAuth.allowedAudience] }
: {})
}
},
{
@@ -457,7 +467,6 @@ export const identityKubernetesAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityKubernetesAuth.identityId,
@@ -479,7 +488,35 @@ export const identityKubernetesAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityKubernetesAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.KUBERNETES_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityKubernetesAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityKubernetesAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.KUBERNETES_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachKubernetesAuth = async ({
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import slugify from "@sindresorhus/slugify";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
@@ -29,6 +30,7 @@ import {
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -151,6 +153,7 @@ export const identityLdapAuthServiceFactory = ({
};
const login = async ({ identityId }: TLoginLdapAuthDTO) => {
const appCfg = getConfig();
const identityLdapAuth = await identityLdapAuthDAL.findOne({ identityId });
if (!identityLdapAuth) {
@@ -162,6 +165,7 @@ export const identityLdapAuthServiceFactory = ({
const identity = await identityDAL.findById(identityLdapAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
const plan = await licenseService.getPlan(identity.orgId);
if (!plan.ldap) {
throw new BadRequestError({
@@ -170,6 +174,7 @@ export const identityLdapAuthServiceFactory = ({
});
}
try {
const identityAccessToken = await identityLdapAuthDAL.transaction(async (tx) => {
await membershipIdentityDAL.update(
{ scope: AccessScope.Organization, scopeOrgId: identity.orgId, actorIdentityId: identity.id },
@@ -191,7 +196,6 @@ export const identityLdapAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityLdapAuth.identityId,
@@ -207,7 +211,35 @@ export const identityLdapAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityLdapAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.LDAP_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityLdapAuth, identityAccessToken, identity };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityLdapAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.LDAP_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachLdapAuth = async ({
@@ -1,5 +1,6 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AxiosError } from "axios";
import RE2 from "re2";
@@ -23,6 +24,7 @@ import {
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -63,6 +65,7 @@ export const identityOciAuthServiceFactory = ({
orgDAL
}: TIdentityOciAuthServiceFactoryDep) => {
const login = async ({ identityId, headers, userOcid }: TLoginOciAuthDTO) => {
const appCfg = getConfig();
const identityOciAuth = await identityOciAuthDAL.findOne({ identityId });
if (!identityOciAuth) {
throw new NotFoundError({ message: "OCI auth method not found for identity, did you configure OCI auth?" });
@@ -71,6 +74,8 @@ export const identityOciAuthServiceFactory = ({
const identity = await identityDAL.findById(identityOciAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
// Validate OCI host format. Ensures that the host is in "identity.<region>.oraclecloud.com" format.
if (!headers.host || !new RE2("^identity\\.([a-z]{2}-[a-z]+-[1-9])\\.oraclecloud\\.com$").test(headers.host)) {
throw new BadRequestError({
@@ -124,7 +129,6 @@ export const identityOciAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityOciAuth.identityId,
@@ -139,12 +143,40 @@ export const identityOciAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityOciAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.OCI_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return {
identityOciAuth,
accessToken,
identityAccessToken,
identity
};
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityOciAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.OCI_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachOciAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import axios from "axios";
import https from "https";
import jwt from "jsonwebtoken";
@@ -22,6 +23,7 @@ import {
UnauthorizedError
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { getValueByDot } from "@app/lib/template/dot-access";
import { ActorType, AuthTokenType } from "../auth/auth-type";
@@ -67,6 +69,7 @@ export const identityOidcAuthServiceFactory = ({
orgDAL
}: TIdentityOidcAuthServiceFactoryDep) => {
const login = async ({ identityId, jwt: oidcJwt }: TLoginOidcAuthDTO) => {
const appCfg = getConfig();
const identityOidcAuth = await identityOidcAuthDAL.findOne({ identityId });
if (!identityOidcAuth) {
throw new NotFoundError({ message: "OIDC auth method not found for identity, did you configure OIDC auth?" });
@@ -75,6 +78,8 @@ export const identityOidcAuthServiceFactory = ({
const identity = await identityDAL.findById(identityOidcAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
orgId: identity.orgId
@@ -198,7 +203,6 @@ export const identityOidcAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityOidcAuth.identityId,
@@ -219,7 +223,35 @@ export const identityOidcAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityOidcAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.OIDC_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return { accessToken, identityOidcAuth, identityAccessToken, identity, oidcTokenData: tokenData };
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityOidcAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.OIDC_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachOidcAuth = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -19,6 +20,7 @@ import {
UnauthorizedError
} from "@app/lib/errors";
import { extractIPDetails, isValidIpOrCidr } from "@app/lib/ip";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -27,6 +29,7 @@ import { TIdentityAccessTokenJwtPayload } from "../identity-access-token/identit
import { TKmsServiceFactory } from "../kms/kms-service";
import { KmsDataKey } from "../kms/kms-types";
import { TMembershipIdentityDALFactory } from "../membership-identity/membership-identity-dal";
import { TOrgDALFactory } from "../org/org-dal";
import { validateIdentityUpdateForSuperAdminPrivileges } from "../super-admin/super-admin-fns";
import { TIdentityTlsCertAuthDALFactory } from "./identity-tls-cert-auth-dal";
import { TIdentityTlsCertAuthServiceFactory } from "./identity-tls-cert-auth-types";
@@ -42,6 +45,7 @@ type TIdentityTlsCertAuthServiceFactoryDep = {
licenseService: Pick<TLicenseServiceFactory, "getPlan">;
permissionService: Pick<TPermissionServiceFactory, "getOrgPermission">;
kmsService: Pick<TKmsServiceFactory, "createCipherPairWithDataKey">;
orgDAL: Pick<TOrgDALFactory, "findById">;
};
const parseSubjectDetails = (data: string) => {
@@ -60,9 +64,11 @@ export const identityTlsCertAuthServiceFactory = ({
membershipIdentityDAL,
licenseService,
permissionService,
kmsService
kmsService,
orgDAL
}: TIdentityTlsCertAuthServiceFactoryDep): TIdentityTlsCertAuthServiceFactory => {
const login: TIdentityTlsCertAuthServiceFactory["login"] = async ({ identityId, clientCertificate }) => {
const appCfg = getConfig();
const identityTlsCertAuth = await identityTlsCertAuthDAL.findOne({ identityId });
if (!identityTlsCertAuth) {
throw new NotFoundError({
@@ -73,6 +79,9 @@ export const identityTlsCertAuthServiceFactory = ({
const identity = await identityDAL.findById(identityTlsCertAuth.identityId);
if (!identity) throw new UnauthorizedError({ message: "Identity not found" });
const org = await orgDAL.findById(identity.orgId);
try {
const { decryptor } = await kmsService.createCipherPairWithDataKey({
type: KmsDataKey.Organization,
orgId: identity.orgId
@@ -140,7 +149,6 @@ export const identityTlsCertAuthServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityTlsCertAuth.identityId,
@@ -155,12 +163,40 @@ export const identityTlsCertAuthServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityTlsCertAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.TLS_CERT_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return {
identityTlsCertAuth,
accessToken,
identityAccessToken,
identity
};
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityTlsCertAuth.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.TLS_CERT_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachTlsCertAuth: TIdentityTlsCertAuthServiceFactory["attachTlsCertAuth"] = async ({
@@ -1,4 +1,5 @@
import { ForbiddenError } from "@casl/ability";
import { requestContext } from "@fastify/request-context";
import { AccessScope, IdentityAuthMethod, OrganizationActionScope } from "@app/db/schemas";
import { TLicenseServiceFactory } from "@app/ee/services/license/license-service";
@@ -21,6 +22,7 @@ import {
} from "@app/lib/errors";
import { checkIPAgainstBlocklist, extractIPDetails, isValidIpOrCidr, TIp } from "@app/lib/ip";
import { logger } from "@app/lib/logger";
import { AuthAttemptAuthMethod, AuthAttemptAuthResult, authAttemptCounter } from "@app/lib/telemetry/metrics";
import { ActorType, AuthTokenType } from "../auth/auth-type";
import { TIdentityDALFactory } from "../identity/identity-dal";
@@ -77,6 +79,7 @@ export const identityUaServiceFactory = ({
identityDAL
}: TIdentityUaServiceFactoryDep) => {
const login = async (clientId: string, clientSecret: string, ip: string) => {
const appCfg = getConfig();
const identityUa = await identityUaDAL.findOne({ clientId });
if (!identityUa) {
throw new UnauthorizedError({
@@ -84,6 +87,10 @@ export const identityUaServiceFactory = ({
});
}
const identity = await identityDAL.findById(identityUa.identityId);
const org = await orgDAL.findById(identity.orgId);
try {
checkIPAgainstBlocklist({
ipAddress: ip,
trustedIps: identityUa.clientSecretTrustedIps as TIp[]
@@ -221,7 +228,6 @@ export const identityUaServiceFactory = ({
accessTokenMaxTTL: 1000000000
};
const identity = await identityDAL.findById(identityUa.identityId);
const identityAccessToken = await identityUaDAL.transaction(async (tx) => {
const uaClientSecretDoc = await identityUaClientSecretDAL.incrementUsage(validClientSecretInfo!.id, tx);
await membershipIdentityDAL.update(
@@ -249,7 +255,6 @@ export const identityUaServiceFactory = ({
return newToken;
});
const appCfg = getConfig();
const accessToken = crypto.jwt().sign(
{
identityId: identityUa.identityId,
@@ -266,6 +271,19 @@ export const identityUaServiceFactory = ({
}
);
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityUa.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.UNIVERSAL_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.SUCCESS,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
return {
accessToken,
identityUa,
@@ -274,6 +292,21 @@ export const identityUaServiceFactory = ({
identity,
...accessTokenTTLParams
};
} catch (error) {
if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) {
authAttemptCounter.add(1, {
"infisical.identity.id": identityUa.identityId,
"infisical.identity.name": identity.name,
"infisical.organization.id": org.id,
"infisical.organization.name": org.name,
"infisical.identity.auth_method": AuthAttemptAuthMethod.UNIVERSAL_AUTH,
"infisical.identity.auth_result": AuthAttemptAuthResult.FAILURE,
"client.address": requestContext.get("ip"),
"user_agent.original": requestContext.get("userAgent")
});
}
throw error;
}
};
const attachUniversalAuth = async ({