I want to release the artifact of a github action to a specific update repo, so that my software can use it to update itself. To verify the update in the local update process I want to sign this artifact. I chose to store the update itself and signature in separate files for now.
My github action would take the zipped artifact and should sign it with the given RSA4096 Private Key and should use SHA512 as a digest.
My github action for that looks as follows:
- name: Sign release
run: |
echo $PRIVATE_KEY > privatekey.pem
openssl dgst -sha512 -sign privatekey.pem -out latest.sig latest.zip
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
This github action should take my private key from the repository's secrets, put it in an environment variable, and then put it in a local file so the following openssl command can take this private key to sign it. I went this way to hinder the private key itself being echo'ed to the log.
The private key value is as follows:
(This is of course not the actual private key but one I created solely for testing purposes until this github action works properly. This private key is only 1024 bits instead of the above mentiond 4096 bits. I will not use this private key afterwards anymore.)
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgGwdzKeZPLdOHV+/iDpHHtEk7kephhI5eythCfmoqzy5CSx+GZ6X
Z1GiIzII+CtyN69cOgyzO99uPvquBkbo3lHL5+jZnOEue8nMub8iwPXZgDB6s8BV
sFevjLENx4LWJSZSo8rUn6al3bfoWJUySzkla9xc4g0GiO1K81zGeRH9AgMBAAEC
gYBTZbUs/vYny5i69+pkUeICoEMxgiHKQw6win0AWMwl3fGmoWqvu8hV3wTZHrQY
B1XO7gxVKZigo9Du23g6EH0UhGHZm9s4csjVXm8gVt7LghoOZq82nLmbe+XBrn+C
B3VeQbk7urD5mfdWx5zRYWGPjg/zaCGu47Apuuc1Kw0vvQJBAMhbyHvua2b/Fdbm
fbpO283aTPBaHYrexsqp5DZ8/DUet7BIB/p9yb4hVpV9nDH/WALSl1stfcfe260w
Lsm4/icCQQCKJDAi/ukBW2QpFy9evMNpR0KxtFIETxs6y5v0/EOoaqKDrFjjb7M2
svEybXa/y/AgYMxxVeNbFpfWSC4Sc+k7AkA2D2XJ4qvCD6PB51EXOv3dzkAiPf5o
oPF8b1ivRwv5/T7M5rKYaOZNUct97HV/nAkQQegq5txgWIZndW+6aBrTAkACNG2o
QVVKtkC0/y+8XVrpFUAVQgGFHBYdLB7DHDugNoN9goSwrJm5p8V9vo2Epiag/aqF
rI9CZuvpeaFynfL9AkEApFCO3IxSkXYwx4AjQwxcuVz1w5lUAL5LxvRlmqy8Jj0l
RgXLxBfGTQoTVL9/JuUjE7xLXWfYm+8u9k3KV3FJYQ==
-----END RSA PRIVATE KEY-----
The problem is the following log output of the github action when executing this step:
unable to load key file
6196:error:0909006C:PEM routines:get_name:no start line:crypto\pem\pem_lib.c:745:Expecting: ANY PRIVATE KEY
Which means that whatever was echoed to the privatekey.pem is not the actual private key secret value, but something else. I couldn't get the content of the file printed in subsequent tests. Not with a necho or cat command or anything similar, so I have actually no knowledge of what is written to the file, which makes it impossible for me to get any deeper into my analysis.
Is anyone here able to deduce some helpful tips or a solution to this problem?
It's likely that part of your problem is the lack of quoting. When you don't quote a variable in shell, it is split on whitespace (space, tab, and newline), so what you're passing to echo is several different arguments which, instead of being separated by newlines, are separated by spaces via echo.
You'd probably want to write this (note the quotation marks around $PRIVATE_KEY:
- name: Sign release
run: |
echo "$PRIVATE_KEY" > privatekey.pem
openssl dgst -sha512 -sign privatekey.pem -out latest.sig latest.zip
env:
PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
In general, it's a good practice to place all variables in double quotes when using them unless you're certain that you want the shell to expand them.
Of course, all of this applies only if you're using a POSIX shell, which means that you need to be using Unix or bash on Windows, since the syntax you're using is POSIX shell syntax.
GitHub Actions, like most CI systems, tries to sanitize its output to prevent disclosing secrets that are accidentally printed to logs, which is why you were unable to print the value.
Related
I'm following this documentation to push signed images to ACR from Azure pipelines.
However, this only describes the changes needed in yaml tasks. I'm using a classic release pipeline, and I'm facing some issues.
I'm trying to push the image using an Azure CLI script. Before the script task, I'm using the Secure files in pipeline to download the private key file and used the below CLI script -
echo '---------Create Private Delegate Key for signing--------'
mkdir -p ./docker/trust/private
echo 'Created Trust Directory'
echo 'Copying $(privateKey.secureFilePath) to ./docker/trust/private'
cp $(privateKey.secureFilePath) ./docker/trust/private
I'm getting the below error on running
echo $(SigningPassphrase) | docker push --disable-content-trust=false $(registry)/$REPOSITORY_NAME:$BUILD_TAG
Error:
no valid signing keys for delegation roles
I added the following lines in the script to load the private key -
chmod 600 ./docker/trust/private/$(KeyFileName)
echo '-----Loading Key-----'
docker trust key load ./docker/trust/private/$(KeyFileName)
But signing of the image is still failing after loading the key. I also tried changing the key file name to the repository key.
Am I placing the file in an incorrect location? It's being placed in /home/vsts/.docker/trust/private.
What should be the location to place the private key file in, so that docker can recognize it to sign the images?
I'm having trouble using a multiline Azure Key Vault value inside an Azure Release Pipeline...
I put a multiline value (RSA private key) into Azure Key Vault using the CLI:
az keyvault secret set --vault-name "vault" --name "secret" --file "pk.pem"
This works and I can see the multiline secret in the portal.
Locally using CLI I can also do:
pk=$(az keyvault secret show \
--name "ssh-private-key" \
--vault-name $vault \
--query "value")
This returns a somewhat crappy value (yes including the double quotes):
"-----BEGIN RSA PRIVATE KEY-----\nMIIG4wIBAA .... JtpyW\n-----END RSA PRIVATE KEY-----\n"
I can manage to work with this and send the value to a file like so:
pk="${pk%\"}" #remove first quote
pk="${pk#\"}" #remove last quote
echo $pk | sed 's|\\n|\n|g' | # replace with actual newlines
while IFS= read -r line; do # loop through lines
echo "$line" >> pk.pem # write to file per line
done
This works and I can login to my server using ssh -i pk.pem user#server
But when running the same script in the Azure Devops Release pipeline (also using Bash on a Linux agent) the exact same script fails... I'm also having trouble inspecting the actual value as the log masks all values related to the secret...
Any guide on how to debug or work with actually reading multiline values instead of just storing them would be hugely appreciated!
Here is a troubleshooting advice:
The error "Host key verification failed." doesn't just occur when the key is incorrect. Most of the time, it doesn't refer to your key.
So I recommend you firstly try the connection with a simple value to see if it works on Azure DevOps.
What's more, maybe an SSH service connection can help you with what you're doing. Go to Project Settings -> Service connections -> Create service connection -> SSH to create one.
I can generate an ssh key with Sprig quite easily. But ideally I just need to put it in k8s secrets and display the public part to the user to import on the remote end.
https://play.golang.org/p/9oFBr9LD190
(for a full go example, but I don't get Go, just sprig in Helm.)
The Helm template alone just needs the template bit :
{{ genPrivateKey "rsa" }} to show the text of a key to go into secrets. But other than giving the user the command to query the key from the secret and run it through ssh-keygen :
kubectl get secret ... -o jsonpath=".data.ssh-key" | base64 -d | ssh-keygen -y -f/dev/stdin
is there a way to persuade Sprig to get the public part of the key? (Commands unchecked, but you get the idea.)
I wish to create an environment file not "variable" and get a path to it in the TravisCI pipeline.
Attached is the image of how we do the same in gitlab
gitlab environment file image
I need to store secrets in a file refer is via a path in travisci pipeline.
Ex: this is how we can do the same in Jenkins:
"KUBECONFIG=/var/lib/jenkins/.kube/filename"
I am not will to upload my secrets file to github private repo.
The encrypt-file command will encrypt an entire file using symmetric (AES-256) encryption and stores the secret in a file. Let us create a file called secret.txt and add the following entries into it: SECRET_VALUE=ABCDE12345 CLIENT_ID=rocky123 CLIENT_SECRET=abc222222!
travis encrypt-file secret.txt -> give this command after creating secret.txt file and it will store result as secret.txt.enc and also shows ->add the following to your build script (before_install stage in your .travis.yml , for instance): - openssl aes-256-cbc -K $encrypted_74945c17fbe2_key -iv $encrypted_74945c17fbe2_iv -in secret.txt.enc -out secret.txt -d
Now add this entry into our .travis.yml script: ( before_install: - openssl aes-256-cbc -K $encrypted_74945c17fbe2_key -iv $encrypted_74945c17fbe2_iv -in secret.txt.enc -out secret.txt -d ) , It can then decrypt values in the secret text file for us
So it is to create a file and use command travis encrypt-file secret.txt, it will then produces an entry, copy that entry and add it into our .travis.yml file in before_install stage
make sure to add the secret.txt.enc to the git repository and make sure NOT to add the secret.txt to the git repository
Generally, we cannot keep both the encryption key and encrypted file in the same place(i.e repo). So, we store the file somewhere else. Where are you storing it? How will you fetch it?
I'm trying to access the value of SECRETs sent to a GitHub Action, but I'm struggling. The values are returned as [FILTERED] every time, no matter what the key or the original value is.
I can access ENVIRONMENT VARIABLES without a problem, so I must be screwing up somewhere else.
Essentially, what I'm trying to do is send an ssh key to my action/container, but I get the same issue when sending any other key/value as a secret.
My (simplified) GitHub Action is as follows:
action "Test" {
uses = "./.github/actions/test"
secrets = [
"SSH_PRIVATE_KEY",
"SSH_PUBLIC_KEY",
]
env = {
SSH_PUBLIC_KEY_TEST = "thisisatestpublickey"
}
}
Dockerfile:
FROM ubuntu:latest
# Args
ARG SSH_PRIVATE_KEY
ARG SSH_PUBLIC_KEY
ARG SSH_PUBLIC_KEY_TEST
# Copy entrypoint
ADD entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh:
#! /bin/sh
SSH_PATH="$HOME/.ssh"
mkdir "$SSH_PATH"
touch "$SSH_PATH/known_hosts"
echo "$SSH_PRIVATE_KEY" > "$SSH_PATH/id_rsa"
echo "$SSH_PUBLIC_KEY" > "$SSH_PATH/id_rsa.pub"
echo "$SSH_PUBLIC_KEY_TEST" > "$SSH_PATH/id_rsa_test.pub"
cat "$SSH_PATH/id_rsa"
cat "$SSH_PATH/id_rsa.pub"
cat "$SSH_PATH/id_rsa_test.pub"
The output of those three cat commands is:
[FILTERED]
[FILTERED]
thisisatestpublickey
As you can see, I can get (and use) the value of the environment variables, but the secrets aren't being exposed.
Anyone got any clues?
Just to update this, I've also simply tried echoing out both the secrets without quotes in entrypoint.sh:
echo $SSH_PRIVATE_KEY
echo $SSH_PUBLIC_KEY
...and in the log, I see the full decrypted content of $SSH_PRIVATE_KEY (ie, the actual contents of my ssh key) while $SSH_PUBLIC_KEY still returns [FILTERED].
So, I can assume that we are able to see the contents of secrets inside of an action, but I don't know why I can see just one of them, while the other returns [FILTERED].
Is it a caching thing, maybe?
I'm just trying to figure out a predictable way to work with this.
As you can see, I can get (and use) the value of the environment variables, but the secrets aren't being exposed.
That's because they're secrets. The Actions output is explicitly scrubbed for secrets, and they're not displayed.
The file contents still contain the secret contents.