13

I can't seem to mask a variable on Gitlab CI -

I'm trying to upload a ssh private key and no matter what I do it refuses to mask it.

That is I'm trying to store a private key on Gitlab for use by the Gitlab runner that my production servers have public keys for. I'm not asking about how to introduce it to the runner during the build as described in the answer to this question

I'm using a ed25519 key so the characters aren't all base 64 to start with.

So after generating the key

$ cat gitlab
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmU....etc etc
-----END OPENSSH PRIVATE KEY-----

I piped it to base64

$ cat gitlab|base64

No joy.

Gitlab also seemed to be introducing newlines into the pasted text/variable field

So I did

$ cat gitlab|base64|tr -d '\r'

and even

$ cat gitlab|base64|tr -d '\r'|xclip

I found this guy so what the hell

$ cat gitlab|base64|base32|tr -d '\r'|xclip

all with no joy.

Anyone got this working?

1
  • This is a bad idea. See why. Commented Jan 15 at 9:58

3 Answers 3

19

For me cat gitlab | base64 -w0 works.

In you absolutely want to use tr, you'd use tr -d '\n' instead.

EDIT: of course you also need to unbase64 it when using it.

Here's an example which should clear the confusion:

$ echo secret > gitlab
$ MY_SECRET_ENCODED="$(cat gitlab | base64 -w0)"

$ echo $MY_SECRET_ENCODED
c2VjcmV0Cg==

$ MY_SECRET_DECODED = "$(echo MY_SECRET_ENCODED | base64 -d)"
$ echo $MY_SECRET_DECODED
secret

Here MY_SECRET_ENCODED is your variable in the interface, MY_SECRET_DECODED is what you use in your script.

Sign up to request clarification or add additional context in comments.

3 Comments

I don't get why gitlab enforces the use of base64 encoded variables to be able to mask them if we need to decode them afterwards. base64 is not an encryption... Thanks @PierreBrasseau anyway. Did the trick for me.
Sorry but the output of echo $MY_SECRET_DECODED will still appear as plain text in the gitlab runner logs right?
@IMB: Yes. You need to be careful.
5
+50

GitLab requires a CI variable to be masked (replaced with [MASKED] in the CI job log) in order to make it hidden (not retrievable by any GitLab user through GitLab UI).

Other answers here and many other pages suggest encoding the SSH private key with base64 or similar but then what’s the point of making the CI variable masked?! ⚠️ GitLab won’t be able to effectively mask the private key in the CI job log because it doesn’t know about its real content!

Instead do this:

  1. strip begin/end markers from private key file
  2. join all data lines into a single string
  3. add begin/end markers in CI pipeline to recreate valid format
  4. remove group/world read permissions on key file for ssh not to complain about file permissions
$ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn
NhAAAAAwEAAQAAAYEAmdCdB4vCFxSpFayYLjfu1vRBCAhOMjptCbXMHE84Rz0oRN5GVJnw
...
-----END OPENSSH PRIVATE KEY-----
$ 
$ perl -ne 'chomp; /---/ or print; END{print "\n"}' id_rsa
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcnNhAAAAAwEAAQAAAYEAm...

Then you can create a masked and hidden CI variable in GitLab settings:

screenshot of variable DEPLOY_SSH_PRIVATE_KEY GitLab CI settings

This format will not be accepted as identity file by OpenSSH. Do this in the .gitlab-ci.yml to create a valid identity file:

deploy:
  image: kroniak/ssh-client
  script:
    - echo "-----BEGIN OPENSSH PRIVATE KEY-----" > id_rsa
    - echo "$DEPLOY_SSH_PRIVATE_KEY"            >> id_rsa
    - echo "-----END OPENSSH PRIVATE KEY-----"  >> id_rsa
    - chmod -v 400 id_rsa

    - ssh -i id_rsa ...

3 Comments

Thank you! I was about to comment that on the question...
Could have been so good. But it is substituted for [MASKED] when using echo, even if the echo outputs to a file echo "$SSH_PRIVATE_KEY_PLAIN" > /tmp/SSH_PRIVATE_KEY_PLAIN && cat /tmp/SSH_PRIVATE_KEY_PLAIN --> [MASKED]
@Jos: file operations are not masked. Masking affects only the job log. In your example the key is written to the file in cleartext but the output of cat is masked then. Use something like base64 /tmp/SSH_PRIVATE_KEY_PLAIN (copy & paste and decode locally with base64 --decode) or rev /tmp/SSH_PRIVATE_KEY_PLAIN (characters per line in opposite order) to check the file contents while bypassing masking.
-1

Here's a link - not pretty but effective, that masks the multi-string variables.

Result of echo job screen of masked SSH-key:

37 -----BEGIN OPENSSH PRIVATE KEY-----
38 [MASKED]
39 [MASKED]
40 [MASKED]
41 [MASKED]
42 [MASKED]
43 [MASKED]
44 -----END OPENSSH PRIVATE KEY-----

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.