Access secrets environment variables from C# program

Hi 

I have an issue attempting to read secrets in Action workflow.

There is a password to external service stored as a secret in my github repo.

For  integration tests (.NET Framework 4.5.2, C#, xUnit) I need this password (base64 encoded string) to be set as an environment variable so the test can pickup password and use it.

To get environment variable in code test uses Environment.GetEnvironmentVariable as shown below

var pwd = Environment.GetEnvironmentVariable("SVC_PWD");
var svc_code= Environment.GetEnvironmentVariable("SVC_SECRET_CODE");

But instead of the actual secret’s value code above reads “***” as value for both C# variables.

Is there a way how to get the actual value of the environment variable that stores GitHub secret in C# code?


Simplified workflow that sets environment variables at the beginning of build job 

.....
jobs:
  build:
    runs-on: windows-latest
    env:
      artifacts: POC.Artifacts
      testartifacts: POC.Test
# set secrets as env variables
      SVC_PWD: ${{ secrets.SVC_PWD }}
      SVC_SECRET_CODE: ${{ secrets. SVC_SECRET_CODE }}
.............
# build code and gather artifcacts
    - name: run tests
      working-directory: /test
      run: xunit.console.exe LibExt.Tests.dll -nologo
      shell: powershell

This looks correct to me.

How are you determining that the variable is set to  ***? The logs obfuscate any secret values, so if it’s being printed out, the real value is being hidden.

the value in the secret is base64 encoded string.

It is correct since it has been taken from the config file AS IS. 

I attempt to read it from the env var and decode using Convert.FromBase64String and it fails with error that string is not valid base64 

I tried to set simple value such as “lorem” in secret, read it in test method and verify via

Assert.True(envVarValue.Equals(“lorem”,StringComparison.OrdinalIgnoreCase))

and test constantly fails on this assert

To simplify things and give you more information 

I created following the simplest workflow

secret SERVICE_ACCESS_KEY has 111222333 value 

new environment variable created in workflow with  X_SERVICE_ACCESS_KEY

Workflow reads value of environment variable into PowerShell variable $envSecretVal  using 

call to .NET Framework code 

[Environment]::GetEnvironmentVariable("X_SERVICE_ACCESS_KEY");

Then attempts to compare value with constant string “111222333” and store result into  $testResult   PS variable

$testResult  always has False.

So as far as I understand there is no way to get unencrypted value of secret by using .NET Code

-----------Workflow------------

name: ENV Test Master
on:
  push:
    branches:
      - master
    paths-ignore:
      - .github/*
jobs:
  build:

    runs-on: windows-latest
    env:
      BUILD_ARTIFACTS: BUILD_OUT
      TEST_ARTIFACTS: TEST_OUT
# secret SERVICE_ACCESS_KEY has fake value 111222333
      X_SERVICE_ACCESS_KEY: ${{ secrets.SERVICE_ACCESS_KEY }}

    steps:
    - name: verify secret
      run: |
           $envSecretVal = [Environment]::GetEnvironmentVariable("X_SERVICE_ACCESS_KEY");
           $testResult = $envSecretVal -eq "111222333";
           Write-Output $testResult;
      shell: powershell

@vitaly-pavluk ,

Obviously, we can’t compare secret variable with an explicit text, this is same as the point that the value of secret variable will be hidden in the printing logs. This is a security strategy designed to prevent the actual value of secret variable from being easily obtained in the logs.

I think, as long as the password stored in Secrets can authenticate successfully when you use it to login the its appropriate accounts, you do not need to view the actual value of the password in the process. In this way, the risk of password leakage can be avoided as much as possible.

I had the same problem. I solved it by moving the env up just like this.

name: .NET

env:
  MY_TOKEN : ${{ secrets.MY_TOKEN }}

on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

jobs:
  build:
    strategy:
      fail-fast: false
      matrix:
        os: [windows-latest, ubuntu-latest]
    runs-on: ${{ matrix.os }}

    steps:
    - uses: actions/checkout@v2
    - name: Setup .NET
      uses: actions/setup-dotnet@v1
      with:
        dotnet-version: 5.0.x
    - name: Restore dependencies
      run: dotnet restore
    - name: Build
      run: dotnet build --no-restore
    - name: Test
      run: dotnet test --no-build --verbosity normal /p:CollectCoverage=true

Note that the env is up top

Thanks to everyone who participated in this thread.
I don’t have this issue anymore.
Thread can be closed (honestly I haven’t found a way how to close thread :slight_smile: )
Once again - thank you!
GH community is the most valuable and important part of the GH ecosystem!!!

Hello. This is out of the scope of this discussion, as it has already been solved, but I’m facing the same “issue”. As I see from the replies, there’s no way of accessing the secrets of a GitHub repository as environment variables. Is there any other way I can accomplish this? Or, is there any unrelated method that I can use to store values in GitHub securely while being able to access and use them? Hope this question still fits in this thread.

GH secrets as env variables work for me well.
No issues so far with them.
I use .net /.net core app to get secrets from environment variables and I verified that GH puts them into env variables during the build process but you need to explicitly specify in GH build file mapping between the secret and env variable just for your convenience.
I’ve done that and it works w/o any issues. Sorry, I cannot share the build file since it is part of the private repo.

2 Likes

I was trying different methods and finally got it running doing what you mentioned. Thank you for the explanation!

1 Like