Skip to content

CUT-5090: Secure credential reference in settings#744

Open
lucasmendes-jc wants to merge 4 commits into
masterfrom
CUT-5090-secure-credential-reference-in-settings
Open

CUT-5090: Secure credential reference in settings#744
lucasmendes-jc wants to merge 4 commits into
masterfrom
CUT-5090-secure-credential-reference-in-settings

Conversation

@lucasmendes-jc
Copy link
Copy Markdown

@lucasmendes-jc lucasmendes-jc commented May 20, 2026

Issues

CUT-5090
Avoid user to directly prompt key on console.
Hide key native console functions.
No external module.

What does this solve?

Gets from the credential manager when asked from module/prompt.
By default needs the -select param or $null -eq $env:JCApikKey
When asked from prompt it should:

  • Asks for key and name to be saved on credential manager/keychain acess
  • When the list is empty asks for a new key
  • Delete key when pressed [Backspace]
  • Asks for new key when pressed [Escape]
  • Same behavior when passed the other params
  • Saves with .api.jc by default

Is there anything particularly tricky?

Unlock-Platform is used to compile C# code on Win platform.

How should this be tested?

Connect-JCOnline.ps1 -select
Also can run the : /PowerShell/JumpCloud Module/Tests/Public/Authentication/Connect-JCOnline.Tests.ps1

Screenshots

image image image image image image

Note

High Risk
Changes authentication and how API secrets are stored and read (Keychain, Windows CredWrite with LOCAL_MACHINE persistence, and dynamicparam key resolution), which are security-sensitive and affect every Connect-JCOnline session.

Overview
Connect-JCOnline now resolves the API key from the OS credential store instead of typing it on the console whenever -Select is used, -Credential names a vault entry, or $env:JCApiKey is unset (unless -JumpCloudApiKey is passed on the command line). New -Select and -Credential parameters drive an interactive KeySelector flow that lists keys ending in .api.jc, prompts to add keys via secure input, removes entries on Backspace (with confirm), and adds a new key on Escape.

Supporting Private helpers add a small console UI (Find-Interactive, Confirm-Console, Clear-Console) and vault operations (Unlock-Platform, Get/Set/Remove vault, Get-VaultKeys) backed by macOS Keychain (security) and Windows Credential Manager (inline CredManager C# via advapi32). Linux vault use is explicitly unsupported in these paths.

Reviewed by Cursor Bugbot for commit e5c5a99. Bugbot is set up for automated code reviews on this repo. Configure here.

@lucasmendes-jc lucasmendes-jc self-assigned this May 20, 2026
@lucasmendes-jc lucasmendes-jc added enhancement minor minor version release labels May 20, 2026
@lucasmendes-jc lucasmendes-jc marked this pull request as ready for review May 20, 2026 20:54
@lucasmendes-jc lucasmendes-jc requested a review from a team as a code owner May 20, 2026 20:54
@lucasmendes-jc lucasmendes-jc requested a review from jworkmanjc May 20, 2026 20:54
Comment thread PowerShell/JumpCloud Module/Private/Vault/Get-VaultKeys.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Private/Vault/Unlock-Platform.ps1
Comment thread PowerShell/JumpCloud Module/Private/Vault/Request-NewKey.ps1
Comment thread PowerShell/JumpCloud Module/Private/Vault/Set-ToVault.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Public/Authentication/Connect-JCOnline.ps1 Outdated
Copy link
Copy Markdown
Contributor

@jworkmanjc jworkmanjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay this is very close to what we are looking for here. In general yes, this is close to the Acceptance Criteria in the card.

Connect-JCOnline -Select
If no key in Credential Manager or Keychain ends with "api.jc" then we prompt for a key, ask the customer to name it. That's mostly the functionality in the body of work. I love it, it's easy to use needs a bit of work to clean things up but in general works and is easy enough for someone to use.

Really this is solving a big issue for customers, they need to copy & paste their API key in every time the want to use the module. Now they can just select a saved one they have in encrypted storage. Great change.

One issue I saw that needs specific addressing. You can't copy data into the prompt when asked to "Type the api key:" I had to manually try to type my key and I mis-typed it the first time. I had to go edit it in credential manager but did get it to connect.

MacOS Keychain worked for me.

A few other things I think we'd need to do before marking this in the next state for review:

  • Removing items from Keychain/CredManager needs to be behind a prompt. I accidentally removed my key in Keychain and certainly didn't mean to.
  • We probably need to submit for security review this change, it will be an overall improvement on security posture I believe.
  • We'll want to merge this into a release branch, not master branch, we can merge when we get the go-ahead with security.

Write-Host "Select the JumpCloud Api Key. Press [Escape] to type a new key. Press [Backspace] to remove the selected key" -ForegroundColor Green
while (@($false, $null) -contains ($vaultKey = Find-Interactive -choices $keys -Callback {
param($param)
Remove-FromVault -Key $param;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did accidentally call this function and want to be super careful about how we think about implementing this. IMO there should be a confirmation before deleted any Key.

I wasn't super clear on usage first time so I created a key by accident titled "api.jc.api.jc". Somehow it got deleted when I ran Connect-JCOnline -select "api.jc.api.jc

Copy link
Copy Markdown
Author

@lucasmendes-jc lucasmendes-jc May 22, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added confirm dialog with "Yes"/"No"
image

)]
[Switch]$force
[Switch]$force,
[Parameter(
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay awesome to see this here, I kind of knew this was going to be a switch without looking at the code based on the PR. Totally fine, thinking about automation scenarios, it would be good for us to include a way to specify the stored key.

We can create a separate card for this but customers should be able to type:
Connect-JCOnline -Select -Credential "myKey.api.jc" and connect to that org

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added -Credential param Connect-JCOnline -Credential "ok.api.jc".
It will jump the -select param for listing the keys.

[Parameter(Mandatory=$true)]
[string]$Key,
[Parameter(Mandatory=$false)]
[string]$sufix,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious about the choice of suffix here over prefix. For my reference, keys are gathered and parsed to see if they end with some suffix.

I think that results in better looking keys as you are selecting them like:

  • OrgName.api.jc
  • AnotherOrgName.api.jc
  • LastOrg.serviceTotken.jc (assuming we add support for service token credentialing later)

Reference Code:
https://github.com/TheJumpCloud/support/pull/744/changes#diff-2283fb1a2772f5d917313a140539f71ffb3860db63e32f4d1c0b4e1fec3549a1R11
https://github.com/TheJumpCloud/support/pull/744/changes#diff-2283fb1a2772f5d917313a140539f71ffb3860db63e32f4d1c0b4e1fec3549a1R20

Comment thread PowerShell/JumpCloud Module/Public/Authentication/Connect-JCOnline.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Private/Vault/Unlock-Platform.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Private/Vault/Set-ToVault.ps1
@lucasmendes-jc lucasmendes-jc changed the title CUT-5090 - DRAFT CUT-5090: Secure credential reference in settings May 26, 2026
Comment thread PowerShell/JumpCloud Module/Private/Vault/Get-KeyFromVault.ps1
Comment thread PowerShell/JumpCloud Module/Private/Vault/Request-NewKey.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Private/Vault/Get-VaultKeys.ps1 Outdated
Comment thread PowerShell/JumpCloud Module/Private/Vault/Remove-FromVault.ps1
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Reviewed by Cursor Bugbot for commit e5c5a99. Configure here.

cred.targetName = target;
cred.comment = null;
cred.lastWritten = 0;
cred.credentialBlobSize = (secret.Length + 1) * 2;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Credential blob size includes null terminator causing authentication failures

High Severity

SetCreds sets credentialBlobSize to (secret.Length + 1) * 2, which includes the null terminator in the stored byte count. When GetCreds later reads the credential using Marshal.PtrToStringUni(cred.credentialBlob, cred.credentialBlobSize / 2), the length-based overload copies exactly that many characters — including the null terminator as a real character in the C# string. The returned API key will have a trailing \0 appended, causing it to differ from the original secret and likely causing authentication failures.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit e5c5a99. Configure here.

Comment thread PowerShell/JumpCloud Module/Private/Console/Find-Interactive.ps1
Comment thread PowerShell/JumpCloud Module/Private/Vault/Remove-FromVault.ps1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement minor minor version release

Development

Successfully merging this pull request may close these issues.

2 participants