Context
Currently there is no good way to pass secrets to a Remote Execution job. All the information that is passed as an input, or even rendered directly by the template can be read from Foreman’s UI.
Proposal
Add a new type for inputs to indicate that the input is a secret.
Values for those inputs would be encrypted before it’s stored.
They will be transferred to the Smart Proxy as encrypted and decrypted there.
The decrypted value would be injected as an ENV variable for both Ansible and Script job types.
Ideally the values would be encrypted with the relevant Smart Proxy public key, so only the proxy would be able to decrypt those values.
@Bernhard_Suttner Would be interesting to hear if this strategy (injecting ENV variables) will also work for Salt-based job types.
It would be a bit more complicated than using the encrypted column, since we need to decrypt the value in the proxy (as opposed to decrypting it in the Foreman server process). Of course we can pass the decryption key to the proxy as a method parameter, but I find it less secure and prone to key exposure.
For 1 I suppose we will need to encrypt only parameters of a certain type, meaning Encryptable won’t fit, unless we extend it with a conditional option (which is not a bad thing).
As for transport - that would be yet another can of worms.
We already connect to proxies using HTTPS. In theory you could figure out the public key from the proxy, but that feels redundant.
Are env vars really a good idea? They often get dumped in process traces. https://www.redhat.com/sysadmin/ansible-playbooks-secrets describes passing them in an encrypted store. Not sure how much sense that makes, but it I’d lean to that.
Another aspect where I don’t know Ansible well enough, but in Puppet you have Sensitive as a type that shows up in logs as [redacted] and file diffs aren’t shown (because they can contain sensitive data). How does Ansible handle this?
From my understanding Ansible Vault meant to store variables on disk in a secure manner.
Here the problem is different - we are trying to protect the values from being stored in Foreman as plain text and then treated as non-secure data (being logged e.t.c.). I think the no-log directive is closer concept in the Ansible world.
Another problem that will need solving is non-ansible executors like Salt and Bash. We will need a generic way to pass secrets to all three executors. In my opinion ENV is a good compromise here, since it’s ubiquitous for all executors.
Is it the only way we can connect to a proxy? If it is, it makes our lives much easier and we can pass the secrets as parameters to the smart proxy call (as long as we don’t log it of course). If we still have a way to define HTTP proxies, we will need to make sure we do pass a secret somehow to the proxy.
Technically Foreman supports plain text HTTP, but I think it’s rare that it’s deployed that way. We should consider the Foreman ↔ Foreman Proxy as a trusted channel. Our threat model doesn’t account for it being compromised.