Secrets are not available in sub-script, how to fix?

I wrote a script, that gets some data from a REST Endpoint and returns it.
It does access some API keys stored as secret variables ($Secret:APIKey)
If I run the script directly it does work just fine, but if I call it via “$Pipeline = Invoke-PSUScript -Script ‘GetStuff.ps1’ -Parameter ‘SomeValue’ -Integrated -Wait”
It does not work, because it cannot access the $Secret store when called via Invoke-PSUScript from another script.
How do I allow it to still access secrets?

Can you please give more details about how you have your endpoint configured and the script you’re invoking via Invoke-PSUScript? I have endpoints that are configured to use Invoke-PSUScript on scripts that have MANY $Secret variables being referenced in them, and have not had any issues in doing so.

To simplify the problem these are my tests which produce the same issue:

TestSubscript.ps1

param(
    [ComponentModel.DisplayName("test")]
    [Parameter(HelpMessage = "test", Mandatory, Position=0)]
    [string]$test
)


write-host "Param test: $($test)"
write-host "Global var: $($M42AccessTokenLifetime)"
write-host "Secret: $($Secret:M42AccessToken)"
# removed some stuff that would uses the variables above.

Output when running from UI:

[information] Param test: foo 
[information] Global var: 09.07.2024 01:58:06 
[information] Secret: Lorem ipsum dolor sit amet 

Above output as expected, it can access the $Secret.

Now the second script that will call the first one:

Test.ps1

Write-Host "Invoke PSUScript:"
$Pipeline = Invoke-PSUScript -Integrated -Script 'TestSubscript.ps1' -test 'foo' -Wait
Write-Host "Pipeline is:"
Write-Host $Pipeline

This should produce the same output when running from UI:

[information] Invoke PSUScript: 
[information] Param test: foo 
[information] Global var: 09.07.2024 01:58:06 
[information] Secret:  
[information] Pipeline is: 

But it does not. Apparently a script can only access global vars when called by Invoke-PSUScript but not secrets.
The user I do this from is in the Administrator role, nothing else.
And the secrets itself are assigned to the Administrator role.

However if I do the same when logged in with the buildin admin user, everything works just fine, so this looks like a permissions thing.
Apparently my Administrator role does not get forewarded to Invoke-PSUScript? But for the builtin admin it does?

PSU Version 4.2.21

What role does your endpoint have assigned to it?

None. There are no PSU Endpoints used in this. I edited my posts to make this more clear.
Only those 2 scripts under Automation > Scrips are envolved and for now only get called by clicking the “Run” Button next to it.

I see. So, the REST endpoint you mentioned in the initial post is an external API.

I’ll try recreating your scenario to see if I get similar results.

Yes, exactly. Tyvm!

So far, I’ve not been able to recreate your issue. I’ve created identical scripts to what you provided above and filled the global variable and secret variable with dummy info, and set the secret variable to have the Administrator role.

When I run Test.ps1 as an admin account that is NOT the built-in PSU admin account, I still get valid output. For reference, I log into PSU with my Azure AD account via SAML integration, and this is the account I ran the script from.

[information] Invoke PSUScript: 
[information] Param test: foo 
[information] Global var: 1234567890 
[information] Secret: token1234 
[information] Pipeline is: 
[information] Param test: foo 
[information] Global var: 1234567890 
[information] Secret: token1234

With this info I was able to narrow it down further!
I get my Administrator permissions implicitly from a validation in Security>Roles>Adminitrator
Inside this script I do check for an ActiveDirectory group and return “true” if the user is a member of it.
As a result my user account is listed as “Policy Defined” in Security>Identities.
The bultin admin however is listet as “Administrator”, since it is an internal account and roles are grantet explicitly.
So if I manually change my roles to “Administrator” (so I m now an explicit Administrator instead of an implicit one) and then run the Script, it suddenly does work!
So apparently this is an issue with implicit / explicit roles.

Can you check if your user is Policy defined or not?

We don’t do that. All of our Azure AD accounts that are allowed to access PSU are explicitly defined under Security/Identities and have explicit roles (Administrator, in this case) defined on them.

The issue with implicit/explicit roles sounds very familiar, like I’ve heard other users say something similar in the past. Maybe @adam can speak to that, and if it’s a known issue.

This confirms my assumption. Sadly this does not solve the problem.
The issue is now: “Policy Defined” users can not access the $Secret scope in scipts called by Invoke-PSUScript.

Thanks for your help! Lets see if adam can provide some more details on this :slight_smile:

1 Like

@Sebi I was right about hearing of this issue before (I think).
See Role-Mapping for AD SSO Users not working · Issue #3283 · ironmansoftware/powershell-universal · GitHub.

According to that issue, it was fixed in 4.3.0, so that may be what you need to do since you’re still on 4.2.21.

I did update to 4.3.2 now, but sadly the issue persists and even got worse.
I now also cannot access the secret when calling the script directly and always need to be an explicit Administrator to access the $Secret scope …
@adam @Jesse.Peden

1 Like

I’m sorry it didn’t fix the issue and ended up compounding things. Hopefully Adam has an idea of what to try. In the meantime, can you share the role-mapping part of your authentication script to see if there’s maybe something that could explain this odd behavior?

Sure. It is not very pretty, but it does the job.

Administrator role script (as found and adjusted from docs and forums):


param(
[Security.ClaimsPrincipal]$User
)
        
<# 
  Policies should return $true or $false to determine whether the user has the particular 
  claim that require them for that role.
#>

$UserName = ($User.Identity.Name)
# remove domain from username
$UserName = $UserName.Substring($UserName.IndexOf('\')+1,($UserName.Length -($UserName.IndexOf('\')+1)))

#default
$IsMember = $false;

# Perform LDAP Group Member Lookup
$Searcher = New-Object DirectoryServices.DirectorySearcher
# ROOT LDAP
$Searcher.SearchRoot = 'LDAP://OU=Administrators,OU=Accounts,DC=our,DC=domain,DC=com'
#GROUP DN TO CHECK
$Searcher.Filter = "(&(objectCategory=person)(memberOf=CN=PSUniversal_Admins,OU=Groups,DC=our,DC=domain,DC=com))"
$Users = $Searcher.FindAll()
$Users | ForEach-Object{
    If($_.Properties.samaccountname -eq $UserName)
    {
        $IsMember = $true;
        Write-Host "$UserName is a member of admin group!"
        return $IsMember
    }
}

Write-Host "$UserName is NOT member of admin group!"
return $IsMember
1 Like

This is buggy. I’ll open an issue for this.

1 Like

The issue related to this is at Secrets not available to Policy Defined users. · Issue #3452 · ironmansoftware/powershell-universal · GitHub, for reference.

The issue was closed as fixed in 4.3.3, so you’ll be able to test again soon.