Credential management cmdlets

The credential management cmdlets provide a secure mechanism for distributing credentials (secrets) such as usernames and passwords to devices.

About credentials

It is often necessary to provide credentials or other secrets to devices in order for scripts to perform operations using these credentials. For example, a script might need to connect to an external resource that requires a username and password, or it may need an access token or other secret in order to perform various tasks.

However, while it is simple to provide plaintext credentials as parameters to 1E Platform instructions, it is very poor security practice. Firstly, the parameters for any platform instruction are stored in the platform database and can be retrieved by anyone with appropriate database access permissions. Secondly, at the receiving device, the credentials would need to be either stored in a file that the script can read or passed on the command line to the script. An attacker could, therefore, easily obtain plaintext credentials and then misuse them. To ensure that credentials can be securely stored on devices, Windows provides a Credential Store, which holds credentials in encrypted form, only accessible by the account under which the credentials are stored.

The 1E PowerShell Toolkit credential management cmdlets provide a mechanism for sending credentials securely down to one or more devices and storing them in the Windows Credential Store. From there, a script can easily and securely retrieve these credentials and use them when it requires access to external resources.

About the Windows Credential Store

The Windows Credential Store is accessible from the Windows Control Panel. It allows credentials of various types to be stored and retrieved. Only the credentials accessible by the current account context can be seen at any time.

The 1E PowerShell Toolkit credential management cmdlets work with Web Credentials. This is because there is direct PowerShell access to these. Other credential types, such as Generic Credentials, require additional PowerShell modules in order to access them. Despite their name, Web Credentials are entirely general purpose. Any application can store or retrieve them and use them, for any purpose.

The screenshot below shows a typical set of Web Credentials. They contain three components:

  • URL associated with the credential
  • Username 
  • Password

You can store multiple sets of credentials against a common URL as long as the username differs between each credential stored.

The credential management cmdlets assume that only one credential is stored for a given URL or credential name. They will remove any additional credentials against that name to ensure that this is so. This simplifies credential management by ensuring that the relationship between credential names and credentials is always 1:1.

Note that there is an option to reveal the password. Only an appropriately privileged user can do this. If you click Show, you will be prompted to enter an appropriately privileged password in order to view the hidden password.

Credentials are encrypted using the DPAPI subsystem and can only be retrieved by the account under which they were stored.

The URL need not be a validly formatted URL. It is simply a string. Therefore, the 1E PowerShell Toolkit cmdlet allows you to enter a simple credential name, which will be stored as the credential URL. However, Web Credentials can be used for any purpose, not just internet access. They are extremely simple to retrieve in a script.

Sending credentials

The following sends the specified credentials securely to the specified devices given by the target scope or fqdn list. The name (that is, URL component) will be as specified by the -Name parameter.

Copy
Set-1eCredential -Credential <credentials> -Name <name> -TargetScope <scope>|-TargetFqdns <fqdns>

This cmdlet uses the 1E-Exchange-CreateEncryptionCert and 1E-Exchange-CreateCredential instructions (supplied with the Toolkit). You must upload (publish) these instructions to your 1E Platform instance prior to using this cmdlet. Once the instructions are uploaded, the cmdlet will work from any device and will not require you to upload the instructions again.

Any existing credential associated with the specified name is overwritten. If multiple credentials are associated with the specified name, these are removed, so that at the conclusion of this command, there will be just a single credential associated with the specified name.

Because instructions run in the context of the LocalSystem account on endpoints, these credentials will only be retrievable by scripts running in that account context. This will normally be the case for any script launched from a platform instruction.

As shown here, if you do not specify a set of credentials, you are securely prompted to supply them. To avoid a prompt, you can assign credentials to a variable. To do this, use the get-credential cmdlet. For example:

Copy
$creds = get-credential

You will be prompted for credentials which you can then supply via the -Credential parameter to the Set-1ECredential cmdlet.

Copy
Set-1ECredential -TargetScope urth-dev

During the execution of this cmdlet, a certificate is temporarily placed into the localsystem account's personal certificate store on each targeted device. Additionally, each returned public key certificate is temporarily placed, one at a time, into the personal certificate store of the user running the command on their own device. Each of these certificates is automatically deleted once it is no longer required, as is the certificate at each device.

Retrieving credentials securely

The PowerShell code shown below will securely retrieve a credential which was stored with the name (URL) xyz1. Note that in order to see the password, it is necessary to invoke the RetrievePassword() method against the credential first.

Copy
[void]([Windows.Security.Credentials.PasswordVault,Windows.Security.Credentials,ContentType=WindowsRuntime])
$vault = New-Object Windows.Security.Credentials.PasswordVault
$creds = $vault.RetrieveAll()
$mycred = $creds | where-object {$_.Resource -eq "xyz1"}
$mycred.RetrievePassword()
write-host $mycred.Resource
write-host $mycred.UserName
write-host $mycred.password

If you stored the credential with the Set-1ECredential cmdlet, remember that you must be running as LocalSystem to retrieve it in a script. If you want to test this out, you can use the SysInternals psexec utility to run a command prompt as LocalSystem with the following:

Copy
psexec -i -s cmd

Then launch PowerShell from there and run the above code snippet. Note that you must launch psexec from an administrator command prompt to be able to impersonate the LocalSystem account.

The following retrieves the credentials at the target devices and returns their names. No other information is returned, for security reasons, since even the username is potentially sensitive information.

Copy
Get-1ECredential -TargetScope <scope>|-TargetFqdns <fqdns>

This cmdlet uses the 1E-Exchange-ListCredentials instruction (supplied with the Toolkit). You must upload (publish) this instruction to your 1E Platform instance prior to using this cmdlet. Once the instruction is uploaded, the cmdlet will work from any device and will not require you to upload the instruction again.

Removing credentials

The following deletes the named credential (if it exists) from the target devices:

Copy
Remove-1ECredential -Name <name> -TargetScope <scope>|-TargetFqdns <fqdns>

This cmdlet uses the 1E-Exchange-DeleteCredential instruction (supplied with the Toolkit). You must upload (publish) this instruction to your 1E Platform instance prior to using this cmdlet. Once the instruction is uploaded, the cmdlet will work from any device and will not require you to upload the instruction again.

Example of using credentials to perform a privileged operation on an device

For an example of using credentials to perform a privileged operation, in this case, joining a computer to a domain, refer to Using Credential Vault Credentials.

Secure credential marshaling

Since the set-1Ecredential cmdlet is intended to marshal and store credentials securely, it is necessary to understand how it works in detail in order to be confident about its overall security. The cmdlet relies on two underlying platform instructions (1E-Exchange-CreateEncryptionCert and 1E-Exchange-CreateCredential), both of which are supplied with the 1E PowerShell Toolkit.

1E-Exchange-CreateEncryptionCert

This instruction has no parameters. When sent to the target devices, it creates a self-signed certificate for encryption and decryption purposes in the LocalSystem user personal certificate store. The certificate has a subject of CN=TachyonEncrypt.

The certificate is then exported (without its private key), and the public-key only certificate is returned as the result of the instruction. Each device will have its own certificate and hence the keypair (public/private keys) will be different on each device.

1E-Exchange-CreateCredential

This instruction takes two parameters:

  • The encrypted base64 representation of the credentials. These were encrypted by the Set-1ECredential cmdlet using the public key for the target endpoint. (See below.)

  • The name of the credential to be associated with these in the device's web store (that is, the URL property of the credential). As noted previously, this is just a string which identifies a set of related credentials and does not have to be a valid URL.

    For simplicity, the instruction assumes that only one set of credentials will be associated with a name. It will remove any additional credentials for that name and then ensure that only the supplied credentials are then stored against the name.

The Set-1ECredential cmdlet loops through the result set returned by 1E-Exchange-CreateEncryptionCert. For each device result, it loads the certificate into the current user's personal certificate store, and it then encrypts the credentials supplied with the certificate public key.

For 1E Platform releases from version 5.2 onwards, it then uses the Invoke-1ESyncInstruction cmdlet to send a synchronous platform instruction to that device, supplying the encrypted credentials. Otherwise, for older 1E Platform releases, it uses Invoke-1EInstruction to send a normal instruction, targeting just the specific device.

After each device has been processed, the certificate stored locally is deleted and replaced by the certificate for the next device. This means that the 1E Platform database and any log files never contain plaintext credentials. Only the receiving devices can decrypt them. Because the credentials are encrypted separately for each device, they can only be decrypted on the specific receiving device for which they are intended.

At each device, the 1E Client runs the 1E-Exchange-CreateCredential instruction. It passes down the encrypted credentials to an embedded PowerShell script contained in the instruction. That script then decrypts the credentials using the certificate that was placed there earlier by the 1E-Exchange-CreateEncryptionCert instruction. It then deletes that certificate and stores the decrypted credentials as Web Credentials in the device Credential Store. They are re-encrypted using DPAPI by Windows and are now available for secure script access in other 1E Platform instructions.

The encryption and decryption processes make use of PowerShell's integrated certificate encryption/decryption capabilities, using the protect-cmsmessage and unprotect-cmsmessage cmdlets.

The diagram below shows you how the process works: