Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add secrets config and vault secret actions #22

Merged
merged 25 commits into from
Jul 29, 2024
Merged

add secrets config and vault secret actions #22

merged 25 commits into from
Jul 29, 2024

Conversation

kelkawi-a
Copy link
Collaborator

@kelkawi-a kelkawi-a commented Jul 18, 2024

This PR introduces the following changes and additions:

  • Prior to this, users would attach an env-file resource to specify a set of environment variables which should be injected into the workload container and used by the workflow definitions. This approach was problematic in that it handles secret credentials poorly. The env-file is now deprecated in favor of the secrets config described below.
  • Adds the secrets config parameter, which can be used to instruct the charm to fetch secrets from three sources and inject them as environment variables into the workload container:
    • env: These are plaintext environment variables, which are usually not secret.
    • juju (Requires Juju 3.3+): These are variables stored as Juju secrets, where the user provides the ID of the secret and the key from which to fetch the value.
    • vault: These are variables fetched from Vault, provided the charm is related to a Vault charm.
  • Removes the logic where the charm was injecting Vault connection parameters into the workload container, as the workflows ideally do not need to interact with Vault to fetch secrets. This work is now handled by the charm, the workload container should only expect specific environment variables to be present.
  • Adds actions for adding and reading secrets from Vault.
  • Updates docs and tests to reflect the changes.

Thanks to @gtato for the suggestions and useful design discussions.

@kelkawi-a kelkawi-a force-pushed the worker-secrets branch 6 times, most recently from 20cacf7 to 24634f3 Compare July 18, 2024 22:03
@kelkawi-a kelkawi-a force-pushed the worker-secrets branch 6 times, most recently from 431eb11 to fed3761 Compare July 21, 2024 16:34
@kelkawi-a kelkawi-a marked this pull request as ready for review July 23, 2024 13:57
@kelkawi-a kelkawi-a changed the title add secrets config and vault secret action add secrets config and vault secret actions Jul 24, 2024
Copy link

@AmberCharitos AmberCharitos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work! This is really nice, some non-blocking suggestions and one important question around the use of temporal actions to add and remove vault secrets.

README.md Outdated Show resolved Hide resolved
src/secret_processors.py Outdated Show resolved Hide resolved
src/secret_processors.py Outdated Show resolved Hide resolved
charm.framework.observe(charm.on.get_vault_secret_action, self._on_get_vault_secret)

@log_event_handler(logger)
def _on_add_vault_secret(self, event):

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I'm a bit confused as to why we would add secrets to vault via Temporal - is there no way to do this directly on vault? Seems to me this should be Vault not Temporal functionality. I thought there might be some separation of access such that whoever has access to the worker charm didn't necessarily have access to vault to change credentials - this seems to go against that.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a case of separation of access v practicality. We had a similar discussion for the Temporal charm when adding the OpenFGA relation in this PR, where we added utility actions for interacting with the OpenFGA store through the Temporal charm.

There is a way of doing it directly through the vault snap, but not through actions on the Vault charm. I opted to go down a similar path as the Temporal charm and add some utility methods that allow users to easily add secrets to Vault through the Temporal worker charm.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is required at the moment to make the charm functional, ok, but i agree with Amber that this defies a bit the point of Valut. If the same party can read and write secrets in/from Vault, there is practically no difference between using vault or an environment variable. If we have a centralized vault, we'd assume that different people add secrets potentially via the UI.

README.md Outdated Show resolved Hide resolved
Copy link
Contributor

@onurmus onurmus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left some small comments but none of them is a blocker. Great work!

src/relations/vault.py Outdated Show resolved Hide resolved
src/relations/vault.py Outdated Show resolved Hide resolved
src/vault/actions.py Outdated Show resolved Hide resolved
src/vault/actions.py Outdated Show resolved Hide resolved
src/vault/actions.py Outdated Show resolved Hide resolved
tests/integration/helpers.py Show resolved Hide resolved
Copy link

@gtato gtato left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments, nothing blocking.

README.md Outdated Show resolved Hide resolved
README.md Outdated
##### **`secrets.yaml`**

```yaml
secrets:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if we called it environment.yaml (since not all envs are secrets, but all secrets are envs)
what if we put env as root:

env:
    plain (or default):
     - key1: value1
    juju:
     ...
    vault:
     ...

or a more k8s-ish syntax

env: 
   - name: key1
     value: val1
   - name: key2
     valueFromSecret:
        type: juju
        id: secret-id
        key: key2 
   - name: key3
     valueFromSecret:
        type: vault
        id: secret-path
        key: key3      

or a more compact form of this:

env: 
   - name: key1
     value: val1
   - name: key2
     valueFromSecret: juju@secret-id:key2
   - name: key3
     valueFromSecret: vault@secret-path:key3 

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I went with the low impact change, as I'd like to avoid having the config look k8s-ish, and the compact form might have readability issues.

secrets:
juju:
- secret-id: <secret_id>
key: key1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: the key here matches both the key in the secret and the name of the environment variable right? I think there might be cases when that could be annoying because as a developer you are obliged to use an env that you might not know from the beginning

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure I understand but yes the key in the secret must match the key that the user specified in their code. What would be an alternative?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit related to the convo Amber touched on. People who set secrets should in general be different from the ones who write the code. So in the code you know you need some environment variable, but you should be able to call it whatever you want (say MY_ENV). Similarly, the person who writes the secret, can put a whatever key (say my_secret). Only at the moment of the deployment, you should say: load my_secret value into MY_ENV. We should not assume that the programmer knows that the key is my_secret and do os.getenv('my_secret') from the beginning.

Copy link
Collaborator Author

@kelkawi-a kelkawi-a Jul 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. So for juju and Vault, I guess we will need to add an optional key of what the env variable name should be? Something like:

juju:
   - secret-id: <secret_id>
     src-key: key
     dest-key: MY_ENV

Or it could be (I like this more):

juju:
   - secret-id: <secret_id>
     key-name: MY_ENV
     from-key: key

Any suggestions?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is fine, but then i think you would need to keep the env consistent:

env:
   - name: MY_ENV1
     value: bla bla
juju:
   - name: MY_ENV2
     secret-id: secret-id
     key: key2
vault:
   - name: MY_ENV3
     secret-path: secret-path
     key: key3

README.md Show resolved Hide resolved
src/charm.py Outdated Show resolved Hide resolved
README.md Show resolved Hide resolved
src/secret_processors.py Outdated Show resolved Hide resolved
charm.framework.observe(charm.on.get_vault_secret_action, self._on_get_vault_secret)

@log_event_handler(logger)
def _on_add_vault_secret(self, event):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is required at the moment to make the charm functional, ok, but i agree with Amber that this defies a bit the point of Valut. If the same party can read and write secrets in/from Vault, there is practically no difference between using vault or an environment variable. If we have a centralized vault, we'd assume that different people add secrets potentially via the UI.

@kelkawi-a kelkawi-a merged commit 56a1b70 into main Jul 29, 2024
19 checks passed
@kelkawi-a kelkawi-a mentioned this pull request Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants