PowerShell icon indicating copy to clipboard operation
PowerShell copied to clipboard

[SecretManagment not supported in non-standard Windows accounts] Get-Secret breaks JEA transcript

Open pkosek opened this issue 2 years ago • 16 comments

Hi,

I've been investigating an odd issue, where Get-Secret is exposed through JEA. And when it's called, it breaks transcript logging for the reminder of the entire JEA session. I wonder if this a bug, or by design.

JEA transcript log:


Windows PowerShell transcript start Start time: 20220329205906 Username: n/a Host Application: C:\Windows\system32\wsmprovhost.exe -Embedding Process ID: 2956 PSVersion: 5.1.17763.771 PSEdition: Desktop PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.17763.771 BuildVersion: 10.0.17763.771 CLRVersion: 4.0.30319.42000 WSManStackVersion: 3.0 PSRemotingProtocolVersion: 2.3 SerializationVersion: 1.1.0.1

PS>CommandInvocation(Get-Secret): "Get-Secret"

ParameterBinding(Get-Secret): name="Name"; value="testcred" ParameterBinding(Get-Secret): name="Verbose"; value="True" ParameterBinding(Get-Secret): name="Debug"; value="True" CommandInvocation(Out-Default): "Out-Default"


Windows PowerShell transcript end End time: 20220329205913


thanks Pete

pkosek avatar Mar 29 '22 19:03 pkosek

No, this is not by design for SecretManagement. It seems like it may be a bug in PowerShell transcripts, but I don't really know without a repro to look at. Can you provide a simple JEA set up that demonstrates this problem?

PaulHigin avatar Apr 04 '22 22:04 PaulHigin

Hi Paul,

thanks for looking into this. I have reproduced it on couple of machines, both running Windows Server 1809 with Windows Powershell 5.1.

JEA Role:

@{   
    SchemaVersion = '2.0.0.0'
    GUID = 'dcfe83a6-9346-4250-ae38-3c5247a61962'
    Author = 'pkosek'
    CompanyName = 'Company'
    Copyright = '(c) Company. All rights reserved.'
    Description = 'Test Role'
    SessionType = 'RestrictedRemoteServer'
    TranscriptDirectory = '\\server\share'
    GroupManagedServiceAccount = 'domain\gMSA'
    ScriptsToProcess = 'C:\Program Files\WindowsPowerShell\Modules\JEAConfiguration\InitScript.ps1'
    RoleDefinitions = @{
        'domain\JEA-Role' = @{'RoleCapabilities' = 'JEA.testRole' }
    }
}

JEA Capability:

@{
    GUID = '7c5815e5-8899-4fc1-b6dd-73be6664addd'
    Author = 'pkosek'
    CompanyName = 'Company'
    Copyright = '(c) 2019 Company. All rights reserved.'
    ModulesToImport = 'Microsoft.PowerShell.SecretStore', 'Microsoft.PowerShell.SecretManagement'
    VisibleAliases = 'Help'
    VisibleCmdlets = 'Get-Secret', 'Clear-Host', 'Exit-PSSession', 'Get-Command', 'Get-FormatData', 'Get-Help', 'Measure-Object', 'Out-Default', 'Select-Object'
    VisibleProviders = 'FileSystem'
}

pkosek avatar Apr 05 '22 10:04 pkosek

Thanks for the repro information. I suspect that the problem is with this in your configuration:

GroupManagedServiceAccount = 'domain\gMSA'

Both SecretManagement and SecretStore are designed to install and run under user accounts. Windows virtual and managed accounts are different from normal user accounts, and SecretManagement/SecretStore will likely not run correctly under them. I wanted to eventually update these modules to optionally install and run at 'machine' scope, so that they would run under these kinds of accounts. But there has been no funding for this yet, sadly.

My guess is that transcriptions ended after 'Get-Secret' because a terminating error ended the session. Unfortunately, there is no workaround other than doing the work needed to run under these kinds of managed accounts.

PaulHigin avatar Apr 05 '22 19:04 PaulHigin

This may well be, however I must emphasize that it is only the log transcript that breaks. Everything else works just fine under gMSA - I can retrieve secrets from vaults using my custom wrapper functions that utilize SecretManagement module.

One thing to note here, I have a 'special' JEA admin role that allows me to manage secrets - add / change / remove secrets. This works in the context if the gMSA account. Once secrets are set up, I can use them across all other JEA roles that run under the same gMSA.

My JEA admin role looks like this:

@{   
    SchemaVersion = '2.0.0.0'
    GUID = '011d1b86-914a-4a26-b10b-a27115f61bb5'
    Description = 'JEA Admin'
    SessionType = 'Default'
    TranscriptDirectory = 'C:\Logs'
    GroupManagedServiceAccount = 'domain\gMSA'
    RoleDefinitions = @{
        'domain\jeaAdmin' = @{'RoleCapabilities' = 'JEA.Admin' }
    }
}
@{
    GUID = '5df50060-d798-4b5f-99e3-8ff3ba7f33d6'
    Description = 'JEA Admin'
    ModulesToImport = 'Microsoft.PowerShell.SecretManagement', 'Microsoft.PowerShell.SecretStore'
    VisibleAliases = '*'
    VisibleCmdlets = '*'
    VisibleFunctions = '*'
    VisibleExternalCommands = 'C:\Windows\System32\whoami.exe'
    VisibleProviders = '*'
}

pkosek avatar Apr 07 '22 08:04 pkosek

I should have added that Get-Secret does not seem to throw, it definitely doe not terminate the session and everything else seems to work fine, except for the transcripts from the point when Get-Secret is called.

pkosek avatar Apr 07 '22 08:04 pkosek

Hmm, that is interesting. I know virtual accounts won't work, but have not tried managed. Let me try to get a repro and see what is going on.

PaulHigin avatar Apr 07 '22 15:04 PaulHigin

Hi @PaulHigin - have you had a chance looking into this yet? I'm still scratching my head here.

pkosek avatar Jun 29 '22 09:06 pkosek

Sorry, no I haven't had a chance to look at this yet. But I have bumped it back up the priority list.

PaulHigin avatar Jun 30 '22 20:06 PaulHigin

Unfortunately, I am not able to repro this since I cannot get a set-up with gMSA accounts. But I looked at the code and PowerShell will only write the transcript epilog (other than when calling Stop-Transcript explicitly) when it thinks all session runspaces are closed. SecretManagement loads and runs extension vaults in separate runspaces for isolation, and I am thinking some non-terminating error is causing the extension vault runspaces to be recreated, which in turn is somehow triggering transcription to end. I know this is speculative, but it is all I have for now.

In general I think we can say that SecretManagement/SecretStore is not supported for non-standard accounts (such as virtual or gMSA accounts). At some point I want to upgrade both modules to support 'AllUsers' or machine wide scope operation, but that may not happen soon as we don't currently have resources to allocate for the work.

PaulHigin avatar Jul 05 '22 22:07 PaulHigin

We are using the Secretsmanagement module also under a gMA account. After we execute 'get-secret' all logging (Write-information, Write-debug etc.) is also broken.

As a workaround I execute the get secret as job on localhost. This works (for me) like a charm, for now:

Old: $FTPCredential = Get-Secret -Name "MySecret" -> logging broken after executing New: $FTPCredential = Invoke-Command -ComputerName localhost -ScriptBlock { Get-Secret -Name "MySecret"} -AsJob | Receive-Job -Wait -AutoRemoveJob -> logging keeps working

jaamarcelis avatar Jul 14 '22 09:07 jaamarcelis

We are using the Secretsmanagement module also under a gMA account. After we execute 'get-secret' all logging (Write-information, Write-debug etc.) is also broken.

As a workaround I execute the get secret as job on localhost. This works (for me) like a charm, for now:

Old: $FTPCredential = Get-Secret -Name "MySecret" -> logging broken after executing New: $FTPCredential = Invoke-Command -ComputerName localhost -ScriptBlock { Get-Secret -Name "MySecret"} -AsJob | Receive-Job -Wait -AutoRemoveJob -> logging keeps working

HA! This is very cool. I'll give it a try. Thank you @jaamarcelis!!

pkosek avatar Jul 14 '22 09:07 pkosek

I'm curious if it is a solution for the broken Transcript logging also. Happy to hear from you.

jaamarcelis avatar Jul 14 '22 10:07 jaamarcelis

It worked a treat! It may not be the prettiest of solutions but as a workaround I'm happy with it!! Thanks again!

pkosek avatar Jul 26 '22 13:07 pkosek

This is very interesting, and I suspect it works because SecretManagement is being run in a PowerShell job, which in turn runs in a child process. So whatever breaks transcripts/information data is isolated there. Fortunately, PowerShell's remoting layer (which is used by PowerShell jobs) safely handles the SecureSting type so the returned string secret type is protected.

I am re-opening this because I think the PowerShell team should investigate. My suspicion is that something is breaking in the console host, since that is one of the common points for transcripts and data streams.

PaulHigin avatar Jul 26 '22 15:07 PaulHigin

Closing this issue as I feel it needs to be investigated by PowerShell team, since it is breaking PowerShell transcripts/data streams, and it has been transferred to PowerShell repository.

PaulHigin avatar Jul 27 '22 22:07 PaulHigin

Oh, I see this is the same PR just transferred. Re-opening.

PaulHigin avatar Jul 27 '22 22:07 PaulHigin

@PaulHigin It looks like the microsoft-github-policy-service bot is over actively closing stale issues. Would you be able to reopen this?

LeonarddeR avatar Dec 05 '23 14:12 LeonarddeR