Infisical / infisical

♾ Infisical is the open-source secret management platform: Sync secrets across your team/infrastructure, prevent secret leaks, and manage internal PKI
https://infisical.com
Other
13.16k stars 698 forks source link

Confusion over secret rotation on free self-hosted version #2043

Closed yeurch closed 2 weeks ago

yeurch commented 3 weeks ago

Describe the bug

The pricing page suggests that secret rotation is only available in the Pro plan. I'm running a self-hosted free instance of Infisical.

Most features that are gated behind a paid plan are clearly identified as such. E.g. if I navigate to audit logs, I get a popup with text reading Unleash Infisical's Full Power - You can use audit logs if you switch to a paid Infisical plan. Upgrade and get access to this, as well as to other powerful enhancements.

No such warning appears on the Secret Rotation screen, and in fact it lets me go through the full flow of configuring a secret rotation without any warnings. However, the created rotation just doesn't work.

To Reproduce

  1. Install a self-hosted free version of Infisical on Docker.
  2. Follow the steps on the AWS IAM key rotation guide to set up an AWS IAM rotation.
  3. Click the "Rotate now" button.
  4. The toast notification saying "Secret rotation initiated" appears, but the secret is not actually rotated.

Expected behavior

If secret rotation is supposed to be supported in the free self-hosted version, then the rotation should succeed and update the configured secrets.

If secret rotation is not supposed to be supported in the free self-hosted version, then a warning should appear, preventing me from configuring a new key rotation.

Screenshots

image

Platform you are having the issue on:

Version v0.72.3-postgres running on Docker using the Docker Compose script provided by Infisical.

akhilmhdh commented 2 weeks ago

@yeurch Can you check your server logs please? And yes it is indeed free in self hosted version too

yeurch commented 2 weeks ago

Great to hear this is included in the self-hosted version - thanks for confirming that @akhilmhdh.

There is actually an error message in my server log. The error is logged at the time I create my secret rotation, not when it attempts to rotate the key. The message says "Provider not found" as can be seen below:

2024-07-01 17:36:25 {"level":50,"time":1719851785366,"pid":1,"hostname":"e1e26f843290","severity":"ERROR","err":{"type":"DisableRotationErrors","message":"Provider not found","stack":"DisableRotationErrors: Provider not found\n    at Worker.processFn (file:///backend/dist/ee/services/secret-rotation/secret-rotation-queue/secret-rotation-queue.mjs:58:15)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at async Worker.processJob (/backend/node_modules/bullmq/dist/cjs/classes/worker.js:408:28)\n    at async Worker.retryIfFailed (/backend/node_modules/bullmq/dist/cjs/classes/worker.js:597:24)","name":"DisableRotationErrors"},"msg":"Provider not found"}

Despite this error occurring during the creation of the secret rotation, you can see by the screen image in my original issue above that the rotation does appear to have been created, but has no value in the status column.

akhilmhdh commented 2 weeks ago

@yeurch May i know what happens when you do the retry?

yeurch commented 2 weeks ago

I get the toast notification in the bottom right saying "Secret rotation initiated". Then nothing visibly happens on screen, and the secret is not rotated.

Logs for the rotation are as follows:

2024-07-02 08:45:43 {"level":30,"time":1719906342332,"pid":1,"hostname":"e1e26f843290","reqId":"req-58r","severity":"INFO","req":{"method":"POST","url":"/api/v1/secret-rotations/restart","hostname":"localhost","remoteAddress":"172.18.0.1","remotePort":61746},"msg":"incoming request"}
2024-07-02 08:45:43 {"level":30,"time":1719906342336,"pid":1,"hostname":"e1e26f843290","severity":"INFO","msg":"injectPermission: Injecting permissions for [permissionsForIdentity=667b9301-8b6d-4c78-bf0c-b114cf81f63a] [type=user]"}
2024-07-02 08:45:43 {"level":30,"time":1719906342338,"pid":1,"hostname":"e1e26f843290","severity":"INFO","msg":"getPlan: attempting to fetch plan for [orgId=26e0974a-f7db-4916-9ca0-68c19bb9e377] [projectId=undefined]"}
2024-07-02 08:45:43 {"level":30,"time":1719906342343,"pid":1,"hostname":"e1e26f843290","reqId":"req-58r","severity":"INFO","res":{"statusCode":200},"responseTime":11.46742695569992,"msg":"request completed"}
2024-07-02 08:45:43 {"level":30,"time":1719906342349,"pid":1,"hostname":"e1e26f843290","reqId":"req-58s","severity":"INFO","req":{"method":"GET","url":"/api/v1/secret-rotations?workspaceId=9166ba55-7633-4bd1-9aa8-c771e1b40736","hostname":"localhost","remoteAddress":"172.18.0.1","remotePort":61746},"msg":"incoming request"}
2024-07-02 08:45:43 {"level":30,"time":1719906342352,"pid":1,"hostname":"e1e26f843290","severity":"INFO","msg":"injectPermission: Injecting permissions for [permissionsForIdentity=667b9301-8b6d-4c78-bf0c-b114cf81f63a] [type=user]"}
2024-07-02 08:45:43 {"level":30,"time":1719906342359,"pid":1,"hostname":"e1e26f843290","reqId":"req-58s","severity":"INFO","res":{"statusCode":304},"responseTime":9.392515003681183,"msg":"request completed"}
2024-07-02 08:45:43 {"level":30,"time":1719906342557,"pid":1,"hostname":"e1e26f843290","reqId":"req-58t","severity":"INFO","req":{"method":"GET","url":"/api/v1/secret-approval-requests/count?workspaceId=9166ba55-7633-4bd1-9aa8-c771e1b40736","hostname":"localhost","remoteAddress":"172.18.0.1","remotePort":61746},"msg":"incoming request"}
2024-07-02 08:45:43 {"level":30,"time":1719906342562,"pid":1,"hostname":"e1e26f843290","severity":"INFO","msg":"injectPermission: Injecting permissions for [permissionsForIdentity=667b9301-8b6d-4c78-bf0c-b114cf81f63a] [type=user]"}
2024-07-02 08:45:43 {"level":30,"time":1719906342575,"pid":1,"hostname":"e1e26f843290","reqId":"req-58t","severity":"INFO","res":{"statusCode":304},"responseTime":17.48214900493622,"msg":"request completed"}
2024-07-02 08:45:48 {"level":30,"time":1719906347590,"pid":1,"hostname":"e1e26f843290","reqId":"req-58u","severity":"INFO","req":{"method":"GET","url":"/api/v1/secret-approval-requests/count?workspaceId=9166ba55-7633-4bd1-9aa8-c771e1b40736","hostname":"localhost","remoteAddress":"172.18.0.1","remotePort":61746},"msg":"incoming request"}
2024-07-02 08:45:48 {"level":30,"time":1719906347595,"pid":1,"hostname":"e1e26f843290","severity":"INFO","msg":"injectPermission: Injecting permissions for [permissionsForIdentity=667b9301-8b6d-4c78-bf0c-b114cf81f63a] [type=user]"}
2024-07-02 08:45:48 {"level":30,"time":1719906347604,"pid":1,"hostname":"e1e26f843290","reqId":"req-58u","severity":"INFO","res":{"statusCode":304},"responseTime":14.817283034324646,"msg":"request completed"}
yeurch commented 2 weeks ago

Further, the AWS Console says that the IAM credentials I created to do the rotation have never been used.

akhilmhdh commented 2 weeks ago

Hey @yeurch I found why the create rotation is failing will get it fixed. But i think the restart should have rotated. Can you check the status section once please.

yeurch commented 2 weeks ago

Thanks for your work on this so far @akhilmhdh. I'm not sure that I understand what you mean by "restart should have rotated" and "check the status section once". Please can you explain further?

I restarted the docker compose stack and re-ran the rotation. The result is the same as before and was not successful. The status column on the Infisical user interface is still blank.

I've also been looking into this myself a little, and I confirmed that the row with the correct rotation id exists in the db table secret_rotations and the provider column has the value aws-iam. I was able to decrypt the encryptedData column and the parameters in the decrypted JSON's inputs value look correct. The creds key is just an empty array though ... [].

Looking at this code, from secret-rotation-queue.ts suggests that the provider aws-iam might not be present in rotationTemplates.

    const { rotationId } = job.data;
    logger.info(`secretRotationQueue.process: [rotationDocument=${rotationId}]`);
    const secretRotation = await secretRotationDAL.findById(rotationId);
    const rotationProvider = rotationTemplates.find(({ name }) => name === secretRotation?.provider);

    try {
      if (!rotationProvider || !secretRotation) throw new DisableRotationErrors({ message: "Provider not found" });
yeurch commented 2 weeks ago

I also tried setting up a MySQL rotation (with garbage data, so I don't ever expect this MySQL rotation to work). The "Provider not found" error was logged for this rotation provider too.

akhilmhdh commented 2 weeks ago

@yeurch Don't worry i have found out why your getting that one error. Now regarding the restart i meant this one

344397140-a5f73c37-0ad0-4719-9938-90ddffb955ef

If you click here and may be wait couple of seconds, then refresh the page can you check the status

yeurch commented 2 weeks ago

Sorry, I thought I had explained that I had already tried that, and it didn't work. After hitting the restart button, waiting a while, and refreshing the page, there is no change to the status or last rotation columns in the UI.

I have verified the credentials are correct, and network connectivity to AWS is working by:

  1. Connecting to the backend docker container as root and running a shell.
  2. Installing the AWS CLI with apk add aws-cli.
  3. Logging in to the AWS CLI with aws configure (using the manager access key and secret I entered into Infisical).
  4. Generating IAM credentials for the target user with aws iam create-access-key --user-name <target_user_name>.

The above manual steps worked correctly from the backend container, and generated IAM credentials for the user.