Repository navigation
Jamf Platform Commands
jamf-cli platform is the namespace for Jamf Platform services that are separate from Jamf Pro: Jamf AI Governance, Jamf Account (licensing, partners, environments, tenants, SSO) and the platform audit event log. Forty-four commands across twelve resource groups. Platform API commands that manage Jamf Pro resources (blueprints, compliance benchmarks, platform devices and device groups, DDM reports) live under pro; see Platform API Commands.
The Jamf Platform Gateway serves everything under platform, and every command needs a platform-auth profile. See Platform API GA Migration for the GA base URL and credentials, and Setup Guide for platform setup.
An API integration is created at one of three levels in the Jamf Account portal, and its credential works at that level alone. Moving a profile between levels means a different integration and a different client ID.
| Level | Header sent | What it reaches on this page |
|---|---|---|
| organization | none (resolved from the access token) | Jamf Account (account-licenses, deal-registrations, distributor-*, environments, tenants, sso-*) |
| platform environment | X-Environment-Id |
AI Governance, platform audit (the level to prefer) |
| tenant | X-Tenant-Id |
the legacy level; nothing on this page accepts it |
AI Governance declares environment alone, so an organization-scoped profile reaches the Jamf Account commands and nothing else on this page: GET /ai/governance/policies/v1/policies with no scope header answers 400 REQUEST_CONTEXT_NOT_PROVIDED. platform setup says so in its closing summary, and jamf-cli commands -o json carries each command's declared level under scopes.
# Organization scope: supply neither ID. The gateway host selects platform auth.
jamf-cli config add-profile org --url https://us.api.jamfcloud.com --auth-method platform
# Platform environment scope
jamf-cli config add-profile env --url https://eu.api.jamfcloud.com \
--auth-method platform --environment-id <environment-id>
# Or answer the prompts, which ask for the environment ID first and stop there if you give one
jamf-cli platform setupEnvironment and tenant are mutually exclusive; supplying both (on the profile, as flags, or as JAMF_ENVIRONMENT_ID + JAMF_TENANT_ID) is refused before anything is sent. A level supplied as a flag or an environment variable replaces the profile's: --environment-id against a tenant profile means "use this environment".
| Command | Alias |
|---|---|
ai-policies |
aip |
ai-tools |
ait |
account-licenses |
lic |
deal-registrations |
deals |
distributor-configuration |
dcfg |
distributor-purchase-orders |
dpo |
distributor-quotes |
dq |
environments |
envs |
sso-connections |
ssoc |
sso-domains |
ssod |
platform audit and platform tenants have no alias.
Identifiers. Like every Platform API command, these take the resource ID positionally and resolve names through
--name. A name passed positionally goes to the API as an ID. Two exceptions:platform sso-domains allocation, whose path parameter is the domain name and which therefore has no--name(see SSO domains), andplatform ai-policies apply, which takes no identifier and reads the name out of the body.A
--namelookup lists the collection and matches client-side, accumulating matches across every page before deciding, so a name repeated either side of a 100-item page boundary is an ambiguity error. A name that matches an item the list returns no ID for is reported as that.
Thirteen commands. AI Governance manages per-tool policies (what an AI coding tool is permitted to do) and reads the vendor JSON Schemas those policies are validated against. Needs an environment-scoped credential.
All thirteen are Preview. Every AI Governance operation is declared Preview upstream, meaning the endpoint may change without warning, and since v1.30.0 the CLI says so.
jamf-cli commands -o jsoncarriespreview: trueon each of the thirteen, theapplythe CLI synthesizes included, and these are the only thirteen rows in the catalog that carry the field. The twelve that take their summary from upstream also have adescriptionopening withPreview -(Preview - List active AI governance policies for the tenant):jamf-cli commands -o json | jq -r '.[] | select(.preview) | .command'Key a script or a CI gate on
preview, not on thePreview -prefix: the prefix is upstream summary prose and can be reworded at any ingest. Nothing about Preview status changes how a command behaves; build on these knowing the request and response shapes are not yet fixed.
--helpsays what the command does again in v1.30.0. Twelve of the thirteen take their text from an upstream description (applyis synthesized here and always had its own). Upstream now opens every one of those twelve with two markdown banners, and the CLI's first-paragraph extraction returned the banner alone: through v1.29.0 all twelveLongtexts said the endpoint may change without warning and nothing about what the command does. The extraction now reads past leading admonitions and keeps the preview banner as a prefix, so the statements quoted below out ofdelete --helpare what the binary prints.
| Command | Description |
|---|---|
list |
List active policies for the tenant |
get <policyId> |
Get a policy with its current draft settings |
create |
Create a policy with draft settings |
apply |
Create or update by the name in the body, writing a draft |
patch <policyId> |
Replace the draft settings on a policy |
publish <policyId> |
Snapshot the draft as a new immutable version |
versions <policyId> |
List published versions |
version <policyId> <versionNumber> |
Get one published version's settings snapshot |
deployment <policyId> |
Deployment state across the blueprints referencing this policy |
delete <policyId> |
Archive the policy (destructive, needs --yes) |
# Discover the tools and their current schema versions first
jamf-cli platform ai-tools list
# Print the create body template (no auth needed)
jamf-cli platform ai-policies create --scaffold{
"description": "AI governance policy for engineering team",
"name": "Claude Code - Engineering",
"schemaVersion": "2026-05-12",
"settings": {},
"toolId": "com.anthropic.claudecode"
}# Create (writes a draft, nothing is published yet)
jamf-cli platform ai-policies create --from-file policy.json
# Or idempotently, keyed on the policy name in the body
jamf-cli platform ai-policies apply --from-file policy.json --yes
# Publish the draft as an immutable version
jamf-cli platform ai-policies publish <policyId>
# Inspect the version history
jamf-cli platform ai-policies versions <policyId>
jamf-cli platform ai-policies version <policyId> 1
# Blueprints referencing this policy, with their deployment state
jamf-cli platform ai-policies deployment --name "Claude Code - Engineering"
# Archive it
jamf-cli platform ai-policies delete <policyId> --yescreate and patch write a draft (hasDraft: true); publish promotes it to an immutable PolicyVersion and takes no request body. A fresh policy has currentVersionNumber: null until you publish.
# Publishing when nothing is pending is an error, not a no-op
jamf-cli platform ai-policies publish <policyId>
# 409 NO_DRAFT_TO_PUBLISHpublish is therefore not idempotent, and neither is delete: it archives the policy (published versions are retained for the audit trail), and a second delete on the same ID answers 404 POLICY_NOT_FOUND (verified 2026-09-11). An archived policy is invisible to both get and list.
deletedeclares a409 POLICY_IN_USEthat has not been observed. The spec anddelete --helpsay archiving is refused while a blueprint references the policy; the last probe (2026-08-30) got a clean204and left the blueprint pointing at a policy nothing can read. Detach the policy from its blueprints before archiving it.
patchreplacessettingswholesale. Despite being a PATCH sent asapplication/merge-patch+json, the server treatssettingsas a full replacement: seed{permissions: …, env: …}, patch with{permissions: …}alone, andenvis gone.nameanddescriptionare leave-unchanged-if-omitted, so the two halves of one request body behave differently. BothschemaVersionandsettingsare required, so there is no partial-edit body to build.Consequence:
--set settings.x=ydiscards every other setting, and the same applies toapply, whose update is this PATCH.apply --helpnamessettingsas replaced wholesale. Read the policy, edit the wholesettingsobject, send it back with--from-file:jamf-cli platform ai-policies get <policyId> -o json > policy.json # edit the whole settings object in policy.json jamf-cli platform ai-policies patch <policyId> --from-file policy.json
apply composes the resource's own list, create and patch. It reads a body, takes the name out of it, and looks that name up: absent, it creates; present, it updates after a confirmation, which --yes skips. Its update is the PATCH patch sends, with the same wholesale settings replacement.
# Idempotent: run it twice, get one policy
jamf-cli platform ai-policies apply --from-file policy.json --yes
# Scaffold, edit, apply with no temp file, because the body can arrive on stdin
jamf-cli platform ai-policies apply --scaffold | vipe | jamf-cli platform ai-policies apply --yesFour properties a script can rely on:
-
The name comes from the body. There is no
--nameonapply. A body with noname, or anamethat is not a non-empty string, is refused before anything is sent. - A failed lookup takes no branch. Only a genuine "not found" creates; an auth error or a 5xx during the lookup aborts.
-
The lookup and the create are separate requests, so two runs racing on the same absent name (a CI retry, or concurrent jobs) can both create one. No spec here declares a name-uniqueness
409. Serialiseapplyper policy where that matters. -
applywrites a draft and leaves it unpublished. A draft is inert untilplatform ai-policies publish <id>, so follow a successful apply with one.
apply carries the jamf:scopes annotation its sibling verbs carry, so it appears under scopes in jamf-cli commands -o json and earns the note the CLI appends to a missing-scope 400.
patch and apply send no precondition, so two people editing one draft resolve as last-writer-wins with nothing reported. The API's If-Match protocol is a header parameter and the platform command generator emits flags for query parameters, so there is no flag to set.
Observed 2026-09-11 on an EU environment credential: a new policy reads version: 0 and its GET carries ETag: "0"; one patch took it to version: 1; and every PATCH increments the counter whether or not it changed anything (that patch resent the same settings: {}). version is independent of currentVersionNumber, which only publish moves.
version: nullmarks a policy with no ETag. A policy predating the rollout has none: both policies on the probe tenant, created 2026-07-01, answerversion: nulland theirGETsends noETagheader. Nothing can update those conditionally.
page is 0-based server-side, totalCount is the unfiltered total, and the CLI auto-paginates.
# Sort: property:(asc|desc) over createdAt, updatedAt or name. Anything else is a 400
jamf-cli platform ai-policies list --sort updatedAt:desc
jamf-cli platform ai-policies list --sort name:asc -o table
# Only policies whose stored schemaVersion differs from the tool's current one
jamf-cli platform ai-policies list --schema-drift
--schema-driftnarrows the list. The CLI sends the parameter only when set, and server-sideschema-drift=falsereturns everything. Pass the flag for drifted policies; omit it for all of them.
| Command | Description |
|---|---|
list |
List available vendor tools with their current schema versions |
get <toolId> |
Tool metadata, including every available schema version |
schema <toolId> <schemaVersion> |
The vendor JSON Schema for that pair |
jamf-cli platform ai-tools list
jamf-cli platform ai-tools get com.anthropic.claudecode
jamf-cli platform ai-tools schema com.anthropic.claudecode 2026-05-12Read the schema before you trust a
settingskey. The vendor schema decides what happens to an unrecognised key.com.anthropic.claudecodedeclaresadditionalProperties: trueand stores a bogus key without comment;com.openai.codexsetsfalseand answers422 SCHEMA_VALIDATION_FAILEDnaming the offending property. So a typo in--set settings.…is caught for some tools and persisted for others. A declared field with a bad value is always caught, and the error names the legal enum.
ai-tools schemareturns a large JSON Schema (roughly 250 KB forcom.anthropic.claudecode). There is no table shape for it, so read it as JSON or pipe it tojq.
The envelope is the gateway's, {httpStatus, traceId, errors}.
| Code | Meaning |
|---|---|
TOOL_ID_UNKNOWN |
no such toolId
|
SCHEMA_VERSION_UNKNOWN |
no such schema version; arrives as 422 |
SCHEMA_VALIDATION_FAILED |
settings rejected by the vendor schema |
POLICY_NOT_FOUND |
no such policy, or it has been archived |
NO_DRAFT_TO_PUBLISH |
publish with nothing pending |
POLICY_VERSION_CONFLICT |
a conditional PATCH whose If-Match is stale; unreachable from this CLI, which sends no If-Match
|
POLICY_IN_USE |
declared on delete for a blueprint-referenced policy, and not observed; see above |
A non-UUID policyId answers 404.
Twenty-seven commands covering organization-level licensing, partner deal registration, environments and the tenants assigned to them, the distributor purchase-order surface, and SSO connection and domain configuration.
US-only and organization-scoped. These organization-level services are served from one region by design, so re-probing EU or APAC buys nothing: both answer a bare
404 page not foundfor these paths, which reads like a wrong path, and the CLI therefore refuses a non-US gateway profile before sending anything. The credential must be created at the organization level in Jamf Account, with neither a tenant ID nor an environment ID on the profile. The gateway resolves the organization from the access token and no scope header is sent.
jamf-cli config add-profile jamf-account \
--url https://us.api.jamfcloud.com --auth-method platform
jamf-cli -p jamf-account platform account-licenses list# Every licence held by the organization resolved from the token
jamf-cli platform account-licenses list
jamf-cli platform account-licenses list -o table
# Every deal registration submitted by the partner organization,
# including ones since denied or expired
jamf-cli platform deal-registrations list
# One registration, with its current status and, once approved, its expiry
jamf-cli platform deal-registrations get <partnerRegistrationId>deal-registrations create (v1.34.0) submits a registration for a prospective end customer. Jamf creates it in PENDING status and reviews it. --scaffold prints a full body, and businessType takes Commercial, Government, Education-K12, Education-High Ed or Education-Intl Ed.
jamf-cli platform deal-registrations create --scaffold > deal.json
jamf-cli platform deal-registrations create --from-file deal.json --dry-runNeither list endpoint paginates: the full set arrives in one response and totalCount reflects it. An organization with none gets an empty results array and totalCount: 0.
The v1.30.0 spec ingest narrowed the licensing server's own region enum to us alone, where it previously listed several, which is the upstream confirmation of the US-only rule above. The same ingest dropped the deprecated License.type; licenseType is the field to read, and was already the one the CLI printed.
The licence activation code is not a column in table output, being the value that entitles an installation. Use
-o json(or--select) when you need it.
Added in v1.34.0. An environment groups tenants, and a tenant is one Jamf Pro, Protect, School or Security Cloud instance. Both commands are organization-scoped and US-only, like the rest of this section.
jamf-cli platform environments list
jamf-cli platform tenants list -o tableenvironments list returns id, name, label and metaRegion for each environment. tenants list returns every tenant Jamf holds for the organization, assigned or not, with product, type, metaRegion, url and the environmentId it belongs to. A null environmentId marks a tenant that can still be assigned. The id of an environment is the value platform setup and --environment-id ask for, so these two commands are how you find it:
# Environments with their IDs, as a profile's environment-id wants them
jamf-cli platform environments list --select id,name,metaRegion -o table
# Tenants not yet in any environment
jamf-cli platform tenants list -o json | jq '.[] | select(.environmentId == null) | {id, name, product, url}'Wire-checked on v1.34.0 against an organization-scoped US credential: 9 environments and 40 tenants, 14 of the tenants unassigned.
| Command | Does |
|---|---|
environments list |
List environments |
environments create |
Create one. label is BETA, NFR, PRODUCTION, SANDBOX or TRIAL; metaRegion is US, EU, APAC, HIGH_COMPLIANCE or FEDRAMP
|
environments update <id> |
Replace name and label (its body takes no metaRegion) |
environments apply |
Create or update by the name in the body. The update is a PUT, so omitted fields are cleared |
environments delete <id> |
Delete one. Confirms first unless --yes
|
environments tenants <id> |
Assign tenants to the environment, from a tenantIds list in the body |
jamf-cli platform environments create --set name="Lab" --set label=SANDBOX --set metaRegion=US
# Assign tenants (--scaffold prints the body)
jamf-cli platform environments tenants <environment-id> \
--set 'tenantIds=["<tenant-id>"]'
# Preview any of them: nothing is sent
jamf-cli platform environments tenants --name "Lab" --set 'tenantIds=["<tenant-id>"]' --dry-run--name resolves an environment by name on update, delete and tenants. -n prints the method, path and body, for example PUT /organization/v1/environments/<id>/tenants. tenants is a write that moves a tenant between scopes, so preview it first. tenants list is read-only: a tenant is assigned from the environment side, with environments tenants.
The catalog carries no capability names for these commands, since upstream strips them from the Jamf Account specs. A 403 names the grant the integration is missing.
For organizations registered as Jamf distributors: read the integration configuration, read a quote, and validate or submit a purchase order against it.
jamf-cli platform distributor-configuration get
jamf-cli platform distributor-configuration patch --from-file config.json
jamf-cli platform distributor-quotes get Q-0012345
# Validate before submitting: same rules, no side effect
jamf-cli platform distributor-purchase-orders validate --from-file po.json
jamf-cli platform distributor-purchase-orders create --from-file po.json
jamf-cli platform distributor-purchase-orders get PO-88231
# Templates for the three write bodies
jamf-cli platform distributor-purchase-orders create --scaffold
jamf-cli platform distributor-configuration patch --scaffolddistributor-configuration patch is a partial update: only the fields present in the body change.
As of 2026-09-01 all five distributor operations answer an undocumented 400 for every caller,
patchincluded, and including calls carrying a bogus ID:400 [UPSTREAM_ERROR] "Failed to <verb> ... via Skyway distributor service"Jamf Account's own call to the Skyway distributor service fails before your request is evaluated. No credential, privilege grant or distributor registration changes the answer, so do not hunt for a permission. The CLI detects the fault and appends a note, so what you see is more than a bare
[UPSTREAM_ERROR]. Report it to Jamf Support with thetraceIdwhen one is present. The wording of the upstream fault has changed once already without the surface becoming usable, so re-check this section against the wire before relying on it.
| Command | Description |
|---|---|
list |
Every identity provider connection enabled for the organization, across all regions |
get <connectionId> |
One connection, with the provider settings for its type and the domains it serves |
create |
Create a connection and assign its domains and products in one call |
update <connectionId> |
Replace the settings and reapply domains and products |
delete <connectionId> |
Delete it (destructive, needs --yes) |
jamf-cli platform sso-connections list
jamf-cli platform sso-connections get --name "Example Corp Entra"
jamf-cli platform sso-connections create --scaffold
jamf-cli platform sso-connections create --from-file connection.json
jamf-cli platform sso-connections update <connectionId> --from-file connection.json
jamf-cli platform sso-connections delete <connectionId> --yes--help on create and update lists the allowed values for every enum-constrained field, which a scaffold renders as "":
connectionType: OIDC, WAAD, OKTA, GOOGLE_APPS
connection.region: US, EU, AU, JP, RAMP
connection.pkceAuthType: PLAIN, S256, AUTO, DISABLED
connection.tokenEndpointAuthMethod: CLIENT_SECRET_POST, PRIVATE_KEY_JWT
enabledProducts[].product: ACCOUNT, PRO, PROTECT, SCHOOL, SECURITY_CLOUD,
JETP, ROUTINES, INSIGHTS, ELEVATE
connection.region was connection.authZeroRegion before the v1.30.0 spec ingest: a breaking rename upstream, inert here because nothing in the CLI reads that field by name. A --set path or a request body copied out of an older --help still names the old spelling; take the field list from the installed binary's --help or --scaffold.
Deleting a connection does not release its domains: users on the domains it served stop being redirected to the identity provider and fall back to whatever else is configured, while the domains stay claimed and verified.
| Command | Description |
|---|---|
list |
Every domain claimed by the organization, in every status, plus domains shared with it |
create |
Claim a domain and return its verificationKey
|
verify <domainId> |
Re-check DNS for the TXT record and report domainStatus
|
delete <domainId> |
Remove a domain (destructive, needs --yes) |
allocation <domain> |
Which connections a domain is assigned to, and whether Jamf ID sign-in is on |
jamf-cli platform sso-domains list
# Claim a domain: created PENDING, with a verificationKey to publish as a TXT record
jamf-cli platform sso-domains create --set domain=example.com
# Re-check DNS. A failed check is a 200, so read domainStatus and not the exit code
jamf-cli platform sso-domains verify <domainId>
jamf-cli platform sso-domains verify --name example.com
# Is this domain in use before you change or delete its connection?
jamf-cli platform sso-domains allocation example.com
jamf-cli platform sso-domains delete --name example.com --yesA domain cannot be assigned to a connection until it is VERIFIED. list marks a domain another organization has shared with yours as sharedDomain: true, carrying the owning organization's accountId.
Two identifier quirks on this resource.
--namematches thedomainproperty. An SSO domain has no name and its only other handle is an opaque ID, so--name example.comis the lookup to use onverifyanddelete.allocationtakes the domain positionally and has no--name. Its path parameter is the hostname, and resolving a name to the numeric ID and substituting it produced404 Domain not foundfor a call that works when you pass the domain.
Four commands reading the platform's audit event log: who called what, through which transaction, against which resource. jamf-cli platform audit queries an event log and reports events; jamf-cli pro audit runs cross-resource health checks against a Jamf Pro instance (undeployed blueprints, stale configuration, failed declarations) and reports findings. Different namespaces, different jobs.
Environment scope only. Audit needs a profile carrying an environment ID. An organization-scoped profile sends no scope header and the gateway answers
400 REQUEST_CONTEXT_NOT_PROVIDED, to which the CLI appends a note naming the fix. A tenant-scoped profile answers400 INVALID_REQUEST_CONTEXT_TYPE, which names both the level sent and the level expected, so the CLI passes that one through untouched. Audit is served in every region.
| Command | Description |
|---|---|
sources |
The audit sources available in your environment and the event types each has emitted |
list |
Filter audit events, newest-first |
lineage <resourceId> |
Complete transactions that touched a resource |
transaction <txId> |
Every event for one transaction, ordered by time |
# Start here: it populates the filter vocabulary for `list`
jamf-cli -p env platform audit sources
jamf-cli -p env platform audit sources --since 2026-08-01T00:00:00Zsources returns one entry per source with its event types. Observed 2026-09-11 on an EU environment: api-gateway (http.request), blueprints (five blueprint.* types), ai-policy (four ai-policy.* types) and uem-connect (five connector.* types). Its --since is optional and defaults to 90 days ago.
--since is required, and at least one of --actor, --audit-source, --audit-type, --resource-id.
# Omitting --since: refused by the CLI before anything is sent
jamf-cli platform audit list
# usage error, exit 2: required flag(s) "since" not set
# --since alone reaches the server and is refused there
jamf-cli platform audit list --since 2026-09-01T00:00:00Z
# 400 MISSING_REQUIRED_FILTER
# "At least one of actor, audit-source, audit-type, resource-id is required"Cobra can insist on one flag and not on one-of-four, so the command's --help states the second rule and the server enforces it.
# A filtered read
jamf-cli platform audit list \
--since 2026-09-01T00:00:00Z --audit-source api-gateway --page-size 50
# Event types take comma-separated values (max 50) and trailing wildcards
jamf-cli platform audit list --since 2026-09-01T00:00:00Z --audit-type 'blueprint.*'
# Bound the window at both ends; --until defaults to now
jamf-cli platform audit list --since 2026-09-01T00:00:00Z --until 2026-09-02T00:00:00Z \
--resource-id <resource-id>
# Actor ids from auth0 carry a pipe, which must be URI-encoded as %7C
jamf-cli platform audit list --since 2026-09-01T00:00:00Z --actor 'auth0%7C1234567890'Every event carries auditId, auditSource, auditType, environmentId, orgId, resourceId, tenantId, time and txId, so a list result hands you the txId and resourceId the other two commands take. The rest of the shape depends on the source: an api-gateway event carries actor{id,kind} and requestContext{method,path,remoteIp,userAgent,oauthClientId,…} and no data, while a service event (ai-policy, blueprints, uem-connect) carries data{before,after} and neither actor nor requestContext. Both observed 2026-09-11.
list and lineage take --page-size and --cursor, not --page. The CLI's auto-pagination loop handles page + page-size only, so page by hand: pass the previous response's nextCursor back as --cursor.
list allows a page size of 1–200 (default 50); lineage counts transactions and allows 1–100 (default 25).
# lineage prints the whole envelope, so its nextCursor is readable
page=$(jamf-cli platform audit lineage <resource-id> --page-size 25 -o json)
cursor=$(printf '%s' "$page" | jq -r '.nextCursor // empty')
[ -n "$cursor" ] && jamf-cli platform audit lineage <resource-id> \
--page-size 25 --cursor "$cursor"Caveat on
list. Like every generated list command it unwraps the response envelope to the bareitemsarray, sonextCursoris absent from its output and alistpage past the first cannot be driven from the command's own result. Set--page-sizeto 200 and narrow the window with--since/--untiland the filters, or recover the cursor from-vvvbody logging.lineageis unaffected: it prints the envelope intact.
# Everything that touched one resource, with each transaction's full context
jamf-cli platform audit lineage <resource-id> --since 2026-09-01T00:00:00Z
jamf-cli platform audit lineage <resource-id> --audit-type 'blueprint.*' --page-size 25
# One transaction end to end
jamf-cli platform audit transaction <tx-id>lineage returns complete transactions (every event in each one, including events that do not match the resource), which is what gives you the context for a change.
Reading a refusal. The gateway checks ownership before capability, so a foreign
X-Environment-Idmasks whether your credential holdsaudit:read. A502from these endpoints is evidence of a grant.
Platform capabilities are granted when the API integration is created, in the Jamf Account portal's Platform API integrations picker. You search the picker by name, so both spellings are given below; the CLI prints them in a 403 and carries them in the command catalog (jamf-cli commands -o json → privileges, gatewayPermissions, with the declared scope level under scopes).
| Commands | Capability | Jamf Account picker |
|---|---|---|
ai-policies list/get/versions/version/deployment, ai-tools *
|
ai-policies:read |
Compliance > AI policies: Read |
ai-policies create |
ai-policies:create |
Compliance > AI policies: Create |
ai-policies patch, publish
|
ai-policies:update |
Compliance > AI policies: Update |
ai-policies delete |
ai-policies:delete |
Compliance > AI policies: Delete |
audit * |
audit:read |
Admin identity and access > Audit events: Read |
The Jamf Account commands report no privileges in the catalog, because upstream strips that metadata from the published specs they are generated from. The grants they need, all under Organization management in the picker, are:
| Commands | Capability | Jamf Account picker |
|---|---|---|
account-licenses list |
licensing:read |
Licensing: Read |
deal-registrations list, get
|
deal-registration:read |
Partner deal registration: Read |
deal-registrations create |
not verified | A 403 names it |
distributor-* |
distributor-actions:read / :create / :update
|
Distributor actions |
sso-connections * |
sso-connections:read / :create / :update / :delete
|
SSO connections |
sso-domains * |
sso-domains:read / :create / :update / :delete
|
SSO domains |
A permission failure on any platform command exits 5. See Error Handling & Exit Codes.
- Platform API GA Migration: the GA base URL, credentials, scope levels and the refused-command list
-
Platform API Commands: blueprints, compliance benchmarks, platform devices and DDM reports (under
pro) -
Setup Guide:
platform setupand first-run configuration - Configuration & Profiles: profiles, scope IDs and secret references
- Error Handling & Exit Codes: exit 5 for a 403, exit 8 for a policy refusal
-
CLI Patterns:
--from-file,--set,--scaffold,--dry-run, output formats
Repository · Issues · Releases
jamf-cli Wiki
- Home
- Community
- Getting Started
- CLI Reference
- Product Commands
- Workflows
- Configuration
- Reference
Products
- Jamf Pro:
jamf-cli pro - Jamf Platform API:
jamf-cli pro(blueprints, benchmarks, DDM reports) - Jamf Platform:
jamf-cli platform(AI Governance, Jamf Account, audit) - Jamf Protect:
jamf-cli protect - Jamf School:
jamf-cli school - Jamf Security Cloud:
jamf-cli security