Rash
Rash

Reputation: 8197

Hide sensitive information from git changes

Is there a way to instruct git to hide my sensitive information. E.g.

credentials.php (in local repository).

Line1: $dbname = 'xyz';
Line2: $dbpassword = 'password';

credentials.php (in github repository and history).

Line1: $dbname = 'xyz';
Line2: $dbpassword = 'xxxxxxxx';

So git automatically hides the information with 'x'.

If not via git, how should I do it? I try and keep all my credentials in one place, but it becomes hard when you are using 3rd party libraries and they keep credentials all over the place.

Sidenote: Its not possible for me to NOT track the credentials.php file at all because it may also contain some other logic which needs to be version controlled.

Note: I found this post with a similar question. But the answer is not satisfactory for me. Is there an automated way to do what is told in the "accepted answer" ?

Upvotes: 1

Views: 1535

Answers (3)

Rash
Rash

Reputation: 8197

I finally ended up using a variation of poke's answer. Please redirect all votes to his answer.

I used env variables to solve my problem. Laravel (which I use) uses phpdotenv framework to handle env variables.

In all my configuration files, I write env('USERNAME'), env('PASSWORD'), etc variables and I also define a .env file in my project's root directory.

Sample content of .env file

USERNAME=rash
PASSWORD=pass
... Other key-value pairs.

At runtime, in configuration files, all these keys are replaced by the values defined in this file.

I also define a .env.example file where I keep my sample data.

Sample content of .env.example file

USERNAME=PUT_USERNAME_HERE
PASSWORD=PUT_PASSWORD_HERE
...

Then I version-control this file. Any user who uses my project, makes a copy of this file, replaces all values with their own, and renames that file to .env. The project then runs smoothly.

This solves my problem because:

  1. There is no sensitive information in my configuration files. Each conf files have values such as env('USERNAME'). The actual sensitive info is in the .env file. Hence I can version-control my conf files.
  2. Since I also pass .env.example file, the users at other end know exactly what needs to be put in the appropriate fields.
  3. It does not matter how many conf files I have. I may have 100 files and still this solution works flawlessly.

Upvotes: 0

poke
poke

Reputation: 387557

A common solution to this is to have a file credentials.example.php which you add to the repository and which does not contain any real credentials but just the general format that is used to specify them, to show others on how to create the real credentials.php. Because that file is then ignored via the .gitignore file so it is not added to the repository. So you can place your actual credentials there for both development or even deployment.

The downside is that you may need to synchronize format changes into both files when the file changes. But you should try to keep such a credentials (or config) file really concise, so it shouldn’t change too often.

Another solution would be to have two configuration files, like credentials.default.php and credentials.user.php where the former is checked into the repository and the latter is ignored again. The program then attempts to load both (in order), so you can overwrite things in the user file but do not need to respecify everything. So if you have many configurations, which defaults are sane (they should), then you probably only need to overwrite a few important configurations (like credentials), so you can just specify those in the user file.

Upvotes: 2

David Deutsch
David Deutsch

Reputation: 19025

What you probably are looking for is a filter. You set these up in your .gitattributes file to run one substitution upon adding a file to the staging area, and another substitution upon checkout:

enter image description here

The image is from the .gitattributes section of the Git book, which has details on how to create such a filter.

Upvotes: 2

Related Questions