keptn / keptn

Cloud-native application life-cycle orchestration. Keptn automates your SLO-driven multi-stage delivery and operations & remediation of your applications.
https://keptn.sh
Apache License 2.0
1.79k stars 244 forks source link

OpenSSF Badge: Research on storing end-user facing credentials #2296

Closed johannes-b closed 1 year ago

johannes-b commented 4 years ago

CII Badge - Requirement: The software produced by the project causes the storing of passwords for authentication of external users, the passwords MUST be stored as iterated hashes with a per-user salt by using a key stretching (iterated) algorithm (e.g., Argon2id, Bcrypt, Scrypt, or PBKDF2). See also OWASP Password Storage Cheat Sheet).

Subjects: Subjects that are related to the security requirement are listed first. Hence, the following keys/tokens are used to secure communication ways in Keptn 0.7.1:

--> All keys/tokens are stored in a Kubernetes secret.

Issue:

Research Task:

jetzlstorfer commented 4 years ago

As of discussed in the CNCF Slack channel: https://cloud-native.slack.com/archives/CDJ7MLT8S/p1599738451025900

User Guus van der Weerd commented on it like this:

There’s a big difference between two kinds of secrets here:

  1. Credentials needed in runtime to connect to other services, such your mongodb password or apikey. Those are for example used by your k8s service to identify itself to another service. K8s secrets are a good way to mount them into your pod.
  2. Credentials of other users, human or system. These should be hashed with a salt, so a compromise of your own service does not leak passwords of others. Your service uses these credentials to verify identity of another user, and luckily you don’t need the original password to do that. You can verify them with the stored hash too. If the hashes match, the user entered a matching password.

Where you store those hashes is of secondary concern, but I would opt for a more mutable location than a k8s secret, depending how often it changes. It depends a bit on your architecture. Maybe a database, or a persistent volume. As long as it’s not available to services that don’t need to use it.

justincormack commented 4 years ago

The advice is specifically for external user passwords, as these are low entropy and can be brute forced.

For internal tokens, in general you should not use passwords where possible, eg asymmetric keys have security advantages for communication between services (eg mutual TLS), but if you use passwords they should be long random ones. K8s secrets should be ok for these, but it may be worth doing some threat modelling, and working out how high risk they are, and what kind of rotation policies you should have.

christian-kreuzberger-dtx commented 4 years ago

First of all a big thank you to everyone that commented on this (on Slack and here on GitHub).

I understand and totally agree that runtime secrets such as our mongodb password or the api key can be stored as K8s secrets.

Regarding user credentials, I would like to discuss this a little bit in detail.

  1. Keptn does not have a user-based authentication as of right now, but it's on our roadmap. Whether this is an external SSO (OAuth, ...) LDAP or some sort of internal user database is not defined yet, but surely we will take any precautions, such as a strong password hash with salt, to ensure that the passwords can not be reversed (easily).
  2. Keptn stores git credentials (needed for our GitOps approach), which are read by the configuration-service to pull and push git commits. Right now these credentials are stored in K8s secrets, they are not hashed nor encrypted. I believe that this is something that can be improved, either by encrypting, a password-fault, or something else, so here we would need some advise.
jetzlstorfer commented 4 years ago

Is there any update on this issue? Has there already been a decision made on how this will be implemented going forward?

christian-kreuzberger-dtx commented 4 years ago

No udpates so far.

thisthat commented 2 years ago

I think point (2) is not relevant anymore since we implemented OIDC with #6069 which replaces the Bridge credentials