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

[Secrets] Support using key maps for secrets #1195

Merged
merged 12 commits into from
Aug 11, 2021

Conversation

Hedingber
Copy link
Contributor

We started saving each schedule credentials in project secrets, so far we used the schedule key to generate the secret key, but secret keys in k8s have restriction which schedule names might not X to.
Therefore I added a mechanism to save a key map in a value of another secret key, that is simply a json dump of a map between the schedule names to generated uuids that are used as the actual secret keys.
Note that we're using the key map only when needed - for schedule names that are invalid secret keys
2 other solutions brought up that we decided not to choose:

  1. "Hashing"/base64 encoding the schedule name - hashing is not bidirectional, and base64 has characters that are invalid in a secret key
  2. Adding an annotation on the schedule holding the secret key - this makes debugging harder as in order to understand which secret key relevant to what schedule you need either access to the DB or to the logs (which might rotate)

@Hedingber
Copy link
Contributor Author

Hedingber commented Aug 9, 2021

Reminding myself - add a test that creates a schedule with name that is an invalid secret key

Copy link
Member

@theSaarco theSaarco left a comment

Choose a reason for hiding this comment

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

Looks very good, I do have some change requests, but those are mostly style-related and some more validations needed.

mlrun/api/crud/secrets.py Outdated Show resolved Hide resolved
mlrun/api/crud/secrets.py Outdated Show resolved Hide resolved
mlrun/api/crud/secrets.py Outdated Show resolved Hide resolved
mlrun/api/crud/secrets.py Outdated Show resolved Hide resolved
return key.startswith(self.internal_secrets_key_prefix)

def _is_key_map_secret_key(self, key: str) -> bool:
return key.startswith(self.key_map_secrets_key_prefix)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
return key.startswith(self.key_map_secrets_key_prefix)
return key.startswith(self.key_map_secrets_key_prefix) and validate_secret_key_regex(key, raise_on_failure=False)

A key-map secret must be stored as a 1st level secret (otherwise you'll get issues with key-map pointing at key-map which obviously won't work).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I already the validate the key map secret key regex on creation (in _validate_and_enrich_secrets_to_store in line 349) as a proof, the test you asked to verify that was working
I don't see a reason validating the key every time I'm calling this function which is just there to check whether we're dealing with a key map secret key

Copy link
Member

Choose a reason for hiding this comment

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

If the client is used a key name generated by generate_schedule_key_map_secret_key then of course there's no issue. But, the other methods actually get a key-map name, which can be anything. For example, I can call get_secret and pass a name that is not valid for the key-map. In this case the flow will eventually fail in _resolve_secret_key as it tries to list_secrets on the invalid key name. It's not terrible, but it is easier to debug if there's a specific check for the key-map name that puts out an indicative error on that.
I don't mind too much keeping it as-is, but it would have been clearer that way.

tests/api/crud/test_secrets.py Show resolved Hide resolved
tests/api/crud/test_secrets.py Outdated Show resolved Hide resolved
tests/api/crud/test_secrets.py Outdated Show resolved Hide resolved
tests/api/crud/test_secrets.py Outdated Show resolved Hide resolved
tests/api/crud/test_secrets.py Outdated Show resolved Hide resolved
Copy link
Member

@theSaarco theSaarco left a comment

Choose a reason for hiding this comment

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

Looks good - approved. There's one comment which is a nice-to-have improvement for better error handling IMO, but it's up to you.

return key.startswith(self.internal_secrets_key_prefix)

def _is_key_map_secret_key(self, key: str) -> bool:
return key.startswith(self.key_map_secrets_key_prefix)
Copy link
Member

Choose a reason for hiding this comment

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

If the client is used a key name generated by generate_schedule_key_map_secret_key then of course there's no issue. But, the other methods actually get a key-map name, which can be anything. For example, I can call get_secret and pass a name that is not valid for the key-map. In this case the flow will eventually fail in _resolve_secret_key as it tries to list_secrets on the invalid key name. It's not terrible, but it is easier to debug if there's a specific check for the key-map name that puts out an indicative error on that.
I don't mind too much keeping it as-is, but it would have been clearer that way.

@Hedingber
Copy link
Contributor Author

Sounds good, I will add it in a followup PR (already have one in progress, which I'm afraid gonna conflict with this one, so want to merge it)

@Hedingber Hedingber merged commit 57dd590 into mlrun:development Aug 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants