enroll

package
v0.2.4 Latest Latest
Warning

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

Go to latest
Published: Sep 27, 2026 License: Apache-2.0 Imports: 9 Imported by: 0

Documentation

Overview

Package enroll handles agent authentication for the hosted control plane: per-agent enrollment tokens (validated against Neon) and the browser-session + PKCE handshake behind `ushr login`. See DESIGN-enrollment.md.

OSS single-host does not use this — it keeps the static shared token (or loopback with no token). Enrollment is the hosted, multi-tenant path.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Challenge

func Challenge(verifier string) string

Challenge is the PKCE challenge for a verifier: hex sha256(verifier). The CLI sends this; FetchSession recomputes it from the presented verifier.

func HashToken

func HashToken(token string) string

HashToken is the at-rest form of an enrollment token: hex sha256. Both this control plane and the hosted web app minter must hash identically.

Types

type PG

type PG struct {
	// contains filtered or unexported fields
}

PG is the Neon-backed enroll.Store. The hosted web app web app writes agent_tokens (mint) and approves cli_sessions; this reads/validates and serves the CLI poll. It shares the control plane's pgxpool (see NewWithPool).

func NewWithPool

func NewWithPool(ctx context.Context, pool *pgxpool.Pool) (*PG, error)

NewWithPool applies any unapplied enrollment migrations on an existing pool and returns a store sharing it (the control plane's dispatch store owns the pool's lifetime). An advisory lock serializes concurrent boots.

func (*PG) CreateSession

func (p *PG) CreateSession(id, challenge string, meta SessionMeta) error

CreateSession records a pending login session and prunes expired ones.

func (*PG) FetchSession

func (p *PG) FetchSession(id, verifier string) (Session, SessionStatus, error)

FetchSession consumes an approved session and returns its token. The delete and read are one statement, so a session is single-use: two racing fetches can't both receive the token. A wrong verifier fails the challenge match and reads as expired — no oracle for pending vs unknown.

func (*PG) ValidateToken

func (p *PG) ValidateToken(token string) ([]string, string, bool)

ValidateToken looks up an active enrollment token by its hash. A DB error fails closed (ok=false) so a blip rejects rather than admits.

type Session

type Session struct {
	Token string
	Orgs  []string
	Name  string
}

Session is the approved result the CLI writes into its config.

type SessionMeta

type SessionMeta struct {
	// AgentName is the enrolling host's own declared name (its agent config
	// name or hostname). The approval page displays it read-only.
	AgentName string
	// RequesterIP is the CLI's egress address as seen by the control plane.
	RequesterIP string
	// UserCode is the short confirmation code the CLI prints; the approver
	// checks it matches the page before approving (RFC 8628-style binding).
	UserCode string
}

SessionMeta is requester context captured at session creation and shown on the browser approval page, so the approver can recognize (or reject) the machine asking to enroll — the defense against device-flow phishing.

type SessionStatus

type SessionStatus int

SessionStatus is the state of a CLI login session when the CLI polls for it.

const (
	// Pending: the browser side hasn't approved yet.
	Pending SessionStatus = iota
	// Ready: approved, token available.
	Ready
	// Expired: unknown or past its TTL.
	Expired
)

type Store

type Store interface {
	// ValidateToken reports the orgs an enrollment token may serve and the agent
	// name it is bound to. A token covers the set of orgs the enrolling account
	// selected (all verified by that account), so one agent can serve several.
	// ok is false for unknown or revoked tokens; errors are treated as not-ok.
	ValidateToken(token string) (orgs []string, name string, ok bool)
	// CreateSession records a pending login session (idempotent on id).
	CreateSession(id, challenge string, meta SessionMeta) error
	// FetchSession returns the approved Session iff verifier matches the stored
	// challenge, consuming it. Pending/expired sessions return no token.
	FetchSession(id, verifier string) (Session, SessionStatus, error)
}

Store authenticates enrollment tokens and drives the CLI login handshake. The web app (hosted web app) writes agent_tokens and approves cli_sessions; the control plane only reads/validates here.

Jump to

Keyboard shortcuts

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