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

Feature: Auto-generate datastore_crypto_key if not provided #225

Closed
cognifloyd opened this issue Jul 28, 2021 · 0 comments · Fixed by #266
Closed

Feature: Auto-generate datastore_crypto_key if not provided #225

cognifloyd opened this issue Jul 28, 2021 · 0 comments · Fixed by #266
Assignees

Comments

@cognifloyd
Copy link
Member

cognifloyd commented Jul 28, 2021

It would be nice to auto-generate the datastore_crypto_key as part of the helm install.
All of the templates get templated at once, so using the st2-generate-symmetric-crypto-key utility (as described in the datastore doc) cannot be encapsulated within the chart. Instead, we need to be able to generate the key using helm or sprig functions.

Internally, st2-generate-symmetric-crypto-key uses st2common.util.crypto.AESKey.generate(key_size=256). That returns a json document with two keys that need to be generated: hmacKey.hmacKeyString and aesKeyString.

Those strings are "Base64 web safe encoding [with] suppress[ed] padding characters (=)." Here "web safe encoding" means "Uses URL-safe alphabet: - replaces +, _ replaces /." (from the docstrings)

Essentially, those two strings are generated with this snippet of python:

base64.urlsafe_b64encode(os.urandom(int(256 / 8))).decode("utf-8").replace("=", "")

Looking over the helm and sprig docs, I believe we can generate those strings with this (32 = 256/8):

"{{ randBytes 32 | replace '+' '-' | replace '_' '/' | replace '=' '' }}"

So, in values, the datastore_crypto_key could be generated with something like this:

st2:
  datastore_crypto_key:
    hmacKey:
      # 32 bytes = 256 bits / 8 bits/byte
      # this formula is based on an st2-specific version of python's base64.urlsafe_b64encode.
      # randBytes returns a base64 encoded string.
      hmacKeyString: "{{ randBytes 32 | replace '+' '-' | replace '_' '/' | replace '=' '' }}"
      size: 256
    aesKeyString: "{{ randBytes 32 | replace '+' '-' | replace '_' '/' | replace '=' '' }}"
    mode: CBC
    size: 256

When this gets integrated in templates/secrets_datastore_crypto_key.yaml, we also need to account for converting from the dict/hash to a json-encoded string. So, maybe something like:

  {{- if kindOf .Values.st2.datastore_crypto_key | eq "string" }}
  datastore_crypto_key: {{ .Values.st2.datastore_crypto_key | b64enc }}
  {{- else }}
  datastore_crypto_key: {{ tpl (.Values.st2.datastore_crypto_key | toJson) . | b64enc }}
  {{- end }}

And, we need to use a technique similar to how we generate & presserve the st2auth password; We want to generate the datastore_crypto_key and preserve it across upgrades:
https://github.com/StackStorm/stackstorm-ha/blob/db4d3f25ec1272dbf67bd96a0fd65d156fd0b036/templates/secrets_st2auth.yaml#L27-L32

I'm not going to submit this as a PR. Instead I'll leave it for a first-time contributor. Hopefully there are enough details here so someone can create a PR out of this. edit: I pushed a PR.

@cognifloyd cognifloyd added help wanted Extra attention is needed good first issue Good for newcomers feature security labels Jul 28, 2021
@cognifloyd cognifloyd removed help wanted Extra attention is needed good first issue Good for newcomers labels Nov 11, 2021
@cognifloyd cognifloyd self-assigned this Nov 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant