Migrating from CircleCI to Mint

Migrating Secrets

The easiest way to migrate secrets from CircleCI to Mint secrets is to use the Mint CLI from a CircleCI workflow to import them automatically.

You can use the following code in CircleCI. It contains two jobs, import-project-secrets-into-mint and import-context-secrets-into-mint, which can be called multiple times for as many projects and contexts as you have.

  • Make a new Context in CircleCI named mint-secret-import
    • Add an environment variable in the context for CIRCLECI_API_TOKEN set to a personal access token from CircleCI
    • Add an environment variable in the context for RWX_ACCESS_TOKEN set to an RWX access token
  • Configure a job for each project you want to import secrets from by calling import-project-secrets-into-mint with the respective project-slug
    • Set into-vault to the Mint vault that you want to import into
  • Configure a job for each context you want to import secrets from by calling import-context-secrets-into-mint with the respective context-name
    • Set into-vault to the Mint vault that you want to import into
  • Note that dry-run is true in each job in the workflow so you can first take a look at the names of the secrets that will be sent over to Mint. If everything looks good in there, set dry-run to false and run it again
version: 2.1

jobs:
  import-project-secrets-into-mint:
    docker:
      - image: cimg/base:current
    parameters:
      project-slug:
        type: string
      into-vault:
        type: string
      dry-run:
        type: boolean
    steps:
      - run:
          name: Import Project Secrets Into Mint
          command: |
            # Find the environment variables in the project
            project="<< parameters.project-slug >>"
            environment_variables="[]"
            next_page=""

            while : ; do
              response=$(
                curl -fsSL \
                  -H "Circle-Token: ${CIRCLECI_API_TOKEN}" \
                  "https://circleci.com/api/v2/project/${project}/envvar?page_token=${next_page}"
              )
              next_page=$(echo "${response}" | jq -r '.next_page_token // ""')
              environment_variables=$(echo "${response}" | jq --argjson existing "${environment_variables}" '.items += $existing | .items')

              [[ -n "${next_page}" ]] || break
            done

            # Write them to a dotenv-style file
            cat \<< "EOF" > write-secret.sh
            echo "$1=\"$(printenv $1 | sed -r 's/"/\\"/g')\"" >> secrets.txt
            EOF
            echo "${environment_variables}" \
              | jq -r '.[].name' \
              | xargs -I {} bash write-secret.sh {}

            curl -fsSL https://github.com/rwx-research/mint-cli/releases/download/v1/mint-linux-x86_64 > mint
            chmod +x mint
            ./mint --version

            if [[ "<< parameters.dry-run >>" == "true" ]]; then
              echo "${environment_variables}" | jq -r '.[].name'
            else
              ./mint vaults set-secrets --vault "<< parameters.into-vault >>" --file secrets.txt
            fi

  import-context-secrets-into-mint:
    docker:
      - image: cimg/base:current
    parameters:
      organization-slug:
        type: string
      context-name:
        type: string
      into-vault:
        type: string
      dry-run:
        type: boolean
    steps:
      - run:
          name: Import Context Secrets Into Mint
          command: |
            # Find all contexts in the org
            organization_slug="<< parameters.organization-slug >>"
            contexts="[]"
            next_page=""

            while : ; do
              response=$(
                curl -fsSL \
                  -H "Circle-Token: ${CIRCLECI_API_TOKEN}" \
                  "https://circleci.com/api/v2/context?owner-slug=${organization_slug}&page-token=${next_page}"
              )
              next_page=$(echo "${response}" | jq -r '.next_page_token // ""')
              contexts=$(echo "${response}" | jq --argjson existing "${contexts}" '.items += $existing | .items')

              [[ -n "${next_page}" ]] || break
            done

            # Find the environment variables in the context
            context_to_import_id=$(echo "${contexts}" | jq --arg contextName "<< parameters.context-name >>" -r '.[] | select(.name == $contextName) | .id')
            environment_variables="[]"
            next_page=""

            while : ; do
              response=$(
                curl -fsSL \
                  -H "Circle-Token: ${CIRCLECI_API_TOKEN}" \
                  "https://circleci.com/api/v2/context/${context_to_import_id}/environment-variable?page-token=${next_page}"
              )
              next_page=$(echo "${response}" | jq -r '.next_page_token // ""')
              environment_variables=$(echo "${response}" | jq --argjson existing "${environment_variables}" '.items += $existing | .items')

              [[ -n "${next_page}" ]] || break
            done

            # Write them to a dotenv-style file
            cat \<< "EOF" > write-secret.sh
            echo "$1=\"$(printenv $1 | sed -r 's/"/\\"/g')\"" >> secrets.txt
            EOF
            echo "${environment_variables}" \
              | jq -r '.[].variable' \
              | xargs -I {} bash write-secret.sh {}

            curl -fsSL https://github.com/rwx-research/mint-cli/releases/download/v1/mint-linux-x86_64 > mint
            chmod +x mint
            ./mint --version

            if [[ "<< parameters.dry-run >>" == "true" ]]; then
              echo "${environment_variables}" | jq -r '.[].variable'
            else
              ./mint vaults set-secrets --vault "<< parameters.into-vault >>" --file secrets.txt
            fi

workflows:
  import-secrets-into-mint:
    jobs:
      - import-project-secrets-into-mint:
          project-slug: github/your-org/your-repo
          into-vault: your-mint-vault
          dry-run: true
          context: mint-secret-import # this must have one secret named CIRCLECI_API_TOKEN and one named RWX_ACCESS_TOKEN

      - import-context-secrets-into-mint:
          name: import-context-secrets-into-mint-your-context
          organization-slug: github/your-org
          context-name: your-context
          into-vault: your-mint-vault
          dry-run: true
          context:
            - mint-secret-import # this must have one secret named CIRCLECI_API_TOKEN and one named RWX_ACCESS_TOKEN
            - your-context