Answers: <p>This is not answering only the question but also a bit more (I put this here for reference):<br>
  I found out a decent way to tackle this and some complications coming afterwards... (after hours and hours of fiddling) - e.g. to execute the script in an SSH session:</p>
  
  <pre class="lang-yaml prettyprint-override"><code>deploy job:
    variables:
      # the variables could come from anywhere (e.g. GitLab Settings - environment variables)
      SSH_DIR: '/srv/app/'
      SCRIPT_CMD: |
        echo "Double quotes are safe"
        echo 'Single quotes are safe'
        echo "Code executions are safe -" `whoami`@`hostname` $$(date)
        # the '$$' is needed as otherwise GitLab itself tries variable substitution
  
    # Here's the magic to get the code from the GitLab variable into a bash variable and then even executed on an SSH session
    script:
      # Put gitlab variable into shell variable to improve quote handling
      - CMD=$SCRIPT_CMD
      # Print for debugging
      - echo -e "Executing:\n$CMD"
      - CMD="set -e; cd $SSH_DIR; $CMD" # 'set -e' = stop on error
      # redirect variable to stdin of ssh bash (the -x causes bash to print each command)
      - ssh -p $SSH_PORT $USERNAME@$SSH_HOST "bash -x" &lt;&lt;&lt; "$CMD"
  
  </code></pre>
  
  <p>More detailed example <a href="https://gist.github.com/TeNNoX/cd8d4b901775f379d74287fa85f924c3" rel="nofollow noreferrer">here</a>.</p>
  
Answers: CC BY-SA 4.0
Answers: 2019-10-03T23:29:41.693Z
Answers: 2019-10-03T23:44:18.603Z
Answers: 2019-10-03T23:44:18.603Z
Answers: TeNNoX
Answers: <p>One should use protected variables in my opinion. One could configure them in the pipeline settings and subsequently call them inside the pipeline. Using base64 formats should be avoided as these could be easily decrypted.</p>
  
  <p><a href="https://docs.gitlab.com/ee/ci/variables/" rel="nofollow noreferrer">https://docs.gitlab.com/ee/ci/variables/</a></p>
  
Answers: CC BY-SA 4.0
Answers: 2019-07-18T09:12:22.763Z
Answers: It's a common misconception. Protected env vars in GitLab are not what you think, the main purpose of them is that they are passed only to pipelines of the Protected branches. They are not otherwise protected. There is also a Masked option for env vars which is probably more what you mean, but still it doesn't work all the time - there's a limitation on value, again because it's internally processed by GitLab which it should really do.
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T20:22:19.993Z
Answers: 2019-07-17T20:22:19.993Z
Answers: 030
Answers: <p>Surprisingly indeed GitLab works weirdly with the env vars.<br>
  It evaluates them internally, though it shouldn't in my view.</p>
  
  <p>Value set as (in project Settings > CI/CD > Variables): <code>'aaa$bbb*%'</code><br>
  becomes <code>'aaa*%'</code>
  (with single quotes left!)</p>
  
  <p>Couple of of proof links:</p>
  
  <ul>
  <li><a href="https://gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865" rel="nofollow noreferrer">https://gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865</a></li>
  <li><a href="https://gitlab.com/gitlab-org/gitlab-ce/issues/27436" rel="nofollow noreferrer">https://gitlab.com/gitlab-org/gitlab-ce/issues/27436</a></li>
  </ul>
  
  <h2>Workarounds:</h2>
  
  <p>1)
  You can duplicate dollar ($) sign, i.e.: <code>aaa$$bbb*%</code><br>
  (as mentioned on the first link above).</p>
  
  <p>2)
  Use base64 to encode and decode the value.</p>
  
  <p>Do this first:</p>
  
  <pre><code>$ echo 'aaa$bbb*%' | base64
  YWFhJGJiYiolCg==
  </code></pre>
  
  <p>Then store this value in project Variables.</p>
  
  <p>And then in your script decode it:</p>
  
  <pre><code>PASS=$(echo ${sensitive_var} | base64 -D)
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2019-07-16T18:58:22.483Z
Answers: Hi Ivan, thanks for the fast reply.
  As explained in the problem I already tried enclosing the value in single quotes.
  It may not be related to Gitlab, but the original value is saved as env var in Gitlab, and then is passed in a job to the deployment script. 
  Also, the script is on a docker image, so it might be possible that I can't access Gitlab's environment from there.
Answers: JJ Yong
Answers: CC BY-SA 4.0
Answers: 2019-07-17T07:40:04.983Z
Answers: Where did you enclose the value in single quotes? In CI/CD Settings?
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T08:08:11.627Z
Answers: Yes, in the env vars of CI/CD settings
Answers: JJ Yong
Answers: CC BY-SA 4.0
Answers: 2019-07-17T13:47:23.243Z
Answers: You are right, I've just tested it... funnily it didn't get rid of single-quotes, how you would expect it in bash case... lemme think...
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T13:50:10.743Z
Answers: See this: https://gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T13:52:11.833Z
Answers: And this: https://gitlab.com/gitlab-org/gitlab-ce/issues/27436
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T13:52:43.237Z
Answers: It's really frustrating... GitLab being awesome has many such weird bugs or missing basic features... it makes me cry sometimes. By the way double-dollar workaround seems to help.
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T13:53:45.783Z
Answers: Another idea to try - is to use `base64` to encode value before storing it, and decode in your script.
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-17T16:13:25.047Z
Answers: Wow thanks, I thought about the base64 encoding but was thinking in the code, not in the script. I will have to see which option is more maintainable in the long run. Thank you very much
Answers: JJ Yong
Answers: CC BY-SA 4.0
Answers: 2019-07-17T16:50:42.197Z
Answers: No problem. Good luck with your project.
Answers: Ivan
Answers: CC BY-SA 4.0
Answers: 2019-07-16T17:00:49.880Z
Answers: 2019-07-17T17:06:55.167Z
Answers: 2019-07-17T17:06:55.167Z
Answers: Ivan
Body: <p>I have the following situation:
  I'm storing sensitive data in Gitlab's environment and then passing these variables to a deployment script in bash.</p>
  
  <p>Gitlab's env var:</p>
  
  <pre><code>Key: sensitive_var
  Value: aaa$bbb*%
  </code></pre>
  
  <p>Then in the <code>.gitlab-ci.yml</code> file the env vars are passed to the deployment script as follows:</p>
  
  <pre><code>.deploy:
    script:
      - deploy.sh PASS=${sensitive_var} 
  </code></pre>
  
  <p>The deployment script parses the arguments as follows:</p>
  
  <pre><code>for arg; do
    TEMP_VAR=$(echo ${arg} | sed -e 's?=? ?')
  done
  </code></pre>
  
  <p>The problem is that when we check the output of the <code>deploy.sh</code> script the variable's value gets expanded resulting in <code>aaa*%</code>.</p>
  
  <p>Solutions tried so far:  </p>
  
  <ul>
  <li>Storing the value in Gitlab's environment with single quotes <code>'</code> but then the value was <code>'aaa*%'</code>.</li>
  <li>Passing the environment variable with double quotes:</li>
  </ul>
  
  <pre><code>.deploy:
    script:
      - deploy.sh PASS="${sensitive_var}" 
  </code></pre>
  
  <pre><code>.deploy:
    script:
      - deploy.sh PASS="$sensitive_var" 
  </code></pre>
  
  <p>But the result was the same: <code>aaa*%</code>.  </p>
  
  <ul>
  <li>Combination of the above solutions didn't work either.</li>
  </ul>
  
  <p>Why is this happening, and how I can fix it?</p>
  
Tags: <gitlab-ci-runner><bash><yaml><environment-variables>
Title: How to pass Gitlab env var with sensitive characters to bash script?
UserDisplayName: JJ Yong
ThreadText: # How to pass Gitlab env var with sensitive characters to bash script?
  
  (Asked by: username_0 on 2019-07-16)
  
  I have the following situation:
  I'm storing sensitive data in Gitlab's environment and then passing these variables to a deployment script in bash.
  
  Gitlab's env var:
  
  ```
  Key: sensitive_var
  Value: aaa$bbb*%
  
  ```
  
  Then in the `.gitlab-ci.yml` file the env vars are passed to the deployment script as follows:
  
  ```
  .deploy:
    script:
      - deploy.sh PASS=${sensitive_var} 
  
  ```
  
  The deployment script parses the arguments as follows:
  
  ```
  for arg; do
    TEMP_VAR=$(echo ${arg} | sed -e 's?=? ?')
  done
  
  ```
  
  The problem is that when we check the output of the `deploy.sh` script the variable's value gets expanded resulting in `aaa*%`.
  
  Solutions tried so far:
  
  * Storing the value in Gitlab's environment with single quotes `'` but then the value was `'aaa*%'`.
  * Passing the environment variable with double quotes:
  
  ```
  .deploy:
    script:
      - deploy.sh PASS="${sensitive_var}" 
  
  ```
  
  ```
  .deploy:
    script:
      - deploy.sh PASS="$sensitive_var" 
  
  ```
  
  But the result was the same: `aaa*%`.
  
  * Combination of the above solutions didn't work either.
  
  Why is this happening, and how I can fix it?
  
  **Tags:** gitlab-ci-runner, bash, yaml, environment-variables
  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_3 on 2019-07-16. Score: 4 | Accepted answer
  
  Surprisingly indeed GitLab works weirdly with the env vars.  
  It evaluates them internally, though it shouldn't in my view.
  
  Value set as (in project Settings > CI/CD > Variables): `'aaa$bbb*%'`  
  becomes `'aaa*%'`
  (with single quotes left!)
  
  Couple of of proof links:
  
  * <https://gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865>
  * <https://gitlab.com/gitlab-org/gitlab-ce/issues/27436>
  
  ## Workarounds:
  
  1)
  You can duplicate dollar ($) sign, i.e.: `aaa$$bbb*%`  
  (as mentioned on the first link above).
  
  2)
  Use base64 to encode and decode the value.
  
  Do this first:
  
  ```
  $ echo 'aaa$bbb*%' | base64
  YWFhJGJiYiolCg==
  
  ```
  
  Then store this value in project Variables.
  
  And then in your script decode it:
  
  ```
  PASS=$(echo ${sensitive_var} | base64 -D)
  
  ```
  
  > **Comments:**
  > **username_0**: Hi username_3, thanks for the fast reply. As explained in the problem I already tried enclosing the value in single quotes. It may not be related to Gitlab, but the original value is saved as env var in Gitlab, and then is passed in a job to the deployment script.  Also, the script is on a docker image, so it might be possible that I can't access Gitlab's environment from there.  
  > **username_3**: Where did you enclose the value in single quotes? In CI/CD Settings?  
  > **username_0**: Yes, in the env vars of CI/CD settings  
  > **username_3**: You are right, I've just tested it... funnily it didn't get rid of single-quotes, how you would expect it in bash case... lemme think...  
  > **username_3**: See this: https://gitlab.com/gitlab-org/gitlab-ce/issues/45173#note_101659865  
  > **username_3**: And this: https://gitlab.com/gitlab-org/gitlab-ce/issues/27436  
  > **username_3**: It's really frustrating... GitLab being awesome has many such weird bugs or missing basic features... it makes me cry sometimes. By the way double-dollar workaround seems to help.  
  > **username_3**: Another idea to try - is to use `base64` to encode value before storing it, and decode in your script.  
  > **username_0**: Wow thanks, I thought about the base64 encoding but was thinking in the code, not in the script. I will have to see which option is more maintainable in the long run. Thank you very much  
  > **username_3**: No problem. Good luck with your project.  
  
  ---
  
  ### Answer by username_1 on 2019-10-03. Score: 2
  
  This is not answering only the question but also a bit more (I put this here for reference):  
  I found out a decent way to tackle this and some complications coming afterwards... (after hours and hours of fiddling) - e.g. to execute the script in an SSH session:
  
  ```yaml
  deploy job:
    variables:
      # the variables could come from anywhere (e.g. GitLab Settings - environment variables)
      SSH_DIR: '/srv/app/'
      SCRIPT_CMD: |
        echo "Double quotes are safe"
        echo 'Single quotes are safe'
        echo "Code executions are safe -" `whoami`@`hostname` $$(date)
        # the '$$' is needed as otherwise GitLab itself tries variable substitution
  
    # Here's the magic to get the code from the GitLab variable into a bash variable and then even executed on an SSH session
    script:
      # Put gitlab variable into shell variable to improve quote handling
      - CMD=$SCRIPT_CMD
      # Print for debugging
      - echo -e "Executing:\n$CMD"
      - CMD="set -e; cd $SSH_DIR; $CMD" # 'set -e' = stop on error
      # redirect variable to stdin of ssh bash (the -x causes bash to print each command)
      - ssh -p $SSH_PORT $USERNAME@$SSH_HOST "bash -x" <<< "$CMD"
  
  ```
  
  More detailed example [here](https://gist.github.com/username_1/cd8d4b901775f379d74287fa85f924c3).
  
  
  ---
  
  ### Answer by username_2 on 2019-07-17. Score: 0
  
  One should use protected variables in my opinion. One could configure them in the pipeline settings and subsequently call them inside the pipeline. Using base64 formats should be avoided as these could be easily decrypted.
  
  <https://docs.gitlab.com/ee/ci/variables/>
  
  > **Comments:**
  > **username_3**: It's a common misconception. Protected env vars in GitLab are not what you think, the main purpose of them is that they are passed only to pipelines of the Protected branches. They are not otherwise protected. There is also a Masked option for env vars which is probably more what you mean, but still it doesn't work all the time - there's a limitation on value, again because it's internally processed by GitLab which it should really do.  
  
  ---
  
  