Why is it recommended to manually provision pre-existing secrets in AWS SecretsManager as opposed via CDK/Cloudformation? - aws-cloudformation

Quote from the aws cdk docs:
If you need to use a pre-existing secret, the recommended way is to manually provision the secret in AWS SecretsManager and use the Secret.fromSecretArn or Secret.fromSecretAttributes method to make it available in your CDK Application
Why is that? Is it because it's not ideal to save the plain text secret into code?
Or we don't want the secret to appear in the cloudformation template?

Yes and yes. Earlier CDK versions did not even permit passing text values to the Secret constructor. We only recently got the secretStringBeta1: string prop along with a stern warning:
It is highly encouraged to leave this field undefined and allow SecretsManager to create the secret value. The secret string -- if provided -- will be included in the output of the cdk as part of synthesis, and will appear in the CloudFormation template in the console. This can be secure(-ish) if that value is merely reference to another resource (or one of its attributes), but if the value is a plaintext string, it will be visible to anyone with access to the CloudFormation template (via the AWS Console, SDKs, or CLI).
Our CDK code and generated templates are meant to be deterministic and version-controlled, further heightening the risk of leakage if plaintext secrets are used.
Edit: Per #gshpychka's comment, a safe alternative to importing with Secret.fromSecretArn is to construct a new Secret without a secret value. This creates a secret with a random password, which you change post-deploy in the Console. This approach helpfully ties the secret's lifecycle to the Stack and lets you set its properties in the context of the Stack.

Related

How does a Secret .yaml file keep secret (username/password safe) as base64 could be decoded

In deployment.yaml file, we don't add username and password but refer them using secret. This way,the username/password don't get stored in code repositories. In secret.yaml, the username and password are encoded in base64 (which can be decoded). From best practice persepective, doesn't secret.yaml also get source-controlled somewhere (thereby also storing the username/password in version control). If so, what is the benefit of using Secret ?
There are a few aspects to be considered when keeping k8s secrets secret.
Data encryption at rest
There's the configuration option --encryption-provider-config, which instructs the api server whether and how to encrypt data in etcd. There's lots more in the docs.
Authorization
Role Based Access Control is one authz possibility for k8s. Using it, access to secrets can be restricted, so not every user or service account can see secrets, already existing in the cluster, think of kubectl get secret others-secret -n some-ns -o yaml. With RBAC you can create roles with specific sets of permissions - allowing or not access to secrets per namespace - and then assign those roles to users, groups or even service accounts, as you see fit.
Secrets manifests and VCS
3.1 Encryption
There are quite a few tools allowing for encryption of files with sensitive data, which would allow you to commit the file with the secrets to a version control system, if that's what you need. A simpler one would be mozilla SOPS and one somewhat sophisticated and complex might be Vault for example. Whichever it is, it would definitely be nice if not necessary, to be possible to easily integrate it in any delivery pipeline.
3.2 Don't store secrets manifests
An alternative approach to the above would be to not store any files with secrets. Create the secret and with regular cluster backups (tools like velero for instance) you should have nothing to worry about.
As you said, secrets are not encrypted but only base64 encoded. Where secrets really add value is that they allow you to keep your passwords, keys, tokens out of your codebase/git repos. If you push your code to Github, you will not be pushing your secrets there. For this reason they are called secrets and add a layer of safety.
However, if someone gets access to your cluster, secrets will be mere plaintext to them.
The recommended way to store the secrets is to use a vault.
https://www.hashicorp.com/blog/injecting-vault-secrets-into-kubernetes-pods-via-a-sidecar
Good one. Some time ago I already answered Kubernetes secret is really secret? question, check there all the info.
If you configure the secret through a manifest (JSON or YAML) file
which has the secret data encoded as base64, sharing this file or
checking it in to a source repository means the secret is compromised.
Base64 encoding is not an encryption method and is considered the same
as plain text.

Pulumi: how to create an ApplicationPassword and let Azure set the value

I'd like to be able to do the following:
Generate an ApplicationPassword without generating the actual value for the password (let Azure do it, similar to the way Azure generates the secret value for you in the UI, or that secretText is a return value from this azure api method: https://learn.microsoft.com/en-us/graph/api/application-addpassword?view=graph-rest-1.0&tabs=http)
Put that secret in an Azure key vault
Redeploy the stack without having it generate a new secret everytime
Is this possible?
The reason I'd like to not specify the secret value, is that I then need to commit the secret value to code, which I don't want.
The only workaround I can think of is generating the secret value in code, storing it in keyvault, retrieving it from keyvault and using that to create the ApplicationPassword, but then that would cause Pulumi to create a new secret in the keyvault (and then a new ApplicationPassword) each time I deploy the stack.
You can use the RandomPassword resource to generate a password that is stable between multiple runs of the same stack. It's generated once and then stored in the state file.
const password = new random.RandomPassword("password", {
length: 16,
special: true,
});
// use password.result somewhere

How to make Keycloak use its database password from keyvault instead of env file

Currently I am using keycloak on postgres db. and the db creds are provided to environment files. Wanted to know how I can make keycloak obtain the db creds from keyvault something like Azure keyvault ? Is there any documentation / guideline around it?
As per the official documentation ,some part already done but look like still work in progress
To use a vault, a vault provider must be registered within Keycloak.
It is possible to either use a built-in provider described below or
implement your own provider. See the Server Developer Guide for more
information.
To obtain a secret from a vault instead of entering it directly, enter the following specially crafted string into the appropriate field: ${vault.entry-name} where you replace the entry-name with the name of the secret as recognized by the vault.
https://www.keycloak.org/docs/latest/server_admin/#_vault-administration
https://issues.redhat.com/browse/KEYCLOAK-3205

How to set secrets in Github Actions?

The official boilerplate code injects the npm token as follows
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
How do I access and set this variable? I cant find it in the GUI.
Go to your project in Github
Select the Settings tab
Click the Secrets section in the left hand menu
Add a new secret and provide a name (e.g. npm_token) and a value.
In addition to the GUI, you now (January 2020) have a GitHub Actions API(!, still beta though), as announced here.
And it does include a GitHub Actions Secrets API:
Create or update an repository secret:
Creates or updates an organization secret with an encrypted value. Encrypt your secret using LibSodium.
You must authenticate using an access token with the admin:repo scope to use this endpoint.
GitHub Apps must have the secrets organization permission to use this endpoint.
PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}
Get a repository secret
Gets a single secret without revealing its encrypted value.
Anyone with write access to the repository can use this endpoint.
GitHub Apps must have the secrets permission to use this endpoint.
GET /repos/:owner/:repo/actions/secrets/:name
So the GUI is no longer the sole option: you can script and get/set an Actions secret through this new API.
This page is hard to find, but it exists in the official docs here: Creating and using secrets (encrypted variables).
Copied from the docs below for convenience:
Secret names cannot include any spaces. To ensure that GitHub redacts
your secret in logs, avoid using structured data as the values of
secrets, like JSON or encoded Git blobs.
On GitHub, navigate to the main page of the repository.
Under your repository name, click Settings.
In the left sidebar, click Secrets.
Type a name for your secret in the "Name" input box.
Type the value for your secret.
Click Add secret.
The link above has a bit more info around using secrets as well.
I've created a simple CLI that can help you achieve that - https://github.com/unfor19/githubsecrets
This CLI is based on the official API. You can install it with pip or use Docker, read the README.md for more information

How to use sensitive passwords needed to run scripts within RunDeck?

I have a case where the RunDeck scripts do need some credentials in order to run. Obviously we do not want to store these in the job definitions because these are visible and also stored in SCM.
While I was able to use the Key Storage vault to put these secrets in, I was not able to find a way to access them from the job itself.
Rundeck 2.6.2 (released 2015-12-02) allows you to specify key storage secrets as default values for secure job options. See Secure Options using Key Storage