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

Improved P12 handling #255

Merged
merged 6 commits into from
Feb 28, 2020
Merged

Improved P12 handling #255

merged 6 commits into from
Feb 28, 2020

Conversation

FISHMANPET
Copy link
Collaborator

This isn't fully ready to be merged, but I wanted to open this PR to see how you feel about these changes.

I'm trying to migrate from a Google API module my team has written, UMN-Google, to this module. Our primary use case is running from within Azure Automation. Additionally, We're currently using a service account with a .p12 cert to do all our authentication, though our .p12 isn't a super admin, it's just a "regular" user in our domain. Additionally, when we first created our .p12 cert we re-exported it with a new more secure password, instead of notasecret.

So the first change I've made here is to create a P12KeyPassword config item. It can be specified with Set-PSGSuiteConfig. If it exists, New-GoogleService will use it instead of the default password. I've constructed it in the way I have such that, if someone doesn't use this parameter, they'll never see it in their config. This also makes it backwards compatible with existing configs, and doesn't require anything like setting the notasecret password in every config file.

The rest of the changes are because of our primary use case, Azure Automation. First I'll note that I wrote the rest of this before I saw the Import and Export Config commands. So it's entirely possible I could be using those, but at a first glance I don't think they'd fully work in my scenario.

Azure Automation has its own secrets management. It can store/retrieve strings. It can also store/retreive a few object types, like PSCredential and X509Certificate2. Because we do all our secrets management in Azure Automation directly, I don't want to have to do any work to store my configuration on the actual machine, and make the deployment of new HybridRunbookWorkers as simple and automated as possible.

So first, I've modified the Get-PSGsuiteConfig function, specifically the internal Decrypt function. Now it will "decrypt" one additional datatype, a ScriptBlock. It does this by actually executing the ScriptBlock, which makes the configuration incredibly versatile. I haven't modified the corresponding Set command for this, because I think it may be advanced enough that someone should have to edit their Configuration by hand if they want to do it.

In Azure Automation if I want to retrieve a string value, I would use the command Get-AutomationVariable -Name <name>. For example if I stored my App Email in a variable called gcert-email then Get-AutomationVariable -Name 'gcert-email' in a runbook would return the App Email. Then I can do something like this in my Configuration, making it fully portable:

AppEmail = (ScriptBlock "Get-AutomationVariable -Name 'gcert-email'")

The ScriptBlock construction here is a feature of the Configuration module, when it deseralizes this, the AppEmail property will be an actual ScriptBlock

To Decrypt this I added another case, if the $String being decrypted is of type [ScriptBlock] it will execute it and return whatever it returns. In my case it will return an actual string, so the end result is the AppEmail config item is being set and defined by my Azure Automation Variable.

Azure Automation can also produce exportable passwordless certificates, in the same format as your certificate construction code currently takes. So I've added another config that can be retreived with Get-PSGsuiteConfig, P12KeyObject. If P12KeyObject is defined, New-GoogleService will skip trying to write the bytes of the password protected cert, and skip creating the certificate object, and just use the value of P12KeyObject directly.

The end result of all this is I can write a config file that looks like this:

@{
  aaservice = @{
    ConfigPath = 'C:\ProgramData\powershell\SCRT HQ\PSGSuite\Configuration.psd1'
    AppEmail = (ScriptBlock "Get-AutomationVariable -Name 'gcert-email'")
    AdminEmail = (ScriptBlock "Get-AutomationVariable -Name 'gcert-email'")
    P12KeyObject = (ScriptBlock "Get-AutomationCertificate -Name 'gcert'")
  }
  DefaultConfig = 'aaservice'
}

I've been able to test this in my environment, but that's the extent of testing I've done. I'm opening this to see what you think about this, to determine if I'll put more work into making it merge ready.

Allow the option to specify your own P12 password if you've re-exported the P12 with your own password.

Also add the ability to use an X509Certificate2 object directly, useful for environments with some kind of secrets management that will handle this for you.
"Decrypt" a scriptblock by executing it
need to decrypt  the object as well
@scrthq
Copy link
Member

scrthq commented Jan 3, 2020

This is great @FISHMANPET !!! Thank you! I'll review it, but I don't see any issues with it so long as it doesn't introduce any bugs to existing users.

@scrthq scrthq self-assigned this Jan 3, 2020
@scrthq scrthq self-requested a review January 3, 2020 22:30
modify config to hold service account key in json format
support json service account key in new-google service
need to document precedence of 3 key types in set-config
@scrthq scrthq added this to the 2.36.0 milestone Jan 22, 2020
@scrthq
Copy link
Member

scrthq commented Feb 27, 2020

@FISHMANPET - Loving this. The only feedback I have is that JSONServiceAccountKeyPath seems to me to be the same as ClientSecretsKeyPath (intended for the client_secrets.json file that you'd normally use when setting up other tools like GAM). Is there a different use case for that config value or is this a potential docs issue?

image

@scrthq
Copy link
Member

scrthq commented Feb 28, 2020

Made some adjustments, getting this merged in for now :-)

@scrthq scrthq merged commit 988c685 into SCRT-HQ:master Feb 28, 2020
@scrthq scrthq mentioned this pull request Feb 28, 2020
scrthq added a commit that referenced this pull request Feb 28, 2020
## 2.36.0 - 2020-02-28

* [PR #255](#255) - _Thanks, [@FISHMANPET](https://github.com/FISHMANPET)!_
    * Added support for `[ScriptBlock]` values on the config, allowing you to provide a script to run that will pull in a configuration value (vs embedded the value directly on the config)
* [PR #255](#260) - _Thanks, [@vaskotoo](https://github.com/vaskotoo)!_
    * Added support for an array of Users on `Get-GSGmailMessageList`
* [PR #261](#261) - _Thanks, [@Foggy2](https://github.com/Foggy2)!_
    * Added support for all license types including undocumented ones.
    * Closed out [Issue #252](#252) as well.
* [PR #262](#262) - _Thanks, [@nwls-hermesj](https://github.com/nwls-hermesj)!_
    * Added support for pipeline input of Drive file objects to `Remove-GSDriveFile`.
* [Issue #256](#256)
    * Cleaned up docs on `Send-GSChatMessage`.
* [Issue #258](#258)
    * Removed URL Shortener functions due to Google deprecation.
* [Issue #263](#263)
    * Fixed `[SecureString]` decryption on Unix machines running PowerShell 7
* Miscellaneous
    * Removed the Tasks API functions. Google has not pushed an update to the Tasks .NET SDK in over 2 months, so it is now behind the current release versions of the core Google.Apis assemblies, resulting in failure to import.
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.

2 participants