feat: add decryption capability in userdata with Jinja template#6708
feat: add decryption capability in userdata with Jinja template#6708acolombier wants to merge 2 commits intocanonical:mainfrom
Conversation
93c04fb to
79256a6
Compare
|
Thanks for the proposal. Test failures aside, this isn't packaged in Ubuntu main - I expect other distros would need packaging work too - so this approach is a non-starter. On another note, this only addresses one security concern (secrets in meta-data), while other significant ones remain: platform trust, platform confidentiality, etc. I don't think that this is the path that we would prefer to take - a more comprehensive TPM-based solution would be preferred. |
|
Thank you for your initial input.
That's a fair point. Would it make sense to explore this as an optional feature, perhaps enabled conditionally, whether GPG is available or not? (note that I have suggested dropping the added Python deps and use subprocess instead)
I understand your perspective. To clarify, I actually submitted a separate feature request (#6655) to address userdata sensitive info separately to platform trust, as I see these as distinct but complementary security layers. For context, TPM-based solutions might not always be practical in PaaS environments, where TPMs are often virtualised and don’t provide the level of trust as in bare-metal/IaaS scenarios. |
|
Hi @holmanb, I have pushed a fixup that brings the two mentioned changes above:
This certainly would require more tests and likely more explicit documentation, but keen to hear if this is now aiming to something that could be accepted, before I spent more time on it. |
|
Hello! Thank you for this proposed change to cloud-init. This pull request is now marked as stale as it has not seen any activity in 14 days. If no activity occurs within the next 7 days, this pull request will automatically close. If you are waiting for code review and you are seeing this message, apologies! Please reply, tagging blackboxsw, and he will ensure that someone takes a look soon. (If the pull request is closed and you would like to continue working on it, please do tag blackboxsw to reopen it.) |
|
Hi @blackboxsw, this is waiting for feedback |
|
I don't think that this proposal fits the current scope of this project. The core functionality proposed here is already possible. A user that is willing to modify an image to deploy GPG keys can already craft a runcmd / bootscript / etc to access encrypted secrets embedded in user-data. Rather than implementing a new UI for a preexisting capability, a proposal that documents how to do this would be welcome. Or, like I mentioned before, it would be more interesting to see a new solution that utilizes cloud capabilities to provide stronger guarantees than are currently possible with cloud-init. |
I don't think this is quite accurate. Of course, you can run
Furthermore, if we follow your thinking, then TPM is also already supported and can be used to decrypt files using Here is some cloud-init userdata example to highlight the value users:
- name: machine
passwd: |-
{{gpgdecrypt("bG9yZW0gaXBzdW0K")}}
write_files:
- content: |
api_key: {{gpgdecrypt("bG9yZW0gaXBzdW0K")}}
site: datadog.eu
tags:
- "foo:yes"
- "bar:no"
cloud_provider_metadata:
- "aws"
- "azure"
- "gcp"
logs_enabled: true
logs_config:
auto_multi_line_detection: true
# Truncating other log ingestion specific config which would benefit being visible and
# editable by a larger audienceAs you can see with this datadog config file, only For full disclosure, here is how we previously workaround this lack of feature: # No simple workaround for users
write_files:
- path: /etc/datadog-agent/datadog.yaml
content: |
api_key: $DD_API_KEY
site: datadog.eu
tags:
- "foo:yes"
- "bar:no"
cloud_provider_metadata:
- "aws"
- "azure"
- "gcp"
logs_enabled: true
logs_config:
auto_multi_line_detection: true
- path: /var/run/secrets/dd_api_key.gpg
content: bG9yZW0gaXBzdW0K
runcmds:
- sed -i 's/$DD_API_KEY/'`base64 -d /var/run/secrets/dd_api_key.gpg | gpg --decrypt`'/' /etc/datadog-agent/datadog.yamlFinally, just to close the argument of opposing this feature with TPM, here is how the same can be accomplished with TPM encryption: write_files:
- path: /etc/datadog-agent/datadog.yaml
content: |
api_key: $DD_API_KEY
site: datadog.eu
tags:
- "foo:yes"
- "bar:no"
cloud_provider_metadata:
- "aws"
- "azure"
- "gcp"
logs_enabled: true
logs_config:
auto_multi_line_detection: true
- path: /var/run/secrets/dd_api_key.secret
content: |-
eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2R0NNIiwiY2xldmlzIjp7InBpbiI6InRwbTIiLCJ0cG0yIjp7Imhhc2giOiJzaGEyNTYiLCJqd2tfcHJpdiI6IkFOMEFJTVFTSnA0ZEtTV0E5WDBGNmlJR0lQOURraV9zTXE0NG1DcGJOVDBrOUtrQ0FCQ2dTSTlZY0VYdUVaY1JWd2pFOFFBRnNEZ1FHaFBHRnpPakpVVmI5WDlUamlfUGo2Vl94MjZ1OUQ3T0RZbVVqTjhEV1A3b3NzOVMwT0NwYVhqOUhzTTd2V3lJOU5XMU90VTdweFVYZ19VWjVMRDltcmhVTVIxdWI0akZNOGt6V3N4SFFxcnN2cjF4b1h6dUtKUzRSazg4VFF1WURNcUY2QVZKcWxJWXJJUUluMzFSTlZqMG5UV0oxRHdDT1M4bDdpWkVzWU5LaGRMYXNUTkhHNjNwNW1LYzBjRnFPY0ZKZ3FMMzhFT1ZibXhYamZvRV9VNjRIV0dEaHciLCJqd2tfcHViIjoiQUM0QUNBQUxBQUFFMGdBQUFCQUFJTzcxWFlMSTJEUEttS28xcnBTMlVacDdvVVMxZ3hSalA5bWFZLVNGRldEdiIsImtleSI6ImVjYyJ9fX0..Kf-C6HWum3FilI9V.MzXraw.13HOCcxhQIJzYuJMwFgnfA
runcmds:
- sed -i 's/$DD_API_KEY/'`clevis decrypt tpm2 '{"pcrs":"7"}' < /var/run/secrets/dd_api_key.secret`'/' /etc/datadog-agent/datadog.yaml |
The requirements were met with existing cloud-init features. This is similar to the documentation example previously suggested. The primary objection to this proposal is that there is limited usefulness and user-base for a cloud-init feature that cannot be used without building a custom image. Additionally, this proposal increases the size of the UI without adding new functionality - a burden for upstream to maintain without a benefit to the majority of users.
The configuration could be stored as a template and rendered during a continuous deployment step. Alternatively, cloud-init has boothook scripts, user-data scripts, MIME, and cloud-config archive as possible formats to encrypt only part of the file.
A preferred solution would use a (v)TPM and not require the user to modify the image. Besides encrypting the user-data, this would be transparent to the user. |
"having workaround to accomplish a functionality" != "having the functionality" Closing as we have wasted enough time already. |
This aims to fix #4417 by implementing the plan proposed in #6655. It uses GPG to pass sensitive information in an encrypted way.
tests/unittests/cloudinit/example.pyshould be tested bytests/unittests/test_example.pytox -e py3tox -e doc.Proposed Commit Message
Additional Context
1. This currently requires to add a dependencies to python-gnupg, which might turn out to be controversial. Note that due to the simple use of GPG (Now use the command directly via std lib.--decrypt), it should be possible to also directly wrap GPG invocation by a subprocess2. I have added documentation, by I expect some user manual text might need updating too. Since I couldn't find where this would be the most relevant, I am keeping this as a TODO, and will follow your feedback as of where to document this.
Test Steps
Unit test can be use to confirm it works. To test on a real setup, make sure to install the GPG key with "encrypt" usage on the cloudinit's user keyring (root by default) or to any keyring pointed by the
GNUPGHOMEenvvar (e.g using systemd).Encrypt sensitive value and pass it to the userdata in base64 format (see
doc/userdata.txtfor further details)Merge type