Documentation
¶
Overview ¶
Package ab is the Apple Business API client: ES256 client-assertion auth + typed read methods. Auth OMITS the JWT `kid` (verified live: a kid -> invalid_client).
Index ¶
- Constants
- Variables
- func BlueprintRel(collection string) string
- type APIError
- type Client
- func (c *Client) APIWrite(method, path string, payload any) (int, []byte, error)
- func (c *Client) AddBlueprintMembers(bpID, rel, memberType string, ids []string) error
- func (c *Client) AssignDevices(serverID string, deviceIDs []string) (string, error)
- func (c *Client) AuditEvents(start, end string) ([]Resource, error)
- func (c *Client) BlueprintRelationship(id, rel string) ([]Resource, error)
- func (c *Client) CreateBlueprint(name, description string, members map[string][]string) (*Resource, error)
- func (c *Client) CreateConfiguration(name, xml string, platforms []string) (id, updated string, err error)
- func (c *Client) CreateMDMServer(name, certName string, certPEM []byte, disown *bool) (*Resource, error)
- func (c *Client) DeleteBlueprint(id string) error
- func (c *Client) DeleteConfiguration(id string) error
- func (c *Client) DeleteMDMServer(id string) error
- func (c *Client) DeviceAppleCare(id string) ([]Resource, error)
- func (c *Client) DeviceAssignedServer(id string) (*Resource, error)
- func (c *Client) FetchBlueprintMemberMaps(collections []string, progress func(string)) (nameByID, canonicalByAlias map[string]map[string]string, err error)
- func (c *Client) FetchBlueprints(collections []string, nameByID map[string]map[string]string, ...) ([]LiveBlueprint, error)
- func (c *Client) FetchCustomSettingDetail(id string) (LiveConfig, error)
- func (c *Client) FetchCustomSettings() ([]LiveConfig, error)
- func (c *Client) FetchCustomSettingsMetadata(progress func(string)) ([]LiveConfig, error)
- func (c *Client) FetchCustomSettingsWithProgress(progress func(string)) ([]LiveConfig, error)
- func (c *Client) GetApp(id string) (*Resource, error)
- func (c *Client) GetBlueprint(id string) (*Resource, error)
- func (c *Client) GetConfiguration(id string) (*Resource, error)
- func (c *Client) GetDevice(id string) (*Resource, error)
- func (c *Client) GetMDMDevice(id string) (*Resource, error)
- func (c *Client) GetMDMDeviceDetails(id string) (*Resource, error)
- func (c *Client) GetMDMServer(id string) (*Resource, error)
- func (c *Client) GetOrgDeviceActivity(id string) (*Resource, error)
- func (c *Client) GetPackage(id string) (*Resource, error)
- func (c *Client) GetUser(id string) (*Resource, error)
- func (c *Client) GetUserGroup(id string) (*Resource, error)
- func (c *Client) ListApps() ([]Resource, error)
- func (c *Client) ListBlueprints() ([]Resource, error)
- func (c *Client) ListConfigurations() ([]Resource, error)
- func (c *Client) ListDevices() ([]Resource, error)
- func (c *Client) ListMDMDevices() ([]Resource, error)
- func (c *Client) ListMDMServers() ([]Resource, error)
- func (c *Client) ListPackages() ([]Resource, error)
- func (c *Client) ListUserGroups() ([]Resource, error)
- func (c *Client) ListUsers() ([]Resource, error)
- func (c *Client) MDMServerDeviceIDs(id string) ([]string, error)
- func (c *Client) Raw(method, path string, body io.Reader) (int, []byte, error)
- func (c *Client) RemoveBlueprintMembers(bpID, rel, memberType string, ids []string) error
- func (c *Client) ResolveApp(nameOrID string) (*Resource, error)
- func (c *Client) ResolveBlueprint(nameOrID string) (*Resource, error)
- func (c *Client) ResolveConfig(nameOrID string) (*Resource, error)
- func (c *Client) ResolveDevice(serialOrID string) (*Resource, error)
- func (c *Client) ResolveMDMServer(nameOrID string) (*Resource, error)
- func (c *Client) ResolvePackage(nameOrID string) (*Resource, error)
- func (c *Client) ResolveUser(emailOrID string) (*Resource, error)
- func (c *Client) ResolveUserGroup(nameOrID string) (*Resource, error)
- func (c *Client) TokenSource() *TokenSource
- func (c *Client) UnassignDevices(serverID string, deviceIDs []string) (string, error)
- func (c *Client) UpdateBlueprint(id string, name, description *string) error
- func (c *Client) UpdateConfiguration(id, name, xml string) (updated string, err error)
- func (c *Client) UpdateMDMServer(id string, name *string, disown *bool) error
- func (c *Client) UserGroupUserIDs(id string) ([]string, error)
- type LiveBlueprint
- type LiveConfig
- type Resource
- type TokenSource
Constants ¶
const ( CollectionConfigurations = "configurations" CollectionApps = "apps" CollectionPackages = "packages" CollectionDevices = "devices" CollectionUsers = "users" CollectionGroups = "groups" )
Blueprint member collections, keyed by the manifest key used in gitops/blueprints/*.yml (see gitops.BlueprintSpec.Members).
Variables ¶
var BlueprintCollections = []string{ CollectionConfigurations, CollectionApps, CollectionPackages, CollectionDevices, CollectionUsers, CollectionGroups, }
BlueprintCollections lists the six member collections in manifest order.
Functions ¶
func BlueprintRel ¶ added in v0.4.15
BlueprintRel maps a manifest collection key to the blueprint relationship name (== member type). The empty key maps to "configurations" so plan items that predate the Collection field keep working; an unknown key returns "".
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a thin Apple Business API client (read methods for Phase 0).
func (*Client) APIWrite ¶
APIWrite issues an authenticated non-GET request with a JSON body (used by the gated `api` passthrough). A nil payload sends no body. It retries 401 (re-mint) and 429, never 5xx (a write may have partially applied).
func (*Client) AddBlueprintMembers ¶
AddBlueprintMembers / RemoveBlueprintMembers converge a blueprint relation via explicit per-member ops (correct whether Apple merges or replaces). Gated in the engine — not used by autonomous config-only apply.
func (*Client) AssignDevices ¶ added in v0.4.15
AssignDevices POSTs an ASSIGN_DEVICES activity moving deviceIDs (orgDevice ids) onto the MDM server. It returns the activity id for status polling (GetOrgDeviceActivity) — the assignment completes asynchronously.
func (*Client) AuditEvents ¶
AuditEvents returns audit events between the start and end timestamps (ISO 8601).
func (*Client) BlueprintRelationship ¶
BlueprintRelationship returns linkage IDs for a blueprint member relation.
func (*Client) CreateBlueprint ¶ added in v0.4.15
func (c *Client) CreateBlueprint(name, description string, members map[string][]string) (*Resource, error)
CreateBlueprint POSTs a new blueprint. description is optional (omitted when empty). members maps a relationship name (see BlueprintRel) to resolved ABM ids and is INLINED in the create request: live testing (2026-07-05, HANDOFF.md) showed Apple rejects a member-less create (`409 …MISSING_MEMBERS` / `MISSING_RESOURCES`), so a bare POST is only useful if Apple relaxes that — callers should inline what they can and surface the 409 verbatim otherwise. Post-create convergence still goes through Add/RemoveBlueprintMembers (relationships POST merges additively).
func (*Client) CreateConfiguration ¶
func (c *Client) CreateConfiguration(name, xml string, platforms []string) (id, updated string, err error)
CreateConfiguration POSTs a CUSTOM_SETTING config with the raw .mobileconfig XML. It returns the new config's ID and its server-assigned updatedDateTime (parsed from the 201 body) so the caller can record an exact baseline with no extra GET.
func (*Client) CreateMDMServer ¶ added in v0.4.15
func (c *Client) CreateMDMServer(name, certName string, certPEM []byte, disown *bool) (*Resource, error)
CreateMDMServer POSTs a new MDM server with its push-certificate PEM. disown is optional (nil = omit, let Apple default enableMdmDisownFlag). The PEM is sent to Apple verbatim and never logged.
func (*Client) DeleteBlueprint ¶ added in v0.4.15
DeleteBlueprint deletes a blueprint by id.
func (*Client) DeleteConfiguration ¶
DeleteConfiguration deletes a configuration by id.
func (*Client) DeleteMDMServer ¶ added in v0.4.15
DeleteMDMServer deletes an MDM server by id. Apple refuses (409) while devices are still assigned to it — that error is surfaced verbatim so the caller can tell the user to unassign first.
func (*Client) DeviceAppleCare ¶ added in v0.4.15
DeviceAppleCare returns an organization device's AppleCare coverage records.
func (*Client) DeviceAssignedServer ¶ added in v0.4.15
DeviceAssignedServer returns the MDM server an organization device is assigned to, or (nil, nil) when the device is unassigned (Apple answers 404).
func (*Client) FetchBlueprintMemberMaps ¶ added in v0.4.15
func (c *Client) FetchBlueprintMemberMaps(collections []string, progress func(string)) (nameByID, canonicalByAlias map[string]map[string]string, err error)
FetchBlueprintMemberMaps builds the id → display-name map for each requested member collection by listing that collection's tenant resources once (one paginated list per collection — fetch only the collections some manifest manages, or five full-tenant lists are wasted). Devices are keyed by serialNumber, users by email (falling back to managedAppleAccount, matching ResolveUser), apps/packages/user groups by name. "configurations" is skipped — the config map is ownership-scoped to the sync baseline and supplied by the caller — and a resource with no display name is omitted, so its id passes through membership lists as-is and is never planned for detach.
The second map resolves the ALIASES the imperative resolvers also accept — per collection, lowercased alias → canonical display name (devices: serial case variants; users: email AND managedAppleAccount, case-insensitive) — so a manifest entry written as an accepted alias can be canonicalized before the byte-exact membership diff. An alias claimed by more than one canonical name maps to "" (ambiguous — the caller must leave the manifest entry untouched).
func (*Client) FetchBlueprints ¶
func (c *Client) FetchBlueprints(collections []string, nameByID map[string]map[string]string, progress func(string)) ([]LiveBlueprint, error)
FetchBlueprints lists all blueprints and resolves each one's membership to display names for the requested collections. "configurations" is always fetched (blueprint sync depends on it) whether or not it is listed; each other collection costs one relationship call per blueprint, so callers pass only the collections their manifests actually manage. nameByID maps collection key → member id → display name (see FetchBlueprintMemberMaps); an unresolved or unnamed id passes through as-is.
func (*Client) FetchCustomSettingDetail ¶ added in v0.4.9
func (c *Client) FetchCustomSettingDetail(id string) (LiveConfig, error)
FetchCustomSettingDetail returns one CUSTOM_SETTING configuration with profile XML.
func (*Client) FetchCustomSettings ¶
func (c *Client) FetchCustomSettings() ([]LiveConfig, error)
FetchCustomSettings returns all CUSTOM_SETTING configs with their raw XML. Uses one list call with fields[] (incl. customSettingsValues) to avoid a GET per config; falls back to a per-config GET only if the list came back sparse.
func (*Client) FetchCustomSettingsMetadata ¶ added in v0.4.9
func (c *Client) FetchCustomSettingsMetadata(progress func(string)) ([]LiveConfig, error)
FetchCustomSettingsMetadata returns CUSTOM_SETTING configurations without requesting profile XML.
func (*Client) FetchCustomSettingsWithProgress ¶ added in v0.4.4
func (c *Client) FetchCustomSettingsWithProgress(progress func(string)) ([]LiveConfig, error)
FetchCustomSettingsWithProgress returns live CUSTOM_SETTING configurations while reporting long-running list and per-profile detail fetch progress through progress.
func (*Client) GetBlueprint ¶
GetBlueprint fetches a single blueprint by ID.
func (*Client) GetConfiguration ¶
GetConfiguration fetches a single configuration by ID.
func (*Client) GetDevice ¶ added in v0.4.15
GetDevice fetches a single organization device (orgDevice) by id.
func (*Client) GetMDMDevice ¶ added in v0.4.15
GetMDMDevice fetches a single built-in-MDM device by id.
func (*Client) GetMDMDeviceDetails ¶ added in v0.4.15
GetMDMDeviceDetails fetches a built-in-MDM device's last-reported posture (OS version, FileVault/firewall state, storage, lock/erase/lost-mode status).
func (*Client) GetMDMServer ¶ added in v0.4.15
GetMDMServer fetches a single MDM server by id.
func (*Client) GetOrgDeviceActivity ¶ added in v0.4.15
GetOrgDeviceActivity fetches a device-management activity (assign/unassign job) by id.
func (*Client) GetPackage ¶ added in v0.4.15
GetPackage fetches a single package (custom app/pkg) by id.
func (*Client) GetUser ¶ added in v0.4.15
GetUser fetches a single user by id (users are API-read-only).
func (*Client) GetUserGroup ¶ added in v0.4.15
GetUserGroup fetches a single user group by id (read-only).
func (*Client) ListBlueprints ¶
ListBlueprints returns all blueprints.
func (*Client) ListConfigurations ¶
ListConfigurations returns all configurations (every type; only CUSTOM_SETTING is writable).
func (*Client) ListDevices ¶
ListDevices returns the organization's devices (orgDevices).
func (*Client) ListMDMDevices ¶ added in v0.4.15
ListMDMDevices returns the devices enrolled in built-in MDM (mdmDevices).
func (*Client) ListMDMServers ¶
ListMDMServers returns the organization's MDM servers (read-only).
func (*Client) ListPackages ¶
ListPackages returns the organization's packages (custom apps/pkgs; read-only). The endpoint is gated by the built-in-device-management permission, so it may 403 for an account without it.
func (*Client) ListUserGroups ¶
ListUserGroups returns the organization's user groups (read-only).
func (*Client) ListUsers ¶
ListUsers returns the organization's users (read-only; identity is not API-writable).
func (*Client) MDMServerDeviceIDs ¶ added in v0.4.15
MDMServerDeviceIDs returns the orgDevice ids assigned to an MDM server (paginated linkage list).
func (*Client) Raw ¶
Raw issues an authenticated request. For replayable (nil-body) requests it re-mints once on 401 and backs off on 429/5xx (respecting Retry-After).
func (*Client) RemoveBlueprintMembers ¶
RemoveBlueprintMembers detaches members (per-member DELETE) from a blueprint relation.
func (*Client) ResolveApp ¶ added in v0.2.0
ResolveApp finds an owned app by id, bundleId, or name. id/bundleId are unique so they win immediately; name may collide, so a name that matches >1 app is an error (caller should use the id/bundleId). App ids are numeric adamIds, not UUIDs, so looksLikeID never matches — always list and match here.
func (*Client) ResolveBlueprint ¶
ResolveBlueprint finds a blueprint by id (UUID) or by its `name` attribute.
func (*Client) ResolveConfig ¶
ResolveConfig finds a configuration by id (UUID) or by its `name` attribute.
func (*Client) ResolveDevice ¶ added in v0.4.15
ResolveDevice finds an organization device by id or serial number (serials compare case-insensitively). Device ids are serial-shaped, not UUIDs, so looksLikeID never matches — always list and match here.
func (*Client) ResolveMDMServer ¶ added in v0.4.15
ResolveMDMServer finds an MDM server by id or by its `serverName` attribute; a name shared by >1 server is an error (caller should use the server id).
func (*Client) ResolvePackage ¶ added in v0.4.15
ResolvePackage finds a package by id or by its `name` attribute; a name shared by >1 package is an error (caller should use the package id).
func (*Client) ResolveUser ¶ added in v0.4.15
ResolveUser finds a user by id, email, or managed Apple Account (addresses compare case-insensitively). id is unique so it wins immediately; an address that matches >1 user is an error (caller should use the id).
func (*Client) ResolveUserGroup ¶ added in v0.4.15
ResolveUserGroup finds a user group by id or by its `name` attribute; a name shared by >1 group is an error (caller should use the group id).
func (*Client) TokenSource ¶
func (c *Client) TokenSource() *TokenSource
TokenSource exposes the underlying bearer-token source (for whoami/health checks).
func (*Client) UnassignDevices ¶ added in v0.4.15
UnassignDevices POSTs an UNASSIGN_DEVICES activity removing deviceIDs (orgDevice ids) from the MDM server. It returns the activity id for status polling.
func (*Client) UpdateBlueprint ¶ added in v0.4.15
UpdateBlueprint PATCHes a blueprint's name and/or description. Only fields whose pointer is non-nil are sent; with neither provided it is a no-op (no API call).
func (*Client) UpdateConfiguration ¶
UpdateConfiguration PATCHes a CUSTOM_SETTING config's name + profile XML and returns the server-assigned updatedDateTime (parsed from the 200 body).
func (*Client) UpdateMDMServer ¶ added in v0.4.15
UpdateMDMServer PATCHes an MDM server's serverName and/or enableMdmDisownFlag. Only fields whose pointer is non-nil are sent; with neither provided it is a no-op (no API call).
type LiveBlueprint ¶
type LiveBlueprint struct {
Name string
ID string
Description string
Configs []string // config names, sorted; an unresolved id passes through as-is
Apps []string // app names
Packages []string // package names
Devices []string // device serial numbers
Users []string // user emails (managed Apple Account when email is empty)
Groups []string // user-group names
}
LiveBlueprint is a blueprint with the NAMES of its attached members, one list per collection. Configs is always fetched; the other five are fetched only for the collections the caller asked for, so nil means "not fetched" (unknown) — NEVER "empty membership".
func (LiveBlueprint) Members ¶ added in v0.4.15
func (l LiveBlueprint) Members(collection string) []string
Members returns the live display-name list for one member collection key.
type LiveConfig ¶
LiveConfig is a CUSTOM_SETTING configuration with its raw profile XML.
func (LiveConfig) ContentHash ¶ added in v0.4.9
func (l LiveConfig) ContentHash() string
ContentHash returns the known normalized profile hash, deriving it from XML when present.
type Resource ¶
type Resource struct {
Type string `json:"type"`
ID string `json:"id"`
Attributes json.RawMessage `json:"attributes"`
}
Resource is a JSON:API resource object.
type TokenSource ¶
type TokenSource struct {
// contains filtered or unexported fields
}
TokenSource mints and caches a bearer token from an ES256 client assertion.
func NewTokenSource ¶
func NewTokenSource(cfg *config.Config, hc *http.Client) *TokenSource
NewTokenSource caches the bearer in a stable, per-credential file (see tokenCachePath).
func (*TokenSource) Expiry ¶
func (ts *TokenSource) Expiry() time.Time
Expiry returns the cached token expiry (after a successful Token()).
func (*TokenSource) Invalidate ¶
func (ts *TokenSource) Invalidate()
Invalidate forces a re-mint on the next Token() (e.g., after a 401).
func (*TokenSource) Token ¶
func (ts *TokenSource) Token() (string, error)
Token returns a valid bearer, minting/refreshing if <60s remain.