Skip to content

Jamf Platform Commands

Neil Martin edited this page Oct 23, 2026 · 7 revisions

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.

Scope levels

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 setup

Environment 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".

Aliases

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), and platform ai-policies apply, which takes no identifier and reads the name out of the body.

A --name lookup 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.


Jamf AI Governance (aip, ait)

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 json carries preview: true on each of the thirteen, the apply the 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 a description opening with Preview - (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 the Preview - 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.

--help says what the command does again in v1.30.0. Twelve of the thirteen take their text from an upstream description (apply is 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 twelve Long texts 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 of delete --help are what the binary prints.

Policies (ai-policies, aip)

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> --yes

Draft and published versions are separate

create 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_PUBLISH

publish 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.

delete declares a 409 POLICY_IN_USE that has not been observed. The spec and delete --help say archiving is refused while a blueprint references the policy; the last probe (2026-08-30) got a clean 204 and left the blueprint pointing at a policy nothing can read. Detach the policy from its blueprints before archiving it.

patch replaces settings wholesale. Despite being a PATCH sent as application/merge-patch+json, the server treats settings as a full replacement: seed {permissions: …, env: …}, patch with {permissions: …} alone, and env is gone. name and description are leave-unchanged-if-omitted, so the two halves of one request body behave differently. Both schemaVersion and settings are required, so there is no partial-edit body to build.

Consequence: --set settings.x=y discards every other setting, and the same applies to apply, whose update is this PATCH. apply --help names settings as replaced wholesale. Read the policy, edit the whole settings object, 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: create or update by the name in the body

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 --yes

Four properties a script can rely on:

  • The name comes from the body. There is no --name on apply. A body with no name, or a name that 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. Serialise apply per policy where that matters.
  • apply writes a draft and leaves it unpublished. A draft is inert until platform 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.

Concurrent edits are last-writer-wins

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: null marks a policy with no ETag. A policy predating the rollout has none: both policies on the probe tenant, created 2026-07-01, answer version: null and their GET sends no ETag header. Nothing can update those conditionally.

list paginates and sorts

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-drift narrows the list. The CLI sends the parameter only when set, and server-side schema-drift=false returns everything. Pass the flag for drifted policies; omit it for all of them.

Tools and schemas (ai-tools, ait)

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-12

Read the schema before you trust a settings key. The vendor schema decides what happens to an unrecognised key. com.anthropic.claudecode declares additionalProperties: true and stores a bogus key without comment; com.openai.codex sets false and answers 422 SCHEMA_VALIDATION_FAILED naming 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 schema returns a large JSON Schema (roughly 250 KB for com.anthropic.claudecode). There is no table shape for it, so read it as JSON or pipe it to jq.

AI Governance error codes

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.


Jamf Account (lic, deals, envs, dcfg, dpo, dq, ssoc, ssod)

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 found for 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

Licensing and deal registration

# 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-run

Neither 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.

Environments and tenants (envs)

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 table

environments 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.

Distributor operations

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 --scaffold

distributor-configuration patch is a partial update: only the fields present in the body change.

Known upstream issue: the distributor 400

As of 2026-09-01 all five distributor operations answer an undocumented 400 for every caller, patch included, 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 the traceId when 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.

SSO connections (ssoc)

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.

SSO domains (ssod)

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 --yes

A 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.

  • --name matches the domain property. An SSO domain has no name and its only other handle is an opaque ID, so --name example.com is the lookup to use on verify and delete.
  • allocation takes the domain positionally and has no --name. Its path parameter is the hostname, and resolving a name to the numeric ID and substituting it produced 404 Domain not found for a call that works when you pass the domain.

Platform Audit (platform audit)

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 answers 400 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:00Z

sources 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.

list has two required-parameter rules

--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.

Audit pages by cursor, with no --all

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 bare items array, so nextCursor is absent from its output and a list page past the first cannot be driven from the command's own result. Set --page-size to 200 and narrow the window with --since/--until and the filters, or recover the cursor from -vvv body logging. lineage is 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-Id masks whether your credential holds audit:read. A 502 from these endpoints is evidence of a grant.


Required privileges

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.

See also

jamf-cli Wiki


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

Clone this wiki locally