Migrations contain sensitive information

Describe the issue:

We configured our primary environment to “Force the use of sandbox environments”. This means that we need to do plugin updates in a fork and create a migration from it. When we do this update and autogenerate a migration this migration contains plugin parameters. In our case these parameters contain sensitive information (API keys). Is it possible to exclude certain plugin parameters in a migration? We would like to avoid to commit sensitive information to our repository.

Do you have any sample code you can provide?

Here is an example migration. It is generated when updating the “Translate Fields” DatoCMS plugin (Translate - Plugins — DatoCMS):

import { Client, SimpleSchemaTypes } from "@datocms/cli/lib/cma-client-node";

export default async function (client: Client) {
  console.log("Manage upload filters");

  console.log('Upgrade version of plugin "Translate"');
  await client.plugins.update("152128", {
    parameters: {
      autoApply: true,
      openAIApiKey: "<SENSITIVE INFORMATION>",
      fieldsToEnable: [
        { label: "String fields", value: "string" },
        { label: "Text fields", value: "text" },
        { label: "Structured text fields", value: "structured_text" },
        { label: "SEO fields", value: "seo" },
        { label: "Modular content fields", value: "rich_text" },
      ],
      deeplFreeApiKey: "<SENSITIVE INFORMATION>",
      deeplGlossaryId: "<SENSITIVE INFORMATION>",
      translationService: { label: "DeepL API Free", value: "deeplFree" },
    },
    package_version: "1.11.0",
  });
}

(Previous reply deleted)

Sorry, I misunderstood your question at first. Please ignore my previous response (now deleted, but you might’ve gotten it in an email notification).

I don’t think we explicitly account for secrets in generating migrations with plugins, but let me double-check that for you… please give us some time for that.

1 Like

@fusion, I checked with the devs on this, and unfortunately we don’t do anything special for secrets handling in plugins :frowning: They’re all just text fields to us. That might be a nice feature request, but in the meantime, could you perhaps use a pre-commit hook to detect the secret, and then either block the commit until someone manually edits it out, or else write a simple regex replace to get rid of it automatically, possibly replacing it with a dotenv secret instead?

Some example tutorials:

https://eloquentcode.com/prevent-committing-secrets-with-a-pre-commit-hook

There are also tools that can help with detection (though because you know exactly the shape of the migration script, you should also just be able to write a simple bash or node regex script to do this):

(They would still need to be integrated into your migration script repo as a pre-commit hook).

Note that pre-commit hooks can be manually disabled by individual devs, so if you’re really concerned about that, you might want to back that up with Github secrets scanning and/or a CI action (like a Github Action) that can do a similar scan, and optionally maybe retroactively strip it from the repo.

It’s a lot of work, I know, and nowhere as easy as just having plugin secrets automatically marked and sanitized :frowning: Sorry about that!

Thanks a lot for the detailed answer. But does this mean I can leave out some variables in the parameters object of the migration? Doesn’t this change the value when this migration is executed on the primary environment? If that’s the case I would just manually remove them by now.

Update: Just checked it and it seems to empty the plugin configuration values as soon as the migration gets applied without the parameter fields. :confused:

That’s where the dotenv secret would come in. You’d have the API key stored in an env file on your local machine (git ignored) and use process.env.api-key instead of hardcoding it.

So what gets committed to git would just be process.env.api-key, which dotenv would resolve to the actual key when you run the script.

Does that make sense?

Yes sure makes sense :+1: Let me try this.

1 Like