{"id":3518,"date":"2016-09-05T09:38:30","date_gmt":"2016-09-05T08:38:30","guid":{"rendered":"https:\/\/www.devco.net\/?p=3518"},"modified":"2016-09-05T10:31:04","modified_gmt":"2016-09-05T09:31:04","slug":"puppet-4-sensitive-data-types","status":"publish","type":"post","link":"https:\/\/www.devco.net\/archives\/2016\/09\/05\/puppet-4-sensitive-data-types.php","title":{"rendered":"Puppet 4 Sensitive Data Types"},"content":{"rendered":"

You often need to handle sensitive data in manifests when using Puppet. Private keys, passwords, etc. There has not been a native way to deal with these and so a cottage industry of community tools have spring up. <\/p>\n

To deal with data at rest various Hiera backends like the popular hiera-eyaml<\/a> exist, to deal with data on nodes a rather interesting solution called binford2k-node_encrypt<\/a> exist. There are many more but less is more, these are good and widely used.<\/p>\n

The problem is data leaks all over the show in Puppet – diffs, logs, reports, catalogs, PuppetDB – it’s not uncommon for this trusted data to show up all over the place. And dealing with this problem is a huge scope issue that will require adjustments to every component – Puppet, Hiera \/ Lookup, PuppetDB, etc.<\/p>\n

But you have to start somewhere and Puppet is the right place, lets look at the first step.<\/p>\n

Sensitive[T]<\/H2>
\nPuppet 4.6.0 introduce – and 4.6.1 fixed – a new data type that decorates other data telling the system it’s sensitive. And this data cannot by accident become logged or leaked since the type will only return a string indicating it’s redacted.<\/p>\n

It’s important to note this is step one of a many step process towords having a unified blessed way of dealing with Sensitive data all over. But lets take a quick look at them. The official specification for this feature lives here<\/a>.<\/p>\n

In the most basic case we can see how to make sensitive data, how it looks when logged or leaked by accident:<\/p>\n

\r\n$secret = Sensitive(\"My Socrates Note\")\r\nnotice($secret)\r\n<\/pre>\n

This prints out the following:<\/p>\n

\r\nNotice: Scope(Class[main]): Sensitive [value redacted]\r\n<\/pre>\n

To unwrap this and gain access to the real original data:<\/p>\n

\r\n$secret = Sensitive(hiera(\"secret\"))\r\n\r\n$unwrapped = $secret.unwrap |$sensitive| { $sensitive }\r\nnotice(\"Unwrapped: ${unwrapped}\")\r\n\r\n$secret.unwrap |$sensitive| { notice(\"Lambda: ${sensitive}\") }\r\n<\/pre>\n

Here you can see how to assign it unwrapped to a new variable or just use it in a block. Important to note you should never print these values like this and ideally you’d only ever use them inside a lambda if you have to use them in .pp code. Puppet has no concept of private variables so this $unwrapped<\/em> variable could be accessed from outside of your classes. A lambda scope is temporary and private.<\/p>\n

The output of above is:<\/p>\n

\r\nNotice: Scope(Class[main]): Unwrapped: Too Many Secrets\r\nNotice: Scope(Class[main]): Lambda: Too Many Secrets\r\n<\/pre>\n

So these are the basic operations, you can now of course pass the data around classes.<\/p>\n

\r\nclass mysql (\r\n  Sensitive[String] $root_pass\r\n) {\r\n  # somehow set the password\r\n}\r\n\r\nclass{\"mysql\":\r\n  root_pass => Sensitive(hiera(\"mysql_root\"))\r\n}\r\n<\/pre>\n

Note here you can see the class specifically wants a String that is sensitive and not lets say a Number using the Sensitive[String]<\/em> markup. And if you attempted to pass Sensitive(1)<\/em> into it you’d get a type missmatch error.<\/p>\n

Conclusion<\/H2>
\nSo this appears to be quite handy, you can see down the line that lookup()<\/em> might have a eyaml like system and emit Sensitive data directly and perhaps some providers and types will support this. But as I said it’s early days so I doubt this is actually useful yet.<\/p>\n

I mentioned how other systems like PuppetDB and so forth also need updates before this is useful and indeed today PuppetDB is oblivious to these types and stores the real values:<\/p>\n

\r\n$ puppet query 'resources[parameters] { type = \"Class\" and title = \"Test\" }'\r\n...\r\n  {\r\n    \"parameters\": {\r\n      \"string\": \"My Socrates Note\"\r\n    }\r\n  },\r\n...\r\n<\/pre>\n

So this really does not yet serve any purpose but as a step one it’s an interesting look at what will come.<\/p>\n","protected":false},"excerpt":{"rendered":"

You often need to handle sensitive data in manifests when using Puppet. Private keys, passwords, etc. There has not been a native way to deal with these and so a cottage industry of community tools have spring up. To deal with data at rest various Hiera backends like the popular hiera-eyaml exist, to deal with […]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_et_pb_use_builder":"","_et_pb_old_content":"","footnotes":""},"categories":[7],"tags":[121,85,21],"_links":{"self":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3518"}],"collection":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/comments?post=3518"}],"version-history":[{"count":6,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3518\/revisions"}],"predecessor-version":[{"id":3524,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/posts\/3518\/revisions\/3524"}],"wp:attachment":[{"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/media?parent=3518"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/categories?post=3518"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devco.net\/wp-json\/wp\/v2\/tags?post=3518"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}