mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-10-08 04:27:38 +00:00
Move MI endpoints from v3 to v1
This commit is contained in:
@@ -26,7 +26,7 @@ import {
|
|||||||
ProjectPermissionActions,
|
ProjectPermissionActions,
|
||||||
ProjectPermissionSub,
|
ProjectPermissionSub,
|
||||||
getAuthDataProjectPermissions,
|
getAuthDataProjectPermissions,
|
||||||
getRolePermissions,
|
getWorkspaceRolePermissions,
|
||||||
isAtLeastAsPrivilegedWorkspace
|
isAtLeastAsPrivilegedWorkspace
|
||||||
} from "../../ee/services/ProjectRoleService";
|
} from "../../ee/services/ProjectRoleService";
|
||||||
import { ForbiddenError } from "@casl/ability";
|
import { ForbiddenError } from "@casl/ability";
|
||||||
@@ -550,7 +550,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
|
|||||||
message: "Failed to add machine identity to project in another organization"
|
message: "Failed to add machine identity to project in another organization"
|
||||||
});
|
});
|
||||||
|
|
||||||
const rolePermission = await getRolePermissions(role, workspaceId);
|
const rolePermission = await getWorkspaceRolePermissions(role, workspaceId);
|
||||||
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
|
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
|
||||||
|
|
||||||
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
|
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
|
||||||
@@ -621,7 +621,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
|
|||||||
message: `Machine identity with id ${machineId} does not exist in project with id ${workspaceId}`
|
message: `Machine identity with id ${machineId} does not exist in project with id ${workspaceId}`
|
||||||
});
|
});
|
||||||
|
|
||||||
const machineIdentityRolePermission = await getRolePermissions(
|
const machineIdentityRolePermission = await getWorkspaceRolePermissions(
|
||||||
machineMembership?.customRole?.slug ?? machineMembership.role,
|
machineMembership?.customRole?.slug ?? machineMembership.role,
|
||||||
machineMembership.workspace.toString()
|
machineMembership.workspace.toString()
|
||||||
);
|
);
|
||||||
@@ -630,7 +630,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
|
|||||||
message: "Failed to update role of more privileged MI"
|
message: "Failed to update role of more privileged MI"
|
||||||
});
|
});
|
||||||
|
|
||||||
const rolePermission = await getRolePermissions(role, workspaceId);
|
const rolePermission = await getWorkspaceRolePermissions(role, workspaceId);
|
||||||
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
|
const isAsPrivilegedAsIntendedRole = isAtLeastAsPrivilegedWorkspace(permission, rolePermission);
|
||||||
|
|
||||||
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
|
if (!isAsPrivilegedAsIntendedRole) throw ForbiddenRequestError({
|
||||||
@@ -705,7 +705,7 @@ export const addMachineToWorkspace = async (req: Request, res: Response) => {
|
|||||||
message: `Machine with id ${machineId} does not exist in project with id ${workspaceId}`
|
message: `Machine with id ${machineId} does not exist in project with id ${workspaceId}`
|
||||||
});
|
});
|
||||||
|
|
||||||
const machineIdentityRolePermission = await getRolePermissions(
|
const machineIdentityRolePermission = await getWorkspaceRolePermissions(
|
||||||
machineMembership?.customRole?.slug ?? machineMembership.role,
|
machineMembership?.customRole?.slug ?? machineMembership.role,
|
||||||
machineMembership.workspace.toString()
|
machineMembership.workspace.toString()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as machineIdentitiesController from "./machineIdentitiesController";
|
||||||
import * as secretController from "./secretController";
|
import * as secretController from "./secretController";
|
||||||
import * as secretSnapshotController from "./secretSnapshotController";
|
import * as secretSnapshotController from "./secretSnapshotController";
|
||||||
import * as organizationsController from "./organizationsController";
|
import * as organizationsController from "./organizationsController";
|
||||||
@@ -13,6 +14,7 @@ import * as secretRotationProviderController from "./secretRotationProviderContr
|
|||||||
import * as secretRotationController from "./secretRotationController";
|
import * as secretRotationController from "./secretRotationController";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
machineIdentitiesController,
|
||||||
secretController,
|
secretController,
|
||||||
secretSnapshotController,
|
secretSnapshotController,
|
||||||
organizationsController,
|
organizationsController,
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import * as machineIdentityController from "./machineIdentityController";
|
|
||||||
import * as apiKeyDataController from "./apiKeyDataController";
|
import * as apiKeyDataController from "./apiKeyDataController";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
machineIdentityController,
|
|
||||||
apiKeyDataController
|
apiKeyDataController
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import machineIdentities from "./machineIdentities";
|
||||||
import secret from "./secret";
|
import secret from "./secret";
|
||||||
import secretSnapshot from "./secretSnapshot";
|
import secretSnapshot from "./secretSnapshot";
|
||||||
import organizations from "./organizations";
|
import organizations from "./organizations";
|
||||||
@@ -13,6 +14,7 @@ import secretRotationProvider from "./secretRotationProvider";
|
|||||||
import secretRotation from "./secretRotation";
|
import secretRotation from "./secretRotation";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
|
machineIdentities,
|
||||||
secret,
|
secret,
|
||||||
secretSnapshot,
|
secretSnapshot,
|
||||||
organizations,
|
organizations,
|
||||||
|
|||||||
+8
-9
@@ -2,14 +2,14 @@ import express from "express";
|
|||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
import { requireAuth } from "../../../middleware";
|
import { requireAuth } from "../../../middleware";
|
||||||
import { AuthMode } from "../../../variables";
|
import { AuthMode } from "../../../variables";
|
||||||
import { machineIdentityController } from "../../controllers/v3";
|
import { machineIdentitiesController } from "../../controllers/v1";
|
||||||
|
|
||||||
router.get(
|
router.get(
|
||||||
"/:machineId/client-secrets",
|
"/:machineId/client-secrets",
|
||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.getMIClientSecrets
|
machineIdentitiesController.getMIClientSecrets
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -17,7 +17,7 @@ router.post(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.createMIClientSecret
|
machineIdentitiesController.createMIClientSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
@@ -25,13 +25,12 @@ router.delete(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.deleteMIClientSecret
|
machineIdentitiesController.deleteMIClientSecret
|
||||||
);
|
);
|
||||||
|
|
||||||
// consider moving to /auth/machine/login
|
|
||||||
router.post(
|
router.post(
|
||||||
"/login",
|
"/login",
|
||||||
machineIdentityController.loginMI
|
machineIdentitiesController.loginMI
|
||||||
);
|
);
|
||||||
|
|
||||||
router.post(
|
router.post(
|
||||||
@@ -39,7 +38,7 @@ router.post(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT, AuthMode.MACHINE_ACCESS_TOKEN]
|
acceptedAuthModes: [AuthMode.JWT, AuthMode.MACHINE_ACCESS_TOKEN]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.createMachineIdentity
|
machineIdentitiesController.createMachineIdentity
|
||||||
);
|
);
|
||||||
|
|
||||||
router.patch(
|
router.patch(
|
||||||
@@ -47,7 +46,7 @@ router.patch(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.updateMachineIdentity
|
machineIdentitiesController.updateMachineIdentity
|
||||||
);
|
);
|
||||||
|
|
||||||
router.delete(
|
router.delete(
|
||||||
@@ -55,7 +54,7 @@ router.delete(
|
|||||||
requireAuth({
|
requireAuth({
|
||||||
acceptedAuthModes: [AuthMode.JWT]
|
acceptedAuthModes: [AuthMode.JWT]
|
||||||
}),
|
}),
|
||||||
machineIdentityController.deleteMachineIdentity
|
machineIdentitiesController.deleteMachineIdentity
|
||||||
);
|
);
|
||||||
|
|
||||||
export default router;
|
export default router;
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import machineIdentity from "./machineIdentity";
|
|
||||||
import apiKeyData from "./apiKeyData";
|
import apiKeyData from "./apiKeyData";
|
||||||
|
|
||||||
export {
|
export {
|
||||||
machineIdentity,
|
|
||||||
apiKeyData
|
apiKeyData
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,7 @@ export const getAuthDataProjectPermissions = async ({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getRolePermissions = async (role: string, workspaceId: string) => {
|
export const getWorkspaceRolePermissions = async (role: string, workspaceId: string) => {
|
||||||
const isCustomRole = ![ADMIN, MEMBER, VIEWER, NO_ACCESS].includes(role);
|
const isCustomRole = ![ADMIN, MEMBER, VIEWER, NO_ACCESS].includes(role);
|
||||||
if (isCustomRole) {
|
if (isCustomRole) {
|
||||||
const workspaceRole = await Role.findOne({
|
const workspaceRole = await Role.findOne({
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
secretSnapshot as eeSecretSnapshotRouter,
|
secretSnapshot as eeSecretSnapshotRouter,
|
||||||
users as eeUsersRouter,
|
users as eeUsersRouter,
|
||||||
workspace as eeWorkspaceRouter,
|
workspace as eeWorkspaceRouter,
|
||||||
|
machineIdentities as v1MachineIdentitiesRouter,
|
||||||
roles as v1RoleRouter,
|
roles as v1RoleRouter,
|
||||||
secretApprovalPolicy as v1SecretApprovalPolicyRouter,
|
secretApprovalPolicy as v1SecretApprovalPolicyRouter,
|
||||||
secretApprovalRequest as v1SecretApprovalRequestRouter,
|
secretApprovalRequest as v1SecretApprovalRequestRouter,
|
||||||
@@ -33,7 +34,6 @@ import {
|
|||||||
secretScanning as v1SecretScanningRouter
|
secretScanning as v1SecretScanningRouter
|
||||||
} from "./ee/routes/v1";
|
} from "./ee/routes/v1";
|
||||||
import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3";
|
import { apiKeyData as v3apiKeyDataRouter } from "./ee/routes/v3";
|
||||||
import { machineIdentity as v3MachineIdentityRouter } from "./ee/routes/v3";
|
|
||||||
import {
|
import {
|
||||||
admin as v1AdminRouter,
|
admin as v1AdminRouter,
|
||||||
auth as v1AuthRouter,
|
auth as v1AuthRouter,
|
||||||
@@ -198,6 +198,7 @@ const main = async () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// (EE) routes
|
// (EE) routes
|
||||||
|
app.use("/api/v1/machine-identities", v1MachineIdentitiesRouter);
|
||||||
app.use("/api/v1/secret", eeSecretRouter);
|
app.use("/api/v1/secret", eeSecretRouter);
|
||||||
app.use("/api/v1/secret-snapshot", eeSecretSnapshotRouter);
|
app.use("/api/v1/secret-snapshot", eeSecretSnapshotRouter);
|
||||||
app.use("/api/v1/users", eeUsersRouter);
|
app.use("/api/v1/users", eeUsersRouter);
|
||||||
@@ -206,7 +207,6 @@ const main = async () => {
|
|||||||
app.use("/api/v1/sso", eeSSORouter);
|
app.use("/api/v1/sso", eeSSORouter);
|
||||||
app.use("/api/v1/cloud-products", eeCloudProductsRouter);
|
app.use("/api/v1/cloud-products", eeCloudProductsRouter);
|
||||||
app.use("/api/v3/api-key", v3apiKeyDataRouter);
|
app.use("/api/v3/api-key", v3apiKeyDataRouter);
|
||||||
app.use("/api/v3/machines", v3MachineIdentityRouter); // TODO: consider moving to v1
|
|
||||||
app.use("/api/v1/secret-rotation-providers", v1SecretRotationProviderRouter);
|
app.use("/api/v1/secret-rotation-providers", v1SecretRotationProviderRouter);
|
||||||
app.use("/api/v1/secret-rotations", v1SecretRotation);
|
app.use("/api/v1/secret-rotations", v1SecretRotation);
|
||||||
|
|
||||||
@@ -247,7 +247,7 @@ const main = async () => {
|
|||||||
app.use("/api/v2/workspace", v2TagsRouter);
|
app.use("/api/v2/workspace", v2TagsRouter);
|
||||||
app.use("/api/v2/workspace", v2WorkspaceRouter);
|
app.use("/api/v2/workspace", v2WorkspaceRouter);
|
||||||
app.use("/api/v2/secret", v2SecretRouter); // deprecate
|
app.use("/api/v2/secret", v2SecretRouter); // deprecate
|
||||||
app.use("/api/v2/secrets", v2SecretsRouter); // note: in the process of moving to v3/secrets
|
app.use("/api/v2/secrets", v2SecretsRouter);
|
||||||
app.use("/api/v2/service-token", v2ServiceTokenDataRouter);
|
app.use("/api/v2/service-token", v2ServiceTokenDataRouter);
|
||||||
|
|
||||||
// v3 routes (experimental)
|
// v3 routes (experimental)
|
||||||
|
|||||||
@@ -82,12 +82,12 @@ In the following steps, we explore how to create and use MIs for your applicatio
|
|||||||
<Step title="Accessing the Infisical API with the MI">
|
<Step title="Accessing the Infisical API with the MI">
|
||||||
To access the Infisical API as the MI, you should first perform a login operation
|
To access the Infisical API as the MI, you should first perform a login operation
|
||||||
that is to exchange the **Client ID** and **Client Secret** of the MI for an access token
|
that is to exchange the **Client ID** and **Client Secret** of the MI for an access token
|
||||||
by making a request to the `/api/v3/machines/login` endpoint.
|
by making a request to the `/api/v1/machine-identities/login` endpoint.
|
||||||
|
|
||||||
#### Sample request
|
#### Sample request
|
||||||
|
|
||||||
```
|
```
|
||||||
curl --location --request POST 'https://app.infisical.com/api/v3/machines/login' \
|
curl --location --request POST 'https://app.infisical.com/api/v1/machine-identities/login' \
|
||||||
--header 'Content-Type: application/x-www-form-urlencoded' \
|
--header 'Content-Type: application/x-www-form-urlencoded' \
|
||||||
--data-urlencode 'clientSecret=...' \
|
--data-urlencode 'clientSecret=...' \
|
||||||
--data-urlencode 'clientId=...'
|
--data-urlencode 'clientId=...'
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ export const useCreateMachineIdentity = () => {
|
|||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
return useMutation<CreateMachineIdentityRes, {}, CreateMachineIdentityDTO>({
|
return useMutation<CreateMachineIdentityRes, {}, CreateMachineIdentityDTO>({
|
||||||
mutationFn: async (body) => {
|
mutationFn: async (body) => {
|
||||||
const { data } = await apiRequest.post("/api/v3/machines/", body);
|
const { data } = await apiRequest.post("/api/v1/machine-identities/", body);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: ({ machineIdentity }) => {
|
onSuccess: ({ machineIdentity }) => {
|
||||||
@@ -37,7 +37,7 @@ export const useCreateMachineIdentityClientSecret = () => {
|
|||||||
usageLimit
|
usageLimit
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const { data } = await apiRequest.post(`/api/v3/machines/${machineId}/client-secrets`, {
|
const { data } = await apiRequest.post(`/api/v1/machine-identities/${machineId}/client-secrets`, {
|
||||||
machineId,
|
machineId,
|
||||||
description,
|
description,
|
||||||
ttl,
|
ttl,
|
||||||
@@ -62,7 +62,7 @@ export const useDeleteMachineIdentityClientSecret = () => {
|
|||||||
machineId:string;
|
machineId:string;
|
||||||
clientSecretId: string;
|
clientSecretId: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { data } = await apiRequest.delete(`/api/v3/machines/${machineId}/client-secrets/${clientSecretId}`);
|
const { data } = await apiRequest.delete(`/api/v1/machine-identities/${machineId}/client-secrets/${clientSecretId}`);
|
||||||
return data;
|
return data;
|
||||||
},
|
},
|
||||||
onSuccess: (_, { machineId }) => {
|
onSuccess: (_, { machineId }) => {
|
||||||
@@ -83,7 +83,7 @@ export const useUpdateMachineIdentity = () => {
|
|||||||
accessTokenTTL
|
accessTokenTTL
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const { data: { machineIdentity } } = await apiRequest.patch(`/api/v3/machines/${machineId}`, {
|
const { data: { machineIdentity } } = await apiRequest.patch(`/api/v1/machine-identities/${machineId}`, {
|
||||||
name,
|
name,
|
||||||
role,
|
role,
|
||||||
clientSecretTrustedIps,
|
clientSecretTrustedIps,
|
||||||
@@ -105,7 +105,7 @@ export const useDeleteMachineIdentity = () => {
|
|||||||
mutationFn: async ({
|
mutationFn: async ({
|
||||||
machineId
|
machineId
|
||||||
}) => {
|
}) => {
|
||||||
const { data: { machineIdentity } } = await apiRequest.delete(`/api/v3/machines/${machineId}`);
|
const { data: { machineIdentity } } = await apiRequest.delete(`/api/v1/machine-identities/${machineId}`);
|
||||||
return machineIdentity;
|
return machineIdentity;
|
||||||
},
|
},
|
||||||
onSuccess: ({ organization }) => {
|
onSuccess: ({ organization }) => {
|
||||||
|
|||||||
@@ -14,8 +14,10 @@ export const useGetMachineIdentityClientSecrets = (machineId: string) => {
|
|||||||
return useQuery({
|
return useQuery({
|
||||||
queryKey: machineIdentityKeys.getMachineIdentityClientSecrets(machineId),
|
queryKey: machineIdentityKeys.getMachineIdentityClientSecrets(machineId),
|
||||||
queryFn: async () => {
|
queryFn: async () => {
|
||||||
|
if (machineId === "") return [];
|
||||||
|
|
||||||
const { data: { clientSecretData } } = await apiRequest.get<{ clientSecretData: MachineIdentityClientSecret[] }>(
|
const { data: { clientSecretData } } = await apiRequest.get<{ clientSecretData: MachineIdentityClientSecret[] }>(
|
||||||
`/api/v3/machines/${machineId}/client-secrets`
|
`/api/v1/machine-identities/${machineId}/client-secrets`
|
||||||
);
|
);
|
||||||
|
|
||||||
return clientSecretData;
|
return clientSecretData;
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const MembersPage = withPermission(
|
|||||||
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||||
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
|
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
|
||||||
<p className="mr-4 mb-4 text-3xl font-semibold text-white">
|
<p className="mr-4 mb-4 text-3xl font-semibold text-white">
|
||||||
Access Control
|
Organization Access Control
|
||||||
</p>
|
</p>
|
||||||
<Tabs defaultValue={TabSections.Member}>
|
<Tabs defaultValue={TabSections.Member}>
|
||||||
<TabList>
|
<TabList>
|
||||||
|
|||||||
+1
-1
@@ -244,7 +244,7 @@ export const CreateClientSecretModal = ({
|
|||||||
<div className="flex">
|
<div className="flex">
|
||||||
<Input
|
<Input
|
||||||
{...field}
|
{...field}
|
||||||
placeholder="7200"
|
placeholder="0"
|
||||||
type="number"
|
type="number"
|
||||||
min="0"
|
min="0"
|
||||||
step="1"
|
step="1"
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ export const MembersPage = withProjectPermission(
|
|||||||
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
<div className="container mx-auto flex flex-col justify-between bg-bunker-800 text-white">
|
||||||
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
|
<div className="mb-6 w-full py-6 px-6 max-w-7xl mx-auto">
|
||||||
<p className="mr-4 mb-4 text-3xl font-semibold text-white">
|
<p className="mr-4 mb-4 text-3xl font-semibold text-white">
|
||||||
Access Control
|
Project Access Control
|
||||||
</p>
|
</p>
|
||||||
<Tabs defaultValue={TabSections.Member}>
|
<Tabs defaultValue={TabSections.Member}>
|
||||||
<TabList>
|
<TabList>
|
||||||
|
|||||||
Reference in New Issue
Block a user