Best practices for handling Local Windows Credentials in an Azure AD authenticated PowerShell App

Best practices for handling Local Windows Credentials in an Azure AD authenticated PowerShell App

avatar

Hi everyone,

I'm looking for architectural best practices regarding credential handling in a hybrid scenario.

Our Setup & Problem:
Users authenticate to our web app (PowerShell Universal) using Azure AD / Entra ID. However, the app needs to perform remote actions on local On-Premises PCs (via WinRM/CIM).

Because the Azure identity cannot be used directly for local Windows authentication, we need a separate set of Active Directory credentials.

What we want to achieve:

  1. Prompt the user inside the app for their local Windows/AD credentials.
  2. Cache these credentials securely only for the duration of their browser session (they must expire when the browser is closed).
  3. Reuse the cached credentials during the session to query remote PCs by passing them to background jobs via Invoke-PSUScript.


My Questions:

  • What is the most secure way to temporarily store a PSCredential object in the server's session memory (e.g., $Session scope) without risking plaintext exposure?
  • How do you reliably ensure the credentials are wiped as soon as the user closes the browser?
  • Are there better alternative architectural patterns for this specific "Azure App to On-Premises Management" transition? Serviceuser aint an Option.


Thanks in advance for your advice!

All Comments (3)

avatar
Hi everyone,

I'm looking for architectural best practices regarding credential handling in a hybrid scenario.

Our Setup & Problem:
Users authenticate to our web app (PowerShell Universal) using Azure AD / Entra ID. However, the app needs to perform remote actions on local On-Premises PCs (via WinRM/CIM).

Because the Azure identity cannot be used directly for local Windows authentication, we need a separate set of Active Directory credentials.

What we want to achieve:
  1. Prompt the user inside the app for their local Windows/AD credentials.
  2. Cache these credentials securely only for the duration of their browser session (they must expire when the browser is closed).
  3. Reuse the cached credentials during the session to query remote PCs by passing them to background jobs via Invoke-PSUScript.

My Questions:
  • What is the most secure way to temporarily store a PSCredential object in the server's session memory (e.g., $Session scope) without risking plaintext exposure?
  • How do you reliably ensure the credentials are wiped as soon as the user closes the browser?
  • Are there better alternative architectural patterns for this specific "Azure App to On-Premises Management" transition? Serviceuser aint an Option.

Thanks in advance for your advice!


@Marco

Dear Marco,

Thank you very much for contacting Ironman Software!

My name is Ruben Tapia, a support engineer in charge of request #F-55534. While we review the details provided, please remember that you can add additional information by replying to this email.

To start over kindly share with me the following information:
• When did you start designing or testing this workflow?
• PSU Version:
• Installation type: MSI, ZIP, IIS, Docker, or other:
• Are the remote WinRM/CIM calls executed from an app event handler, API, or background job only?
• Are you currently passing the credential object directly to Invoke-PSUScript, or only planning the design?
• Do users need to authenticate with their own AD accounts, or would delegated/controlled access through roles be acceptable?

Based on the PowerShell Universal v5 documentation, the $Session scope is the closest documented pattern for per-user app session storage. The documentation states that session variables are per app session, have an idle timeout, are cleared when the session ends, and are not persisted to disk. It also specifically documents storing credentials in session scope for the duration of a user session.

One important limitation is that $Session variables are not available in REST API endpoints or scheduled endpoints, so we should confirm how the background job is launched and whether the credential needs to cross into Automation.

https://docs.powershelluniversal.com/apps/custom-variable-scopes
https://docs.powershelluniversal.com/platform/cache
https://docs.powershelluniversal.com/automation/triggers

Best regards,
Ruben Tapia

avatar
Hi everyone,

I'm looking for architectural best practices regarding credential handling in a hybrid scenario.

Our Setup & Problem:
Users authenticate to our web app (PowerShell Universal) using Azure AD / Entra ID. However, the app needs to perform remote actions on local On-Premises PCs (via WinRM/CIM).

Because the Azure identity cannot be used directly for local Windows authentication, we need a separate set of Active Directory credentials.

What we want to achieve:
  1. Prompt the user inside the app for their local Windows/AD credentials.
  2. Cache these credentials securely only for the duration of their browser session (they must expire when the browser is closed).
  3. Reuse the cached credentials during the session to query remote PCs by passing them to background jobs via Invoke-PSUScript.

My Questions:
  • What is the most secure way to temporarily store a PSCredential object in the server's session memory (e.g., $Session scope) without risking plaintext exposure?
  • How do you reliably ensure the credentials are wiped as soon as the user closes the browser?
  • Are there better alternative architectural patterns for this specific "Azure App to On-Premises Management" transition? Serviceuser aint an Option.

Thanks in advance for your advice!

@Marco

Dear Marco,

Thank you very much for contacting Ironman Software!

My name is Ruben Tapia, a support engineer in charge of request #F-55534. While we review the details provided, please remember that you can add additional information by replying to this email.

To start over kindly share with me the following information:
• When did you start designing or testing this workflow?
• PSU Version:
• Installation type: MSI, ZIP, IIS, Docker, or other:
• Are the remote WinRM/CIM calls executed from an app event handler, API, or background job only?
• Are you currently passing the credential object directly to Invoke-PSUScript, or only planning the design?
• Do users need to authenticate with their own AD accounts, or would delegated/controlled access through roles be acceptable?

Based on the PowerShell Universal v5 documentation, the $Session scope is the closest documented pattern for per-user app session storage. The documentation states that session variables are per app session, have an idle timeout, are cleared when the session ends, and are not persisted to disk. It also specifically documents storing credentials in session scope for the duration of a user session.

One important limitation is that $Session variables are not available in REST API endpoints or scheduled endpoints, so we should confirm how the background job is launched and whether the credential needs to cross into Automation.

https://docs.powershelluniversal.com/apps/custom-variable-scopes
https://docs.powershelluniversal.com/platform/cache
https://docs.powershelluniversal.com/automation/triggers

Best regards,
Ruben Tapia


@rubentapia

Hello Ruben,

thanks for your message.

  • I am still in the design phase, as we generally work with roles, but for the app we are currently planning we need to rethink things a bit.
  • Basically, we are still starting with the app structure.
  • We are using PSU version 2026.2.0 via IIS.
  • Ideally, when opening the app, the credentials would be requested and temporarily stored in a variable for further processing.
  • From within the app, the credentials should then either be passed to scripts in PSU via Invoke-PSUScript or possibly handled through the Modules tab.
  • In principle, I prefer using roles, but on the on-premise side (using Azure login) there are problems with using WinRM or CIM.


That’s why I was asking how I should best proceed.

Best regards,
Marco

avatar
Hi everyone,

I'm looking for architectural best practices regarding credential handling in a hybrid scenario.

Our Setup & Problem:
Users authenticate to our web app (PowerShell Universal) using Azure AD / Entra ID. However, the app needs to perform remote actions on local On-Premises PCs (via WinRM/CIM).

Because the Azure identity cannot be used directly for local Windows authentication, we need a separate set of Active Directory credentials.

What we want to achieve:
  1. Prompt the user inside the app for their local Windows/AD credentials.
  2. Cache these credentials securely only for the duration of their browser session (they must expire when the browser is closed).
  3. Reuse the cached credentials during the session to query remote PCs by passing them to background jobs via Invoke-PSUScript.

My Questions:
  • What is the most secure way to temporarily store a PSCredential object in the server's session memory (e.g., $Session scope) without risking plaintext exposure?
  • How do you reliably ensure the credentials are wiped as soon as the user closes the browser?
  • Are there better alternative architectural patterns for this specific "Azure App to On-Premises Management" transition? Serviceuser aint an Option.

Thanks in advance for your advice!

@Marco

Dear Marco,

Thank you very much for contacting Ironman Software!

My name is Ruben Tapia, a support engineer in charge of request #F-55534. While we review the details provided, please remember that you can add additional information by replying to this email.

To start over kindly share with me the following information:
• When did you start designing or testing this workflow?
• PSU Version:
• Installation type: MSI, ZIP, IIS, Docker, or other:
• Are the remote WinRM/CIM calls executed from an app event handler, API, or background job only?
• Are you currently passing the credential object directly to Invoke-PSUScript, or only planning the design?
• Do users need to authenticate with their own AD accounts, or would delegated/controlled access through roles be acceptable?

Based on the PowerShell Universal v5 documentation, the $Session scope is the closest documented pattern for per-user app session storage. The documentation states that session variables are per app session, have an idle timeout, are cleared when the session ends, and are not persisted to disk. It also specifically documents storing credentials in session scope for the duration of a user session.

One important limitation is that $Session variables are not available in REST API endpoints or scheduled endpoints, so we should confirm how the background job is launched and whether the credential needs to cross into Automation.

https://docs.powershelluniversal.com/apps/custom-variable-scopes
https://docs.powershelluniversal.com/platform/cache
https://docs.powershelluniversal.com/automation/triggers

Best regards,
Ruben Tapia

@rubentapia

Hello Ruben,

thanks for your message.
  • I am still in the design phase, as we generally work with roles, but for the app we are currently planning we need to rethink things a bit.
  • Basically, we are still starting with the app structure.
  • We are using PSU version 2026.2.0 via IIS.
  • Ideally, when opening the app, the credentials would be requested and temporarily stored in a variable for further processing.
  • From within the app, the credentials should then either be passed to scripts in PSU via Invoke-PSUScript or possibly handled through the Modules tab.
  • In principle, I prefer using roles, but on the on-premise side (using Azure login) there are problems with using WinRM or CIM.

That’s why I was asking how I should best proceed.

Best regards,
Marco


@rubentapia
Couldn’t this be turned into a feature in the future, so that when creating an app (PSU mask) there is also the option to decide which type of authorization you want to use? (forms, windows, entra...)