Passing Credentials in Powershell Scripts

388 views
Skip to first unread message

Ian Oberst

unread,
Apr 20, 2016, 10:55:46 AM4/20/16
to Puppet Developers

I've had a number of conversations with various Puppet folks about this and it remains a bit of a sticky issue, namely how do we safely handle powershell scripts where we need to pass credentials or other sensitive information to Powershell?

The scenario here is that we have a situation where we need to give Powershell some credentials to perform some sort of work on the system. Due to restrictions we have to pass these credentials via Puppet in some fashion, e.g. we can't or don't have access to a key manager that Powershell can talk to directly, meaning that Puppet is the only route of providing the secrets to the node.  (I do understand there are other issues here as well, such as getting secrets securely passed in the catalog, but I'm setting that aside for now.)


Recent incarnations of the Powershell provider all write a temp file to disk that contains the powershell code to be invoked. This means that if I have the credentials placed directly in the script (which generally seems the route I have to take) that I'll have written them to disk. Additionally, the exec module itself has logging that will log the command out to both the event log and the Puppet report, which will expose credentials. None of these outcomes are very good.


The approach I've tried to take is going the route of signed powershell scripts so we can invoke them with command line parameters rather than using stdin, which is the route the current Powershell provider takes. This seems at the moment to side-step some of the above mentioned problems depending on how you communicate those command line parameters to the provider. However, I'd like to align with the longer-term strategy, if possible, of how Powershell scripts are invoked within the Puppet supported provider.


So...what's the best way of handling this?

Rob Nelson

unread,
Apr 20, 2016, 11:49:19 AM4/20/16
to puppe...@googlegroups.com
Can you pass a $PSCredential down, maybe as a File resource that the script can rely on? The scripts may need modified per https://technet.microsoft.com/en-us/magazine/ff714574.aspx

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/5bd0c1ad-d53a-4135-872c-62cfe4463cf5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Rob Reynolds

unread,
Apr 20, 2016, 12:26:02 PM4/20/16
to puppe...@googlegroups.com
On Wed, Apr 20, 2016 at 10:49 AM, Rob Nelson <rnel...@gmail.com> wrote:
Can you pass a $PSCredential down, maybe as a File resource that the script can rely on? The scripts may need modified per https://technet.microsoft.com/en-us/magazine/ff714574.aspx


On Wed, Apr 20, 2016 at 10:52 AM, Ian Oberst <ian.o...@gmail.com> wrote:

I've had a number of conversations with various Puppet folks about this and it remains a bit of a sticky issue, namely how do we safely handle powershell scripts where we need to pass credentials or other sensitive information to Powershell?

The scenario here is that we have a situation where we need to give Powershell some credentials to perform some sort of work on the system. Due to restrictions we have to pass these credentials via Puppet in some fashion, e.g. we can't or don't have access to a key manager that Powershell can talk to directly, meaning that Puppet is the only route of providing the secrets to the node.  (I do understand there are other issues here as well, such as getting secrets securely passed in the catalog, but I'm setting that aside for now.)


Recent incarnations of the Powershell provider all write a temp file to disk that contains the powershell code to be invoked. This means that if I have the credentials placed directly in the script (which generally seems the route I have to take) that I'll have written them to disk.

Additional information here - when the 1.x PowerShell provider writes this file to disk, it holds an exclusive lock on the file and it deletes it immediately after use. Still touches the disk, so I understand your concern. The 2.x PowerShell provider (unreleased at this time) does not write out a file to disk.

 

Additionally, the exec module itself has logging that will log the command out to both the event log and the Puppet report, which will expose credentials. None of these outcomes are very good.


The approach I've tried to take is going the route of signed powershell scripts so we can invoke them with command line parameters rather than using stdin, which is the route the current Powershell provider takes. This seems at the moment to side-step some of the above mentioned problems depending on how you communicate those command line parameters to the provider. However, I'd like to align with the longer-term strategy, if possible, of how Powershell scripts are invoked within the Puppet supported provider.


So...what's the best way of handling this?

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-dev/5bd0c1ad-d53a-4135-872c-62cfe4463cf5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "Puppet Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-dev+...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
Rob Reynolds
Developer, Puppet


PuppetConf 2016
, October 17-21, San Diego, California
Early Birds save $350 - Register by June 30th

Ian Oberst

unread,
Apr 20, 2016, 12:37:32 PM4/20/16
to Puppet Developers
Possibly. I'm assuming that you mean an encrypted one? There would be quite a bit of overhead there, as I'd have to generate the encrypted PSCredential for each individual node. That makes using an encrypted hiera backend to store the credentials much more gross since I can't store a single credential for each cluster of nodes that use it.

I should probably add that I have come up with a working method that I think works. However, I wasn't sure if this was a method that lined up with the longer-term direction that general community wanted. Here's what I have at the moment:

I wrote a Puppet function that, given an Authenticode certificate, signs the Powershell script (or anything you pass it, really) on the Puppet master before adding it to the catalog. I then forked the Powershell provider and changed it so that instead of invoking scripts via STDIN it instead invokes scripts using the "-file" parameters, as well as settings the execution policy to only allow signed scripts. Once I have my certificate in place on a node I can then save to disk, temporarily, powershell scripts and execute them without worrying about them being altered (which was the given reason for the current Powershell provider passing the script via STDIN).

I also modified the new provider to search the catalog for a custom resource type which essentially holds parameters to pass to the Powershell script. If it finds them it adds them to the command line call to Powershell. This allows me to pass credentials as a parameter, which avoids having them written to disk as part of the Powershell script or by some other means. Finally I also had the provider temporarily bump the log level and override the parent logging so that parameters are not shown in the event log or debug output.

So far it seems to work well, issues with securing the catalog itself not withstanding. Again, I wanted to try see what the larger community felt was a good direction to take this rather then continue to head in some other direction. It may be that when the Powershell Manager finally gets released that putting credentials directly into templates won't be an issue any more.

Corey Osman

unread,
May 20, 2016, 3:27:28 PM5/20/16
to Puppet Developers
I have been in this same situation before and used node_encrypt to do the job.


You can do the following.

1. encrypt hiera data with hiera-eyaml
2. encrypt parameter or other item during compilation using node_encrypt as the eyaml encrypted data is decrypted during compilation
3. create an exec resource 
4. set an env variable with the encrypted data
5. inline the decryption of that variable in the command  using puppet node decrypt

exec { 'set service passphrase':
  command     => 'some-service --set-passphrase="$(puppet node decrypt --env SECRET)"',
  path        => '/opt/puppetlabs/bin:/usr/bin',
  environment => "SECRET=${node_encrypt('and your father smelt of elderberries')}",
}


The outcome of this is that the secret is encrypted throughout the entire lifecycle of the code, catalog and on the node itself. 

The only time the secret is unencrypted is during execution of the command which should only last a few seconds.  Which to my knowledge does not get recorded anywhere. 

You could inline this same strategy in a custom provider as well. 

Ideally we should get the powershell provider to use node_encrypt as an option.


Corey

Trevor Vaughan

unread,
May 20, 2016, 3:55:24 PM5/20/16
to puppe...@googlegroups.com
It will be shown unencrypted if you run in debug mode. Other than that, it should be fine.

Trevor


For more options, visit https://groups.google.com/d/optout.



--
Trevor Vaughan
Vice President, Onyx Point, Inc

-- This account not approved for unencrypted proprietary information --

Ian Oberst

unread,
May 20, 2016, 10:22:33 PM5/20/16
to Puppet Developers
Thanks Corey.

I've been evaluating node_encrypt since it was talked about in the last Puppet User group that I went to. At this point I'm likely going to use a combination of node_encrypt for managing the catalog and the new Powershell provider (version 2.0) that now has in-memory execution of scripts without needing temporary files on disk. Between those two it should cover my needs.
Reply all
Reply to author
Forward
0 new messages