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

Support sensitive values in to_json_pretty #1418

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

alexjfisher
Copy link
Collaborator

@alexjfisher alexjfisher commented Feb 14, 2024

The idea is being able to do something like this, (where just the call to to_json_pretty is explicitly Deferred - needed because node_encrypt returns a Deferred)

file { '/etc/my_secret.json':
  content => Deferred('to_json_pretty',[{
    username => 'myuser',
    password => lookup('my_eyaml_secret').node_encrypt::secret,
  }]),
}

... instead of having to also explicitly defer unwrap and Sensitive and end up with a huge mess similar to...

file { '/etc/my_secret.json':
  content => Sensitive(
    Deferred('to_json_pretty',[{
      username => 'myuser',
      password => Deferred('unwrap', [lookup('my_eyaml_secret').node_encrypt::secret]),
    }])
  ),
}

The thought behind rewrap_sensitive_data is it makes it easy to extend this functionality into other similar functions, (to_yaml, to_toml etc.)

Later, we might consider adding a deferrable_to_XXX functions to further simplify this sort of use-case.

No spec tests yet. Just wanted to get some early feedback before taking it further.

call_function('stdlib::rewrap_sensitive_data', data) do |unwrapped_data|
# Call ::JSON to ensure it references the JSON library from Ruby's standard library
# instead of a random JSON namespace that might be in scope due to user code.
::JSON.pretty_generate(unwrapped_data, opts) << "\n"
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Leading colons put back in to match existing comment. See #1307 (comment)

@alexjfisher
Copy link
Collaborator Author

@binford2k Would be interested to hear your thoughts around this. I dunno if I've come up with a great or terrible idea! :)

@LukasAud
Copy link
Contributor

I like the idea behind this. Looks like a nice QoL update to clean up functions and make things a bit more readable 👍

Unfortunately, I can't tell right away if there is any limitations or issues with this approach but I'll try to shine some light on this PR and see if it catches some eyes.

Comment on lines 43 to 50
obj.each_with_object({}) do |(key, value), result|
result[key] = deep_unwrap(value)
end
Copy link
Collaborator

Choose a reason for hiding this comment

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

Probably unlikely that you want to unwrap keys, so you can also use transform_values for shorter code:

Suggested change
obj.each_with_object({}) do |(key, value), result|
result[key] = deep_unwrap(value)
end
obj.transform_values { |value| deep_unwrap(value) }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Thanks. If anyone ever does come up with a situation where they've ended up with a sensitive(string) as a hash key we can always change it back and add this functionality.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I've had a rethink! :) I agree it's probably unlikely to come across sensitive keys, but not impossible or inherently wrong. It's also easy enough to code for, so I've added a test and now handle this case.


unwrapped = deep_unwrap(data)

result = block_given? ? yield(unwrapped) : unwrapped
Copy link
Collaborator

Choose a reason for hiding this comment

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

Should the yielded unwrapped actually return a Sensitive. Or in other words, should it be yield(wrapped) instead?

Copy link
Collaborator Author

@alexjfisher alexjfisher Feb 15, 2024

Choose a reason for hiding this comment

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

No, I think this is correct. The block, (if provided), needs to be handed the unwrapped data so that it can mutate it as desired (eg. serialising to yaml or json), before this function then wraps the result back up with sensitive.

I've added the first spec tests that hopefully illustrates this a bit better.

@alexjfisher alexjfisher force-pushed the why_so_sensitive branch 4 times, most recently from 6a51eed to 1f22947 Compare February 16, 2024 15:10
The idea is being able to do something like this, (where just the call
to `to_json_pretty` is explicitly `Deferred` - needed because
`node_encrypt` returns a `Deferred`)

```puppet
file { '/etc/my_secret.json':
  content => Deferred('to_json_pretty',[{
    username => 'myuser',
    password => lookup('my_eyaml_secret').node_encrypt::secret,
  }]),
}
```

... instead of having to also explicitly defer `unwrap` and `Sensitive` and
end up with a huge mess similar to...

```puppet
file { '/etc/my_secret.json':
  content => Sensitive(
    Deferred('to_json_pretty',[{
      username => 'myuser',
      password => Deferred('unwrap', [lookup('my_eyaml_secret').node_encrypt::secret]),
    }])
  ),
}
```

The thought behind `rewrap_sensitive_data` is it makes it easy to
extend this functionality into other similar functions, (`to_yaml`,
`to_toml` etc.)

Later, we might consider adding a `deferrable_to_XXX` functions to
further simplify this sort of use-case.
@alexjfisher alexjfisher changed the title PoC/RFC: Support sensitive values in to_json_pretty Support sensitive values in to_json_pretty Feb 19, 2024
@alexjfisher alexjfisher marked this pull request as ready for review February 19, 2024 13:10
@binford2k
Copy link
Contributor

I really like the rewrap-with-a-block idea. I hate that we have to do it. 🤣

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.

5 participants