Cut 5088 updating power shell module to handle o auth/service account tokens#742
Conversation
jworkmanjc
left a comment
There was a problem hiding this comment.
Okay I did add one change to support getting some data with ClientID/ClientSecret. I suspect we'll need to add more to clear this work up.
One question I had was if it was really required to get a new token on each request. I'm running Get-JCUser -username "someUser" -debug to test the new flow and watching the flow from Connect-JCOnline -> New-JCBearerToken. We should be making use of the Token "Expires_in" value which I believe is in seconds so we don't have to do another request to auth every time we hit "Connect-JCOnline" Not sure if it's best to just set it as en Environment Variable or set it in the config. But we shouldn't be generating a new token each time I do a request for data. I think we can do something like this:
First ClientID/Secret request, Get-CurrentDate, get authToken, look at expires_in value and record (Current-Date + add expires_in(in seconds) as some env variable. Next time we do a request check if Current date -gt that Env variable and perform auth again if necessary.
What do you think about that @shashisinghjc? We'd have to do the same thing for OIDC auth right?
|
hi @jworkmanjc , here's the flow. New-Bearer token is only called when the token is missing or expired. Every API request flow: Invoke-JCApi → calls Get-JCAuthHeaders New token is Stored in $env:JCAccessToken and $global:JCAccessToken. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 3 potential issues.
Reviewed by Cursor Bugbot for commit 2683b3c. Configure here.
| $Param_JumpCloudOrgId.Add('Mandatory', $true) | ||
| } else { | ||
| $Param_JumpCloudOrgId.Add('Default', $env:JCOrgId) | ||
| } |
There was a problem hiding this comment.
JumpCloudOrgId now incorrectly mandatory for apiKey mode
High Severity
In the old code, JumpCloudOrgId was never mandatory — it only received a default when $env:JCOrgId was already set. Now, when $env:JCOrgId is empty (e.g., first connection in a session), the parameter is made Mandatory, forcing users to supply an OrgId upfront. This breaks the existing workflow where users call Connect-JCOnline -JumpCloudApiKey "xxx" and the module auto-discovers the org via Set-JCOrganization. This applies to both apiKey and clientSecret branches.
Additional Locations (1)
- [
PowerShell/JumpCloud Module/Public/Authentication/Connect-JCOnline.ps1#L65-L70](https://github.com/TheJumpCloud/support/blob/2683b3c56ac9149f3be0a319ad7dc8304f25eb4b/PowerShell/JumpCloud Module/Public/Authentication/Connect-JCOnline.ps1#L65-L70)
Reviewed by Cursor Bugbot for commit 2683b3c. Configure here.
| if ($oauthErrorDetail) { | ||
| $msg += " Response body: $oauthErrorDetail" | ||
| } | ||
| throw $msg |
There was a problem hiding this comment.
Nested catch shadows $_ corrupting error message
Low Severity
In New-JCBearerToken, the inner catch block (for stream-reading failures) overwrites $_ in the shared scope. After the inner try/catch completes, lines that reference $_.ErrorDetails and $_.Exception.Message to build the error message may reference the stream-reading error instead of the original REST/OAuth error. PowerShell's try/catch doesn't create a new scope, so the inner catch clobbers the outer $_.
Reviewed by Cursor Bugbot for commit 2683b3c. Configure here.
| begin { | ||
| $hdrs = @{ | ||
| 'Content-Type' = 'application/json' | ||
| 'Accept' = 'application/json' |
There was a problem hiding this comment.
Fallback x-org-id in Get-JCResults is dead code
Medium Severity
Get-JCAuthHeaders always includes the x-org-id key in its returned hashtable (even when $env:JCOrgId is empty). The ContainsKey('x-org-id') check is therefore always true, making the fallback to add x-org-id from $JCOrgID dead code. The old code conditionally added x-org-id only when $JCOrgID was truthy; now x-org-id is always present (potentially with an empty string value), which could cause API errors if $env:JCOrgId isn't set yet.
Reviewed by Cursor Bugbot for commit 2683b3c. Configure here.


Issues
What does this solve?
This adds a new authentication method i.e. ClientSecret(OIDC). Earlier only API key was allowed.
Is there anything particularly tricky?
NA
How should this be tested?
Use Connect-JCOnline - Default is the API key authentication
Use Set-JCSettings -authPreferenceMethod ClientSecret (This will switch to ClientSecret) and opt for the client ID and Client Secret
Screenshots
Note
High Risk
Touches core authentication for all API traffic and stores client secrets and tokens in environment variables; client-secret mode also disables some SDK-dependent features until bearer support exists.
Overview
Adds OAuth client-credentials as an optional auth path alongside the existing API key, controlled by
authPreference.MethodinConfig.json(apiKeydefault, orclientSecretviaSet-JCSettingsFile).New plumbing issues and refreshes bearer tokens (
New-JCBearerToken,Get-JCAccessTokenwith expiry skew), andGet-JCAuthHeadersswitches betweenx-api-keyandAuthorization: Bearer.Connect-JCOnline,Set-JCOrganization,Invoke-JCApi, andGet-JCResultsnow branch on auth method and use shared headers.Get-JCAuthStatusreports masked client ID and token expiry in client-secret mode.JumpCloud.SDK policy template argument completion is skipped when
clientSecretis active (SDK still requires-ApiKey). Pester tests cover token, headers, and bearer issuance.Reviewed by Cursor Bugbot for commit 2683b3c. Bugbot is set up for automated code reviews on this repo. Configure here.