Talisman

Talisman is an open-source tool written in Go by the technology consultancy ThoughtWorks (home of the well-known Martin Fowler).
It's essentially a tool that can hook into the git version control system and attempt to stop you from pushing secrets into your public or private git repositories. As it runs as at the time you do a git push
, it's completely agnostic of the repository manager you're using.
For the purposes of this experiment, we're just going to run Talisman on a single project. It can also be run as a git hook that gets run against every git repository on your machine.
Installing Talisman
Talisman is availble on GitHub, so installation is as easy as downloading its installer script and then making it executable:
curl https://thoughtworks.github.io/talisman/install.sh > ~/install-talisman.sh
chmod +x ~/install-talisman.sh
Then, in a directory where git init
has already been run:
➜ talisman git:(master) ~/install-talisman.sh
Downloading and verifying binary...
Talisman successfully installed to '.git/hooks/pre-push'.
Testing Talisman
Ok, on to the fun part! Can Talisman really stop you accidently putting secrets into the cloud?
A simple base64-encoded variable
Test 1 was a simple Python file that contained a single, relatively long, base64-encoded variable:
# "I'm a secret, please don't tell anyone about me"
my_secret = 'SSdtIGEgc2VjcmV0LCBwbGVhc2UgZG9uJ3QgdGVsbCBhbnlvbmUgYWJvdXQgbWU='
Upon trying to push, I got the message:
So far, so good. On to the next one...
A short base64-encoded variable
Talisman can detect nice, long, base64-encoded strings via its aggressive detector, but how does it do against everyone's favourite password?
# "password1"
my_secret = 'cGFzc3dvcmQx'
Good stuff, it's still working:
A hexed SHA256 variable
This time, I've taken "password1", SHA256ed it and expressed it as a hex value:
# "password1" SHA256ed and expressed as a hex value
my_secret = '0b14d501a594442a01c6859541bcb3e8164d183d32937b851835442f69d5c94e'
Again, it spotted it:
A private key
For this experiment, I've created an RSA keypair using the command:
ssh-keygen -b 4096 -t rsa -f my_key
This creates two different files: my_key and my_key.pub
my_key
:
-----BEGIN RSA PRIVATE KEY-----
MIIJKgIBAAKCAgEA2/jpcmopwncmc/5FVet88RofV6vYyF48zixcUDe3TgmOCuh2
zhUFdQT+fMpfkVdzkGYrdWfdfdasdfafweBcJQCXcneBO/jZM8on/8KfHzNKiqJt
...
-----END RSA PRIVATE KEY-----
my_key.pub
:
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDb8rFnkz2SvDhD/kVV63zxGh9Xq9jIXjzOLFxQN7dOCY4K6HbOFQV1BP58yl+RV3OQZit1bhZdEqR1q6PB4FwlAJdyd4E7+Nkzyif/wp8fM0qKom0OpzE4fBWg934mD15aGrtdZwnLdKq44snbI3ChSA+aRDBFCXH7ft+oeL8UxiasxNIGHf0NKjYZpuU+eIEgzLGk12P...
As expected, Talisman caught them both:
No funny business
This time, no base64ing, just a plain-old, hardcoded password:
username = 'stephenfalken'
password = 'joshua'
And again, Talisman caught it:
So, it did well! What if I really, really, really want to put a secret in the repository manager?
Sometimes, you really do want to put something that looks like a secret into a git repo:
my_json = 'ew0KICAgJ2hlbGxvJzogJ3dvcmxkJw0KfQ=='
Ouch, that really wasn't what I wanted.
In these cases, you can force Talisman to ignore a file by building a .talismanignore
file:
echo 'this_is_fine.py' >> .talismanignore
But, the downside of this is where you ignore the file due to a secret-looking value and it ends up containing a secret too. This is pretty bad practice though and possibly breaches separation of concerns.
Conclusion
Talisman is really rather good, providing protection against loading secrets into a git repo. But, there are some potential downsides that need to be understood:
- As it acts as a pre-push control, it needs to be installed by the developer on to their own machine. This almost certainly makes governance hard as you may not be able to demand that developers install it on their machines. You probably want to look into gitrob or repo-supervisor as additional controls. The issue with both of these is that they work post-push, meaning that the damage has already been done.
- There doesn't seem to be anyway of informing Talisman to ignore a single-line in a file. Instead, you ignore whole files, which could lead to some trouble.
- If you were running this against a large project, it could potentially raise quite a few false positives.
- There are also potential situations where there could be false negatives and Talisman misses a value. I didn't encounter this in these (admittedly non-complex) scenarios though.
All-in-all a useful tool to add to your armoury...just don't expect it to replace common sense!