What is the recommended approach to encrypt existing parameters? - aws-ssm

I have few hundreds, if not thousands, entries in the parameter store on one of my AWS accounts. At the moment they are just plain strings. I would like to encrypt them using the default KMS key but so far the only way I found to do this involves deleting the existing parameter. I also need to encrypt all the versions of existing parameters.
Is there a way to do this without deleting parameters?

I know you can update an existing String parameter to become a SecureString.
aws ssm put-parameter --name "test" --value "param" --type String
aws ssm put-parameter --name "test" --value "param" --type SecureString --overwrite
However, I don't think there is a way to edit the parameter version history to encrypt previous version values.
If it is unacceptable that the parameter history is unencrypted, I think you will need to write a script to delete each parameter and replace it with a SecureString parameter.

Related

Create a simple text secret in Google Cloud Secret Manager using CLI

When using the GUI on Google Cloud Console to create a secret all I needed to provide was the secret name and it's value and I'm done.
However, I would like to use the gcloud cli to create simple string secrets.
So far, all the documentations in the docs keep mentioning --data-file like below:
gcloud secrets create sample-secret --data-file="/path/to/file.txt"
How can I use simple strings as the secret value similar to the GUI flow such that I can have a command like
gcloud secrets create apiKey "adadadad181718783"
Must it always be a file?
you could try with this sample command
printf "s3cr3t" | gcloud secrets create my-secret --data-file=-
setting the --data-file=- flag to "-" will read the secret data from stdin.
You can check this documentation for reference

Best Practice for BICEP to Ignore Overwriting Existing KeyVault Secrets

I have the following GUID that is generated in my BICEP module and used as a value in a KeyVault secret
param keyVaultName string
param apiKey string = newGuid()
resource apikey_secret 'Microsoft.KeyVault/vaults/secrets#2021-11-01-preview' = {
name: '${keyVaultName}/ApiKey'
properties:{
value: apiKey
attributes:{
enabled: true
}
}
}
Every time I run the BICEP files this GUID is generated and replaces the previous value. My preference is for this to only be generated on the first run and then ignored if it exits on any subsequent run.
I came across this solution which uses tags to track existing secrets and then conditionals within the BICEP file checking to see if the tag exists.
I feel like there should be a more elegant solution than having to manage tags in addition to secrets but cannot find anything in the docs so far.
There isn't any way to do a "deploy only if it doesn't exist" in bicep/ARM - ARM is declarative so will always seek the goal specified in the template.
Another option you can consider is to use a deterministic guid that way it won't change, but someone with knowledge of how the function works could "determine" the secret value, e.g.
#secure
param apiKey string = guid(apikey_secret.id)
Nit - in your code snippet the param is not secure so someone with permission to the deployment at scope can retrieve the value.

override deleted aws_secretsmanager_secret resource using terraform

I have some secret which is created using terraform , due to some mistake I had commented and applied tf so the reource marked for deletion, but now if I enable it and apply it is saying the resource is marked for deletion.
resource "aws_secretsmanager_secret" "rotation-example" {
name = "mysecret"
description ="sccretatexample"
recovery_windows_in_days = 7
}
I can't change the name and create other resource, and also I dont have access to aws console/cli . pls guide me how to create again or is it possible to use the old one by overriding
As of now there is no functionality available to retrieve deleted secret using terraform. Check this open issue -
https://github.com/terraform-providers/terraform-provider-aws/issues/10259
But you can do it using some manual work but either you will require help from your AWS administrator or AWS access key should be having below permission.
To restore a secret and the metadata in the console, you must have these permissions:
secretsmanager:ListSecrets – Use to navigate to the secret you want to restore.
secretsmanager:RestoreSecret – Use to delete any versions still associated with the secret.
if AWS access key have above permission use below cmd to restore password.
aws secretsmanager restore-secret --secret-id mysecret
follow this AWS document to restore secret.
https://docs.aws.amazon.com/secretsmanager/latest/userguide/manage_delete-restore-secret.html
once secret is restored you can use "terraform import" as below to updated you state file with existing secret details.
terraform import aws_secretsmanager_secret.rotation-example mysecret
In addition, if you want to create and delete secret frequently use below.
recovery_windows_in_days = 0

Terraform - Access SSM Parameter Store Value Access

I would like some help / guidance on how to securely access SSM Parameter store for the (decrypted) value on an existing secureString for use in other terraform resources?
e.g we have a github access token stored in SSM for CI - I need to pass this value to the GitHub provider to enable webhooks for codepipeline.
The SSM Parameter is not something managed from terraform, but its decrypted value can be used.
Is this insecure given the value would end up in the state file? What is the best practice for this type of use case?
Many thanks!
You can use the data source to reference an already existing resource:
data "aws_ssm_parameter" "foo" {
name = "foo"
}
one of the properties of the data source is value, which contains the actual value of the parameter. You can use this elsewhere in your terraform code:
data.aws_ssm_parameter.foo.value

Securing Kubernetes secret files for source control?

According to the Kubernetes secrets docs, creating a secret is as easy as base64-encoding the data and placing it in a file.
How then, if base64 can be decoded as easily as it's encoded, can we secure/encrypt the secret values in the file? It would be nice to be able to commit the secret files into source control, however simply committing the file with base64-encoded data is in no way secure.
For example, here is the example given in the docs:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
password: dmFsdWUtMg0K
username: dmFsdWUtMQ0K
If you went to base64decode.org, you would see that those password/username values simply are "value-2". This file is unfit for source control. How can we secure the data in the file so that it is safe for source control? Or is this considered bad practice, and we should just add the file to .gitignore?
It isn't base64 encoded for security, it is to allow binary content to be stored in secrets. You likely should not commit secret definitions to source control.
For confidential secret keys, can you store them in etcd and retrieve them with confd ?
otherwise, if you really want them in scm, then can you use git-crypt?
https://github.com/AGWA/git-crypt
I'd deploy them with ansible, and encrypt the secrets using ansible-vault, so they could be inside the repository. In addition, they could be stored as text, applying the base64 filter over a template.
Anyway, as it was said before, secrets are not secure. They are just encoded in base64 and could be decoded with:
kubectl get secret mysecret -o jsonpath="{.data.username}" | base64 -d
kubectl get secret mysecret -o jsonpath="{.data.password}" | base64 -d
(what is very useful, by the way)

Resources