JumpCloud — Integration Setup
Prerequisites
- A JumpCloud organisation
- A JumpCloud Administrator account that can read users and systems
- CMDash Essentials tier or above
Step 1: Create an API Key
JumpCloud API keys belong to the administrator who created them and inherit that administrator's permissions — there is no separate scope picker.
- Log in to the JumpCloud Admin Console.
- Click your account (top right) → My API Key.
- Click Generate New API Key.
- Copy the key immediately — it is shown only once, and generating a new one invalidates the previous key for that administrator.
Least privilege: create the key from a dedicated administrator with a read-only admin role rather than from a Manager/Owner account. CMDash only ever issues
GETrequests, so a read-only role is sufficient and removes the possibility of the credential being used to change your directory.
Step 2 (MSP / multi-tenant only): find your Organization ID
Skip this if you have a single JumpCloud organisation.
- In the Admin Console, go to Settings → General.
- Copy the Organization ID.
CMDash sends it as the x-org-id header on every call. A single-org account must leave this blank — sending the header when it is not needed can cause JumpCloud to reject the request.
Step 3: Connect in CMDash
- Navigate to Integrations in your CMDash dashboard.
- Find JumpCloud and click Connect.
- Enter:
- API Key (stored as this connection's access token, sent as
x-api-key: <key>) - Organization ID — optional, MSP/multi-tenant accounts only
- API Key (stored as this connection's access token, sent as
- Click Save & Test Connection.
What Syncs
| Data Type | JumpCloud API | Behaviour on failure |
|---|---|---|
| Identity / MFA coverage, privileged (sudo) accounts | GET /api/systemusers | Fails the sync — this is the primary dataset |
| Managed device inventory, incl. FileVault/BitLocker state and OS version | GET /api/systems | Degrades silently — endpoint inventory is skipped for that cycle, identity data still lands |
How the numbers are computed
- MFA coverage counts users with
mfa.configuredortotp_enabled. SUSPENDED and STAGED users are excluded from both the numerator and the denominator — a user who cannot authenticate cannot enrol a factor, so counting them would make good offboarding hygiene (and normal staged provisioning) look like a control failure. - Privileged accounts are users with
sudo— administrative access on bound systems. - Devices land as endpoint inventory: hostname, OS family, OS version, full-disk encryption state, agent connectivity, and last check-in. A device that has never checked in is recorded with an epoch
lastSeenAt, never with "now".
Troubleshooting
- 401 Unauthorized: The API key was regenerated (which invalidates the old one) or the owning administrator was removed.
- 403 Forbidden on
/systems: The administrator's role can read users but not devices. CMDash keeps syncing identity data and skips endpoint inventory for that cycle rather than failing the whole sync — check the connection's sync log for the warning. - Everything 401s on an MSP account: You almost certainly need the Organization ID. An MSP admin's key is not scoped to one org on its own.
- A single-org account started failing after you set an Organization ID: clear it. The
x-org-idheader should be absent for single-org accounts. - MFA coverage looks higher than expected: suspended and staged users are excluded by design (see above). The excluded count is carried in the observation drill-down so you can see the denominator.
- Privileged-access governance shows no data: CMDash emits nothing rather than a perfect score when it reads zero sudo users. JumpCloud privilege can legitimately be held entirely through console administrators — a separate resource CMDash does not read — so a zero here is indistinguishable from missing data, and absence must never render as a perfect score.
Rate Limits & Sync Behavior
| Setting | Value |
|---|---|
| Sync frequency | Every 4 hours by default (syncInterval is configurable per connection) |
| Pagination | skip/limit, 100 records per page, capped at 5,000 records per collection per sync |
| Rate limit handling | This adapter does not route through CMDash's shared token-bucket limiter — a JumpCloud 429 fails the sync attempt rather than being paced mid-run |
| Failed sync retry | Job queue retries 3 times with exponential backoff (starting at 30s) — see docs/developers/dead-letter.md |
Credential Rotation
JumpCloud API keys do not expire. Rotate quarterly.
To rotate:
- In JumpCloud: My API Key → Generate New API Key. Note that this immediately invalidates the previous key for that administrator, so update CMDash promptly.
- In CMDash: Settings → Integrations → JumpCloud → Edit.
- Enter the new API Key and Save.
Known Limitations
- No dormant-account signal. JumpCloud's
/systemusersresource does not expose a last-login timestamp; login events live in the separate Directory Insights product, which this integration does not read. Rather than derive dormancy fromcreatedorpassword_date— a fabrication dressed as a measurement — CMDash reports no dormancy telemetry from this source. Okta and Entra ID do provide it. - Disk encryption and OS version are read for devices JumpCloud reports them for. Full-disk encryption state (
fde.active— FileVault/BitLocker) and per-device OS version now land on the endpoint record and feed fleet encryption coverage. A device JumpCloud reports nofdeblock for is recorded as unknown, never as unencrypted, and is excluded from both sides of the coverage percentage — a source that cannot see a device must not drag your coverage down. (Resolved 2026-08-12; these two fields were read from the API and discarded in earlier releases.) - Console administrators are not read. Only directory users (
/systemusers) are inventoried; JumpCloud's separate admin accounts are not, which is why the privileged-account signal keys onsudo.