No key is attached while writing the secret to vault - hashicorp-vault

I am trying to write a vault secret which is a file.
PS C:\workspace> vault kv put -address=https://someserver.com -namespace=somenamespace secret/runtime/other/dev value="#test.pwd"
Key Value
--- -----
created_time 2022-08-22T06:54:50.018110723Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 15
PS C:\workspace> vault kv get -address=https://someserver.com -namespace=somenamespace secret/runtime/other/dev
======= Metadata =======
Key Value
--- -----
created_time 2022-08-22T06:54:50.018110723Z
custom_metadata <nil>
deletion_time n/a
destroyed false
version 15
== Data ==
Key Value
--- -----
:�<↕zMn�L��T2���홆j����?Н�xil܉
The file is getting stored to vault but the key is null. Is there a way to to attached any key also to it.

That is just bad luck. The file test.pwd probably happens to have a carriage return (\r) in it. When Vault command line displays the secret value, the carriage return is interpreted by the shell and it overwrites the key name, which is value in your example.
You can see them both if you output the in JSON format with:
vault kv get -format json -address=https://someserver.com -namespace=somenamespace secret/runtime/other/dev

Related

Using kubernetes secret env var inside another env var

I have a secret being used as env var in another env var as follows:
- name: "PWD"
valueFrom:
secretKeyRef:
name: "credentials"
key: "password"
- name: HOST
value: "xyz.mongodb.net"
- name: MONGODB_URI
value: "mongodb+srv://user:$(PWD)#$(HOST)/db_name?"
When i exec into the container and run env command to see the values of env i see -
mongodb+srv://user:password123
#xyz.mongodb.net/db_name?
The container logs show error as authentication failure.
Is this something that is expected to work in kubernetes ? There docs talk about dependent env vars but do not give example using secrets. Did not find clear explanation on this after extensive search. Only found this one article doing something similar.
Some points to note -
The secret is a sealed secret.
This is the final manifest's contents, but all this is templated using helm.
The value is being used inside a spring boot application
Is the new line after 123 expected ?
If this evaluation of env from a secret in another env is possible then what am I doing wrong here ?
The issue was with the command used to encode the secret - echo "pasword" | base64. The echo adds a newline character at the end of the string. Using echo -n "password" | base64 fixed the secret.
Closing the issue.

VaultSharp AppRole Login Unwrapping problem

I logged in via the CLI using my standard Token obtained from the UI. Then I ran this to get a wrapping token:
vault write auth/approle/login role_id="e309ea24-994c-771e-939f-49e24a936ef2" secret_id="9597c7d0-3a88-c8f7-e43f-e8999600e38e"
that call returned:
Key Value
--- -----
token s.5NuuJxEfdiJrfSiXXCU5MjZ6.dYgGw
token_accessor 3JFGpuaO45DuxD9nd6mUL6ic.dYgGw
token_duration 1h
token_renewable true
token_policies ["default" "transaction"]
identity_policies []
policies ["default" "transaction"]
token_meta_role_name transaction
Now, I used the token in an unwrapping call like this:
IVaultClient vaultClientForUnwrapping = new VaultClient(
new VaultClientSettings(_settings.Address, new TokenAuthMethodInfo(vaultToken: wrappingToken))
);
string appRoleAuthSecretId
= vaultClientForUnwrapping.V1.System
.UnwrapWrappedResponseDataAsync<Dictionary<string, object>>(tokenId: null)
.Result.Data["secret_id"]
.ToString();
And when attempting to run the Unwrapping call above, I get this exception:
One or more errors occurred. ({"errors":["wrapping token is not valid or does not exist"]}
Can anyone help out here?
The call vault write auth/approle/login role_id="e309ea24-994c-771e-939f-49e24a936ef2" secret_id="9597c7d0-3a88-c8f7-e43f-e8999600e38e" is not returning a wrapped token, but instead a raw token.
Essentially, in order to get a wrapped token, you need to provide the -wrap-ttl flag.
#!/usr/bin/env bash
vault server -dev -dev-root-token-id=root -dev-listen-address=127.0.0.1:8200 &
VAULT_SERVER_PID=$!
export VAULT_ADDR=http://127.0.0.1:8200
export VAULT_TOKEN=root
vault auth enable approle
vault write auth/approle/role/test-role policies=default
ROLE_ID=$(vault read -format=json auth/approle/role/test-role/role-id | jq -r .data.role_id)
SECRET_ID=$(vault write -f -format=json auth/approle/role/test-role/secret-id | jq -r .data.secret_id)
VAULT_WRAP_TOKEN=$(vault write -wrap-ttl=1h -format=json auth/approle/login role_id=${ROLE_ID} secret_id=${SECRET_ID} | jq -r .wrap_info.token)
VAULT_TOKEN=${VAULT_WRAP_TOKEN} vault write -f sys/wrapping/unwrap
kill -9 ${VAULT_SERVER_PID}
This is a sample script that would provide an actual wrapped token, and the process for unwrapping it. You can add the -output-curl-string flag to any of the vault commands above to see what the API commands might be. I've used jq for the programmatic passing of IDs to the next commands, but you can omit the -format=json and trailing | jq -r ... if you wish to see the table-formatted responses from the vault binary.
The reason that most libraries that require Vault Tokens do the wrapping step is so that it can be certain that nothing except the end user of the token has ever seen the token. A wrapping token can only be used once, and so ensures that nothing else has unwrapped the token before being used.
However, in the case of VaultSharp, a casual glance suggests that you can pass the Role ID and Secret ID directly to the library and have it generate its own tokens on demand. You may wish to look into this instead.

Parameter name containing special characters on Helm chart

In my Helm chart, I need to set the following Java Spring parameter name:
company.sms.security.password#id(name):
secret:
name: mypasswd
key: mysecretkey
But when applying the template, I encounter a syntax issue.
oc apply -f template.yml
The Deployment "template" is invalid: spec.template.spec.containers[0].env[79].name: Invalid value: "company.sms.security.password#id(name)": a valid environment variable name must consist of alphabetic characters, digits, '_', '-', or '.', and must not start with a digit (e.g. 'my.env-name', or 'MY_ENV.NAME', or 'MyEnvName1', regex used for validation is '[-._a-zA-Z][-._a-zA-Z0-9]*')
What I would usually do is defining this variable at runtime like this:
JAVA_TOOL_OPTIONS:
-Dcompany.sms.security.password#id(name)=mypass
But since it's storing sensitive data, obviously I cannot log in clear the password.
So far I could only think about defining an Initcontainer as a workaround, changing the parameter name is not an option.
Edit: So the goal is to not log the password neither in the manifest nor in the application logs.
Edited:
Assign the value from your secret to one environment variable, and use it in the JAVA_TOOL_OPTIONS environment variable value. the way to expand the value of a previously defined variable VAR_NAME, is $(VAR_NAME).
For example:
- name: MY_PASSWORD
valueFrom:
secretKeyRef:
name: mypasswd
key: mysecretkey
- name: JAVA_TOOL_OPTIONS
value: "-Dcompany.sms.security.password#id(name)=$(MY_PASSWORD)"
Constrains
There are some conditions for kuberenetes in order to parse the $(VAR_NAME) correctly, otherwise $(VAR_NAME) will be parsed as a regular string:
The variable VAR_NAME should be defined before the one that uses it
The value of VAR_NAME must not be another variable, and must be defined.
If the value of VAR_NAME consists of other variables or is undefined, $(VAR_NAME) will be parsed as a string.
In the example above, if the secret mypasswd in the pod's namespace doesn't have a value for the key mysecretkey, $(MY_PASSWORD) will appear literally as a string and will not be parsed.
References:
Dependent environment variables
Use secret data in environment variables

Kubectl create multiline secret

I'm trying to put a Service Account into a secret - I did it previously a year ago and it works but now - no matter how I approach it, the application doesn't see it right and says there is Input byte array has incorrect ending byte - When creating normal secret I know you've gotta do it with a new line so
echo -n "secret" | base64
and put that value in secret and apply, but my multiline file
cat secret.json
{
"type": "service_account",
"project_id": "smth-smth",
"private_key_id": "blabla"
...
}
No matter how I approach - whether put it by hand like in the first example, or do it with
cat secret.json | base64
# or
base64 < secret.json
the secret is created but application throws
Constructor threw exception; nested exception is java.lang.IllegalArgumentException: Input byte array has incorrect ending byte at 3104
When I compare the new secret to the last one of the service account the difference is how the output looks like
The working one is smth like this - when I try to decrypt the base64
echo -n "<long string of base64 encrypred sa> | base64 -D
{ "type": "service_account", "project_id": "blabla"... }
so it's in one line, and the new SA I try to decrypt is outputed in the format as in the file - so each part of json in new line - I tried manually putting it all in one line but without success
Anyone know ? how to put a multiline file in a secret (base64) properly?
The easiest way to create a secret from a file is to use kubectl create secret generic.
Put your file secret.json in a folder config and then run:
kubectl create secret generic my-secret --from-file=config
You will get a secret my-secret with one key secret.json containing your file (which you can then mount to a pod volume).
If you cannot create files an option is to write into a variable and then load the result into a --file-literal. This may be necessary because it seems kubectl either escapes newline characters \n when inside a quoted string and ignores them if no quotes are supplied. When reading from a variable the \nare treated as expected.
EDIT: With regards to multi-line strings do take care to use correct linefeed characters, as explained here. I ran into that when trying my answer at home :)
target_string=$(echo "string1\nstring2")
kubectl create secret generic your-secret-name --from-literal=your_key=$target_string

Kubernetes edit secret error: "cannot restore slice from..."

I'm trying to edit a kubernetes secret using:
kubectl edit secret mysecret -o yaml
And adding a new variable on data:
data:
NEW_VAR: true
But I receive the error:
cannot restore slice from bool
If I try to use some number, like:
data:
NEW_VAR: 1
I receive another error after close the editor:
cannot restore slice from int64
What this error means?
This error happens when the variable is not a valid base64 value.
So, to use the value true, you need to use his base64 representation:
NEW_VAR: dHJ1ZQ==