diff --git a/backend/src/ee/controllers/v3/machineIdentityController.ts b/backend/src/ee/controllers/v3/machineIdentityController.ts index 66e9c12d2..7dc439ec2 100644 --- a/backend/src/ee/controllers/v3/machineIdentityController.ts +++ b/backend/src/ee/controllers/v3/machineIdentityController.ts @@ -531,6 +531,8 @@ export const updateMachineIdentity = async (req: Request, res: Response) => { if (!machineIdentity) throw ResourceNotFoundError({ message: `Machine identity with id ${machineId} not found` }); + + // TODO: validate existing role (if it is currently admin then cant demote it) const { permission } = await getUserOrgPermissions(req.user._id, machineIdentity.organization.toString()); diff --git a/docs/documentation/platform/machine-identity.mdx b/docs/documentation/platform/machine-identity.mdx index 3974eee2c..7865cd5d0 100644 --- a/docs/documentation/platform/machine-identity.mdx +++ b/docs/documentation/platform/machine-identity.mdx @@ -19,11 +19,11 @@ fetch secrets back from the `/` path of the `development` environment in some pr Here's a few pointers to get you acquainted with MIs: -- When you create a MI, you get issued a refresh token that can be exchanged for an access token to authenticate with the Infisical API. +- Each MI has a **Client ID** for which you can generate one or more **Client Secret(s)**. Together, a **Client ID** and **Client Secret** can be exchanged for an access token to authenticate with the Infisical API. - MIs support IP allowlisting; this means you can restrict the usage of a MI access token to a specific IP or CIDR range. - MIs rely on the role-based permission system to provision access to resources like secrets. -- MIs support expiration, so, if specified, the refresh token of the MI will automatically be defunct after a period of time. -- MIs tracks most recent usage of their refresh and access tokens; they also keeps track of each token's usage count. +- MIs support expiration, so, if specified, the client secret of the MI will automatically be defunct after a period of time. +- MIs tracks most recent usage of their client secrets and access tokens; they also keep track of each token's usage count. - MIs are editable. ## Using machine identities @@ -32,7 +32,7 @@ In the following steps, we explore how to create and use MIs for your applicatio - To create a machine identity, head to your Organization Settings > Access Control > Machine Identities and press **Create MI**. + To create a machine identity, head to your Organization Settings > Access Control > Machine Identities and press **Create identity**. ![machine identities organization](../../images/platform/machine-identity/machine-identity-org.png) @@ -42,23 +42,36 @@ In the following steps, we explore how to create and use MIs for your applicatio - Name (required): A friendly name for the MI - Role (required): A role from the **Organization Roles** tab to permit the MI to access certain resources. - - Refresh Token Expires In: The number of days from now to deactivate the MI refresh token - - Trusted IPs: The IPs or CIDR ranges that the refresh and access tokens can be used from. By default, each token is given the `0.0.0.0/0` entry representing all possible IPv4 addresses. - Access Token TTL: The time-to-live for each acccess token in seconds. - - Refresh Token Rotation: Whether or not to return a new refresh token when exchanging an existing refresh token; if enabled, the existing refresh token is invalidated upon the refresh operation. + - Client Secret Trusted IPs: The IPs or CIDR ranges that the **Client Secret** can be used from together with the **Client ID** to get back an access token. By default, **Client Secrets** are given the `0.0.0.0/0` entry representing all possible IPv4 addresses. + - Access Token Trusted IPs: The IPs or CIDR ranges that access tokens can be used from. By default, each token is given the `0.0.0.0/0` entry representing all possible IPv4 addresses. - Restricting token usage to specific trusted IPs is a paid feature. + Restricting **Client Secret** and access token usage to specific trusted IPs is a paid feature. If you’re using Infisical Cloud, then it is available under the Pro Tier. If you’re self-hosting Infisical, then you should contact team@infisical.com to purchase an enterprise license to use it. - Once you've created the MI, you'll be issued a refresh token for it; copy the token and keep it handy. + + + In order to use the MI, you'll need the non-sensitive **Client ID** + of the MI and a **Client Secret** for it; you can think of these credentials akin to a username + and password used to authenticate with the Infisical API. With that, press on the key icon on the MI to generate a **Client Secret** + for it. + + ![machine identities client secret create](../../images/platform/machine-identity/machine-identity-org-client-secret.png) + ![machine identities client secret create](../../images/platform/machine-identity/machine-identity-org-client-secret-create-1.png) + ![machine identities client secret create](../../images/platform/machine-identity/machine-identity-org-client-secret-create-2.png) + + Feel free to input any (optional) details for the **Client Secret** configuration: + + - Description: A description for the **Client Secret**. + - TTL: The time-to-live for the **Client Secret**. By default, the TTL will be set to 0 which implies that the **Client Secret** will never expire. - If you intend the MI access project-level resources such as secrets within a specific project, you should add it to that project. + To enable the MI to access project-level resources such as secrets within a specific project, you should add it to that project. - To do this, head over to the project you want to add the MI to and go to Project Settings > Access Control > Machine Identities and press **Add MI**. + To do this, head over to the project you want to add the MI to and go to Project Settings > Access Control > Machine Identities and press **Add identity**. Next, select the MI you want to add to the project and the role you want to assign it. @@ -67,22 +80,23 @@ In the following steps, we explore how to create and use MIs for your applicatio ![machine identities project create](../../images/platform/machine-identity/machine-identity-project-create.png) - To access the Infisical API as the MI, you should first exchange the MI refresh token from **Step 1** for an access token - by making a request to the `/api/v3/machines/me/token` endpoint. + 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 + by making a request to the `/api/v3/machines/login` endpoint. #### Sample request ``` - curl --location --request POST 'http://localhost:8080/api/v3/machines/me/token' \ + curl --location --request POST 'https://app.infisical.com/api/v3/machines/login' \ --header 'Content-Type: application/x-www-form-urlencoded' \ - --data-urlencode 'refreshToken=' + --data-urlencode 'clientSecret=...' \ + --data-urlencode 'clientId=...' ``` #### Sample response ``` { - "refreshToken": "...", "accessToken": "...", "expiresIn": 7200, "tokenType": "Bearer" @@ -92,11 +106,11 @@ In the following steps, we explore how to create and use MIs for your applicatio Next, you can use the access token to authenticate with the [Infisical API](/api-reference/overview/introduction) - Each MI access token has a time-to-live (TLL) which you can infer from the response of the refresh token exchange; + Each MI access token has a time-to-live (TLL) which you can infer from the response of the login operation; the default TTL is `7200` seconds which can be adjusted in the **Advanced** settings of the MI. If a MI access token expires, it can no longer authenticate with the Infisical API. In this case, - a new access token should be obtained from the refresh token exchange. + a new access token should be obtained from the aforementioned login operation. @@ -113,10 +127,10 @@ In the following steps, we explore how to create and use MIs for your applicatio There are a few reasons for why this might happen: - - The refresh/access token has expired. + - The client secret or access token has expired. - The MI is insufficently permissioned to interact with the resources you wish to access. - You are attempting to access a `/raw` secrets endpoint that requires your project to disable E2EE. - - The refresh/access token is being used from an untrusted IP. + - The client secret/access token is being used from an untrusted IP. 1. `/**`: This pattern matches all folders at any depth in the directory structure. For example, it would match folders like `/folder1/`, `/folder1/subfolder/`, and so on. diff --git a/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-1.png b/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-1.png new file mode 100644 index 000000000..5e8970dc2 Binary files /dev/null and b/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-1.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-2.png b/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-2.png new file mode 100644 index 000000000..5c50589b5 Binary files /dev/null and b/docs/images/platform/machine-identity/machine-identity-org-client-secret-create-2.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-org-client-secret.png b/docs/images/platform/machine-identity/machine-identity-org-client-secret.png new file mode 100644 index 000000000..71c6d4334 Binary files /dev/null and b/docs/images/platform/machine-identity/machine-identity-org-client-secret.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-org-create.png b/docs/images/platform/machine-identity/machine-identity-org-create.png index f66c16388..947a0b552 100644 Binary files a/docs/images/platform/machine-identity/machine-identity-org-create.png and b/docs/images/platform/machine-identity/machine-identity-org-create.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-org.png b/docs/images/platform/machine-identity/machine-identity-org.png index 0cd1fd316..885e51e1c 100644 Binary files a/docs/images/platform/machine-identity/machine-identity-org.png and b/docs/images/platform/machine-identity/machine-identity-org.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-project-create.png b/docs/images/platform/machine-identity/machine-identity-project-create.png index 243c20c82..084c2b4c4 100644 Binary files a/docs/images/platform/machine-identity/machine-identity-project-create.png and b/docs/images/platform/machine-identity/machine-identity-project-create.png differ diff --git a/docs/images/platform/machine-identity/machine-identity-project.png b/docs/images/platform/machine-identity/machine-identity-project.png index f087ed485..a35e957cc 100644 Binary files a/docs/images/platform/machine-identity/machine-identity-project.png and b/docs/images/platform/machine-identity/machine-identity-project.png differ diff --git a/frontend/src/views/Org/MembersPage/MembersPage.tsx b/frontend/src/views/Org/MembersPage/MembersPage.tsx index a2d7e5011..03680c486 100644 --- a/frontend/src/views/Org/MembersPage/MembersPage.tsx +++ b/frontend/src/views/Org/MembersPage/MembersPage.tsx @@ -27,7 +27,7 @@ export const MembersPage = withPermission( People
-

App Clients

+

Machine Identities

New
diff --git a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx index ae436395b..1c556c010 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx @@ -263,7 +263,7 @@ export const AddMachineIdentityModal = ({ reset(); }} > - +
diff --git a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/CreateClientSecretModal.tsx b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/CreateClientSecretModal.tsx index 4e3961eab..99b4fa70d 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/CreateClientSecretModal.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/CreateClientSecretModal.tsx @@ -270,7 +270,7 @@ export const CreateClientSecretModal = ({ {!isLoading && data && data?.length === 0 && ( - + )} diff --git a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx index e9d8764cc..f006a9bfe 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx @@ -51,7 +51,7 @@ export const MachineIdentitySection = withPermission(

- App Clients + Machine Identities

handlePopUpOpen("machineIdentity")} isDisabled={!isAllowed} > - Create client + Create identity )} diff --git a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx index 868d55625..7fd70da34 100644 --- a/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx +++ b/frontend/src/views/Org/MembersPage/components/OrgMachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx @@ -151,29 +151,9 @@ export const MachineIdentityTable = ({ customRole }) => { return ( - + {name} {clientId} - {/* - - {(isAllowed) => ( - handleToggleStatus({ - serviceTokenDataId: _id, - isActive: value - })} - isChecked={isActive} - isDisabled={!isAllowed} - > -

{isActive ? "Active" : "Inactive"}

-
- )} -
- */} - {/* - {trustedIps.map(({ - _id: trustedIpId, - ipAddress, - prefix - }) => { - return ( -

- {`${ipAddress}${prefix !== undefined ? `/${prefix}` : ""}`} -

- ); - })} - */} - {/* {accessTokenTTL} */} - {/* {format(new Date(createdAt), "yyyy-MM-dd")} */} - {/* {expiresAt ? format(new Date(expiresAt), "yyyy-MM-dd") : "-"} */} - - + +
{ @@ -292,6 +256,7 @@ export const MachineIdentityTable = ({ )} +
); @@ -299,7 +264,7 @@ export const MachineIdentityTable = ({ {!isLoading && data && data?.length === 0 && ( - + )} diff --git a/frontend/src/views/Project/MembersPage/MembersPage.tsx b/frontend/src/views/Project/MembersPage/MembersPage.tsx index 551b088e2..8b946810e 100644 --- a/frontend/src/views/Project/MembersPage/MembersPage.tsx +++ b/frontend/src/views/Project/MembersPage/MembersPage.tsx @@ -32,7 +32,7 @@ export const MembersPage = withProjectPermission( People
-

App Clients

+

Machine Identities

New
diff --git a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx index 4c982a67a..fdcc0e1c7 100644 --- a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx +++ b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/AddMachineIdentityModal.tsx @@ -120,7 +120,7 @@ export const AddMachineIdentityModal = ({ reset(); }} > - + {filteredMachineMembershipOrgs.length ? ( ( diff --git a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx index 948934b42..e02b03cdb 100644 --- a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx +++ b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentitySection.tsx @@ -62,7 +62,7 @@ export const MachineIdentitySection = withProjectPermission(

- App Clients + Machine Identities

handlePopUpOpen("machineIdentity")} isDisabled={!isAllowed} > - Add client + Add identity )} diff --git a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx index d7fe40023..0bddc7f21 100644 --- a/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx +++ b/frontend/src/views/Project/MembersPage/components/MachineIdentityTab/components/MachineIdentitySection/MachineIdentityTable.tsx @@ -188,7 +188,7 @@ export const MachineIdentityTable = ({ {!isLoading && data && data?.length === 0 && ( - + )}