Skip to content

Commit fc9a5fa

Browse files
authored
Feat: enhance Linux credential management with secure storage and retrieval (#5429)
* Feat: enhance Linux credential management with secure storage and retrieval * Fix: fall back to OS credential store when no default vault is registered Resolve the default vault once in AddCredential, GetCredential and RemoveCredential and fall through to the OS specific credential store when it is empty, matching what AddAppId, GetAppId and RemoveAppid already do. Previously these branched on whether the SecretManagement module was installed, so a machine with the module installed but no default vault registered stored nothing while reporting success, and retrieved and removed nothing. Document the Linux Secret Service storage and its prerequisites in the stored credential cmdlet documentation and the credential management article.
1 parent ade98c3 commit fc9a5fa

7 files changed

Lines changed: 207 additions & 79 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
2727
- Changed `Export-PnPFlow -AsZipPackage` and `Export-PnPPowerApp` to ask for confirmation before overwriting an existing file when `-OutPath` is omitted, as they already did when `-OutPath` is specified. Unattended scripts that rely on the previous silent overwrite need to specify `-Force`. [#5421](https://github.com/pnp/powershell/pull/5421)
2828

2929
### Fixed
30+
- Fixed `Add-PnPStoredCredential`, `Get-PnPStoredCredential` and `Remove-PnPStoredCredential` not working on Linux when `Microsoft.PowerShell.SecretManagement` is not configured. Storing a credential reported success while writing nothing, and retrieving or removing one always came back empty, which also meant `Connect-PnPOnline` never resolved a stored credential on Linux. Credentials are now written to and read from the Linux Secret Service, and the username is stored alongside the password so a complete `PSCredential` is returned rather than the password on its own. Credentials are kept under their own keyring schema, separate from the one holding managed application ids. The same cmdlets were also silently doing nothing when `Microsoft.PowerShell.SecretManagement` is installed without a default vault being registered, on every platform, and now fall back to the credential store of the operating system in that situation. [#5429](https://github.com/pnp/powershell/pull/5429)
3031
- Fixed the access token permission validation reporting a required permission as missing when the token holds a scope which covers it, such as a token with `Sites.FullControl.All` being reported as lacking `Sites.Read.All`. The permission metadata states the least privileged scope which suffices, so a more privileged scope now satisfies it. This affects the validation message written to the trace log by every cmdlet as well as `Test-PnPConnectionPermission`. [#5428](https://github.com/pnp/powershell/pull/5428)
3132
- Fixed the documented permissions of `Get-PnPGraphSubscription`, which listed `Subscription.Read.All` as required. That permission is only needed to also return subscriptions created by other applications; reading back a subscription created by the current application requires the same permissions on the subscribed resource that were needed to create it. Also documented the resource dependent permissions of `New-PnPGraphSubscription`, `Set-PnPGraphSubscription`, `Remove-PnPGraphSubscription` and `Invoke-PnPGraphMethod`, and corrected `Set-PnPGraphSubscription` linking to the delete instead of the update API documentation. [#5427](https://github.com/pnp/powershell/pull/5427)
3233
- Fixed the documented Microsoft Graph permission of `Sync-PnPSharePointUserProfilesFromAzureActiveDirectory`, which listed `User.Read`. Listing all users from Entra ID requires `User.Read.All`, and Microsoft Graph is only called when `-Users` is not provided. Its SharePoint permissions are now declared as metadata as well. [#5427](https://github.com/pnp/powershell/pull/5427)

documentation/Add-PnPStoredCredential.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ title: Add-PnPStoredCredential
1010
# Add-PnPStoredCredential
1111

1212
## SYNOPSIS
13-
Adds a credential to the Windows Credential Manager or Mac OS Key Chain Entry.
13+
Adds a credential to a secret vault, the Windows Credential Manager, the macOS Keychain or the Linux Secret Service.
1414

1515
## SYNTAX
1616

@@ -20,7 +20,9 @@ Add-PnPStoredCredential -Name <String> -Username <String> [-Password <SecureStri
2020
```
2121

2222
## DESCRIPTION
23-
Adds an entry to the Windows Credential Manager or Mac OS Key Chain Entry. If you add an entry in the form of the URL of your tenant/server PnP PowerShell will check if that entry is available when you connect using Connect-PnPOnline. If it finds a matching URL it will use the associated credentials.
23+
Adds an entry to the credential store of your platform. If a default vault has been registered through `Microsoft.PowerShell.SecretManagement`, the credential is stored in that vault. If not, it is stored in the credential store native to the operating system: the Windows Credential Manager on Windows, the Keychain on macOS and the Secret Service on Linux. Storing a credential on Linux without a default vault requires a Secret Service provider such as GNOME Keyring or KWallet to be installed and unlocked; if none is available, the cmdlet will report that it could not store the credential rather than silently discarding it. See [Credential Management](https://pnp.github.io/powershell/articles/credentialmanagement.html) for the details.
24+
25+
If you add an entry in the form of the URL of your tenant/server PnP PowerShell will check if that entry is available when you connect using Connect-PnPOnline. If it finds a matching URL it will use the associated credentials.
2426

2527
If you add a Credential with a name of "https://yourtenant.sharepoint.com" it will find a match when you connect to "https://yourtenant.sharepoint.com" but also when you connect to "https://yourtenant.sharepoint.com/sites/demo1". Of course you can specify more granular entries, allow you to automatically provide credentials for different URLs.
2628

@@ -65,7 +67,7 @@ Accept wildcard characters: False
6567
```
6668
6769
### -Overwrite
68-
Use parameter to overwrite existing Mac OS Key Chain Entry. Not required on Windows.
70+
Use parameter to overwrite an existing macOS Keychain entry. Not required on Windows or Linux.
6971
7072
```yaml
7173
Type: SwitchParameter

documentation/Get-PnPStoredCredential.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Get-PnPStoredCredential -Name <String>
1919
```
2020

2121
## DESCRIPTION
22-
Returns a stored credential from the Windows Credential Manager or Mac OS Key Chain Entry.
22+
Returns a stored credential. If a default vault has been registered through `Microsoft.PowerShell.SecretManagement`, the credential is read from that vault. If not, it is read from the credential store native to the operating system: the Windows Credential Manager on Windows, the Keychain on macOS and the Secret Service on Linux. Reading a credential from the Linux Secret Service requires a provider such as GNOME Keyring or KWallet to be installed and unlocked. See [Credential Management](https://pnp.github.io/powershell/articles/credentialmanagement.html) for the details.
2323

2424
## EXAMPLES
2525

documentation/Remove-PnPStoredCredential.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ online version: https://pnp.github.io/powershell/cmdlets/Remove-PnPStoredCredent
1010
# Remove-PnPStoredCredential
1111

1212
## SYNOPSIS
13-
Removes a credential from the Credential Manager
13+
Removes a stored credential
1414

1515
## SYNTAX
1616

@@ -19,7 +19,7 @@ Remove-PnPStoredCredential -Name <String> [-Force]
1919
```
2020

2121
## DESCRIPTION
22-
Removes a stored credential from the Credential Manager
22+
Removes a stored credential. If a default vault has been registered through `Microsoft.PowerShell.SecretManagement`, the credential is removed from that vault. If not, it is removed from the credential store native to the operating system: the Windows Credential Manager on Windows, the Keychain on macOS and the Secret Service on Linux. See [Credential Management](https://pnp.github.io/powershell/articles/credentialmanagement.html) for the details.
2323

2424
## EXAMPLES
2525

@@ -28,7 +28,7 @@ Removes a stored credential from the Credential Manager
2828
Remove-PnPStoredCredential -Name "https://tenant.sharepoint.com"
2929
```
3030

31-
Removes the specified credential from the Credential Manager
31+
Removes the specified credential from the credential store
3232

3333
## PARAMETERS
3434

pages/articles/credentialmanagement.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ PnP PowerShell is the ultimate library to execute cmdlets unattended in scripts,
44

55
However, in order to automate authentication you need to safely store these credentials. You should -never- store them in your scripts.
66

7-
We currently recommend the Microsoft provided Secret Management and Secret Store modules to set up a vault which PnP PowerShell can use to store and retrieve credentials.
7+
We currently recommend the Microsoft provided Secret Management and Secret Store modules to set up a vault which PnP PowerShell can use to store and retrieve credentials. This works the same way on every platform PnP PowerShell runs on, which is why it is the recommended option.
8+
9+
If you do not register a default vault, `Add-PnPStoredCredential`, `Get-PnPStoredCredential` and `Remove-PnPStoredCredential` fall back to the credential store built into your operating system, described under [Storing credentials without a vault](#storing-credentials-without-a-vault) below.
810

911
## Install the required modules
1012

@@ -78,3 +80,17 @@ Remove-Secret -Name [yourlabel] -Vaultname [VaultName]
7880
```powershell
7981
Remove-PnPStoredCredential -Name [yourlabel]
8082
```
83+
84+
## Storing credentials without a vault
85+
86+
When no default vault is registered, the PnP PowerShell cmdlets above use the credential store that comes with your operating system. Nothing needs to be installed for this on Windows and macOS, and the credentials are stored under a name prefixed with `PnPPS:`.
87+
88+
| Platform | Credential store | Prerequisites |
89+
| -------- | ---------------- | ------------- |
90+
| Windows | Windows Credential Manager | None |
91+
| macOS | Keychain | None |
92+
| Linux | Secret Service | A Secret Service provider such as GNOME Keyring or KWallet must be installed, running and unlocked |
93+
94+
On Linux this means a headless machine, a container or an SSH session without a running keyring daemon typically has no Secret Service available. `Add-PnPStoredCredential` will then fail with an error explaining that the credential could not be stored, and `Get-PnPStoredCredential` will return nothing. On such machines, register a default vault with the Secret Management modules as described above, or pass credentials to `Connect-PnPOnline` in another way.
95+
96+
Note that a credential stored in the operating system credential store is not visible to the Secret Management module, and the other way around. If you register a default vault after having stored credentials natively, PnP PowerShell will look in the vault only and you will need to add the credentials there again.

pages/articles/toc.yml

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,18 @@
22
items:
33
- name: Installation
44
href: installation.md
5+
- name: Command suggestions while you type (predictor)
6+
href: powershellpredictor.md
57
- name: Register your application
68
href: registerapplication.md
79
- name: Determine permissions
8-
href: determinepermissions.md
10+
href: determinepermissions.md
911
- name: Connecting and authenticating
1012
href: authentication.md
13+
- name: Staying signed in between sessions
14+
href: persistedlogin.md
15+
- name: Storing credentials securely
16+
href: credentialmanagement.md
1117
- name: Samples
1218
href: scriptsamples.md
1319
- name: Configure PnP PowerShell
@@ -46,10 +52,6 @@
4652
href: batching.md
4753
- name: Upgrading from the Legacy version
4854
href: upgrading.md
49-
- name: Credential Management
50-
href: credentialmanagement.md
51-
- name: Working with persisted logins
52-
href: persistedlogin.md
5355
- name: Dealing with the ACS deprecation
5456
href: acsdeprecation.md
5557
- name: How to contribute
@@ -69,8 +71,6 @@
6971
- name: Working with permission attributes
7072
href: permissionattributes.md
7173
- name: Useful helper tools
72-
items:
73-
- name: PnP PowerShell predictor
74-
href: powershellpredictor.md
74+
items:
7575
- name: Visual Studio Code extension
7676
href: vscodeextension.md

0 commit comments

Comments
 (0)