We often hear from users, that they want to store “secure information” like password, keys, which should not be shown plain text on the UI. Even on the database, they should not be stored as plain text.
What do you think about
a) moving Content Credentials from Katello to Foreman, extend the functionality so that it can store username/password or other “secure information” and make it therefore available for all foreman plugins
b) implement something completely new so that it can store secure information
In Katello we’re in planning stages to remove all our pages that use AngularJS, and redesign and/or rewrite them in React and modern Patternfly. Content Credentials is one of them, so this update could be in tandem with that.
So now there are two questions:
Should Content Credentials be extended, or should a new entity be created that deals only with secrets?
Where should the code live? Should it stay in Katello or move to Foreman?
For #2 I think it’s clear that the new capabilities should live in Foreman, since that way any plugin will be able to benefit. Assuming the code is in Foreman, I’m slightly leaning toward making a new entity, since that seems cleaner to me. But would be good to get some more inputs and opinions.
I’m proposing option c) and use the existing solution that @nixfu already hinted at.
For values in the DB, this is the way to go. We have EncryptValue for a low level implementation (used in Setting where only certain settings are encrypted) and the more generic Encryptable if you always want to encrypt a column (like the account_password field on AuthSourceLdap).
Fascinatingly, ContentCredentials are not using this encryption while other parts in Katello are. I think this is a bug.
The idea behind this is, to have a storage in foreman which can store ‘somehow sensible data’. Ok, in case of gpg public keys this is not really sensible…
If there is a way to store username/password, ssh keys in general, other plugins can just use this functionality.
But I would also be happy to use a solution which encrypts the data so that it gets never shown plain text in logs, UI, etc.
The first idea was to add a new functionality in foreman which is able to store “sensitive” data - like passwords, keys, etc. Everything a user may want to be stored encryped in the DB. It’s something like a key:value storage.
This kind of data can then be used in host parameters, ansible variable, provisioning templates or by certain plugins. Instead of defining username/password for each Katello repository, it may be nice to select a foreman sensitive data entitiy which provides username/password. In case you want to change the credentials, you would do this in one central place.
Does this make sense? If you think, this is nonsense - I’m happy to receive such a feedback. Then we need to find a better solution for the foreman_ansible git extension to have authentication. Just let me know other possibilities.
I don’t think this makes sense. We already have a mechanism to store columns encrypted. Why complicate it further by introducing a centralized model?
Can you give an example where this would be reused and it’s easier than to implement a specialized model?
In Katello the SSH credentials are irrelevant, so you would have to write code to filter it out again. For completeness, this is how Katello makes sure the repository credentials are encrypted:
In the API it is not presented, but instead a special field is shown whether it exists:
I think the Encryptable module we have in core is a good one, but also very low level. I guess having a model you can ask for a secret by name would be a nice dev’s syntax sugar that could use Encryptable under the hood.
What I like in particular on it is, that the encryption key is stored outside of the DB, where the encrypted data lives. The entire system would have to be compromised to decrypt those secrets. What I don’t like about that approach is, it’s not reusable in external systems, e.g. when the secret needs to be passed to dynflow or smart proxy (e.g. ssh key passphrase for scheduled remote execution job). For that, some external system may be more useful, but I’d love to avoid adding more complexity to our stack unless necessary.
Something like Hashicorp Vault might be a solution for those use cases, but as you say, it comes with a non-trivial added complexity. This is why we’ve traditionally relies on someone (AKA, the admin) provisioning the Smart Proxy with secrets if it needs to. For REX the SSH key lives on the Smart Proxy. It could be reused for VCS cloning. That probably wouldn’t work for username/password so it’d need a different solution.
I was more after passphrase for those keys. That was an example of something that we need to store securely for until the execution happens. Vault/OpenBao was the first thing that came to my mind, but I think it’s too heavy for our current needs.