Go API reference
Generated from Go declarations and purpose/usage comments. Development contracts may change before v1.
Store
go/adapters/filesystem/store.go:21
type Store struct {
// contains filtered or unexported fields
}
Open
go/adapters/filesystem/store.go:25
// Open prepares a durable content-addressed directory; it never creates a temporary fallback.
// Usage: store, err := filesystem.Open("/var/lib/kylok/artifacts").
func Open(dir string) (*Store, error)
Open prepares a durable content-addressed directory; it never creates a temporary fallback. Usage: store, err := filesystem.Open("/var/lib/kylok/artifacts").
*Store.Put
go/adapters/filesystem/store.go:37
// Put verifies the digest and atomically publishes immutable bytes without replacing concurrent content.
// Usage: err := store.Put(ctx, digest, verifiedBytes).
func (s *Store) Put(ctx context.Context, digest string, data []byte) error
Put verifies the digest and atomically publishes immutable bytes without replacing concurrent content. Usage: err := store.Put(ctx, digest, verifiedBytes).
*Store.Open
go/adapters/filesystem/store.go:98
// Open verifies stored bytes and returns a seekable immutable snapshot, detecting on-disk corruption.
// Usage: reader, err := store.Open(ctx, digest); close reader after use.
func (s *Store) Open(ctx context.Context, digest string) (ports.ReadSeekCloser, error)
Open verifies stored bytes and returns a seekable immutable snapshot, detecting on-disk corruption. Usage: reader, err := store.Open(ctx, digest); close reader after use.
Options
go/adapters/postgres/store.go:16
type Options struct {
Schema string
// Initialize requires CREATE on the database/schema and creates only Kylok-owned objects.
// Leave false at runtime after initialization; missing/incomplete/wrong-version schemas fail closed.
Initialize bool
}
Options selects a dedicated existing schema or explicitly opts in to initializing it. Schema must be a lowercase SQL identifier, at most 63 characters; no search_path changes are made.
Store
go/adapters/postgres/store.go:26
type Store struct{ ports.StateStore }
Store implements the concurrent transactional state contract. PostgreSQL effects serialize per schema across processes using a transaction-level advisory lock. The host owns the pool, driver, TLS, credentials, limits and shutdown. No Close method owns that pool.
Open
go/adapters/postgres/store.go:31
// Open verifies a dedicated schema on a supplied pool, optionally initializing it atomically.
// It never closes or reconfigures the pool, including on failure. It does not join host transactions.
// Usage: store, err := postgres.Open(ctx, db, postgres.Options{Schema: "kylok", Initialize: true}).
func Open(ctx context.Context, db *sql.DB, options Options) (*Store, error)
Open verifies a dedicated schema on a supplied pool, optionally initializing it atomically. It never closes or reconfigures the pool, including on failure. It does not join host transactions. Usage: store, err := postgres.Open(ctx, db, postgres.Options{Schema: "kylok", Initialize: true}).
Store
go/adapters/sqlite/store.go:19
type Store struct {
ports.StateStore
// contains filtered or unexported fields
}
Store owns the SQLite pool and promotes the shared transactional state contract.
Open
go/adapters/sqlite/store.go:26
// Open requires a durable path. It never substitutes a temporary or memory DB.
// Usage: store, err := sqlite.Open(ctx, "/var/lib/kylok/state.sqlite").
func Open(ctx context.Context, path string) (*Store, error)
Open requires a durable path. It never substitutes a temporary or memory DB. Usage: store, err := sqlite.Open(ctx, "/var/lib/kylok/state.sqlite").
*Store.Close
go/adapters/sqlite/store.go:61
// Close releases the SQLite-owned pool after the host drains SDK users.
// Usage: defer store.Close().
func (s *Store) Close() error
Close releases the SQLite-owned pool after the host drains SDK users. Usage: defer store.Close().
*SDK.ListApplications
go/applications.go:15
// ListApplications lists verified managed APKs in one authorized scope.
// Usage: page, err := sdk.ListApplications(ctx, scope, "", 100); use the final SHA256 as the next cursor.
func (s *SDK) ListApplications(ctx context.Context, scope, after string, limit int) ([]Artifact, error)
ListApplications lists verified managed APKs in one authorized scope. Usage: page, err := sdk.ListApplications(ctx, scope, "", 100); use the final SHA256 as the next cursor.
*SDK.RegisterApplication
go/applications.go:38
// RegisterApplication publishes verified immutable metadata in one authorized scope.
// Usage: artifact, err := sdk.RegisterApplication(ctx, scope, verifiedAPK).
func (s *SDK) RegisterApplication(ctx context.Context, scope string, apk *provisioning.APK) (Artifact, error)
RegisterApplication publishes verified immutable metadata in one authorized scope. Usage: artifact, err := sdk.RegisterApplication(ctx, scope, verifiedAPK).
*SDK.AssignApplication
go/applications.go:64
// AssignApplication creates a desired revision and one durable install operation.
// Reusing a key with the same device/artifact returns the original operation.
// Usage: operation, err := sdk.AssignApplication(ctx, scope, deviceID, digest, requestKey, 24*time.Hour).
func (s *SDK) AssignApplication(ctx context.Context, scope, device, digest, key string, timeout time.Duration) (Operation, error)
AssignApplication creates a desired revision and one durable install operation. Reusing a key with the same device/artifact returns the original operation. Usage: operation, err := sdk.AssignApplication(ctx, scope, deviceID, digest, requestKey, 24*time.Hour).
*SDK.ListOperations
go/applications.go:85
// ListOperations returns durable scoped progress, failures and observed installation results.
// Usage: operations, err := sdk.ListOperations(ctx, scope, deviceID, "", 100).
func (s *SDK) ListOperations(ctx context.Context, scope, device, after string, limit int) ([]Operation, error)
ListOperations returns durable scoped progress, failures and observed installation results. Usage: operations, err := sdk.ListOperations(ctx, scope, deviceID, "", 100).
*SDK.RemoveApplication
go/applications.go:102
// RemoveApplication removes unreferenced scoped catalog metadata. Content bytes
// are retained: deleting shared files concurrently with registrations is unsafe.
// Usage: err := sdk.RemoveApplication(ctx, scope, digest).
func (s *SDK) RemoveApplication(ctx context.Context, scope, digest string) error
RemoveApplication removes unreferenced scoped catalog metadata. Content bytes are retained: deleting shared files concurrently with registrations is unsafe. Usage: err := sdk.RemoveApplication(ctx, scope, digest).
ErrCursorExpired
go/changes.go:15
var ErrCursorExpired = ports.ErrCursorExpired
Change
go/changes.go:21
type Change struct {
Sequence uint64
Kind string
ResourceID string
}
Change is a durable scoped invalidation or application tombstone, without tokens or raw state. Refresh device_changed through GetDeviceState; application_changed through GetApplication. group_changed/fleet_changed require GetGroup/GetFleetAssignment. application_removed deletes that digest from the host projection. Sequence is strictly ascending per scope.
ChangePage
go/changes.go:29
type ChangePage struct {
Items []Change
Cursor string
More bool
}
ChangePage returns a checkpoint even when no records exist. Persist it with host projection updates; failures may replay a batch and must be handled idempotently. Changes are retained for 10,000 records per scope.
DesiredApplication
go/changes.go:36
type DesiredApplication struct {
Artifact Artifact `json:"artifact"`
Revision uint64 `json:"revision"`
}
DesiredApplication is a host-facing verified desired package and revision.
DeviceState
go/changes.go:43
type DeviceState struct {
Network NetworkStatus `json:"network"`
Device Device `json:"device"`
Desired []DesiredApplication `json:"desired"`
Operations []Operation `json:"operations"`
Commands []Command `json:"commands"`
Policy PolicyStatus `json:"policy"`
}
DeviceState is a consistent scoped projection, including complete operation history and desired/observed policy. Reading does not expire operations or trigger effects; deadline-aware reads use GetOperation/QueryOperations.
ProjectionItem
go/changes.go:53
type ProjectionItem struct {
Device *DeviceState `json:"device,omitempty"`
Application *Artifact `json:"application,omitempty"`
Group *Group `json:"group,omitempty"`
Fleet *FleetAssignment `json:"fleet,omitempty"`
}
ProjectionItem is one snapshot resource: exactly one pointer is populated.
ProjectionPage
go/changes.go:63
type ProjectionPage struct {
Items []ProjectionItem
NextCursor string
ChangesCursor string
ExpiresAt time.Time
}
ProjectionPage contains immutable scoped records. Build a staged projection across all pages, atomically replace the old projection, then use ChangesCursor after the final page. NextCursor expires after fifteen minutes or when this scope starts four newer scans.
*SDK.ListChanges
go/changes.go:118
// ListChanges reads a replayable bounded scope log. Empty cursor starts at sequence zero;
// ErrCursorExpired requires a consistent ReadProjection, never silently skipping missed changes.
// Hosts authorize the scope on every call; callbacks are only optional wakeups, not durable delivery.
// Usage: page, err := sdk.ListChanges(ctx, scope, savedCursor, 100).
func (s *SDK) ListChanges(ctx context.Context, scope, cursor string, limit int) (ChangePage, error)
ListChanges reads a replayable bounded scope log. Empty cursor starts at sequence zero; ErrCursorExpired requires a consistent ReadProjection, never silently skipping missed changes. Hosts authorize the scope on every call; callbacks are only optional wakeups, not durable delivery. Usage: page, err := sdk.ListChanges(ctx, scope, savedCursor, 100).
*SDK.GetDeviceState
go/changes.go:143
// GetDeviceState reads a transactionally consistent scoped aggregate without exposing agent lease tokens.
// Usage: state, err := sdk.GetDeviceState(ctx, scope, deviceID).
func (s *SDK) GetDeviceState(ctx context.Context, scope, id string) (DeviceState, error)
GetDeviceState reads a transactionally consistent scoped aggregate without exposing agent lease tokens. Usage: state, err := sdk.GetDeviceState(ctx, scope, deviceID).
*SDK.GetApplication
go/changes.go:159
// GetApplication reads one scoped verified catalog entry; absent/foreign digests both return ErrNotFound.
// Usage: artifact, err := sdk.GetApplication(ctx, scope, digest).
func (s *SDK) GetApplication(ctx context.Context, scope, digest string) (Artifact, error)
GetApplication reads one scoped verified catalog entry; absent/foreign digests both return ErrNotFound. Usage: artifact, err := sdk.GetApplication(ctx, scope, digest).
*SDK.ReadProjection
go/changes.go:177
// ReadProjection starts or continues an immutable scoped snapshot and matching change watermark.
// Cursor "" starts a new scan. Complete all pages before committing ChangesCursor; expiry/eviction
// returns ErrCursorExpired and requires discarding the staged scan. Never combine pages from different scans.
// Usage: page, err := sdk.ReadProjection(ctx, scope, "", 100).
func (s *SDK) ReadProjection(ctx context.Context, scope, cursor string, limit int) (ProjectionPage, error)
ReadProjection starts or continues an immutable scoped snapshot and matching change watermark. Cursor "" starts a new scan. Complete all pages before committing ChangesCursor; expiry/eviction returns ErrCursorExpired and requires discarding the staged scan. Never combine pages from different scans. Usage: page, err := sdk.ReadProjection(ctx, scope, "", 100).
ErrUnsupported
go/commands.go:11
var ErrUnsupported = ports.ErrUnsupported
CommandKind
go/commands.go:14
type CommandKind string
CommandKind selects a one-shot Device Owner action, subject to platform capability and observed outcome.
CommandReboot
go/commands.go:17
const CommandReboot CommandKind = "REBOOT"
CommandLock
go/commands.go:18
const CommandLock CommandKind = "LOCK"
CommandObservation
go/commands.go:22
type CommandObservation = ports.CommandObservation
CommandObservation is platform readback, not proof of who caused a reboot or cryptographic device attestation.
Command
go/commands.go:26
type Command struct {
ID string `json:"id"`
DeviceID string `json:"device_id"`
Kind CommandKind `json:"kind"`
State string `json:"state"`
Deadline time.Time `json:"deadline"`
ErrorCode string `json:"error_code,omitempty"`
Observation *CommandObservation `json:"observation,omitempty"`
}
Command exposes a one-shot lifecycle without the agent's dispatch credential. UNCERTAIN requires an explicit host decision; retrying the same key never schedules another action.
CommandPage
go/commands.go:37
type CommandPage struct {
Items []Command
NextCursor string
}
CommandPage contains a live ascending-ID history page for one authorized device.
*SDK.SubmitCommand
go/commands.go:46
// SubmitCommand queues reboot or lock only when the device advertises the corresponding Device Owner capability.
// A stable key binds device/kind; its original deadline is retained on retry (timeout 1m–7d).
// Reboot success needs a boot-count increase; lock success needs a configured secure lock and locked readback.
// Usage: command, err := sdk.SubmitCommand(ctx, scope, deviceID, kylok.CommandReboot, "maintenance", time.Hour).
func (s *SDK) SubmitCommand(ctx context.Context, scope, device string, kind CommandKind, key string, timeout time.Duration) (Command, error)
SubmitCommand queues reboot or lock only when the device advertises the corresponding Device Owner capability. A stable key binds device/kind; its original deadline is retained on retry (timeout 1m–7d). Reboot success needs a boot-count increase; lock success needs a configured secure lock and locked readback. Usage: command, err := sdk.SubmitCommand(ctx, scope, deviceID, kylok.CommandReboot, "maintenance", time.Hour).
*SDK.GetCommand
go/commands.go:64
// GetCommand reads an authorized device's one-shot outcome; overdue delivered actions are UNCERTAIN, never replayed.
// Usage: command, err := sdk.GetCommand(ctx, scope, deviceID, commandID).
func (s *SDK) GetCommand(ctx context.Context, scope, device, id string) (Command, error)
GetCommand reads an authorized device's one-shot outcome; overdue delivered actions are UNCERTAIN, never replayed. Usage: command, err := sdk.GetCommand(ctx, scope, deviceID, commandID).
*SDK.QueryCommands
go/commands.go:77
// QueryCommands reads bounded command history with a scope/device-bound cursor; it never triggers a platform action.
// Usage: page, err := sdk.QueryCommands(ctx, scope, deviceID, PageRequest{Limit:20}).
func (s *SDK) QueryCommands(ctx context.Context, scope, device string, page PageRequest) (CommandPage, error)
QueryCommands reads bounded command history with a scope/device-bound cursor; it never triggers a platform action. Usage: page, err := sdk.QueryCommands(ctx, scope, deviceID, PageRequest{Limit:20}).
*SDK.CancelCommand
go/commands.go:107
// CancelCommand cancels queued work; committed delivery becomes UNCERTAIN until a valid platform result resolves it.
// Cancellation cannot undo a delivered reboot/lock, and never schedules a replacement action.
// Usage: command, err := sdk.CancelCommand(ctx, scope, deviceID, commandID).
func (s *SDK) CancelCommand(ctx context.Context, scope, device, id string) (Command, error)
CancelCommand cancels queued work; committed delivery becomes UNCERTAIN until a valid platform result resolves it. Cancellation cannot undo a delivered reboot/lock, and never schedules a replacement action. Usage: command, err := sdk.CancelCommand(ctx, scope, deviceID, commandID).
Event
go/events.go:12
type Event struct {
ID string `json:"id"`
Kind string `json:"kind"`
ScopeID string `json:"scope_id"`
DeviceID string `json:"device_id"`
Revision uint64 `json:"revision"`
At time.Time `json:"at"`
}
Event contains identifiers and committed revisions, never tokens, credentials, enrollment keys, QR contents or raw inventory. ID is stable across RPC retries.
EventSink
go/events.go:25
type EventSink func(context.Context, Event) error
EventSink is an optional best-effort notification hook. Calls are serialized on one SDK-owned worker and must honor cancellation. Errors/panics never change committed results. Delivery can be dropped, duplicated, or lost on shutdown; use ListChanges/ReadProjection for durable projection recovery and export permanent audit records to host storage before retention expires.
Group
go/fleet.go:14
type Group = ports.Group
Group is an opaque scoped membership set, capped at 100 devices; it carries no business metadata.
FleetRequest
go/fleet.go:18
type FleetRequest = ports.FleetRequest
FleetRequest selects one group or an explicit device set with an absolute deployment window. Request ID is the scope-local retry key; membership freezes on creation.
FleetItem
go/fleet.go:21
type FleetItem = ports.FleetItem
FleetItem describes submission progress; use OperationID to read the device's observed execution result.
FleetAssignment
go/fleet.go:24
type FleetAssignment = ports.FleetAssignment
FleetAssignment is a detached durable fan-out checkpoint, not a claim that devices applied its APK.
GroupPage
go/fleet.go:27
type GroupPage struct {
Items []Group
NextCursor string
}
GroupPage contains a live ascending-ID membership page and a scope-bound continuation.
FleetPage
go/fleet.go:33
type FleetPage struct {
Items []FleetAssignment
NextCursor string
}
FleetPage contains durable assignment checkpoints; hosts scan these to resume incomplete work after restart.
*SDK.ReplaceGroup
go/fleet.go:57
// ReplaceGroup replaces the complete membership using optimistic concurrency (zero creates).
// An identical retry with the same expected revision returns the committed set; foreign/revoked members fail.
// Existing fleet assignments keep their frozen targets. An empty set clears membership.
// Usage: group, err := sdk.ReplaceGroup(ctx, scope, "lobby", []string{deviceID}, 0).
func (s *SDK) ReplaceGroup(ctx context.Context, scope, id string, devices []string, expectedRevision uint64) (Group, error)
ReplaceGroup replaces the complete membership using optimistic concurrency (zero creates). An identical retry with the same expected revision returns the committed set; foreign/revoked members fail. Existing fleet assignments keep their frozen targets. An empty set clears membership. Usage: group, err := sdk.ReplaceGroup(ctx, scope, "lobby", []string{deviceID}, 0).
*SDK.GetGroup
go/fleet.go:73
// GetGroup reads membership in one authorized scope; foreign and absent IDs both return ErrNotFound.
// Usage: group, err := sdk.GetGroup(ctx, scope, "lobby").
func (s *SDK) GetGroup(ctx context.Context, scope, id string) (Group, error)
GetGroup reads membership in one authorized scope; foreign and absent IDs both return ErrNotFound. Usage: group, err := sdk.GetGroup(ctx, scope, "lobby").
*SDK.QueryGroups
go/fleet.go:85
// QueryGroups reads a bounded live membership page. Hosts authorize the scope on every call.
// Usage: page, err := sdk.QueryGroups(ctx, scope, PageRequest{Limit:20}).
func (s *SDK) QueryGroups(ctx context.Context, scope string, page PageRequest) (GroupPage, error)
QueryGroups reads a bounded live membership page. Hosts authorize the scope on every call. Usage: page, err := sdk.QueryGroups(ctx, scope, PageRequest{Limit:20}).
*SDK.ScheduleApplication
go/fleet.go:113
// ScheduleApplication creates one durable install with an absolute [notBefore, deadline) window (at most seven days).
// The same key binds artifact and window exactly. The latest committed assignment wins per package;
// cancellation/supersession cannot undo an already delivered platform effect. Expired retries still read the original.
// Usage: op, err := sdk.ScheduleApplication(ctx, scope, deviceID, digest, "nightly", start, start.Add(time.Hour)).
func (s *SDK) ScheduleApplication(ctx context.Context, scope, device, digest, key string, notBefore, deadline time.Time) (Operation, error)
ScheduleApplication creates one durable install with an absolute [notBefore, deadline) window (at most seven days). The same key binds artifact and window exactly. The latest committed assignment wins per package; cancellation/supersession cannot undo an already delivered platform effect. Expired retries still read the original. Usage: op, err := sdk.ScheduleApplication(ctx, scope, deviceID, digest, "nightly", start, start.Add(time.Hour)).
*SDK.CreateFleetAssignment
go/fleet.go:133
// CreateFleetAssignment freezes up to 100 targets without submitting device work. Set GroupID or DeviceIDs, never both.
// Reusing ID requires the same selector, APK and absolute window. Group edits do not expand retries.
// Hosts drive AdvanceFleetAssignment and retain a scan/checkpoint for their authorized scopes.
// Usage: batch, err := sdk.CreateFleetAssignment(ctx, FleetRequest{ScopeID:scope, ID:"nightly", GroupID:"lobby", ArtifactSHA256:digest, NotBefore:start, Deadline:start.Add(time.Hour)}).
func (s *SDK) CreateFleetAssignment(ctx context.Context, request FleetRequest) (FleetAssignment, error)
CreateFleetAssignment freezes up to 100 targets without submitting device work. Set GroupID or DeviceIDs, never both. Reusing ID requires the same selector, APK and absolute window. Group edits do not expand retries. Hosts drive AdvanceFleetAssignment and retain a scan/checkpoint for their authorized scopes. Usage: batch, err := sdk.CreateFleetAssignment(ctx, FleetRequest{ScopeID:scope, ID:"nightly", GroupID:"lobby", ArtifactSHA256:digest, NotBefore:start, Deadline:start.Add(time.Hour)}).
*SDK.GetFleetAssignment
go/fleet.go:152
// GetFleetAssignment reads frozen targets and per-device submission results, without advancing work.
// Usage: batch, err := sdk.GetFleetAssignment(ctx, scope, "nightly").
func (s *SDK) GetFleetAssignment(ctx context.Context, scope, id string) (FleetAssignment, error)
GetFleetAssignment reads frozen targets and per-device submission results, without advancing work. Usage: batch, err := sdk.GetFleetAssignment(ctx, scope, "nightly").
*SDK.QueryFleetAssignments
go/fleet.go:164
// QueryFleetAssignments scans durable checkpoints so host workers can resume pending fan-out after restart.
// Usage: page, err := sdk.QueryFleetAssignments(ctx, scope, PageRequest{Limit:20}).
func (s *SDK) QueryFleetAssignments(ctx context.Context, scope string, page PageRequest) (FleetPage, error)
QueryFleetAssignments scans durable checkpoints so host workers can resume pending fan-out after restart. Usage: page, err := sdk.QueryFleetAssignments(ctx, scope, PageRequest{Limit:20}).
*SDK.AdvanceFleetAssignment
go/fleet.go:192
// AdvanceFleetAssignment atomically submits at most limit pending targets (1–100); permanent per-device errors are retained.
// Infrastructure/context failures roll back the chunk. Concurrent workers and lost responses cannot create duplicate work.
// Complete means fan-out finished; read each OperationID for installation/compliance results.
// Usage: batch, err := sdk.AdvanceFleetAssignment(ctx, scope, "nightly", 20).
func (s *SDK) AdvanceFleetAssignment(ctx context.Context, scope, id string, limit int) (FleetAssignment, error)
AdvanceFleetAssignment atomically submits at most limit pending targets (1–100); permanent per-device errors are retained. Infrastructure/context failures roll back the chunk. Concurrent workers and lost responses cannot create duplicate work. Complete means fan-out finished; read each OperationID for installation/compliance results. Usage: batch, err := sdk.AdvanceFleetAssignment(ctx, scope, "nightly", 20).
*SDK.CancelFleetAssignment
go/fleet.go:205
// CancelFleetAssignment cancels pending targets and stops future dispatch for active submitted operations.
// Completed/superseded operations are preserved; already delivered Android effects may still complete.
// Usage: batch, err := sdk.CancelFleetAssignment(ctx, scope, "nightly").
func (s *SDK) CancelFleetAssignment(ctx context.Context, scope, id string) (FleetAssignment, error)
CancelFleetAssignment cancels pending targets and stops future dispatch for active submitted operations. Completed/superseded operations are preserved; already delivered Android effects may still complete. Usage: batch, err := sdk.CancelFleetAssignment(ctx, scope, "nightly").
*SDK.CancelOperation
go/fleet.go:219
// CancelOperation stops future dispatch/download and signals the agent to abandon uncommitted local work.
// CANCELLED does not prove that a delivered installation stopped. Desired intent stays recorded;
// no implicit uninstall/rollback or drift retry follows. Reassign with a new key to resume.
// Usage: op, err := sdk.CancelOperation(ctx, scope, deviceID, operationID).
func (s *SDK) CancelOperation(ctx context.Context, scope, device, id string) (Operation, error)
CancelOperation stops future dispatch/download and signals the agent to abandon uncommitted local work. CANCELLED does not prove that a delivered installation stopped. Desired intent stays recorded; no implicit uninstall/rollback or drift retry follows. Reassign with a new key to resume. Usage: op, err := sdk.CancelOperation(ctx, scope, deviceID, operationID).
Options
go/kylok.go:38
type Options struct {
// HTTP/HTTPS origin advertised to devices; it does not bind or start a listener.
PublicURL string
// Signed DPC APK verified by provisioning.Inspect.
Bootstrap *provisioning.APK
// Persistent default database/artifact directory; unnecessary when both providers are supplied.
DataDir string
// Optional concurrent transactional provider; never replaced with an in-memory fallback on failure.
Store ports.StateStore
// Optional immutable content provider; must preserve the ArtifactStore integrity contract.
Artifacts ports.ArtifactStore
// Explicit opt-in for local provisioning proofs; disabled for normal hosts.
AllowDebugAPK bool
// Optional wall clock for deterministic expiry/deadline checks; defaults to time.Now.
Clock func() time.Time
// Optional APK origin. Defaults to PublicURL; independently supports HTTP/HTTPS
// and domain/IP hosts. Mount BootstrapHandler on a separate origin as needed.
BootstrapURL string
// Optional sanitized best-effort committed-event sink; see EventSink for cancellation/delivery rules.
Events EventSink
// Optional host-owned resolver for immutable scoped Wi-Fi passphrase versions. Required for protected profiles.
NetworkSecrets ports.NetworkSecretProvider
// Per callback; defaults to one second, at most 30 seconds. A non-cooperative
// host callback can stall only its one worker, never authentication or sync.
EventTimeout time.Duration
}
Options configures one embeddable SDK. Supply verified bootstrap content and a device-reachable origin; durable defaults use DataDir. Supplied providers remain host-owned.
SDK
go/kylok.go:67
type SDK struct {
// contains filtered or unexported fields
}
SDK owns the management facade and agent handlers. Hosts own authorization and listeners, drain requests before Close, and close their own supplied providers.
Enrollment
go/kylok.go:82
type Enrollment struct {
CorrelationID string
Token string
ScopeID string
ExpiresAt time.Time
}
New
go/kylok.go:98
// New validates options/current storage schema and registers the verified APK.
// It starts no listeners. An optional event sink uses one bounded SDK worker.
// The host owns TLS, authorization, supplied providers and shutdown.
// Custom providers remain host-owned even if construction fails.
// Usage: sdk, err := kylok.New(ctx, kylok.Options{PublicURL: origin, Bootstrap: apk, DataDir: dataDir}).
func New(ctx context.Context, o Options) (_ *SDK, err error)
New validates options/current storage schema and registers the verified APK. It starts no listeners. An optional event sink uses one bounded SDK worker. The host owns TLS, authorization, supplied providers and shutdown. Custom providers remain host-owned even if construction fails. Usage: sdk, err := kylok.New(ctx, kylok.Options{PublicURL: origin, Bootstrap: apk, DataDir: dataDir}).
*SDK.Close
go/kylok.go:182
// Close cancels SDK-owned notifications and storage exactly once; supplied providers remain host-owned.
// Usage: defer sdk.Close() after draining host listeners; hosts close supplied stores separately.
func (s *SDK) Close() error
Close cancels SDK-owned notifications and storage exactly once; supplied providers remain host-owned. Usage: defer sdk.Close() after draining host listeners; hosts close supplied stores separately.
*SDK.CreateEnrollment
go/kylok.go:207
// CreateEnrollment creates a single-use token bound to the authorized scope and current verified DPC APK.
// Usage: enrollment, err := sdk.CreateEnrollment(ctx, scope, 15*time.Minute).
func (s *SDK) CreateEnrollment(ctx context.Context, scope string, ttl time.Duration) (Enrollment, error)
CreateEnrollment creates a single-use token bound to the authorized scope and current verified DPC APK. Usage: enrollment, err := sdk.CreateEnrollment(ctx, scope, 15*time.Minute).
*SDK.CreateEnrollmentWithOptions
go/kylok.go:216
// CreateEnrollmentWithOptions creates an opaque correlation binding and a private single-use token.
// Nonempty correlation IDs are unique in their scope, including after consumption/expiry.
// Duplicate creation returns ErrConflict, never the original token. If the creation response
// is lost, use a new correlation ID and let the unclaimed token expire; no read exposes it.
// Usage: e, err := sdk.CreateEnrollmentWithOptions(ctx, EnrollmentOptions{ScopeID: scope, TTL: 15*time.Minute, CorrelationID: requestID}).
func (s *SDK) CreateEnrollmentWithOptions(ctx context.Context, input EnrollmentOptions) (Enrollment, error)
CreateEnrollmentWithOptions creates an opaque correlation binding and a private single-use token. Nonempty correlation IDs are unique in their scope, including after consumption/expiry. Duplicate creation returns ErrConflict, never the original token. If the creation response is lost, use a new correlation ID and let the unclaimed token expire; no read exposes it. Usage: e, err := sdk.CreateEnrollmentWithOptions(ctx, EnrollmentOptions{ScopeID: scope, TTL: 15*time.Minute, CorrelationID: requestID}).
*SDK.QR
go/kylok.go:237
// QR renders private provisioning JSON using this host's configured API and bootstrap origins.
// Usage: payload, err := sdk.QR(ctx, enrollment.Token); keep the returned JSON private.
func (s *SDK) QR(ctx context.Context, token string) ([]byte, error)
QR renders private provisioning JSON using this host's configured API and bootstrap origins. Usage: payload, err := sdk.QR(ctx, enrollment.Token); keep the returned JSON private.
*SDK.QRWithOrigins
go/kylok.go:245
// QRWithOrigins issues the same verified enrollment through host-selected API
// and APK origins, for example another bound LAN interface or a custom domain.
// Changing a QR does not change an already enrolled device's endpoint.
// Usage: payload, err := sdk.QRWithOrigins(ctx, token, "http://192.168.1.5:8080", "http://192.168.1.5:8080").
func (s *SDK) QRWithOrigins(ctx context.Context, token, apiOrigin, bootstrapOrigin string) ([]byte, error)
QRWithOrigins issues the same verified enrollment through host-selected API and APK origins, for example another bound LAN interface or a custom domain. Changing a QR does not change an already enrolled device's endpoint. Usage: payload, err := sdk.QRWithOrigins(ctx, token, "http://192.168.1.5:8080", "http://192.168.1.5:8080").
*SDK.ListDevices
go/kylok.go:274
// ListDevices and RevokeDevice are in-process management APIs. Hosts must authorize
// the business user and scope before invoking them; no remote management route exists.
// Usage: devices, err := sdk.ListDevices(ctx, scope, "", 100).
func (s *SDK) ListDevices(ctx context.Context, scope, after string, limit int) ([]Device, error)
ListDevices and RevokeDevice are in-process management APIs. Hosts must authorize the business user and scope before invoking them; no remote management route exists. Usage: devices, err := sdk.ListDevices(ctx, scope, "", 100).
*SDK.RevokeDevice
go/kylok.go:290
// RevokeDevice rejects future authenticated activity and recovery for one authorized scope/device.
// Usage: err := sdk.RevokeDevice(ctx, scope, deviceID).
func (s *SDK) RevokeDevice(ctx context.Context, scope, id string) error
RevokeDevice rejects future authenticated activity and recovery for one authorized scope/device. Usage: err := sdk.RevokeDevice(ctx, scope, deviceID).
*SDK.Handler
go/kylok.go:308
// Handler exposes agent RPCs, public bootstrap APKs and authorized managed APKs,
// never administrator routes. Hosts enable HTTP/2 (including h2c for HTTP). TLS
// is required for HTTPS origins; forwarded TLS headers are not trusted.
// Usage: server.Handler = sdk.Handler(); enable HTTP/2 and drain the listener before sdk.Close().
func (s *SDK) Handler() http.Handler
Handler exposes agent RPCs, public bootstrap APKs and authorized managed APKs, never administrator routes. Hosts enable HTTP/2 (including h2c for HTTP). TLS is required for HTTPS origins; forwarded TLS headers are not trusted. Usage: server.Handler = sdk.Handler(); enable HTTP/2 and drain the listener before sdk.Close().
*SDK.BootstrapHandler
go/kylok.go:331
// BootstrapHandler serves only immutable APKs, never agent/management routes or QR secrets.
// It follows the selected BootstrapURL scheme, independently of the API origin.
// Usage: bootstrapServer.Handler = sdk.BootstrapHandler().
func (s *SDK) BootstrapHandler() http.Handler
BootstrapHandler serves only immutable APKs, never agent/management routes or QR secrets. It follows the selected BootstrapURL scheme, independently of the API origin. Usage: bootstrapServer.Handler = sdk.BootstrapHandler().
ErrInvalidArgument
go/management.go:23
var ErrInvalidArgument = ports.ErrInvalidArgument
Management errors support errors.Is independently of transport and persistence adapters.
ErrNotFound
go/management.go:24
var ErrNotFound = ports.ErrNotFound
Management errors support errors.Is independently of transport and persistence adapters.
ErrConflict
go/management.go:25
var ErrConflict = ports.ErrConflict
Management errors support errors.Is independently of transport and persistence adapters.
ErrExpired
go/management.go:26
var ErrExpired = ports.ErrExpired
Management errors support errors.Is independently of transport and persistence adapters.
ErrReferenced
go/management.go:27
var ErrReferenced = ports.ErrReferenced
Management errors support errors.Is independently of transport and persistence adapters.
ErrConsumed
go/management.go:28
var ErrConsumed = ports.ErrConsumed
Management errors support errors.Is independently of transport and persistence adapters.
ErrRecoveryExpired
go/management.go:29
var ErrRecoveryExpired = ports.ErrRecoveryExpired
Management errors support errors.Is independently of transport and persistence adapters.
ErrRevoked
go/management.go:30
var ErrRevoked = ports.ErrRevoked
Management errors support errors.Is independently of transport and persistence adapters.
ErrUnauthorized
go/management.go:31
var ErrUnauthorized = ports.ErrUnauthorized
Management errors support errors.Is independently of transport and persistence adapters.
ErrStale
go/management.go:32
var ErrStale = ports.ErrStale
Management errors support errors.Is independently of transport and persistence adapters.
ErrClosed
go/management.go:33
var ErrClosed = errors.New("SDK closed")
Management errors support errors.Is independently of transport and persistence adapters.
EnrollmentOptions
go/management.go:38
type EnrollmentOptions struct {
ScopeID string
TTL time.Duration
CorrelationID string
}
EnrollmentOptions binds a private token to an authorized scope and optional opaque host correlation. CorrelationID is association metadata, never authorization; it must not contain secrets.
Device
go/management.go:45
type Device struct {
ID string `json:"id"`
ScopeID string `json:"scope_id"`
CorrelationID string `json:"correlation_id,omitempty"`
State string `json:"state"`
Inventory Inventory `json:"inventory"`
CreatedAt time.Time `json:"created_at"`
LastSeenAt time.Time `json:"last_seen_at"`
DesiredRevision uint64 `json:"desired_revision"`
ReportedRevision uint64 `json:"reported_revision"`
}
Device is a detached host-facing identity and observation. CorrelationID is host-only association metadata.
Inventory
go/management.go:58
type Inventory struct {
APILevel uint32 `json:"api_level"`
Model string `json:"model"`
BuildFingerprint string `json:"build_fingerprint"`
AgentVersion string `json:"agent_version"`
DeviceOwner bool `json:"device_owner"`
Capabilities []string `json:"capabilities"`
Applications []InstalledApplication `json:"applications"`
SupportedABIs []string `json:"supported_abis"`
}
Inventory contains device-reported observations, not attestation or a firmware support guarantee.
InstalledApplication
go/management.go:70
type InstalledApplication struct {
PackageName string `json:"package_name"`
VersionCode int64 `json:"version_code"`
SigningCertificates []string `json:"signing_certificates"`
}
InstalledApplication identifies an observed package version and signing certificates.
Artifact
go/management.go:77
type Artifact struct {
ScopeID string `json:"scope_id"`
SHA256 string `json:"sha256"`
PackageName string `json:"package_name"`
VersionCode int64 `json:"version_code"`
MinSDK uint32 `json:"min_sdk"`
MaxSDK uint32 `json:"max_sdk"`
SigningCertificates []string `json:"signing_certificates"`
SupportedABIs []string `json:"supported_abis"`
SizeBytes int64 `json:"size_bytes"`
}
Artifact is immutable verified application metadata, with no storage location or download credentials.
Operation
go/management.go:90
type Operation struct {
ID string `json:"id"`
DeviceID string `json:"device_id"`
Artifact Artifact `json:"artifact"`
Revision uint64 `json:"revision"`
State string `json:"state"`
NotBefore time.Time `json:"not_before"`
Deadline time.Time `json:"deadline"`
DownloadedBytes int64 `json:"downloaded_bytes"`
ErrorCode string `json:"error_code"`
ErrorMessage string `json:"error_message"`
Observed *InstalledApplication `json:"observed,omitempty"`
}
Operation exposes durable progress/results without agent lease tokens or report checkpoint internals.
DeviceFilter
go/management.go:105
type DeviceFilter struct {
State string
CorrelationID string
}
DeviceFilter selects exact state/correlation matches within one authorized scope.
OperationFilter
go/management.go:111
type OperationFilter struct{ State string }
OperationFilter selects an exact operation state for one scoped device.
PageRequest
go/management.go:115
type PageRequest struct {
Cursor string
Limit int
}
PageRequest selects a live ascending-ID page; zero Limit defaults to 20, and the maximum is 100. Cursor is opaque and bound to the scope/device/filter; authorization is still required on every request.
DevicePage
go/management.go:121
type DevicePage struct {
Items []Device
NextCursor string
}
DevicePage returns detached observations and a cursor only when more matching results exist.
OperationPage
go/management.go:127
type OperationPage struct {
Items []Operation
NextCursor string
}
OperationPage returns detached progress/results and a cursor only when more matching results exist.
*SDK.Ready
go/management.go:156
// Ready checks current backend/bootstrap availability without mutating state or starting a listener.
// Drain host handlers before Close. Supplied providers remain host-owned and readiness is a point-in-time observation.
// Usage: if err := sdk.Ready(ctx); err != nil { respondUnavailable(err) }.
func (s *SDK) Ready(ctx context.Context) error
Ready checks current backend/bootstrap availability without mutating state or starting a listener. Drain host handlers before Close. Supplied providers remain host-owned and readiness is a point-in-time observation. Usage: if err := sdk.Ready(ctx); err != nil { respondUnavailable(err) }.
*SDK.GetDevice
go/management.go:175
// GetDevice reads one identity in an authorized scope; absent and foreign identities both return ErrNotFound.
// Usage: device, err := sdk.GetDevice(ctx, scope, deviceID).
func (s *SDK) GetDevice(ctx context.Context, scope, id string) (Device, error)
GetDevice reads one identity in an authorized scope; absent and foreign identities both return ErrNotFound. Usage: device, err := sdk.GetDevice(ctx, scope, deviceID).
*SDK.GetOperation
go/management.go:189
// GetOperation reads scoped durable progress and expires overdue work; it never exposes a download lease.
// Absent, foreign-scope and foreign-device operations all return ErrNotFound.
// Usage: operation, err := sdk.GetOperation(ctx, scope, deviceID, operationID).
func (s *SDK) GetOperation(ctx context.Context, scope, device, id string) (Operation, error)
GetOperation reads scoped durable progress and expires overdue work; it never exposes a download lease. Absent, foreign-scope and foreign-device operations all return ErrNotFound. Usage: operation, err := sdk.GetOperation(ctx, scope, deviceID, operationID).
*SDK.QueryDevices
go/management.go:249
// QueryDevices reads a live keyset page with exact optional filters. Concurrent inserts behind
// the cursor or mutable filter changes require a new scan; this is not a frozen snapshot.
// Usage: page, err := sdk.QueryDevices(ctx, scope, DeviceFilter{CorrelationID: requestID}, PageRequest{Limit: 20}).
func (s *SDK) QueryDevices(ctx context.Context, scope string, filter DeviceFilter, page PageRequest) (DevicePage, error)
QueryDevices reads a live keyset page with exact optional filters. Concurrent inserts behind the cursor or mutable filter changes require a new scan; this is not a frozen snapshot. Usage: page, err := sdk.QueryDevices(ctx, scope, DeviceFilter{CorrelationID: requestID}, PageRequest{Limit: 20}).
*SDK.QueryOperations
go/management.go:276
// QueryOperations reads a live operation page for one authorized device; expiry is evaluated on each read.
// Usage: page, err := sdk.QueryOperations(ctx, scope, deviceID, OperationFilter{State: "SUCCEEDED"}, PageRequest{Limit: 20}).
func (s *SDK) QueryOperations(ctx context.Context, scope, device string, filter OperationFilter, page PageRequest) (OperationPage, error)
QueryOperations reads a live operation page for one authorized device; expiry is evaluated on each read. Usage: page, err := sdk.QueryOperations(ctx, scope, deviceID, OperationFilter{State: "SUCCEEDED"}, PageRequest{Limit: 20}).
ErrNetworkSecretUnavailable
go/network.go:20
var ErrNetworkSecretUnavailable = errors.New("network secret unavailable")
ErrNetworkSecretUnavailable hides provider diagnostics so credential values cannot leak through SDK errors.
NetworkPolicy
go/network.go:23
type NetworkPolicy = ports.NetworkPolicy
NetworkPolicy owns managed saved Wi-Fi profiles and private CAs; an empty document releases managed resources safely.
WifiProfile
go/network.go:26
type WifiProfile = ports.WifiProfile
WifiProfile uses a scoped immutable SecretRef; no management read contains a delivered password.
CACertificate
go/network.go:29
type CACertificate = ports.CACertificate
CACertificate carries a CA's DER bytes, without its private key.
DesiredNetworkPolicy
go/network.go:32
type DesiredNetworkPolicy = ports.DesiredNetworkPolicy
DesiredNetworkPolicy binds normalized references and CA ownership to a desired revision.
NetworkReport
go/network.go:35
type NetworkReport = ports.NetworkReport
NetworkReport separates authenticated route verification from association/setter results.
NetworkStatus
go/network.go:38
type NetworkStatus = ports.NetworkStatus
NetworkStatus keeps desired and reported state distinct and excludes resolved network secrets.
NetworkSecretProvider
go/network.go:41
type NetworkSecretProvider = ports.NetworkSecretProvider
NetworkSecretProvider is a host-owned immutable scoped vault contract; rotate using a new reference version.
*SDK.SetNetworkPolicy
go/network.go:47
// SetNetworkPolicy replaces bounded managed networks/trust. Hosts supply immutable passphrase versions through NetworkSecrets.
// Android requires permissions, an independently verified saved recovery network and ownership readback before mutation.
// A failed migration/release retains the working route; a new request key creates the host's retry revision.
// Usage: desired, err := sdk.SetNetworkPolicy(ctx, scope, deviceID, "network-v2", kylok.NetworkPolicy{PrimaryID:"office", Profiles:[]kylok.WifiProfile{{ID:"office",SSID:"Office",Security:"WPA2_PSK",SecretRef:"office-key-v2"}}}).
func (s *SDK) SetNetworkPolicy(ctx context.Context, scope, device, key string, input NetworkPolicy) (DesiredNetworkPolicy, error)
SetNetworkPolicy replaces bounded managed networks/trust. Hosts supply immutable passphrase versions through NetworkSecrets. Android requires permissions, an independently verified saved recovery network and ownership readback before mutation. A failed migration/release retains the working route; a new request key creates the host's retry revision. Usage: desired, err := sdk.SetNetworkPolicy(ctx, scope, deviceID, "network-v2", kylok.NetworkPolicy{PrimaryID:"office", Profiles:[]kylok.WifiProfile{{ID:"office",SSID:"Office",Security:"WPA2_PSK",SecretRef:"office-key-v2"}}}).
*SDK.GetNetworkPolicy
go/network.go:96
// GetNetworkPolicy returns reference-only desired/report/compliance state in the authorized scope.
// Usage: status, err := sdk.GetNetworkPolicy(ctx, scope, deviceID).
func (s *SDK) GetNetworkPolicy(ctx context.Context, scope, device string) (NetworkStatus, error)
GetNetworkPolicy returns reference-only desired/report/compliance state in the authorized scope. Usage: status, err := sdk.GetNetworkPolicy(ctx, scope, deviceID).
Policy
go/policies.go:12
type Policy = ports.Policy
LockTaskPolicy
go/policies.go:13
type LockTaskPolicy = ports.LockTaskPolicy
PermissionRule
go/policies.go:14
type PermissionRule = ports.PermissionRule
RestrictionRule
go/policies.go:15
type RestrictionRule = ports.RestrictionRule
DesiredPolicy
go/policies.go:16
type DesiredPolicy = ports.DesiredPolicy
PolicyStatus
go/policies.go:17
type PolicyStatus = ports.PolicyStatus
ManagedConfiguration
go/policies.go:18
type ManagedConfiguration = ports.ManagedConfiguration
ConfigurationBundle
go/policies.go:19
type ConfigurationBundle = ports.ConfigurationBundle
ConfigurationEntry
go/policies.go:20
type ConfigurationEntry = ports.ConfigurationEntry
ConfigurationValue
go/policies.go:21
type ConfigurationValue = ports.ConfigurationValue
*SDK.SetPolicy
go/policies.go:27
// SetPolicy replaces this device's policy. Required packages must already have
// scoped APK assignments; callers authorize scope/device before calling the SDK.
// An empty document releases only settings captured by Kylok's policy journal.
// Usage: desired, err := sdk.SetPolicy(ctx, scope, deviceID, requestKey, policy).
func (s *SDK) SetPolicy(ctx context.Context, scope, device, key string, p Policy) (DesiredPolicy, error)
SetPolicy replaces this device's policy. Required packages must already have scoped APK assignments; callers authorize scope/device before calling the SDK. An empty document releases only settings captured by Kylok's policy journal. Usage: desired, err := sdk.SetPolicy(ctx, scope, deviceID, requestKey, policy).
*SDK.GetPolicy
go/policies.go:47
// GetPolicy reads scoped desired/reported policy and per-rule compliance without treating assignment as enforcement.
// Usage: status, err := sdk.GetPolicy(ctx, scope, deviceID).
func (s *SDK) GetPolicy(ctx context.Context, scope, device string) (PolicyStatus, error)
GetPolicy reads scoped desired/reported policy and per-rule compliance without treating assignment as enforcement. Usage: status, err := sdk.GetPolicy(ctx, scope, deviceID).
ChangeRetention
go/ports/changes.go:11
const ChangeRetention = 10000
Changes are a bounded projection recovery log, never a permanent audit trail.
SnapshotLifetime
go/ports/changes.go:14
const SnapshotLifetime = 15 * time.Minute
SnapshotLifetime bounds retained consistent snapshots; hosts restart expired scans.
SnapshotLimit
go/ports/changes.go:17
const SnapshotLimit = 4
SnapshotLimit bounds simultaneous scans per scope, with oldest scans evicted explicitly.
ErrCursorExpired
go/ports/changes.go:19
var ErrCursorExpired = errors.New("cursor expired: resnapshot required")
Change
go/ports/changes.go:24
type Change struct {
Sequence uint64 `json:"sequence"`
Kind string `json:"kind"`
ResourceID string `json:"resource_id"`
}
Change invalidates one scoped device aggregate or catalog entry. It carries no payload/secrets. Device changes include desired state, reports, operations, inventory and revocation. Application removals are tombstones; other changes require authoritative scoped reads.
ChangesPage
go/ports/changes.go:31
type ChangesPage struct {
Items []Change
Next uint64
Head uint64
}
ChangesPage continues through a bounded scope log; Next always identifies the last delivered position.
DeviceState
go/ports/changes.go:38
type DeviceState struct {
Network NetworkStatus `json:"network"`
Device Device `json:"device"`
Desired []DesiredApplication `json:"desired"`
Operations []Operation `json:"operations"`
Commands []Command `json:"commands"`
Policy PolicyStatus `json:"policy"`
}
DeviceState is a consistent scoped aggregate for host projection, not an agent transport message.
ProjectionItem
go/ports/changes.go:48
type ProjectionItem struct {
Device *DeviceState `json:"device,omitempty"`
Application *Artifact `json:"application,omitempty"`
Group *Group `json:"group,omitempty"`
Fleet *FleetAssignment `json:"fleet,omitempty"`
}
ProjectionItem is one immutable snapshot record. Exactly one resource pointer is set.
ProjectionPage
go/ports/changes.go:56
type ProjectionPage struct {
Items []ProjectionItem
SnapshotID string
After int
More bool
Watermark uint64
ExpiresAt time.Time
}
ProjectionPage carries a snapshot continuation and the change watermark for after the final page.
ChangeStore
go/ports/changes.go:66
type ChangeStore interface {
// ListChanges reads only the explicit scope; stale cursors fail rather than silently skipping changes.
// Usage: page, err := store.ListChanges(ctx, scope, lastSequence, 100).
ListChanges(context.Context, string, uint64, int) (ChangesPage, error)
// GetDeviceState atomically reads desired/observed state and complete operation history for one scoped device.
// Usage: state, err := store.GetDeviceState(ctx, scope, deviceID).
GetDeviceState(context.Context, string, string) (DeviceState, error)
// ReadProjection starts a new consistent snapshot when snapshotID is empty; otherwise it reads saved immutable records.
// Continuations require the same authorized scope, remain valid across process restart, and expire after SnapshotLifetime.
// Usage: page, err := store.ReadProjection(ctx, scope, "", 0, 100, now).
ReadProjection(context.Context, string, string, int, int, time.Time) (ProjectionPage, error)
}
ChangeStore is embedded in StateStore: state and invalidation records commit or roll back together.
ChangeStore.ListChanges
go/ports/changes.go:69
ListChanges(context.Context, string, uint64, int) (ChangesPage, error)
ListChanges reads only the explicit scope; stale cursors fail rather than silently skipping changes. Usage: page, err := store.ListChanges(ctx, scope, lastSequence, 100).
ChangeStore.GetDeviceState
go/ports/changes.go:72
GetDeviceState(context.Context, string, string) (DeviceState, error)
GetDeviceState atomically reads desired/observed state and complete operation history for one scoped device. Usage: state, err := store.GetDeviceState(ctx, scope, deviceID).
ChangeStore.ReadProjection
go/ports/changes.go:76
ReadProjection(context.Context, string, string, int, int, time.Time) (ProjectionPage, error)
ReadProjection starts a new consistent snapshot when snapshotID is empty; otherwise it reads saved immutable records. Continuations require the same authorized scope, remain valid across process restart, and expire after SnapshotLifetime. Usage: page, err := store.ReadProjection(ctx, scope, "", 0, 100, now).
Command
go/ports/commands.go:12
type Command struct {
ID string `json:"id"`
DeviceID string `json:"device_id"`
Kind string `json:"kind"`
State string `json:"state"`
DispatchToken string `json:"dispatch_token,omitempty"`
Deadline time.Time `json:"deadline"`
ErrorCode string `json:"error_code,omitempty"`
Observation *CommandObservation `json:"observation,omitempty"`
}
Command is a one-shot Android action. DispatchToken binds reports and never changes on retry. DISPATCHED means delivery was committed; UNCERTAIN never authorizes automatic replay. A successful reboot requires a boot-count increase; lock success requires secure, locked readback.
CommandObservation
go/ports/commands.go:24
type CommandObservation struct {
BootBefore int64 `json:"boot_before"`
BootAfter int64 `json:"boot_after"`
Secure bool `json:"secure"`
Locked bool `json:"locked"`
}
CommandObservation carries platform readback; transport reconnection and setter return are not observations.
CommandAssignment
go/ports/commands.go:32
type CommandAssignment struct {
ScopeID, DeviceID, Kind, IdempotencyKey, ID string
Now, Deadline time.Time
}
CommandAssignment binds the device/kind to a stable host request key before any dispatch.
CommandReport
go/ports/commands.go:39
type CommandReport struct {
CommandID, DispatchToken, State, ErrorCode string
Observation *CommandObservation
}
CommandReport is a durable terminal result bound to the original command dispatch token. Exact repeats are accepted; changed reports for the same command conflict.
CommandStore
go/ports/commands.go:45
type CommandStore interface {
// SubmitCommand binds a capability-gated reboot/lock request, with at most sixteen active commands per device.
// Usage: command, err := store.SubmitCommand(ctx, assignment).
SubmitCommand(context.Context, CommandAssignment) (Command, error)
// GetCommand reads a scoped result and expires queued/dispatched work as FAILED/UNCERTAIN respectively.
// Usage: command, err := store.GetCommand(ctx, scope, deviceID, commandID, now).
GetCommand(context.Context, string, string, string, time.Time) (Command, error)
// ListCommands pages one device's command history, expiring overdue work before the read.
// Usage: commands, err := store.ListCommands(ctx, scope, deviceID, afterID, 20, now).
ListCommands(context.Context, string, string, string, int, time.Time) ([]Command, error)
// CancelCommand cancels only undispatched work; dispatched work becomes UNCERTAIN because it may have executed.
// Usage: command, err := store.CancelCommand(ctx, scope, deviceID, commandID, now).
CancelCommand(context.Context, string, string, string, time.Time) (Command, error)
}
CommandStore shares authentication, serialization and transactional changes with the agent state store.
CommandStore.SubmitCommand
go/ports/commands.go:48
SubmitCommand(context.Context, CommandAssignment) (Command, error)
SubmitCommand binds a capability-gated reboot/lock request, with at most sixteen active commands per device. Usage: command, err := store.SubmitCommand(ctx, assignment).
CommandStore.GetCommand
go/ports/commands.go:51
GetCommand(context.Context, string, string, string, time.Time) (Command, error)
GetCommand reads a scoped result and expires queued/dispatched work as FAILED/UNCERTAIN respectively. Usage: command, err := store.GetCommand(ctx, scope, deviceID, commandID, now).
CommandStore.ListCommands
go/ports/commands.go:54
ListCommands(context.Context, string, string, string, int, time.Time) ([]Command, error)
ListCommands pages one device's command history, expiring overdue work before the read. Usage: commands, err := store.ListCommands(ctx, scope, deviceID, afterID, 20, now).
CommandStore.CancelCommand
go/ports/commands.go:57
CancelCommand(context.Context, string, string, string, time.Time) (Command, error)
CancelCommand cancels only undispatched work; dispatched work becomes UNCERTAIN because it may have executed. Usage: command, err := store.CancelCommand(ctx, scope, deviceID, commandID, now).
ManagedConfiguration
go/ports/configuration.go:19
type ManagedConfiguration struct {
PackageName string `json:"package_name"`
Values ConfigurationBundle `json:"values"`
}
ManagedConfiguration owns the complete restrictions bundle for a required managed app. Absence from a replacement policy releases only the bundle journaled by Kylok.
ConfigurationBundle
go/ports/configuration.go:25
type ConfigurationBundle struct {
Entries []ConfigurationEntry `json:"entries"`
}
ConfigurationBundle is a bounded typed Android Bundle. Normalization sorts keys; array order remains significant.
ConfigurationEntry
go/ports/configuration.go:30
type ConfigurationEntry struct {
Key string `json:"key"`
Value ConfigurationValue `json:"value"`
}
ConfigurationEntry assigns one unique application-defined key to exactly one typed value.
ConfigurationValue
go/ports/configuration.go:37
type ConfigurationValue struct {
Boolean *bool `json:"boolean,omitempty"`
Integer *int32 `json:"integer,omitempty"`
String *string `json:"string,omitempty"`
Strings *[]string `json:"strings,omitempty"`
Bundle *ConfigurationBundle `json:"bundle,omitempty"`
Bundles *[]ConfigurationBundle `json:"bundles,omitempty"`
}
ConfigurationValue selects exactly one nonnil pointer. Empty strings/arrays/bundles are supported values. Boolean/int/string pointers preserve explicit zero values and prevent type inference from generic JSON.
MaximumPolicyResults
go/ports/configuration.go:47
const MaximumPolicyResults = 201
MaximumPolicyResults covers 64 required apps, permissions and configurations, four restrictions, three scalars, kiosk and cleanup.
ConfigurationMessage
go/ports/configuration.go:166
// ConfigurationMessage preserves explicit scalar values and typed arrays at the wire boundary.
// The input must be normalized with NormalizePolicy before hashing or transmission.
// Usage: wire := ports.ConfigurationMessage(normalized.ManagedConfigurations[0].Values).
func ConfigurationMessage(bundle ConfigurationBundle) *v1.ConfigurationBundle
ConfigurationMessage preserves explicit scalar values and typed arrays at the wire boundary. The input must be normalized with NormalizePolicy before hashing or transmission. Usage: wire := ports.ConfigurationMessage(normalized.ManagedConfigurations[0].Values).
ConfigurationDigest
go/ports/configuration.go:196
// ConfigurationDigest reports only a digest of normalized typed content, never configuration values.
// A matching DPC readback is separate from acknowledgement that an application applied the configuration.
// Usage: expected := ports.ConfigurationDigest(normalized.ManagedConfigurations[0].Values).
func ConfigurationDigest(bundle ConfigurationBundle) string
ConfigurationDigest reports only a digest of normalized typed content, never configuration values. A matching DPC readback is separate from acknowledgement that an application applied the configuration. Usage: expected := ports.ConfigurationDigest(normalized.ManagedConfigurations[0].Values).
MaximumFleetDevices
go/ports/fleet.go:10
const MaximumFleetDevices = 100
MaximumFleetDevices bounds membership snapshots and per-request partial results.
Group
go/ports/fleet.go:14
type Group struct {
ScopeID string `json:"scope_id"`
ID string `json:"id"`
Revision uint64 `json:"revision"`
DeviceIDs []string `json:"device_ids"`
}
Group is a scoped, opaque membership set. Revision is a compare-and-swap token. Groups select targets at submission; membership edits do not alter an existing fleet assignment.
FleetRequest
go/ports/fleet.go:23
type FleetRequest struct {
ScopeID string `json:"scope_id"`
ID string `json:"id"`
GroupID string `json:"group_id,omitempty"`
DeviceIDs []string `json:"device_ids,omitempty"`
ArtifactSHA256 string `json:"artifact_sha256"`
NotBefore time.Time `json:"not_before"`
Deadline time.Time `json:"deadline"`
}
FleetRequest binds an immutable absolute deployment window and exactly one target selector. ID is a scope-local idempotency key. DeviceIDs are sorted and unique; GroupID freezes its members.
FleetItem
go/ports/fleet.go:36
type FleetItem struct {
DeviceID string `json:"device_id"`
State string `json:"state"`
OperationID string `json:"operation_id,omitempty"`
ErrorCode string `json:"error_code,omitempty"`
}
FleetItem records fan-out progress, not device compliance. ASSIGNED has a durable OperationID; FAILED is a permanent per-device rejection; PENDING can be resumed; CANCELLED was not submitted. Read the device operation to observe installation outcome after ASSIGNED.
FleetAssignment
go/ports/fleet.go:45
type FleetAssignment struct {
Request FleetRequest `json:"request"`
GroupRevision uint64 `json:"group_revision,omitempty"`
Items []FleetItem `json:"items"`
Complete bool `json:"complete"`
Cancelled bool `json:"cancelled"`
}
FleetAssignment persists the frozen target list and bounded per-device results. Complete means fan-out has no pending items; it does not mean APKs were installed.
FleetStore
go/ports/fleet.go:55
type FleetStore interface {
// ReplaceGroup atomically replaces membership if expectedRevision matches (zero creates).
// An identical retry at expectedRevision+1 returns the committed group; foreign devices are rejected.
// Usage: group, err := store.ReplaceGroup(ctx, Group{ScopeID: scope, ID: id, DeviceIDs: ids}, expectedRevision).
ReplaceGroup(context.Context, Group, uint64) (Group, error)
// GetGroup returns detached membership in exactly one authorized scope.
// Usage: group, err := store.GetGroup(ctx, scope, groupID).
GetGroup(context.Context, string, string) (Group, error)
// ListGroups returns live ascending-ID pages, including empty groups.
// Usage: groups, err := store.ListGroups(ctx, scope, afterID, 20).
ListGroups(context.Context, string, string, int) ([]Group, error)
// CreateFleetAssignment atomically freezes targets and binds the request; no device effect occurs here.
// Usage: batch, err := store.CreateFleetAssignment(ctx, request, now).
CreateFleetAssignment(context.Context, FleetRequest, time.Time) (FleetAssignment, error)
// GetFleetAssignment returns the exact frozen request and fan-out checkpoint.
// Usage: batch, err := store.GetFleetAssignment(ctx, scope, batchID).
GetFleetAssignment(context.Context, string, string) (FleetAssignment, error)
// ListFleetAssignments pages durable batches so a restarted host can resume incomplete fan-out.
// Usage: batches, err := store.ListFleetAssignments(ctx, scope, afterID, 20).
ListFleetAssignments(context.Context, string, string, int) ([]FleetAssignment, error)
// AdvanceFleetAssignment atomically submits at most limit pending devices, with per-device stable keys.
// Permanent domain rejections become item failures; storage/context errors roll back this advance.
// Usage: batch, err := store.AdvanceFleetAssignment(ctx, scope, batchID, now, 20).
AdvanceFleetAssignment(context.Context, string, string, time.Time, int) (FleetAssignment, error)
// CancelFleetAssignment stops pending fan-out and cancels submitted active work, preserving completed effects.
// Usage: batch, err := store.CancelFleetAssignment(ctx, scope, batchID, now).
CancelFleetAssignment(context.Context, string, string, time.Time) (FleetAssignment, error)
// CancelOperation stops future dispatch/download; an already delivered platform effect may still finish.
// Desired assignment stays recorded; no implicit rollback/uninstall or future drift retry is created.
// Usage: operation, err := store.CancelOperation(ctx, scope, deviceID, operationID, now).
CancelOperation(context.Context, string, string, string, time.Time) (Operation, error)
}
FleetStore extends the same serialized state boundary used by assignments and sync. Every mutation records scoped change-feed invalidations in its transaction.
FleetStore.ReplaceGroup
go/ports/fleet.go:59
ReplaceGroup(context.Context, Group, uint64) (Group, error)
ReplaceGroup atomically replaces membership if expectedRevision matches (zero creates). An identical retry at expectedRevision+1 returns the committed group; foreign devices are rejected. Usage: group, err := store.ReplaceGroup(ctx, Group{ScopeID: scope, ID: id, DeviceIDs: ids}, expectedRevision).
FleetStore.GetGroup
go/ports/fleet.go:62
GetGroup(context.Context, string, string) (Group, error)
GetGroup returns detached membership in exactly one authorized scope. Usage: group, err := store.GetGroup(ctx, scope, groupID).
FleetStore.ListGroups
go/ports/fleet.go:65
ListGroups(context.Context, string, string, int) ([]Group, error)
ListGroups returns live ascending-ID pages, including empty groups. Usage: groups, err := store.ListGroups(ctx, scope, afterID, 20).
FleetStore.CreateFleetAssignment
go/ports/fleet.go:68
CreateFleetAssignment(context.Context, FleetRequest, time.Time) (FleetAssignment, error)
CreateFleetAssignment atomically freezes targets and binds the request; no device effect occurs here. Usage: batch, err := store.CreateFleetAssignment(ctx, request, now).
FleetStore.GetFleetAssignment
go/ports/fleet.go:71
GetFleetAssignment(context.Context, string, string) (FleetAssignment, error)
GetFleetAssignment returns the exact frozen request and fan-out checkpoint. Usage: batch, err := store.GetFleetAssignment(ctx, scope, batchID).
FleetStore.ListFleetAssignments
go/ports/fleet.go:74
ListFleetAssignments(context.Context, string, string, int) ([]FleetAssignment, error)
ListFleetAssignments pages durable batches so a restarted host can resume incomplete fan-out. Usage: batches, err := store.ListFleetAssignments(ctx, scope, afterID, 20).
FleetStore.AdvanceFleetAssignment
go/ports/fleet.go:78
AdvanceFleetAssignment(context.Context, string, string, time.Time, int) (FleetAssignment, error)
AdvanceFleetAssignment atomically submits at most limit pending devices, with per-device stable keys. Permanent domain rejections become item failures; storage/context errors roll back this advance. Usage: batch, err := store.AdvanceFleetAssignment(ctx, scope, batchID, now, 20).
FleetStore.CancelFleetAssignment
go/ports/fleet.go:81
CancelFleetAssignment(context.Context, string, string, time.Time) (FleetAssignment, error)
CancelFleetAssignment stops pending fan-out and cancels submitted active work, preserving completed effects. Usage: batch, err := store.CancelFleetAssignment(ctx, scope, batchID, now).
FleetStore.CancelOperation
go/ports/fleet.go:85
CancelOperation(context.Context, string, string, string, time.Time) (Operation, error)
CancelOperation stops future dispatch/download; an already delivered platform effect may still finish. Desired assignment stays recorded; no implicit rollback/uninstall or future drift retry is created. Usage: operation, err := store.CancelOperation(ctx, scope, deviceID, operationID, now).
WifiProfile
go/ports/network.go:17
type WifiProfile struct {
ID string `json:"id"`
SSID string `json:"ssid"`
Security string `json:"security"`
SecretRef string `json:"secret_ref,omitempty"`
Hidden bool `json:"hidden"`
}
WifiProfile describes a managed saved network. Secrets are immutable host references, never passwords. Security is OPEN, WPA2_PSK or WPA3_SAE. SSID is literal UTF-8, limited to 32 bytes.
CACertificate
go/ports/network.go:26
type CACertificate struct {
ID string `json:"id"`
DER []byte `json:"der"`
}
CACertificate is one DER-encoded CA, without a private key. ID is an opaque ownership label.
NetworkPolicy
go/ports/network.go:34
type NetworkPolicy struct {
PrimaryID string `json:"primary_id"`
Profiles []WifiProfile `json:"profiles"`
Certificates []CACertificate `json:"certificates"`
}
NetworkPolicy is a full replacement of at most eight Wi-Fi profiles and eight private CAs. PrimaryID chooses the network requiring authenticated management connectivity. An empty document releases ownership. The Android agent preserves an independent saved recovery route before applying or releasing managed settings.
DesiredNetworkPolicy
go/ports/network.go:41
type DesiredNetworkPolicy struct {
Revision uint64 `json:"revision"`
Policy NetworkPolicy `json:"policy"`
}
DesiredNetworkPolicy binds the normalized document to a shared device desired revision.
NetworkReport
go/ports/network.go:48
type NetworkReport struct {
Revision uint64 `json:"revision"`
State string `json:"state"`
Reason string `json:"reason"`
ActiveProfileID string `json:"active_profile_id"`
ConnectivityVerified bool `json:"connectivity_verified"`
CleanupComplete bool `json:"cleanup_complete"`
}
NetworkReport distinguishes readback and authenticated route verification from setters and Wi-Fi association. APPLIED requires primary/recovery connectivity and completion of only the managed-resource cleanup.
NetworkStatus
go/ports/network.go:58
type NetworkStatus struct {
Desired *DesiredNetworkPolicy `json:"desired,omitempty"`
Reported *NetworkReport `json:"reported,omitempty"`
State string `json:"state"`
Reason string `json:"reason"`
}
NetworkStatus contains no delivered passwords. Reported state remains separate from current desired compliance.
NetworkAssignment
go/ports/network.go:66
type NetworkAssignment struct {
ScopeID, DeviceID, IdempotencyKey string
Policy NetworkPolicy
}
NetworkAssignment atomically binds a complete normalized replacement to a scoped device/request key.
NetworkSecretProvider
go/ports/network.go:75
type NetworkSecretProvider interface {
// ReadNetworkSecret returns the passphrase bound to an immutable scoped reference; nil/error fails closed.
// Usage: secret, err := vault.ReadNetworkSecret(ctx, scope, "wifi-key-version-2").
ReadNetworkSecret(context.Context, string, string) ([]byte, error)
}
NetworkSecretProvider resolves immutable versioned references only within an explicitly authorized scope. References must retain identical bytes across retries/restarts. Rotate with a new reference and desired revision. The host owns persistence, encryption, access control and lifetime; failures never permit empty-secret fallback. Returned bytes belong to the caller. Do not log secret values or place them in public snapshots/events.
NetworkSecretProvider.ReadNetworkSecret
go/ports/network.go:78
ReadNetworkSecret(context.Context, string, string) ([]byte, error)
ReadNetworkSecret returns the passphrase bound to an immutable scoped reference; nil/error fails closed. Usage: secret, err := vault.ReadNetworkSecret(ctx, scope, "wifi-key-version-2").
NetworkStore
go/ports/network.go:82
type NetworkStore interface {
// GetNetworkRequest reads the original scoped replacement receipt without resolving secret references.
// Usage: desired, err := store.GetNetworkRequest(ctx, scope, deviceID, requestKey).
GetNetworkRequest(context.Context, string, string, string) (DesiredNetworkPolicy, error)
// SetNetworkPolicy binds a normalized document/key, advances desired revision once and records a device change.
// Usage: desired, err := store.SetNetworkPolicy(ctx, assignment).
SetNetworkPolicy(context.Context, NetworkAssignment) (DesiredNetworkPolicy, error)
// GetNetworkPolicy reads consistent desired/reported/compliance state in exactly one authorized scope.
// Usage: status, err := store.GetNetworkPolicy(ctx, scope, deviceID).
GetNetworkPolicy(context.Context, string, string) (NetworkStatus, error)
}
NetworkStore shares policy/secret-reference state and report invalidations with the serialized device store.
NetworkStore.GetNetworkRequest
go/ports/network.go:85
GetNetworkRequest(context.Context, string, string, string) (DesiredNetworkPolicy, error)
GetNetworkRequest reads the original scoped replacement receipt without resolving secret references. Usage: desired, err := store.GetNetworkRequest(ctx, scope, deviceID, requestKey).
NetworkStore.SetNetworkPolicy
go/ports/network.go:88
SetNetworkPolicy(context.Context, NetworkAssignment) (DesiredNetworkPolicy, error)
SetNetworkPolicy binds a normalized document/key, advances desired revision once and records a device change. Usage: desired, err := store.SetNetworkPolicy(ctx, assignment).
NetworkStore.GetNetworkPolicy
go/ports/network.go:91
GetNetworkPolicy(context.Context, string, string) (NetworkStatus, error)
GetNetworkPolicy reads consistent desired/reported/compliance state in exactly one authorized scope. Usage: status, err := store.GetNetworkPolicy(ctx, scope, deviceID).
NormalizeNetworkPolicy
go/ports/network.go:102
// NormalizeNetworkPolicy detaches, validates and sorts a bounded replacement before idempotency comparison.
// Certificate validity is checked again at delivery/application time; certificates must be complete CA DER objects.
// Usage: policy, err := ports.NormalizeNetworkPolicy(input).
func NormalizeNetworkPolicy(input NetworkPolicy) (NetworkPolicy, error)
NormalizeNetworkPolicy detaches, validates and sorts a bounded replacement before idempotency comparison. Certificate validity is checked again at delivery/application time; certificates must be complete CA DER objects. Usage: policy, err := ports.NormalizeNetworkPolicy(input).
Policy
go/ports/policy.go:15
type Policy struct {
ManagedConfigurations []ManagedConfiguration `json:"managed_configurations,omitempty"`
RequiredPackages []string `json:"required_packages,omitempty"`
LockTask *LockTaskPolicy `json:"lock_task,omitempty"`
CameraDisabled *bool `json:"camera_disabled,omitempty"`
ScreenCaptureDisabled *bool `json:"screen_capture_disabled,omitempty"`
Restrictions []RestrictionRule `json:"restrictions,omitempty"`
Permissions []PermissionRule `json:"permissions,omitempty"`
MaximumTimeToLockMillis *int64 `json:"maximum_time_to_lock_millis,omitempty"`
}
LockTaskPolicy
go/ports/policy.go:25
type LockTaskPolicy struct {
Packages []string `json:"packages"`
KioskPackage string `json:"kiosk_package"`
}
RestrictionRule
go/ports/policy.go:29
type RestrictionRule struct {
Name string `json:"name"`
Enabled bool `json:"enabled"`
}
PermissionRule
go/ports/policy.go:33
type PermissionRule struct {
PackageName string `json:"package_name"`
Permission string `json:"permission"`
State string `json:"state"`
}
DesiredPolicy
go/ports/policy.go:38
type DesiredPolicy struct {
Revision uint64 `json:"revision"`
Policy Policy `json:"policy"`
}
PolicyAssignment
go/ports/policy.go:42
type PolicyAssignment struct {
ScopeID, DeviceID, IdempotencyKey string
Policy Policy
}
PolicyResult
go/ports/policy.go:46
type PolicyResult struct {
RuleID string `json:"rule_id"`
State string `json:"state"`
Reason string `json:"reason"`
ObservedValue string `json:"observed_value"`
}
PolicyReport
go/ports/policy.go:52
type PolicyReport struct {
Revision uint64 `json:"revision"`
SnapshotRevision uint64 `json:"snapshot_revision"`
Results []PolicyResult `json:"results"`
}
PolicyStatus
go/ports/policy.go:57
type PolicyStatus struct {
Desired *DesiredPolicy `json:"desired,omitempty"`
Reported *PolicyReport `json:"reported,omitempty"`
Compliance []PolicyResult `json:"compliance"`
}
NormalizePolicy
go/ports/policy.go:69
// NormalizePolicy validates and copies the document, sorting unordered sets for
// stable idempotency. A setting's absence differs from an explicit false/zero.
// Usage: normalized, err := ports.NormalizePolicy(policy).
func NormalizePolicy(input Policy) (Policy, error)
NormalizePolicy validates and copies the document, sorting unordered sets for stable idempotency. A setting's absence differs from an explicit false/zero. Usage: normalized, err := ports.NormalizePolicy(policy).
PolicyExpectations
go/ports/policy.go:144
// PolicyExpectations defines canonical values shared with the Android observer.
// Required apps bind package/version/signers, so changing an APK invalidates an
// earlier policy observation even if the policy document itself is unchanged.
// Usage: values := ports.PolicyExpectations(policy, desiredApps).
func PolicyExpectations(p Policy, apps []DesiredApplication) map[string]string
PolicyExpectations defines canonical values shared with the Android observer. Required apps bind package/version/signers, so changing an APK invalidates an earlier policy observation even if the policy document itself is unchanged. Usage: values := ports.PolicyExpectations(policy, desiredApps).
PolicyCapability
go/ports/policy.go:192
// PolicyCapability identifies the agent capability required to implement one canonical rule ID.
// Usage: capability := ports.PolicyCapability("camera").
func PolicyCapability(key string) string
PolicyCapability identifies the agent capability required to implement one canonical rule ID. Usage: capability := ports.PolicyCapability("camera").
Changes
go/ports/portstest/changes.go:17
// Changes verifies transactional invalidations, scoped replay, immutable snapshots and explicit expiry/eviction.
// Usage: portstest.Changes(t, factory); run unchanged for both durable SQL adapters.
func Changes(t *testing.T, factory func(*testing.T) ports.StateStore)
Changes verifies transactional invalidations, scoped replay, immutable snapshots and explicit expiry/eviction. Usage: portstest.Changes(t, factory); run unchanged for both durable SQL adapters.
Commands
go/ports/portstest/commands.go:15
// Commands verifies capability gates, stable delivery, report binding, honest uncertainty and scope isolation.
// Usage: portstest.Commands(t, factory).
func Commands(t *testing.T, factory func(*testing.T) ports.StateStore)
Commands verifies capability gates, stable delivery, report binding, honest uncertainty and scope isolation. Usage: portstest.Commands(t, factory).
Fleet
go/ports/portstest/fleet.go:39
// Fleet verifies frozen membership, bounded/restartable fan-out, windows, cancellation, isolation and replay on every provider.
// Usage: portstest.Fleet(t, factory).
func Fleet(t *testing.T, factory func(*testing.T) ports.StateStore)
Fleet verifies frozen membership, bounded/restartable fan-out, windows, cancellation, isolation and replay on every provider. Usage: portstest.Fleet(t, factory).
Management
go/ports/portstest/management.go:16
// Management verifies correlation binding, scoped point/filter reads, expiry and cancellation.
// Usage: portstest.Management(t, factory); run this unchanged for every state adapter.
func Management(t *testing.T, factory func(*testing.T) ports.StateStore)
Management verifies correlation binding, scoped point/filter reads, expiry and cancellation. Usage: portstest.Management(t, factory); run this unchanged for every state adapter.
Network
go/ports/portstest/network.go:15
// Network verifies scoped reference-only intent, idempotency, observed connectivity and atomic rollback with command effects.
// Usage: portstest.Network(t, factory).
func Network(t *testing.T, factory func(*testing.T) ports.StateStore)
Network verifies scoped reference-only intent, idempotency, observed connectivity and atomic rollback with command effects. Usage: portstest.Network(t, factory).
Operations
go/ports/portstest/operations.go:16
// Operations verifies storage-level atomic reports, replay, assignments and retention.
// Usage: portstest.Operations(t, factory).
func Operations(t *testing.T, factory func(*testing.T) ports.StateStore)
Operations verifies storage-level atomic reports, replay, assignments and retention. Usage: portstest.Operations(t, factory).
Policies
go/ports/portstest/policies.go:17
// Policies checks scope, idempotent replacement, observed compliance, atomic
// rollback and revocation for custom providers as well as the default adapter.
// Usage: portstest.Policies(t, factory).
func Policies(t *testing.T, factory func(*testing.T) ports.StateStore)
Policies checks scope, idempotent replacement, observed compliance, atomic rollback and revocation for custom providers as well as the default adapter. Usage: portstest.Policies(t, factory).
ManagedConfigurations
go/ports/portstest/policies.go:94
// ManagedConfigurations verifies typed config idempotency and honest current-snapshot readback on any adapter.
// Usage: portstest.ManagedConfigurations(t, factory).
func ManagedConfigurations(t *testing.T, factory func(*testing.T) ports.StateStore)
ManagedConfigurations verifies typed config idempotency and honest current-snapshot readback on any adapter. Usage: portstest.ManagedConfigurations(t, factory).
State
go/ports/portstest/state.go:20
// State runs against a fresh durable store. Callers should separately prove
// process-restart persistence, resource ownership and backend-specific failures.
// Usage: portstest.State(t, factory).
func State(t *testing.T, factory func(*testing.T) ports.StateStore)
State runs against a fresh durable store. Callers should separately prove process-restart persistence, resource ownership and backend-specific failures. Usage: portstest.State(t, factory).
ErrInvalidArgument
go/ports/state.go:13
var ErrInvalidArgument = errors.New("invalid argument")
ErrNotFound
go/ports/state.go:14
var ErrNotFound = errors.New("not found")
ErrExpired
go/ports/state.go:15
var ErrExpired = errors.New("enrollment expired")
ErrConsumed
go/ports/state.go:16
var ErrConsumed = errors.New("enrollment consumed by another attempt")
ErrRecoveryExpired
go/ports/state.go:17
var ErrRecoveryExpired = errors.New("enrollment recovery expired")
ErrRevoked
go/ports/state.go:18
var ErrRevoked = errors.New("device revoked")
ErrUnauthorized
go/ports/state.go:19
var ErrUnauthorized = errors.New("invalid device credential")
ErrConflict
go/ports/state.go:20
var ErrConflict = errors.New("conflicting idempotency payload")
ErrUnsupported
go/ports/state.go:21
var ErrUnsupported = errors.New("device capability unsupported")
ErrStale
go/ports/state.go:22
var ErrStale = errors.New("stale sync sequence")
ErrReferenced
go/ports/state.go:23
var ErrReferenced = errors.New("artifact is referenced by desired state or pending work")
Inventory
go/ports/state.go:26
type Inventory struct {
APILevel uint32 `json:"api_level"`
Model string `json:"model"`
BuildFingerprint string `json:"build_fingerprint"`
AgentVersion string `json:"agent_version"`
DeviceOwner bool `json:"device_owner"`
Capabilities []string `json:"capabilities"`
Applications []InstalledApplication `json:"applications"`
SupportedABIs []string `json:"supported_abis"`
}
InstalledApplication
go/ports/state.go:36
type InstalledApplication struct {
PackageName string `json:"package_name"`
VersionCode int64 `json:"version_code"`
SigningCertificates []string `json:"signing_certificates"`
}
Device
go/ports/state.go:41
type Device struct {
CorrelationID string `json:"correlation_id,omitempty"`
ID string `json:"id"`
ScopeID string `json:"scope_id"`
State string `json:"state"`
Inventory Inventory `json:"inventory"`
CreatedAt time.Time `json:"created_at"`
LastSeenAt time.Time `json:"last_seen_at"`
DesiredRevision uint64 `json:"desired_revision"`
ReportedRevision uint64 `json:"reported_revision"`
}
Enrollment
go/ports/state.go:52
type Enrollment struct {
CorrelationID string
TokenHash []byte
ScopeID string
ExpiresAt time.Time
ArtifactSHA256 string
}
Attempt
go/ports/state.go:59
type Attempt struct {
TokenHash []byte
ID string
KeyHash []byte
Device Device
CredentialHash []byte
// Encoded encrypted response; never contains a plaintext credential.
Receipt []byte
Now time.Time
RecoverUntil time.Time
}
DeviceQuery
go/ports/state.go:84
type DeviceQuery struct {
ScopeID, After, State, CorrelationID string
Limit int
}
StateStore methods are safe for concurrent calls. Every operation respects context cancellation. Consume atomically validates expiry, consumes the token, inserts the device and persists its encrypted receipt. A matching ID AND key hash retrieves the original receipt until RecoverUntil, including after token expiry. Other attempts fail; revoked devices cannot recover. Revocation and Sync are serialized. Returned slices/values belong to the caller. Hosts close custom stores themselves. SetPolicy atomically validates scope/required assignments, binds the normalized document to the device/key, and advances the shared desired revision once. Sync binds policy observations to its replay body and the desired snapshot; stale observations cannot establish current compliance. GetPolicy reads a consistent scoped desired/reported/compliance view. See portstest.Policies. DeviceQuery is a live keyset read. Mutable filters are evaluated at read time; inserts behind After need a new scan. CorrelationID is an exact opaque match.
OperationQuery
go/ports/state.go:90
type OperationQuery struct {
ScopeID, DeviceID, After, State string
Limit int
Now time.Time
}
OperationQuery filters a single authorized device's live operation history.
StateStore
go/ports/state.go:96
type StateStore interface {
ChangeStore
FleetStore
CommandStore
NetworkStore
// Check verifies that the persistence backend is reachable without changing state.
// Usage: err := store.Check(ctx).
Check(context.Context) error
// GetDevice returns one scoped identity, never its credential verifier.
// Usage: device, err := store.GetDevice(ctx, scope, deviceID).
GetDevice(context.Context, string, string) (Device, error)
// QueryDevices reads an exact scoped live page; callers own returned values.
// Usage: devices, err := store.QueryDevices(ctx, DeviceQuery{ScopeID: scope, Limit: 20}).
QueryDevices(context.Context, DeviceQuery) ([]Device, error)
// GetOperation expires overdue work and reads one operation belonging to the scoped device.
// Usage: operation, err := store.GetOperation(ctx, scope, deviceID, operationID, now).
GetOperation(context.Context, string, string, string, time.Time) (Operation, error)
// QueryOperations expires overdue work and reads a scoped, state-filtered live page.
// Usage: operations, err := store.QueryOperations(ctx, OperationQuery{ScopeID: scope, DeviceID: deviceID, Limit: 20, Now: now}).
QueryOperations(context.Context, OperationQuery) ([]Operation, error)
// Persist a verifier-only enrollment bound to scope, expiry and bootstrap bytes.
// Usage: err := store.CreateEnrollment(ctx, enrollment).
CreateEnrollment(context.Context, Enrollment) error
// Read the original enrollment binding using its token verifier.
// Usage: enrollment, err := store.Enrollment(ctx, tokenHash).
Enrollment(context.Context, []byte) (Enrollment, error)
// Atomically claim a token or recover the same encrypted receipt for its bound attempt and key.
// Usage: receipt, err := store.Consume(ctx, attempt).
Consume(context.Context, Attempt) ([]byte, error)
// Authenticate one device credential and reject revoked identities.
// Usage: device, err := store.Authenticate(ctx, deviceID, credentialHash).
Authenticate(context.Context, string, []byte) (Device, error)
// Atomically bind replay input, accept reports and persist the returned desired/observed snapshot.
// Usage: snapshot, err := store.Sync(ctx, input).
Sync(context.Context, SyncInput) (Snapshot, error)
// Read one authorized scope's stable device cursor page.
// Usage: devices, err := store.ListDevices(ctx, scope, "", 100).
ListDevices(context.Context, string, string, int) ([]Device, error)
// Serialize revocation with enrollment recovery and authenticated sync.
// Usage: err := store.Revoke(ctx, scope, deviceID).
Revoke(context.Context, string, string) error
// Register immutable verified metadata for a scope/digest.
// Usage: err := store.RegisterArtifact(ctx, artifact).
RegisterArtifact(context.Context, Artifact) error
// ListArtifacts returns scoped managed metadata in ascending digest order.
// Usage: page, err := store.ListArtifacts(ctx, scope, lastDigest, 100).
ListArtifacts(context.Context, string, string, int) ([]Artifact, error)
// Read one scope/digest without crossing tenant boundaries.
// Usage: artifact, err := store.Artifact(ctx, scope, digest).
Artifact(context.Context, string, string) (Artifact, error)
// Remove only unreferenced scoped metadata, retaining shared content safely.
// Usage: err := store.RemoveArtifact(ctx, scope, digest).
RemoveArtifact(context.Context, string, string) error
// Atomically bind an install request key, desired revision and supersession of pending work.
// Usage: operation, err := store.Assign(ctx, assignment).
Assign(context.Context, Assignment) (Operation, error)
// Expire overdue work and page scoped durable progress/results.
// Usage: operations, err := store.ListOperations(ctx, scope, deviceID, "", 100, now).
ListOperations(context.Context, string, string, string, int, time.Time) ([]Operation, error)
// Verify device credential, scope, active operation/lease and deadline before returning metadata.
// Usage: artifact, err := store.AuthorizeDownload(ctx, deviceID, credentialHash, operationID, digest, leaseID, now).
AuthorizeDownload(context.Context, string, []byte, string, string, string, time.Time) (Artifact, error)
// Atomically bind a normalized replacement and validate every required app assignment.
// Usage: desired, err := store.SetPolicy(ctx, assignment).
SetPolicy(context.Context, PolicyAssignment) (DesiredPolicy, error)
// Return consistent scoped desired/reported/compliance state.
// Usage: status, err := store.GetPolicy(ctx, scope, deviceID).
GetPolicy(context.Context, string, string) (PolicyStatus, error)
}
StateStore.Check
go/ports/state.go:103
Check(context.Context) error
Check verifies that the persistence backend is reachable without changing state. Usage: err := store.Check(ctx).
StateStore.GetDevice
go/ports/state.go:106
GetDevice(context.Context, string, string) (Device, error)
GetDevice returns one scoped identity, never its credential verifier. Usage: device, err := store.GetDevice(ctx, scope, deviceID).
StateStore.QueryDevices
go/ports/state.go:109
QueryDevices(context.Context, DeviceQuery) ([]Device, error)
QueryDevices reads an exact scoped live page; callers own returned values. Usage: devices, err := store.QueryDevices(ctx, DeviceQuery{ScopeID: scope, Limit: 20}).
StateStore.GetOperation
go/ports/state.go:112
GetOperation(context.Context, string, string, string, time.Time) (Operation, error)
GetOperation expires overdue work and reads one operation belonging to the scoped device. Usage: operation, err := store.GetOperation(ctx, scope, deviceID, operationID, now).
StateStore.QueryOperations
go/ports/state.go:115
QueryOperations(context.Context, OperationQuery) ([]Operation, error)
QueryOperations expires overdue work and reads a scoped, state-filtered live page. Usage: operations, err := store.QueryOperations(ctx, OperationQuery{ScopeID: scope, DeviceID: deviceID, Limit: 20, Now: now}).
StateStore.CreateEnrollment
go/ports/state.go:118
CreateEnrollment(context.Context, Enrollment) error
Persist a verifier-only enrollment bound to scope, expiry and bootstrap bytes. Usage: err := store.CreateEnrollment(ctx, enrollment).
StateStore.Enrollment
go/ports/state.go:121
Enrollment(context.Context, []byte) (Enrollment, error)
Read the original enrollment binding using its token verifier. Usage: enrollment, err := store.Enrollment(ctx, tokenHash).
StateStore.Consume
go/ports/state.go:124
Consume(context.Context, Attempt) ([]byte, error)
Atomically claim a token or recover the same encrypted receipt for its bound attempt and key. Usage: receipt, err := store.Consume(ctx, attempt).
StateStore.Authenticate
go/ports/state.go:127
Authenticate(context.Context, string, []byte) (Device, error)
Authenticate one device credential and reject revoked identities. Usage: device, err := store.Authenticate(ctx, deviceID, credentialHash).
StateStore.Sync
go/ports/state.go:130
Sync(context.Context, SyncInput) (Snapshot, error)
Atomically bind replay input, accept reports and persist the returned desired/observed snapshot. Usage: snapshot, err := store.Sync(ctx, input).
StateStore.ListDevices
go/ports/state.go:133
ListDevices(context.Context, string, string, int) ([]Device, error)
Read one authorized scope's stable device cursor page. Usage: devices, err := store.ListDevices(ctx, scope, "", 100).
StateStore.Revoke
go/ports/state.go:136
Revoke(context.Context, string, string) error
Serialize revocation with enrollment recovery and authenticated sync. Usage: err := store.Revoke(ctx, scope, deviceID).
StateStore.RegisterArtifact
go/ports/state.go:139
RegisterArtifact(context.Context, Artifact) error
Register immutable verified metadata for a scope/digest. Usage: err := store.RegisterArtifact(ctx, artifact).
StateStore.ListArtifacts
go/ports/state.go:142
ListArtifacts(context.Context, string, string, int) ([]Artifact, error)
ListArtifacts returns scoped managed metadata in ascending digest order. Usage: page, err := store.ListArtifacts(ctx, scope, lastDigest, 100).
StateStore.Artifact
go/ports/state.go:145
Artifact(context.Context, string, string) (Artifact, error)
Read one scope/digest without crossing tenant boundaries. Usage: artifact, err := store.Artifact(ctx, scope, digest).
StateStore.RemoveArtifact
go/ports/state.go:148
RemoveArtifact(context.Context, string, string) error
Remove only unreferenced scoped metadata, retaining shared content safely. Usage: err := store.RemoveArtifact(ctx, scope, digest).
StateStore.Assign
go/ports/state.go:151
Assign(context.Context, Assignment) (Operation, error)
Atomically bind an install request key, desired revision and supersession of pending work. Usage: operation, err := store.Assign(ctx, assignment).
StateStore.ListOperations
go/ports/state.go:154
ListOperations(context.Context, string, string, string, int, time.Time) ([]Operation, error)
Expire overdue work and page scoped durable progress/results. Usage: operations, err := store.ListOperations(ctx, scope, deviceID, "", 100, now).
StateStore.AuthorizeDownload
go/ports/state.go:157
AuthorizeDownload(context.Context, string, []byte, string, string, string, time.Time) (Artifact, error)
Verify device credential, scope, active operation/lease and deadline before returning metadata. Usage: artifact, err := store.AuthorizeDownload(ctx, deviceID, credentialHash, operationID, digest, leaseID, now).
StateStore.SetPolicy
go/ports/state.go:160
SetPolicy(context.Context, PolicyAssignment) (DesiredPolicy, error)
Atomically bind a normalized replacement and validate every required app assignment. Usage: desired, err := store.SetPolicy(ctx, assignment).
StateStore.GetPolicy
go/ports/state.go:163
GetPolicy(context.Context, string, string) (PolicyStatus, error)
Return consistent scoped desired/reported/compliance state. Usage: status, err := store.GetPolicy(ctx, scope, deviceID).
Artifact
go/ports/state.go:168
type Artifact struct {
ScopeID string `json:"scope_id"`
SHA256 string `json:"sha256"`
PackageName string `json:"package_name"`
VersionCode int64 `json:"version_code"`
MinSDK uint32 `json:"min_sdk"`
MaxSDK uint32 `json:"max_sdk"`
SigningCertificates []string `json:"signing_certificates"`
SupportedABIs []string `json:"supported_abis"`
SizeBytes int64 `json:"size_bytes"`
}
Empty artifact scope is reserved for public bootstrap content; managed APKs always have an explicit scope. Store metadata is immutable for a scope/digest.
Assignment
go/ports/state.go:179
type Assignment struct {
ScopeID, DeviceID, ArtifactSHA256, IdempotencyKey, OperationID string
Now, NotBefore, Deadline time.Time
}
DesiredApplication
go/ports/state.go:183
type DesiredApplication struct {
Artifact Artifact `json:"artifact"`
Revision uint64 `json:"revision"`
}
Operation
go/ports/state.go:187
type Operation struct {
ID string `json:"id"`
DeviceID string `json:"device_id"`
Artifact Artifact `json:"artifact"`
Revision uint64 `json:"revision"`
State string `json:"state"`
LeaseID string `json:"lease_id"`
LeaseUntil time.Time `json:"lease_until"`
Deadline time.Time `json:"deadline"`
NotBefore time.Time `json:"not_before"`
Attempts int `json:"attempts"`
ReportSequence uint64 `json:"report_sequence"`
DownloadedBytes int64 `json:"downloaded_bytes"`
ErrorCode string `json:"error_code"`
ErrorMessage string `json:"error_message"`
Observed *InstalledApplication `json:"observed,omitempty"`
}
OperationReport
go/ports/state.go:204
type OperationReport struct {
ID, OperationID, LeaseID string
Sequence uint64
State string
DownloadedBytes int64
ErrorCode, ErrorMessage string
Observed *InstalledApplication
}
ReportReceipt
go/ports/state.go:212
type ReportReceipt struct {
ReportID string `json:"report_id"`
Accepted bool `json:"accepted"`
Reason string `json:"reason"`
}
ApplicationCompliance
go/ports/state.go:217
type ApplicationCompliance struct {
PackageName string `json:"package_name"`
Revision uint64 `json:"revision"`
State string `json:"state"`
Reason string `json:"reason"`
}
SyncInput
go/ports/state.go:223
type SyncInput struct {
DeviceID string
CredentialHash []byte
Inventory Inventory
Sequence uint64
ReportedRevision uint64
RetainedOperationIDs []string
CommandReports []CommandReport
Reports []OperationReport
NetworkReport *NetworkReport
PolicyReport *PolicyReport
Now time.Time
}
Snapshot
go/ports/state.go:236
type Snapshot struct {
Network NetworkStatus `json:"network"`
Device Device `json:"device"`
Sequence uint64 `json:"sequence"`
Desired []DesiredApplication `json:"desired"`
Operations []Operation `json:"operations"`
Commands []Command `json:"commands"`
CommandReceipts []string `json:"command_receipts"`
StoppedOperationIDs []string `json:"stopped_operation_ids"`
Receipts []ReportReceipt `json:"receipts"`
Compliance []ApplicationCompliance `json:"compliance"`
DesiredPolicy *DesiredPolicy `json:"desired_policy,omitempty"`
PolicyCompliance []PolicyResult `json:"policy_compliance"`
}
ReadSeekCloser
go/ports/state.go:251
type ReadSeekCloser interface {
io.Reader
io.Seeker
io.Closer
}
ArtifactStore
go/ports/state.go:261
type ArtifactStore interface {
// Atomically publish complete immutable bytes and reject digest mismatches or conflicting replacements.
// Usage: err := store.Put(ctx, digest, verifiedBytes).
Put(context.Context, string, []byte) error
// Return a detached seekable snapshot of immutable content; the caller closes the reader.
// Usage: store, err := filesystem.Open("/var/lib/kylok/artifacts").
Open(context.Context, string) (ReadSeekCloser, error)
}
ArtifactStore puts complete content atomically by SHA-256 and must reject a digest mismatch or replacement with different bytes. Open returns an immutable snapshot. Only empty-scope bootstrap artifacts are publicly served; managed applications require authenticated device/operation/lease authorization.
ArtifactStore.Put
go/ports/state.go:264
Put(context.Context, string, []byte) error
Atomically publish complete immutable bytes and reject digest mismatches or conflicting replacements. Usage: err := store.Put(ctx, digest, verifiedBytes).
ArtifactStore.Open
go/ports/state.go:267
Open(context.Context, string) (ReadSeekCloser, error)
Return a detached seekable snapshot of immutable content; the caller closes the reader. Usage: store, err := filesystem.Open("/var/lib/kylok/artifacts").
MaxAPKBytes
go/provisioning/apk.go:28
const MaxAPKBytes = 64 << 20
Tools
go/provisioning/apk.go:30
type Tools struct{ APKSigner, APKAnalyzer string }
Metadata
go/provisioning/apk.go:31
type Metadata struct {
PackageName string `json:"package_name"`
Receiver string `json:"receiver"`
VersionCode int64 `json:"version_code"`
MinSDK int `json:"min_sdk"`
MaxSDK int `json:"max_sdk"`
SupportedABIs []string `json:"supported_abis"`
SizeBytes int64 `json:"size_bytes"`
TargetSDK int `json:"target_sdk"`
Debuggable bool `json:"debuggable"`
SHA256 string `json:"sha256"`
SigningCertificates []string `json:"signing_certificates_sha256"`
}
APK
go/provisioning/apk.go:46
type APK struct {
// contains filtered or unexported fields
}
APK retains the exact verified bytes; callers cannot mutate metadata or content.
*APK.Verified
go/provisioning/apk.go:55
// Verified distinguishes an inspected immutable artifact from a zero-value APK.
// Usage: if !apk.Verified() { return errors.New("verified APK required") }.
func (a *APK) Verified() bool
Verified distinguishes an inspected immutable artifact from a zero-value APK. Usage: if !apk.Verified() { return errors.New("verified APK required") }.
*APK.IsDPC
go/provisioning/apk.go:59
// IsDPC distinguishes a verified provisioning-capable host from an ordinary signed application.
// Usage: if !apk.IsDPC() { return errors.New("provisioning host required") }.
func (a *APK) IsDPC() bool
IsDPC distinguishes a verified provisioning-capable host from an ordinary signed application. Usage: if !apk.IsDPC() { return errors.New("provisioning host required") }.
*APK.Metadata
go/provisioning/apk.go:63
// Metadata returns detached verified properties so callers cannot mutate registered identity.
// Usage: metadata := apk.Metadata().
func (a *APK) Metadata() Metadata
Metadata returns detached verified properties so callers cannot mutate registered identity. Usage: metadata := apk.Metadata().
*APK.Bytes
go/provisioning/apk.go:72
// Bytes returns a copy of the exact verified APK content for immutable publication.
// Usage: content := apk.Bytes().
func (a *APK) Bytes() []byte
Bytes returns a copy of the exact verified APK content for immutable publication. Usage: content := apk.Bytes().
Inspect
go/provisioning/apk.go:77
// Inspect snapshots the input before invoking Android's signature verifier and XML decoder.
// Both tools inspect the same bytes that are later registered and served.
// Usage: apk, err := provisioning.Inspect(ctx, signedAPKPath, provisioning.Tools{}).
func Inspect(ctx context.Context, path string, tools Tools) (*APK, error)
Inspect snapshots the input before invoking Android's signature verifier and XML decoder. Both tools inspect the same bytes that are later registered and served. Usage: apk, err := provisioning.Inspect(ctx, signedAPKPath, provisioning.Tools{}).
InspectApplication
go/provisioning/apk.go:83
// InspectApplication verifies a single/universal signed APK without requiring DPC components.
// Usage: apk, err := provisioning.InspectApplication(ctx, applicationPath, provisioning.Tools{}).
func InspectApplication(ctx context.Context, path string, tools Tools) (*APK, error)
InspectApplication verifies a single/universal signed APK without requiring DPC components. Usage: apk, err := provisioning.InspectApplication(ctx, applicationPath, provisioning.Tools{}).
Origin
go/provisioning/apk.go:307
// Origin accepts an HTTP or HTTPS origin using a domain name or IP address.
// Route prefixes, credentials and token-bearing URLs are unsupported.
// Usage: origin, err := provisioning.Origin("http://192.168.1.5:8080").
func Origin(value string) (string, error)
Origin accepts an HTTP or HTTPS origin using a domain name or IP address. Route prefixes, credentials and token-bearing URLs are unsupported. Usage: origin, err := provisioning.Origin("http://192.168.1.5:8080").
*APK.Path
go/provisioning/apk.go:317
// Path returns the content-addressed public bootstrap route for these verified bytes.
// Usage: route := apk.Path().
func (a *APK) Path() string
Path returns the content-addressed public bootstrap route for these verified bytes. Usage: route := apk.Path().
*APK.Handler
go/provisioning/apk.go:321
// Handler serves this verified APK only at its immutable GET/HEAD bootstrap path.
// Usage: bootstrapServer.Handler = apk.Handler().
func (a *APK) Handler() http.Handler
Handler serves this verified APK only at its immutable GET/HEAD bootstrap path. Usage: bootstrapServer.Handler = apk.Handler().
*APK.QR
go/provisioning/apk.go:342
// QR returns secret JSON. Hosts must not publish or log the payload.
// Usage: payload, err := apk.QR(bootstrapOrigin, map[string]string{"kylok.server": apiOrigin, "kylok.enrollment_token": token}).
func (a *APK) QR(publicURL string, extras map[string]string) ([]byte, error)
QR returns secret JSON. Hosts must not publish or log the payload. Usage: payload, err := apk.QR(bootstrapOrigin, map[string]string{"kylok.server": apiOrigin, "kylok.enrollment_token": token}).
Version
go/version.go:14
// Version identifies this SDK's source package, independently of its host.
// Usage: version := kylok.Version().
func Version() string
Version identifies this SDK's source package, independently of its host. Usage: version := kylok.Version().
ProtocolVersion
go/version.go:18
const ProtocolVersion uint32 = 1
ProtocolVersion is the current wire version. Development versions must be paired from the same source revision; the number alone is not compatibility.