Skip to content

Instantly share code, notes, and snippets.

@yaningo
Last active March 22, 2024 12:29
Show Gist options
  • Save yaningo/79c0812d9fc7128052e76f9a19b6fec7 to your computer and use it in GitHub Desktop.
Save yaningo/79c0812d9fc7128052e76f9a19b6fec7 to your computer and use it in GitHub Desktop.
description: >
This command deletes SSH keys (checkout or additional) from all projects.
parameters:
delete-deploy-keys:
description: |
Whether or not to delete deploy SSH keys.
type: boolean
default: true
rotate-deploy-keys:
description: |
Whether or not to add new deploy SSH keys after deletion.
type: boolean
default: true
delete-user-keys:
description: |
Whether or not to delete user SSH keys.
type: boolean
default: false
delete-additional-keys:
description: |
Whether or not to delete additional SSH keys.
type: boolean
default: false
threshold:
description: |
The timestamp to compare the kesy creation date to. Any key created on or before that timestamp will be included in the deletion.
Format is: "YYYY-MM-DDT:HH:MM:SSZ". The letters 'T' and 'Z' are required, when specifying a time. Timezone is UTC. Example: "2023-01-06T13:26:07Z"
If you only specify a date ("YYYY-MM-DD"), the value of the 'threshold' parameter will be set to "YYYY-MM-DDT:00:00:00Z".
Note: this parameter only applies to Checkout SSH keys; NOT to Additional SSH keys.
type: string
default: ""
circle-token:
description: |
Name of the environment variable containing the CircleCI personal API token.
It is strongly advised to store this environment variable in a tightly restricted context.
type: env_var_name
default: CIRCLE_TOKEN
steps:
- run:
environment:
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_DELETE_DEPLOY_KEYS: << parameters.delete-deploy-keys >>
PARAM_ROTATE_DEPLOY_KEYS: << parameters.rotate-deploy-keys >>
PARAM_DELETE_USER_KEYS: << parameters.delete-user-keys >>
PARAM_DELETE_ADDITIONAL_KEYS: << parameters.delete-additional-keys >>
PARAM_THRESHOLD: << parameters.threshold >>
PARAM_ORG_NAME: << parameters.org-name >>
name: Deleting SSH keys
command: <<include(scripts/delete/delete-ssh-keys.sh)>>
- run:
environment:
PARAM_VCS: << parameters.vcs >>
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_ORG_NAME: << parameters.org-name >>
# SCRIPT_GET_PROJECTS_GITHUB: << include(scripts/github/get-github-projects.sh) >>
# SCRIPT_GET_PROJECTS_BITBUCKET: << include(scripts/bitbucket/get-bitbucket-projects.sh) >>
# SCRIPT_GET_PROJECTS_GITLAB: << include(scripts/gitlab/get-gitlab-projects.sh) >>
name: Listing organization projects
command: <<include(scripts/projects/get-projects.sh)>>
- when:
condition: << parameters.search-projects-env-vars >>
steps:
- run:
environment:
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_VCS: << parameters.vcs >>
PARAM_ORG_NAME: << parameters.org-name >>
name: Searching for environment variables in projects
command: <<include(scripts/projects/search-env-vars.sh)>>
- when:
condition: << parameters.search-projects-api-tokens >>
steps:
- run:
environment:
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_VCS: << parameters.vcs >>
PARAM_ORG_NAME: << parameters.org-name >>
name: Searching for project-level API tokens
command: <<include(scripts/projects/search-api-tokens.sh)>>
- when:
condition: << parameters.search-projects-ssh-keys >>
steps:
- run:
environment:
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_VCS: << parameters.vcs >>
PARAM_ORG_NAME: << parameters.org-name >>
name: Searching for SSH keys in projects
command: <<include(scripts/projects/search-ssh-keys.sh)>>
- when:
condition: << parameters.search-contexts-env-vars >>
steps:
- run:
environment:
PARAM_CIRCLE_TOKEN: << parameters.circle-token >>
PARAM_VCS: << parameters.vcs >>
PARAM_ORG_NAME: << parameters.org-name >>
name: Searching for environment variables in organization contexts
command: <<include(scripts/contexts/search-env-vars.sh)>>
- store_artifacts:
path: all-projects-report.json
destination: projects-secrets-report.json
- store_artifacts:
path: all-contexts-report.json
destination: contexts-secrets-report.json
#!/bin/bash
if [ -s projects-array-like-list.txt ]; then
echo -e "\n\n######################## SEARCHING FOR SSH KEYS ########################\n" | tee -a projects-ssh-keys.log
while read -r PROJECT
#### Search for Checkout SSH keys
do
PROJECT_NAME="$(echo "$PROJECT" | cut -d ';' -f1)"
PROJECT_SLUG="$(echo "$PROJECT" | cut -d ';' -f2)"
#### This is only necessary for the case of GitLab organizations, where the value of PROJECT_NAME can contain spaces.
#### Using the same approach for all VCS allows us to have unique 'search' scripts, rather than distinct VCS-specific ones.
PROJECT_FILENAME="$(echo "$PROJECT_NAME" | sed -r 's/ +/-spaces-/')"
###########################################################################################################################
curl -s -G "https://circleci.com/api/v2/project/$PROJECT_SLUG/checkout-key" -H "circle-token: ${!PARAM_CIRCLE_TOKEN}" > project-checkout-keys-API-response.json
if [[ $(jq '.items|length' project-checkout-keys-API-response.json) -gt 0 ]]; then
jq '.items' project-checkout-keys-API-response.json > checkout-keys-"$PROJECT_FILENAME".json
#### The below 'echo' triggers the 'SC2005' ShellCheck error but it's the only way I found to use the same file as both input and output of the `jq` command.
echo "$(jq --arg PROJECT_NAME "$PROJECT_NAME" '(.projects[] | select(.name == "'"$PROJECT_NAME"'")) .checkout_keys |= . + input' all-projects-report.json checkout-keys-"$PROJECT_FILENAME".json)" > all-projects-report.json
echo -e "Project '$PROJECT_NAME' has $(jq '.|length' checkout-keys-"$PROJECT_FILENAME".json) Checkout SSH key(s)" | tee -a projects-ssh-keys.log
else
echo -e "There are no Checkout SSH keys in project '$PROJECT_NAME'."
#### The below 'echo' triggers the 'SC2005' ShellCheck error but it's the only way I found to use the same file as both input and output of the `jq` command.
echo "$(jq --arg PROJECT "$PROJECT_NAME" '(.projects[] | select(.name == "'"$PROJECT_NAME"'")) .checkout_keys |= .' all-projects-report.json)" > all-projects-report.json
fi
#### Search for Additional SSH keys
#### Using the files 'project-settings-"$PROJECT_FILENAME".json' saved during execution of 'get-projects.sh'.
if [[ $(jq '.ssh_keys | length' project-settings-"$PROJECT_FILENAME".json) -gt 0 ]]; then
jq '.ssh_keys' project-settings-"$PROJECT_FILENAME".json > extra-ssh-"$PROJECT_FILENAME".json
#### The below 'echo' triggers the 'SC2005' ShellCheck error but it's the only way I found to use the same file as both input and output of the `jq` command.
echo "$(jq --arg PROJECT_NAME "$PROJECT_NAME" '(.projects[] | select(.name == "'"$PROJECT_NAME"'")) .additional_ssh |= . + input' all-projects-report.json extra-ssh-"$PROJECT_FILENAME".json)" > all-projects-report.json
echo -e "Project '$PROJECT_NAME' has $(jq '. | length' extra-ssh-"$PROJECT_FILENAME".json) Additional SSH key(s)." | tee -a projects-ssh-keys.log
else
echo -e "There are no Additional SSH keys in project '$PROJECT_NAME'." | tee -a projects-ssh-keys.log
#### The below 'echo' triggers the 'SC2005' ShellCheck error but it's the only way I found to use the same file as both input and output of the `jq` command.
echo "$(jq --arg PROJECT "$PROJECT_NAME" '(.projects[] | select(.name == "'"$PROJECT_NAME"'")) .additional_ssh |= .' all-projects-report.json)" > all-projects-report.json
fi
echo -e "View in the CircleCI UI --> https://app.circleci.com/settings/project/$PROJECT_SLUG/ssh \n\n" | tee -a projects-ssh-keys.log
done < projects-array-like-list.txt
#### Clean-up
rm -f project-checkout-keys-API-response.json
#### Keeping the files 'project-settings-"$PROJECT_FILENAME".json' to use them in later search for third-party integrations secrets.
#### Keeping the files 'checkout-keys-"$PROJECT_FILENAME".json' and 'extra-ssh-"$PROJECT_FILENAME".json' to use them in 'delete-ssh-keys' command
else
echo "No projects to search in." | tee -a projects-env-vars.log
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment