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