Recovering from Accidentally Pushing Sensitive Information to a Remote Git Repository
Tags: git, github, beginners, security
Published: 2023-04-24 13:49:38

I'm Atsushi Suzuki, and I'm a software developer at a startup in Tokyo. I'm interested in working abroad in the future, so I've decided to start sharing my thoughts and experiences on dev.to, both to practice my English and to connect with the global community. 

While there may be over 100 similar articles out there, I've put together a fresh recap specifically for beginner engineers.

## Situation
For illustration purposes, consider the following situation.
- A file in the `.serverless` subdirectory generated when deploying the Serverless Framework contained API key information.
- The `.serverless` subdirectory should not be Git-managed, but was accidentally pushed to a remote repository.
- The project uses git-flow for branch management, and there are multiple feature branches.

## Step 1: Remove the relevant directory from Git management
Generate a feature branch from the latest develop branch for git-flow.
In this feature branch, delete the `.serverless` directory.

```bash
git rm -r --cached .serverless
```

Add `.serverless` to the `.gitignore` file so that future commits will ignore this directory.

```bash
echo ".serverless" >> .gitignore
```

After committing the changes, remote push and merge them into develop.
Merge the latest develop into the feature branch you are working on, and remove `.serverless` from Git management as well.
*If you forget to do this, when you merge feature into the latest develop, `.serverless` and `.gitignore` will be reverted.

Now you can follow the git-flow and merge in the order develop -> staging -> main, and `.serverless` will be removed from the active branch.

## Step 2: Install git-secrets
Have all development members install `git-secrets`.
`git-secrets` allows us to detect and block commits containing sensitive information before they are pushed.
*Originally, `git-secrets` is introduced when a developer clones a repository.

First, instruct all development members to install `git-secrets`.
The installation procedure varies by platform.

```bash
# macOS
brew install git-secrets

# Linux
git clone https://github.com/awslabs/git-secrets.git
cd git-secrets
make install
```

Each member activates `git-secrets` by running the following command in the local repository.

```bash
cd <your_repository>
git secrets --install
git secrets --register-aws
```

Normally, `git-secrets` is activated as a global setting during installation.
Therefore, there is no need to rerun `git-secrets --install` and `git secrets --register-aws` when creating a new feature branch.

## Step 3: Delete inactive branches in the remote repository
Don't forget to delete branches that have been left uselessly in remote branches.

## Step 4: Remove confidential information from past commit history
Use `git filter-branch` to rewrite previous commits that contain sensitive information.

```bash
git filter-branch --force --index-filter 'git rm -r --cached --ignore-unmatch .serverless' --prune-empty --tag-name-filter cat -- --all
```

Remove the `.serverless` directory from all previous commits that contain it.
It does not affect other developers' repositories and must be force-pushed to a remote repository.

```bash
git push origin --force --all
git push origin --force --tags
```

It seems that tools like BFG Repo-Cleaner can do the same.