Jira (PUP-8947) Automatically cast ACPL results to Sensitive for Sensitive-typed class parameters

4 views
Skip to first unread message

Reid Vandewiele (JIRA)

unread,
Jun 28, 2018, 2:26:03 PM6/28/18
to puppe...@googlegroups.com
Reid Vandewiele updated an issue
 
Puppet / Improvement PUP-8947
Automatically cast ACPL results to Sensitive for Sensitive-typed class parameters
Change By: Reid Vandewiele
Summary: Automatically cast ACPL String results to Sensitive for Sensitive-typed class parameters
Add Comment Add Comment
 
This message was sent by Atlassian JIRA (v7.7.1#77002-sha1:e75ca93)
Atlassian logo

Reid Vandewiele (JIRA)

unread,
Jun 28, 2018, 2:28:04 PM6/28/18
to puppe...@googlegroups.com
Reid Vandewiele updated an issue
h2. When Puppet does an Automatic Class Parameter lookup for a class parameter that is of type Sensitive [T] , a String T value being returned should automatically be cast to Sensitive [T] .

The use case here is that I store sensitive data in hiera encrypted in eyaml. I have corresponding profiles that have class parameters defined like so:
{code:java}
class profile::some_profile (
  Sensitive[String[1]] $some_sensitive_value,
) {
  # puppet code here
}{code}
It is currently a significant amount of extra work to mark each hiera entry that is already encrypted as Sensitive; it actually quadruples the number of lines of data in a given yaml file for the first entry and triples it for all subsequent entries because, as of now, you must do this to mark the value as Sensitive:
{code:java}
---
lookup_options:
  profile::some_profile::some_sensitive_value:
    convert_to: "Sensitive"

profile::some_profile::some_sensitive_value: ENC[PKCS7,encrypted_value_here]{code}

Reid Vandewiele (JIRA)

unread,
Jun 28, 2018, 2:28:04 PM6/28/18
to puppe...@googlegroups.com
Reid Vandewiele commented on Improvement PUP-8947
 
Re: Automatically cast ACPL results to Sensitive for Sensitive-typed class parameters

Updated the title and description to reflect that. I don't know of any use cases for Sensitive values that aren't Strings, but if we support it, consistency is appropriate.

James Ralston (JIRA)

unread,
Jul 18, 2018, 1:48:07 PM7/18/18
to puppe...@googlegroups.com
James Ralston commented on Improvement PUP-8947

The problem I have with using covert_to in lookup_options is that is completely falls down in a case like this:

class duo (
  Struct[{
    Optional['duo'] => Struct[{
      Optional['host']              => Optional[String],
      Optional['ikey']              => Optional[Sensitive[String]],
      Optional['skey']              => Optional[Sensitive[String]],
      Optional['groups']            => Optional[Variant[String, Array[String]]],
      Optional['failmode']          => Optional[Enum['safe', 'secure']],
      Optional['pushinfo']          => Optional[Variant[Boolean, Enum['yes', 'no']]],
      Optional['http_proxy']        => Optional[String],
      Optional['autopush']          => Optional[Variant[Boolean, Enum['yes', 'no']]],
      Optional['prompts']           => Optional[Integer[1,default]],
      Optional['fallback_local_ip'] => Optional[Variant[Boolean, Enum['yes', 'no']]],
      Optional['send_gecos']        => Optional[Variant[Boolean, Enum['yes', 'no']]],
    }]
  }] $pam_duo_conf = {},
)

We want to use the duo::pam_duo_conf parameter in a template file, like so:

;
; This is the /etc/duo/pam_duo.conf.
;
; This file is managed by the Puppet duo module.  The contents of this file
; come from the duo::pam_duo_conf parameter.
;
<% if @pam_duo_conf.length > 0 -%>
<%   @pam_duo_conf.sort.each do |section, settings| -%>
 
[<%= section %>]
 
<%     settings.sort.each do |setting, value| -%>
<%       if value.is_a?(TrueClass) -%>
<%=        setting %> = yes
<%       elsif value.is_a?(FalseClass) -%>
<%=        setting %> = no
<%       elsif value.respond_to?('each') -%>
<%=        setting %> = <%= value.join(',') %>
<%       else -%>
<%=        setting %> = <%= value %>
<%       end -%>
<%     end -%>
<%   end -%>
<% else -%>
 
; The duo::pam_duo_conf parameter was empty.
<% end -%>

But of course, this fails:

Error: Could not retrieve catalog from remote server: Error 500 on SERVER: Server Error: Evaluation Error: Error while evaluating a Method call, Class[Duo]:
  parameter 'pam_duo_conf' entry 'duo' entry 'ikey' expects a value of type Undef or Sensitive[String], got String
  parameter 'pam_duo_conf' entry 'duo' entry 'skey' expects a value of type Undef or Sensitive[String], got String (file: /etc/puppetlabs/code/environments/production/modules/classifier/manifests/init.pp, line: 254, column: 32) on node lx-hamachi.sei.cmu.edu

So yes, I fully support having Sensitive[String] match String and cast it to Sensitive[String].

Alternatively, I would also support permitting manual casting. E.g.:

Cast[String, Sensitive] $foo = ''

Meaning, this will match either String or Sensitive[String], but if it matches String, it will wrap that String type in Sensitive, so that $foo will always be of type Sensitive[String].

The advantage of a manual cast is that it permits module authors to distinguish between "I expect this value to already be of type Sensitive because it's being generated by a function that should return a Sensitive type" versus "this value may originate from a source (e.g., ACPL) that lacks the Sensitive type and therefore I want to manually cast it to Sensitive if it is not already so."

Henrik Lindberg (JIRA)

unread,
Jul 18, 2018, 6:28:03 PM7/18/18
to puppe...@googlegroups.com

James Ralston For the issue you just showed I think we could consider making convert_to to perform type casting from a Struct with non Sensitive values to one having Sensitive entries.

The first workaround is to make the entire hash be Sensitive.

The second workaround I can think if is to have the two sensitive values be included in the hash (in hiera) via aliasing to two separate keys with the use of convert_to: 'Sensitive' for those two keys.

Third option (not so much a workaround) is to update the json and yaml backend functions so that they accept an option rich_data=true that would read a json/yaml file and interpret the format of the data as having our rich-data encoding. In puppet 6.0 that would mean you can write a Sensitive value directly in a data file:

pam::pam_duo_conf:
  duo:
    ikey:
      __ptype: 'Sensitive'
      __pvalue: 'the secret key'
...

Fourth option - support a .pp datafile backend function: it would simply read a .pp file as data - for example containing:

{pam::pam_duo_conf => { duo => { ikey => 'secret key' }}}

Fifth option: Write a small backend function to return the structs that contain Sensitive data elements. (You can easily do this yourself).

It gets a bit complicated if a Sensitive[Hash] returned that way should merge with other sensitive hashes. I think the current implementation simply treats a Sensitive as a leaf value (something that cannot be merged).

Adam Gardner (JIRA)

unread,
Dec 13, 2018, 2:30:05 PM12/13/18
to puppe...@googlegroups.com
Adam Gardner commented on Improvement PUP-8947

I have to say I view this option (8947) as markedly superior to the suggestion in PUP-8946. PUP-8946 would require us to update our entire codebase in one giant update or everything would break - depending on implementation, it may actually not be feasible at all for us. 8947, on the other hand, feels like exactly what is needed - it's what I came here to suggest myself, actually.

Adam Gardner (JIRA)

unread,
Dec 13, 2018, 4:28:04 PM12/13/18
to puppe...@googlegroups.com
Adam Gardner commented on Improvement PUP-8947

I think an ideal implementation would also be able to automatically handle sensitive conversions in cases like

 

type Example = Struct[{
  username => String,
  password => Sensitive[String],
}]

class profile::example(
  Array[Example] $foo,
){
 ...
}

Obviously, if you start introducing complex types including things like `Variant[String,Sensitive[String]]` those wouldn't be converted because the original string also matches.

 

Josh Cooper (Jira)

unread,
Nov 30, 2021, 4:14:03 PM11/30/21
to puppe...@googlegroups.com
Josh Cooper updated an issue
 
Change By: Josh Cooper
Epic Link: PUP-11371
This message was sent by Atlassian Jira (v8.13.2#813002-sha1:c495a97)
Atlassian logo

Josh Cooper (Jira)

unread,
Jul 22, 2022, 2:46:01 PM7/22/22
to puppe...@googlegroups.com
Josh Cooper updated an issue
Change By: Josh Cooper
Component/s: Hiera & Lookup
This message was sent by Atlassian Jira (v8.20.11#820011-sha1:0629dd8)
Atlassian logo
Reply all
Reply to author
Forward
0 new messages