Help us shape the future of Go! Take the 2026 Go Developer Survey

declarations

package
v1.11.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 28, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

Package declarations validates Apple declarative device management declarations before they are sent, against a generated table of Apple's own schemas, built from the `declarative` directory of apple/device-management by `make apple-schemas`.

The table is derived from github.com/apple/device-management, Copyright © Apple Inc., MIT licensed; the licence text is in ../LICENSE-apple.

Why this exists

Jamf validates nothing here. Wire probing on 2026-09-10 established that the blueprints service accepts and stores verbatim every malformed declaration put to it — an unknown declaration type, an invented key, a wrong-cased key, a value of the wrong type, a value outside a declared enum, an integer outside a declared range, a required key omitted — and returns 201 for all of them. A deploy of the same blueprint returns 202 and reports SUCCEEDED. The Jamf Pro editor then renders the declaration's generated form with the offending key blank, and the device never receives it. So the failure is silent at every layer the operator can see, which is exactly why the check belongs in the consumer's plan or pre-flight check, and why every finding here is an error rather than a warning: there is no point letting through a declaration that cannot work on the device.

How the service behaves, and why the findings are classified as they are

The editor's behaviour distinguishes two stages, which is what made the rules observable: a recognised key ticks its own checkbox, and its value populates only if the value is acceptable. "Ticked but empty" therefore means the name was understood and the value rejected, while "unticked" means the name itself was never recognised.

  • Key names are matched CASE-SENSITIVELY and a wrong-cased key is discarded. This is the opposite of configuration profile payloads, where Jamf silently restores Apple's spelling — see package profiles (appleschemas/profiles). The two packages must not share case handling.
  • A declaration type is likewise matched case-sensitively; a wrong-cased type renders no card at all.
  • A value outside a declared `rangelist` is dropped, so an enum violation never applies.
  • A numeric value outside a declared `range` is NOT rejected: the service stores and renders it unchanged. It is still an error here, because the device is what rejects it, and a warning would leave the operator with a declaration that silently never applies.
  • `kind` is accepted in any pairing with `type`, so a mismatch reaches the device as a malformed declaration. The pairing is determined by the type's prefix, so no table is needed.

Snapshot currency

The table is the union of Apple's release branch and its newest seed (pre-release) branch, because Jamf's generative-declarations service tracks seed: at the time of writing seed carries 12 configuration declaration types and keys such as `siri.settings.AllowSiriAI` that release does not, all of them already offered in the Jamf UI. Validating against release alone would reject working configurations. Schema.SeedOnly reports which side a key came from so a diagnostic can say so.

Because an unrecognised name is an error, a stale table blocks a working configuration. Two things mitigate that: the table is refreshed daily by a scheduled pull request, and a consumer should offer an escape hatch that downgrades these findings, for the window between Apple publishing and the consumer picking up the SDK release that carries the refresh.

What none of this can prove is that Jamf tracks the *same* seed branch the table unions. That is inferred from `AllowSiriAI` appearing in the Jamf picker while absent from release. If false positives reappear for keys the UI offers, re-probe that assumption first.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func DeclarationTypes

func DeclarationTypes() []string

DeclarationTypes returns every declaration type in the table, sorted.

func KindForType

func KindForType(declarationType string) string

KindForType returns the kind the service expects alongside a declaration type, derived from its reverse-domain prefix, or "" when the prefix is not one Apple defines.

func Provenance

func Provenance() (commit, release string)

Provenance returns the commit of the release branch and the upstream release subject, for diagnostics that need to say how current the schemas are. The two can name different branches: the subject is the head commit's of the most forward-looking branch unioned, so while a seed branch is open it is the seed's ("Seed8") rather than release's. ProvenanceSummary names each branch with its own commit.

func ProvenanceSummary

func ProvenanceSummary() string

ProvenanceSummary renders the branches and commits the table was built from, e.g. "release@67045e2fa06f + seed_OS_27_0@b0180185a5e4". Preferred over Provenance in a diagnostic: Apple's commit subjects are terse internal labels ("Seed8"), which read as a typo when dropped into a sentence, whereas a branch and commit are things an operator can actually look up.

func Refs

func Refs() []string

Refs returns the upstream branches the table unions, in read order.

func ReleaseRef

func ReleaseRef() string

ReleaseRef returns the branch the table treats as released, which is the first one read.

func StatusItems

func StatusItems() []string

StatusItems returns the subscribable status-item names, sorted.

Types

type Declaration

type Declaration struct {
	Title string             `json:"title,omitempty"`
	Kind  string             `json:"kind"`
	Keys  map[string]*Schema `json:"keys"`
	Any   *Schema            `json:"any,omitempty"`
	Refs  []string           `json:"refs,omitempty"`
}

Declaration is the declared shape of one declaration type.

func Lookup

func Lookup(declarationType string) (*Declaration, bool)

Lookup returns the declared shape of a declaration type. The match is case-sensitive, mirroring the service, which renders no form at all for a wrong-cased type.

The returned value points into the package's decoded table, which every caller and every later Validate share, so it must not be modified. Unlike Refs and StatusItems it is not cloned, because Validate looks up every declaration it checks and a deep copy of a type's key tree would be paid on each call.

func (*Declaration) SeedOnly

func (d *Declaration) SeedOnly() bool

SeedOnly reports whether this declaration type is declared only on a pre-release branch.

type Kind

type Kind string

Kind is the value type Apple declares for a key.

const (
	KindBoolean    Kind = "boolean"
	KindInteger    Kind = "integer"
	KindReal       Kind = "real"
	KindString     Kind = "string"
	KindData       Kind = "data"
	KindDate       Kind = "date"
	KindArray      Kind = "array"
	KindDictionary Kind = "dictionary"
	KindAny        Kind = "any"
)

The declared value types. KindAny accepts anything, and is also what the generator falls back to for a type it does not recognise, so an upstream vocabulary change cannot become a false finding.

type Problem

type Problem struct {
	Kind ProblemKind
	// Path is the dotted path to the offending value within the declaration's payload, with array
	// entries indexed (`StatusItems[0].Name`). It is empty when the problem is the declaration
	// type or its kind rather than something inside the payload.
	Path string
	// Detail describes the problem in one sentence, ready to drop into a diagnostic.
	Detail string
	// Canonical carries Apple's spelling for a miscased type or key, and is empty otherwise.
	Canonical string
	// SeedOnly marks a finding about a key or type that the table knows only from Apple's
	// pre-release branch. It does not soften the finding — the value is still wrong — but it tells
	// the operator the surrounding schema is newer than the released one.
	SeedOnly bool
}

Problem is one finding against a declaration.

func Validate

func Validate(kind, declarationType string, payload map[string]any) []Problem

Validate checks one declaration against Apple's schemas, returning every problem found, ordered by path. A nil payload is still checked, so a declaration omitting a required key is reported.

Null values are treated as absent throughout: a null is never a type error, and a null under a required key is a missing key.

type ProblemKind

type ProblemKind int

ProblemKind classifies a finding against a declaration. Every kind is an error: each one names behaviour the service or the device was observed to reject or silently discard, so none of them can produce a declaration that works. See the package doc for the wire evidence behind each.

const (
	// UnknownDeclarationType means Apple declares no such type on either branch the table unions.
	// The service stores it and the editor renders no card, so it never reaches a device.
	UnknownDeclarationType ProblemKind = iota
	// MiscasedDeclarationType means the type matches a declared one apart from case. The service
	// matches case-sensitively, so this behaves exactly like an unknown type.
	MiscasedDeclarationType
	// KindMismatch means `kind` disagrees with the type's reverse-domain prefix. The service
	// accepts any pairing and passes the mismatch through to the device.
	KindMismatch
	// UnknownKey means Apple declares no such key for this declaration type. The service discards
	// an unrecognised key silently, so it can never appear in state or on the device.
	UnknownKey
	// MiscasedKey means the key matches a declared key apart from case. Unlike a configuration
	// profile payload, where Jamf restores Apple's spelling, a declaration key is DISCARDED.
	MiscasedKey
	// WrongType means the value does not match the declared type. The key is recognised but the
	// value is dropped, leaving the setting unapplied.
	WrongType
	// MissingRequiredKey means a key Apple marks required is absent or null.
	MissingRequiredKey
	// NotInEnum means the value is outside the closed set Apple declares in `rangelist`. The
	// service recognises the key and drops the value.
	NotInEnum
	// OutOfRange means a numeric value falls outside Apple's declared `range`. Jamf does NOT
	// enforce this — it stores and renders the value unchanged — but the device rejects it, so the
	// declaration silently never applies.
	OutOfRange
	// UnknownStatusItem means a status subscription names an item Apple does not publish. Nothing
	// in Apple's schemas types these strings, so this is the only check that can catch a typo.
	UnknownStatusItem
)

func (ProblemKind) String

func (k ProblemKind) String() string

String names the kind, for test failure messages and diagnostics that group findings.

type Schema

type Schema struct {
	Type     Kind     `json:"type"`
	Required bool     `json:"required,omitempty"`
	Enum     []any    `json:"enum,omitempty"`
	Min      *float64 `json:"min,omitempty"`
	Max      *float64 `json:"max,omitempty"`
	// Refs names the upstream branches declaring this key, in read order.
	Refs []string           `json:"refs,omitempty"`
	Keys map[string]*Schema `json:"keys,omitempty"`
	Any  *Schema            `json:"any,omitempty"`
	Item *Schema            `json:"item,omitempty"`
}

Schema is the declared shape of one key's value.

func (*Schema) SeedOnly

func (s *Schema) SeedOnly() bool

SeedOnly reports whether this key is declared only on a pre-release branch.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL