mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-06 22:27:22 +00:00
feat: addressed all review comments
This commit is contained in:
Vendored
+1
-1
@@ -162,7 +162,7 @@ declare module "fastify" {
|
|||||||
};
|
};
|
||||||
// identity injection. depending on which kinda of token the information is filled in auth
|
// identity injection. depending on which kinda of token the information is filled in auth
|
||||||
auth: TAuthMode;
|
auth: TAuthMode;
|
||||||
isPrimaryForwardingMode: boolean;
|
shouldForwardWritesToPrimaryInstance: boolean;
|
||||||
permission: {
|
permission: {
|
||||||
authMethod: ActorAuthMethod;
|
authMethod: ActorAuthMethod;
|
||||||
type: ActorType;
|
type: ActorType;
|
||||||
|
|||||||
@@ -218,7 +218,7 @@ const envSchema = z
|
|||||||
),
|
),
|
||||||
PARAMS_FOLDER_SECRET_DETECTION_ENTROPY: z.coerce.number().optional().default(3.7),
|
PARAMS_FOLDER_SECRET_DETECTION_ENTROPY: z.coerce.number().optional().default(3.7),
|
||||||
|
|
||||||
INFISICAL_PRIMARY_URL: zpStr(z.string().optional()),
|
INFISICAL_PRIMARY_INSTANCE_URL: zpStr(z.string().optional()),
|
||||||
|
|
||||||
// HSM
|
// HSM
|
||||||
HSM_LIB_PATH: zpStr(z.string().optional()),
|
HSM_LIB_PATH: zpStr(z.string().optional()),
|
||||||
|
|||||||
@@ -107,115 +107,117 @@ export const extractAuth = async (req: FastifyRequest, jwtSecret: string) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// ! Important: You can only 100% count on the `req.permission.orgId` field being present when the auth method is Identity Access Token (Machine Identity).
|
// ! Important: You can only 100% count on the `req.permission.orgId` field being present when the auth method is Identity Access Token (Machine Identity).
|
||||||
export const injectIdentity = fp(async (server: FastifyZodProvider, opt: { isPrimaryForwardingMode?: boolean }) => {
|
export const injectIdentity = fp(
|
||||||
server.decorateRequest("auth", null);
|
async (server: FastifyZodProvider, opt: { shouldForwardWritesToPrimaryInstance?: boolean }) => {
|
||||||
server.decorateRequest("isPrimaryForwardingMode", Boolean(opt.isPrimaryForwardingMode));
|
server.decorateRequest("auth", null);
|
||||||
server.addHook("onRequest", async (req) => {
|
server.decorateRequest("shouldForwardWritesToPrimaryInstance", Boolean(opt.shouldForwardWritesToPrimaryInstance));
|
||||||
const appCfg = getConfig();
|
server.addHook("onRequest", async (req) => {
|
||||||
|
const appCfg = getConfig();
|
||||||
|
|
||||||
if (opt.isPrimaryForwardingMode && req.method !== "GET") {
|
if (opt.shouldForwardWritesToPrimaryInstance && req.method !== "GET") {
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (req.url.includes(".well-known/est") || req.url.includes("/api/v3/auth/")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Authentication is handled on a route-level here.
|
|
||||||
if (req.url.includes("/api/v1/workflow-integrations/microsoft-teams/message-endpoint")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const { authMode, token, actor } = await extractAuth(req, appCfg.AUTH_SECRET);
|
|
||||||
|
|
||||||
if (!authMode) return;
|
|
||||||
|
|
||||||
switch (authMode) {
|
|
||||||
case AuthMode.JWT: {
|
|
||||||
const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token);
|
|
||||||
requestContext.set("orgId", orgId);
|
|
||||||
req.auth = {
|
|
||||||
authMode: AuthMode.JWT,
|
|
||||||
user,
|
|
||||||
userId: user.id,
|
|
||||||
tokenVersionId,
|
|
||||||
actor,
|
|
||||||
orgId: orgId as string,
|
|
||||||
authMethod: token.authMethod,
|
|
||||||
isMfaVerified: token.isMfaVerified,
|
|
||||||
token
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case AuthMode.IDENTITY_ACCESS_TOKEN: {
|
|
||||||
const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken(token, req.realIp);
|
if (req.url.includes(".well-known/est") || req.url.includes("/api/v3/auth/")) {
|
||||||
const serverCfg = await getServerCfg();
|
return;
|
||||||
requestContext.set("orgId", identity.orgId);
|
}
|
||||||
req.auth = {
|
|
||||||
authMode: AuthMode.IDENTITY_ACCESS_TOKEN,
|
// Authentication is handled on a route-level here.
|
||||||
actor,
|
if (req.url.includes("/api/v1/workflow-integrations/microsoft-teams/message-endpoint")) {
|
||||||
orgId: identity.orgId,
|
return;
|
||||||
identityId: identity.identityId,
|
}
|
||||||
identityName: identity.name,
|
|
||||||
authMethod: null,
|
const { authMode, token, actor } = await extractAuth(req, appCfg.AUTH_SECRET);
|
||||||
isInstanceAdmin: serverCfg?.adminIdentityIds?.includes(identity.identityId),
|
|
||||||
token
|
if (!authMode) return;
|
||||||
};
|
|
||||||
if (token?.identityAuth?.oidc) {
|
switch (authMode) {
|
||||||
requestContext.set("identityAuthInfo", {
|
case AuthMode.JWT: {
|
||||||
identityId: identity.identityId,
|
const { user, tokenVersionId, orgId } = await server.services.authToken.fnValidateJwtIdentity(token);
|
||||||
oidc: token?.identityAuth?.oidc
|
requestContext.set("orgId", orgId);
|
||||||
});
|
req.auth = {
|
||||||
|
authMode: AuthMode.JWT,
|
||||||
|
user,
|
||||||
|
userId: user.id,
|
||||||
|
tokenVersionId,
|
||||||
|
actor,
|
||||||
|
orgId: orgId as string,
|
||||||
|
authMethod: token.authMethod,
|
||||||
|
isMfaVerified: token.isMfaVerified,
|
||||||
|
token
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (token?.identityAuth?.kubernetes) {
|
case AuthMode.IDENTITY_ACCESS_TOKEN: {
|
||||||
requestContext.set("identityAuthInfo", {
|
const identity = await server.services.identityAccessToken.fnValidateIdentityAccessToken(token, req.realIp);
|
||||||
|
const serverCfg = await getServerCfg();
|
||||||
|
requestContext.set("orgId", identity.orgId);
|
||||||
|
req.auth = {
|
||||||
|
authMode: AuthMode.IDENTITY_ACCESS_TOKEN,
|
||||||
|
actor,
|
||||||
|
orgId: identity.orgId,
|
||||||
identityId: identity.identityId,
|
identityId: identity.identityId,
|
||||||
kubernetes: token?.identityAuth?.kubernetes
|
identityName: identity.name,
|
||||||
});
|
authMethod: null,
|
||||||
|
isInstanceAdmin: serverCfg?.adminIdentityIds?.includes(identity.identityId),
|
||||||
|
token
|
||||||
|
};
|
||||||
|
if (token?.identityAuth?.oidc) {
|
||||||
|
requestContext.set("identityAuthInfo", {
|
||||||
|
identityId: identity.identityId,
|
||||||
|
oidc: token?.identityAuth?.oidc
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (token?.identityAuth?.kubernetes) {
|
||||||
|
requestContext.set("identityAuthInfo", {
|
||||||
|
identityId: identity.identityId,
|
||||||
|
kubernetes: token?.identityAuth?.kubernetes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (token?.identityAuth?.aws) {
|
||||||
|
requestContext.set("identityAuthInfo", {
|
||||||
|
identityId: identity.identityId,
|
||||||
|
aws: token?.identityAuth?.aws
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (token?.identityAuth?.aws) {
|
case AuthMode.SERVICE_TOKEN: {
|
||||||
requestContext.set("identityAuthInfo", {
|
const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token);
|
||||||
identityId: identity.identityId,
|
requestContext.set("orgId", serviceToken.orgId);
|
||||||
aws: token?.identityAuth?.aws
|
req.auth = {
|
||||||
});
|
orgId: serviceToken.orgId,
|
||||||
|
authMode: AuthMode.SERVICE_TOKEN as const,
|
||||||
|
serviceToken,
|
||||||
|
serviceTokenId: serviceToken.id,
|
||||||
|
actor,
|
||||||
|
authMethod: null,
|
||||||
|
token
|
||||||
|
};
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case AuthMode.API_KEY: {
|
||||||
|
const user = await server.services.apiKey.fnValidateApiKey(token as string);
|
||||||
|
req.auth = {
|
||||||
|
authMode: AuthMode.API_KEY as const,
|
||||||
|
userId: user.id,
|
||||||
|
actor,
|
||||||
|
user,
|
||||||
|
orgId: "API_KEY", // We set the orgId to an arbitrary value, since we can't link an API key to a specific org. We have to deprecate API keys soon!
|
||||||
|
authMethod: null,
|
||||||
|
token: token as string
|
||||||
|
};
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case AuthMode.SCIM_TOKEN: {
|
||||||
|
const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token);
|
||||||
|
requestContext.set("orgId", orgId);
|
||||||
|
req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null };
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new BadRequestError({ message: "Invalid token strategy provided" });
|
||||||
}
|
}
|
||||||
case AuthMode.SERVICE_TOKEN: {
|
});
|
||||||
const serviceToken = await server.services.serviceToken.fnValidateServiceToken(token);
|
}
|
||||||
requestContext.set("orgId", serviceToken.orgId);
|
);
|
||||||
req.auth = {
|
|
||||||
orgId: serviceToken.orgId,
|
|
||||||
authMode: AuthMode.SERVICE_TOKEN as const,
|
|
||||||
serviceToken,
|
|
||||||
serviceTokenId: serviceToken.id,
|
|
||||||
actor,
|
|
||||||
authMethod: null,
|
|
||||||
token
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AuthMode.API_KEY: {
|
|
||||||
const user = await server.services.apiKey.fnValidateApiKey(token as string);
|
|
||||||
req.auth = {
|
|
||||||
authMode: AuthMode.API_KEY as const,
|
|
||||||
userId: user.id,
|
|
||||||
actor,
|
|
||||||
user,
|
|
||||||
orgId: "API_KEY", // We set the orgId to an arbitrary value, since we can't link an API key to a specific org. We have to deprecate API keys soon!
|
|
||||||
authMethod: null,
|
|
||||||
token: token as string
|
|
||||||
};
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AuthMode.SCIM_TOKEN: {
|
|
||||||
const { orgId, scimTokenId } = await server.services.scim.fnValidateScimToken(token);
|
|
||||||
requestContext.set("orgId", orgId);
|
|
||||||
req.auth = { authMode: AuthMode.SCIM_TOKEN, actor, scimTokenId, orgId, authMethod: null };
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
throw new BadRequestError({ message: "Invalid token strategy provided" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ interface TAuthOptions {
|
|||||||
export const verifyAuth =
|
export const verifyAuth =
|
||||||
<T extends FastifyRequest>(authStrategies: AuthMode[], options: TAuthOptions = { requireOrg: true }) =>
|
<T extends FastifyRequest>(authStrategies: AuthMode[], options: TAuthOptions = { requireOrg: true }) =>
|
||||||
(req: T, _res: FastifyReply, done: HookHandlerDoneFunction) => {
|
(req: T, _res: FastifyReply, done: HookHandlerDoneFunction) => {
|
||||||
if (req.isPrimaryForwardingMode && req.method !== "GET") {
|
if (req.shouldForwardWritesToPrimaryInstance && req.method !== "GET") {
|
||||||
return done();
|
return done();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import replyFrom from "@fastify/reply-from";
|
import replyFrom from "@fastify/reply-from";
|
||||||
import fp from "fastify-plugin";
|
import fp from "fastify-plugin";
|
||||||
|
|
||||||
export const primaryForwardingMode = fp(async (server, opt: { primaryUrl: string }) => {
|
export const forwardWritesToPrimary = fp(async (server, opt: { primaryUrl: string }) => {
|
||||||
await server.register(replyFrom, {
|
await server.register(replyFrom, {
|
||||||
base: opt.primaryUrl
|
base: opt.primaryUrl
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ import { injectAssumePrivilege } from "../plugins/auth/inject-assume-privilege";
|
|||||||
import { injectIdentity } from "../plugins/auth/inject-identity";
|
import { injectIdentity } from "../plugins/auth/inject-identity";
|
||||||
import { injectPermission } from "../plugins/auth/inject-permission";
|
import { injectPermission } from "../plugins/auth/inject-permission";
|
||||||
import { injectRateLimits } from "../plugins/inject-rate-limits";
|
import { injectRateLimits } from "../plugins/inject-rate-limits";
|
||||||
import { primaryForwardingMode } from "../plugins/primary-forwarding-mode";
|
import { forwardWritesToPrimary } from "../plugins/primary-forwarding-mode";
|
||||||
import { registerV1Routes } from "./v1";
|
import { registerV1Routes } from "./v1";
|
||||||
import { initializeOauthConfigSync } from "./v1/sso-router";
|
import { initializeOauthConfigSync } from "./v1/sso-router";
|
||||||
import { registerV2Routes } from "./v2";
|
import { registerV2Routes } from "./v2";
|
||||||
@@ -2147,14 +2147,14 @@ export const registerRoutes = async (
|
|||||||
user: userDAL,
|
user: userDAL,
|
||||||
kmipClient: kmipClientDAL
|
kmipClient: kmipClientDAL
|
||||||
});
|
});
|
||||||
const isPrimaryForwardingMode = Boolean(envConfig.INFISICAL_PRIMARY_URL);
|
const shouldForwardWritesToPrimaryInstance = Boolean(envConfig.INFISICAL_PRIMARY_INSTANCE_URL);
|
||||||
if (isPrimaryForwardingMode) {
|
if (shouldForwardWritesToPrimaryInstance) {
|
||||||
logger.info(`Infisical primary instance is configured: ${envConfig.INFISICAL_PRIMARY_URL}`);
|
logger.info(`Infisical primary instance is configured: ${envConfig.INFISICAL_PRIMARY_INSTANCE_URL}`);
|
||||||
|
|
||||||
await server.register(primaryForwardingMode, { primaryUrl: envConfig.INFISICAL_PRIMARY_URL as string });
|
await server.register(forwardWritesToPrimary, { primaryUrl: envConfig.INFISICAL_PRIMARY_INSTANCE_URL as string });
|
||||||
}
|
}
|
||||||
|
|
||||||
await server.register(injectIdentity, { isPrimaryForwardingMode });
|
await server.register(injectIdentity, { shouldForwardWritesToPrimaryInstance });
|
||||||
await server.register(injectAssumePrivilege);
|
await server.register(injectAssumePrivilege);
|
||||||
await server.register(injectPermission);
|
await server.register(injectPermission);
|
||||||
await server.register(injectRateLimits);
|
await server.register(injectRateLimits);
|
||||||
|
|||||||
Reference in New Issue
Block a user