event

package
v0.3.2 Latest Latest
Warning

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

Go to latest
Published: Sep 10, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Overview

Package event provides an in-process bus for typed events with enrollment, actor and timestamp metadata.

Design

Subscribers can observe lifecycle and command outcomes without being coupled to the service implementation. The bus supports synchronous and asynchronous dispatch and configurable handler-error reporting. Close drains queued asynchronous work. The bus itself has no durable storage.

Events may contain sensitive protocol data. External sinks in server/eventsink apply an explicit projection, and server/audit persists that projection when configured. Direct subscribers must apply their own disclosure policy. The DDM notifier consumes persistent change rows rather than relying on bus delivery.

References

Index

Constants

This section is empty.

Variables

View Source
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 New

func New(opts ...Option) *Bus

New creates a bus.

func (*Bus) Close

func (b *Bus) Close(ctx context.Context) error

Close stops accepting events and waits for asynchronous deliveries, or until ctx is done.

func (*Bus) Publish

func (b *Bus) Publish(ctx context.Context, e Event) error

Publish delivers e to subscribers of e.Type and of All. In synchronous mode it returns the joined handler errors; in asynchronous mode it returns immediately and errors go to the error handler. Async delivery retains context values but outlives request cancellation; Close drains accepted events.

func (*Bus) Subscribe

func (b *Bus) Subscribe(t Type, h Handler) func()

Subscribe registers h for events of type t (or All). The returned function removes the subscription.

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

type Handler func(ctx context.Context, e Event) error

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

func WithErrorHandler(f func(Event, error)) Option

WithErrorHandler receives handler errors. The default drops them.

type Type

type Type string

Type names an event.

const (
	// Security rejections carry metadata only; never attach credentials or remote errors.
	EnrollmentDenied          Type = "enrollment-denied"
	IdentityRejected          Type = "identity-rejected"
	CertificateStatusRejected Type = "certificate-status-rejected"
	PrivateHopRejected        Type = "private-hop-rejected"
	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"
	// CertificateRevoked is an irreversible issuer-registry status change.
	CertificateRevoked Type = "certificate-revoked"
	// 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 records an administrative request refused by authorization.
	AdminDenied Type = "admin-denied"

	// All subscribes to every type.
	All Type = "*"
)

Event types published by the service layer.

Jump to

Keyboard shortcuts

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