Documentation
¶
Overview ¶
Package event is the in-process event bus every state change in the service layer publishes to: typed events with an enrollment id, an actor, and a timestamp, dispatched to subscribers by type.
Why ¶
Webhooks, audit logs, metrics, and the DDM change notifier all want to know when an enrollment appears, a token changes, a command completes, or a certificate rotates. Making them subscribers of one bus rather than special cases inside the service is the shape decision record 0001 chose for the library, and the threat model's repudiation control depends on it: every state change emits an event, and subscribers persist them. Phase 2 of the plan of record delivers the bus alongside the protocol core.
The bus is deliberately small: synchronous dispatch, a handler error reported through the bus error handler without stopping other handlers, and no persistence. The sinks live in event/sink, which projects an event down to what may leave the process before an slog record or a webhook carries it; the durable trail the threat model's repudiation control needs is package audit.
References ¶
- Decision record 0001: docs/research/decisions/0001-architecture.md
- Decision record 0006: docs/research/decisions/0006-mdm-signature-verification.md (CertRotated)
- Decision record 0015: docs/research/decisions/0015-push-cert-store.md
- Plan of record: docs/research/implementation_plan.md (phase 2)
- Threat model: docs/security/threat-model.md (Repudiation)
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrClosed = errors.New("event: bus closed")
ErrClosed is returned by Publish after Close.
Functions ¶
This section is empty.
Types ¶
type Bus ¶
type Bus struct {
// contains filtered or unexported fields
}
Bus dispatches events to subscribers. It is safe for concurrent use.
func (*Bus) Close ¶
Close stops accepting events and waits for asynchronous deliveries, or until ctx is done.
type Event ¶
type Event struct {
Type Type
At time.Time
Enrollment mdm.EnrollmentID
// Actor is who caused the event: "device", "admin", or a system component.
Actor string
// Data carries type-specific detail, for example *mdm.Response for CommandResult.
Data any
}
Event is one occurrence.
type Handler ¶
Handler receives events. Returning an error is reported through the bus error handler but does not stop other handlers.
type Option ¶
type Option func(*Bus)
Option configures a Bus.
func WithAsync ¶
func WithAsync() Option
WithAsync dispatches each Publish on its own goroutine; Close waits for in-flight deliveries. The default is synchronous delivery in subscription order, which keeps tests and audit ordering deterministic.
func WithErrorHandler ¶
WithErrorHandler receives handler errors. The default drops them.
type Type ¶
type Type string
Type names an event.
const ( Enrolled Type = "enrolled" // Authenticate accepted for a new enrollment Reenrolled Type = "reenrolled" // Authenticate accepted for an existing enrollment TokenUpdated Type = "token-updated" // TokenUpdate stored CheckedOut Type = "checked-out" // CheckOut received CertRotated Type = "cert-rotated" // enrollment identity certificate changed CommandQueued Type = "command-queued" // command enqueued for an enrollment CommandSent Type = "command-sent" // command delivered to the device CommandResult Type = "command-result" // Acknowledged, Error, CommandFormatError, or NotNow BootstrapTokenSet Type = "bootstrap-token-set" // PushTokenInvalid is a token APNs says will never work again (410). // The enrollment is gone until it re-registers. PushTokenInvalid Type = "push-token-invalid" // PushRejected is a push APNs refused for a reason that is not the // device's: a wrong topic, a mismatched or expired push certificate, the // wrong environment, or a malformed request. It is the event to alert // on, because the cause is usually shared by every device on the topic // and no retry will clear it. PushRejected Type = "push-rejected" DDMChanged Type = "ddm-changed" DDMStatusReceived Type = "ddm-status-received" CertReuseDenied Type = "cert-reuse-denied" // Authenticate presented a certificate another enrollment pinned before EnrollmentImported Type = "enrollment-imported" // record written by MigrationStore.Import UserAuthenticated Type = "user-authenticated" // UserAuthenticate digest accepted, AuthToken issued UserAuthFailed Type = "user-auth-failed" // UserAuthenticate digest rejected or challenge expired // ACMEChallengeValid is a device-attest-01 challenge that passed // verification and policy. ACMEChallengeValid Type = "acme-challenge-valid" // ACMEIssued is a device identity certificate issued through ACME. ACMEIssued Type = "acme-issued" // AttestationRejected is an attestation that failed verification, named // the wrong device, or was refused by policy. It is the event to alert // on: a device that fails here is either faulty or not what it claims. AttestationRejected Type = "attestation-rejected" // AdminAction is a mutating admin request that was allowed. Actor is the // principal name and Data names the action, method, path, and the // credential that acted, never the token and never the body. AdminAction Type = "admin-action" // AdminDenied is an admin request refused by authorization. Neither Fleet // nor Zentral records a denial as an event, so neither can answer who // probed what and was refused; this is that record (decision 0034). AdminDenied Type = "admin-denied" // All subscribes to every type. All Type = "*" )
Event types published by the service layer.
Directories
¶
| Path | Synopsis |
|---|---|
|
Package sink publishes events off the bus: a projection registry that decides what each event type may say, an slog audit sink, and a MicroMDM-compatible webhook.
|
Package sink publishes events off the bus: a projection registry that decides what each event type may say, an slog audit sink, and a MicroMDM-compatible webhook. |