Storing a SSH Key in a Gitlab Environment Variable
SSH Keys
A simple ssh key, generated by ssh-keygen is a plain text file that looks like this:
$ ssh-keygen -f id_rsa_temp
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in id_rsa_temp
Your public key has been saved in id_rsa_temp.pub
The key fingerprint is:
SHA256:mW990xW8SSqNTdUxdlshUABmLp38js0zUY3tDFduIhI daniel@Daniel-Netbook
The key's randomart image is:
+---[RSA 3072]----+
| +Eo+o *B|
| * .. O.B|
| . =. .=.Oo|
| .o..*.Bo+|
| S = + =.|
| .=.o ..|
| .o*. o .|
| . o. . |
| |
+----[SHA256]-----+
$ cat id_rsa_temp
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
This key, as is, can be used as an environment variable, however, it is a secret so it should be masked. If you try to mask it, it will not work. That's pretty ridiculous but that's what it is.
Altering the key so it can be masked
In order to make it work, it can be base64 encoded:
$ cat id_rsa_temp | base64 -w0
LS0tLS1CRUdJTiBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0KYjNCbGJuTnphQzFyWlhrdGRqRUFBQUFBQkc1dmJtVUFBQUFFYm05dVpRQUFBQUFBQUFBQkFBQUJsd0FBQUFkemMyZ3RjbgpOaEFBQUFBd0VBQVFBQUFZRUEyUnpqT2hMcW10elp4a1JaTGRzQklqUHA4MC9hRmFsVDE4MzFTQzVoVTJTZXliZXNCUkh1CjRMMlRxVUo0dG94SjJtNG5aOGh3RThFVTJXSVRyZDJhT2ZZS2wxa0xMQzVqVWp6OGgydC9LemtaTVZSOWl3MjRoUDFIczIKM0M2UVBkSFRoLzVIOEU4alJvVFBzTmVuMFhVOUJoWG1DV240YXEwc2U3MnZhT2hud0p4VEZ5Qm1PMkd1a2ZDSnpibXNyQQp5S1lQSUFnSkNGdEE3cmFzUUIveWdmRktzRml4T0JRdzdwL1RjUllCclJuSWIrakYvVndHaEVZMTE0ZXAvUkE4MlZBZ29WCmhxYXBZQWo1NGlkNUc3dFNrVEJiTmxINVBzMVVtZFI2Y0Q0V2ZIb3h1dVEwTUNxclIzclBEMFZaSkRxOWxzc2lKSUdjb00KZ2JWdnV1SXkzWHJjcmFWVEU4djdyQkZMUFBxTXRkSFZBaytTTUJSd0YvMjJWcldsK21OZHp3MjJZeDVPdGpUSFdjU1lZUwpBNWEvRnAzbng0a3d6N2RSZFZyYzZHcjQxc1Ftb3VMQ2czOVUxNE14T1B0UUh5bHNra056NWExcGZOZng5QUc3Y21nN0VnCndGZjdXNVdtVWUrNzJvTnVURWFTVWJoazJhWnhvSUgxS29jZ2tSTkpBQUFGa0hZQlgraDJBVi9vQUFBQUIzTnphQzF5YzIKRUFBQUdCQU5rYzR6b1M2cHJjMmNaRVdTM2JBU0l6NmZOUDJoV3BVOWZOOVVndVlWTmtuc20zckFVUjd1QzlrNmxDZUxhTQpTZHB1SjJmSWNCUEJGTmxpRTYzZG1qbjJDcGRaQ3l3dVkxSTgvSWRyZnlzNUdURlVmWXNOdUlUOVI3TnR3dWtEM1IwNGYrClIvQlBJMGFFejdEWHA5RjFQUVlWNWdscCtHcXRMSHU5cjJqb1o4Q2NVeGNnWmp0aHJwSHdpYzI1ckt3TWltRHlBSUNRaGIKUU82MnJFQWY4b0h4U3JCWXNUZ1VNTzZmMDNFV0FhMFp5Ry9veGYxY0JvUkdOZGVIcWYwUVBObFFJS0ZZYW1xV0FJK2VJbgplUnU3VXBFd1d6WlIrVDdOVkpuVWVuQStGbng2TWJya05EQXFxMGQ2enc5RldTUTZ2WmJMSWlTQm5LRElHMWI3cmlNdDE2CjNLMmxVeFBMKzZ3UlN6ejZqTFhSMVFKUGtqQVVjQmY5dGxhMXBmcGpYYzhOdG1NZVRyWTB4MW5FbUdFZ09XdnhhZDU4ZUoKTU0rM1VYVmEzT2hxK05iRUpxTGl3b04vVk5lRE1UajdVQjhwYkpKRGMrV3RhWHpYOGZRQnUzSm9PeElNQlgrMXVWcGxIdgp1OXFEYmt4R2tsRzRaTm1tY2FDQjlTcUhJSkVUU1FBQUFBTUJBQUVBQUFHQkFKajBDdmlzdnU2ZXpDVXJuWS82aTgvbXR0CmljMXMwUDMydFhRNGU0ZFFSbERLQ2JidXFiZWFpR3BmSkdTL2grMk1DemZidFZyKytheE85b2N1aTRCNkR4dndCazBNUXQKWWZkYjA2UXJqUW1NVGowOGdyMWx5eXFWck4reFlmRDZzZG1XSmpONWNLaVpWeWwwYkVod3UvQm1DMUtMeFZGWmRCck9iMworUTExUFRLcWJyY0tNanQvVTVhbzJNeEFGRytZM2h2eUlYeHhWR0JIYW41cTIrVkFCTFZ3enBUdUJ0Q1JQek1PaW9Va0g2CnVnUnMvcDdCS0M0anNHYkl3bTd2OGtIVUtYaW5Ub1FDSno3N2Y5Q2tRZHVKRTdsbTQ4OWUrZW1YYnBVSmhhOEl6Yzk2RFQKcERXWXVLUWozQmMxMk8xY2dsUjhvNFhxQmdna3lmQVBZQkZQWjRIRkRCUWsrQnl5V1JadjNjY1ZYY24vNytTd2dZdXdISAo1R3p1NXkrSVRqZUtGdktrc2JvaFFQRitnNVo1VlgrUkhaREdIMWE5V0hTMVc0VDNzMnI1ZlpienM1R1NUMExOUlNyYVFYCk5PMWtkMmxDR0daOW9Ccnl4aVg3cS9vM0xpYnJNWHBaNjlsdUZJcG9XQ0FFT0xYdS9aa2ZEV0lkRTJ0TStVMUZLZklRQUEKQU1FQWxiYk9zRi91SHJRdEdDdkxCakJxVjVhVUI0bFJBeThyU2VYck8zTU5Va0FET0NXSmdBNXF6a1RNTStkdGJlYkx3agozZE5YNEhPL2RPRFlkSXg4ZllvSjJJWER6T2Q5OFBOOEdnUlFBMTBESmFqVkwzQU5lMnRySGh1dUlNUHU4Vjdpd3FwQlQxCkxCTkZKdkZHdXZzNGphSWxyak9XUnBud2RyeFVCc3ZxZnBKL1VLZ2k5dXJPZzBlSWhFSHRVVlVhRmtENWJscVdtNmNNRnoKajNtQzg3ZW9pTTJyWGNnTUZhM3R3eThoLy8zVEJDVzJ5ZHdpSXdoK251NlBzMUphL21BQUFBd1FEMHozZzZKVSttcWFlSAoxcDAyMWNKTFg3dlZiRnZhS2VlSGFORjVjbmVYSTRFb1hCMnpGUWZ5Q1VrRGpTb1lXTnpOdmMvV1gyN1hsN1VyZllRZE1qCkQ3N0k3N0Z0VzBLbS9PVmYvN0ZueGxIVllqRVNIeG5VcUtrUWFWMEUvRnF0VWkvOFoxVFNKTUY2RFFnUWFQbDR5amY3WVoKaFlVc1NBRGQwVmg3MWhVckNXOGF2ckhjd2pKTndDbmQxVU9LMHovaW44Y1pNWG8yeUdFeVRXYVAvcnhFQWVoTzEwbHdXaQpzcVJjV2piZURFU3JJdDBBZHN1UUJXa2g1bjNCekdQQ1VBQUFEQkFPTUpVLzh0SHZCU1drbk5SWUtKNXhLS1k4NUQrQU8zClEwSUJROXQzdVZJL2wwTzcrcGxLdkVLNDdGNXRRK2d6UmVTcXU4b3BTYy80RC9WMHE3T3RmQlFIYzVBcnFteitSZEZPOG0KbXIvL3FTMFZYWUQzeURJTllxbDU1SFBxN0wzVHJpaDhpclhoUmdPWVJtRUJtRmdPV2pwMmUvbWtyOGtFeFh6dnZRWFMvYQppZmRqN0NhNzh4dFZnUWlFeFBGQ044RGFyN013ZW1DUjFqY051M0ZhYUoyZnRXbTgrU3FjNmtRekhnRFU2ZWlwNi96MWJmCkpQbi9xaUg3ZGhob28vVlFBQUFCVmtZVzVwWld4QVJHRnVhV1ZzTFU1bGRHSnZiMnNCQWdNRQotLS0tLUVORCBPUEVOU1NIIFBSSVZBVEUgS0VZLS0tLS0K
The -w0 means to discard any wrap of the output, giving it one line which is a requirement for masking variables.
Using the key in a script
Then when wanting to use this variable in a shell script, it can be decoded:
$ echo $SSH_KEY_VARIABLE | base64 --decode
-----BEGIN OPENSSH PRIVATE KEY-----
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
-----END OPENSSH PRIVATE KEY-----
All together :
$ MY_VAR=`cat id_rsa_temp | base64 -w0`; echo $MY_VAR | base64 --decode