auth

package
v0.11.6 Latest Latest
Warning

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

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

Documentation

Overview

Package auth holds the two thin auth surfaces of the admin server:

  • Agent: shared bearer token, and/or a client certificate when the agent listener runs mutual TLS (Config.AgentTLS with ClientAuth = RequireAndVerifyClientCert, set by --agent-client-ca). The TLS handshake itself rejects clients without a valid certificate; this package only attributes the resulting identity. Validated on every Connect-RPC call from an agent.
  • UI: trusted-proxy header pass-through (X-Auth-User / X-Auth-Email) with optional bearer fallback. Per decision 14, the canonical deployment runs oauth2-proxy or equivalent in front of the UI listener; the server does NOT implement OIDC itself.

Index

Constants

View Source
const ProxySecretHeader = "X-Auth-Proxy-Secret"

ProxySecretHeader is the header the trusted proxy uses to present UIConfig.ProxySecret. Fixed (not configurable) to keep the contract between proxy and server unambiguous.

Variables

View Source
var ErrTrustedProxyMisconfigured = errors.New("admin server: malformed trusted_cidrs entry")

ErrTrustedProxyMisconfigured is returned by ValidateTrustedCIDRs (and wrapped by parseCIDRs) when a trusted-proxy CIDR entry is malformed.

Functions

func AgentMiddleware

func AgentMiddleware(token string, logger *slog.Logger) func(http.Handler) http.Handler

AgentMiddleware returns an http middleware that enforces shared-token auth on the agent listener. When token is empty no credential is checked here: the listener is presumed bound to a private network, or the TLS listener already required and verified a client certificate (mutual TLS), in which case the peer certificate's Common Name is attached to the request context as Identity{Subject: "agent:<CN>"}.

logger receives a rate-limited WARN (one per minute per remote IP, with a count of the 401s suppressed in between) every time a request is rejected, so an operator can see in the server log that agents with a bad token are calling (OR5-2). Pass nil for slog.Default.

func UIMiddleware

func UIMiddleware(cfg UIConfig) func(http.Handler) http.Handler

UIMiddleware authenticates UI requests. It returns a generic 401 on failure rather than leaking which credential mode was attempted.

func ValidateTrustedCIDRs

func ValidateTrustedCIDRs(cidrs []string) error

ValidateTrustedCIDRs reports whether every entry parses as a CIDR. The server calls it at boot so a typo in --ui-trusted-cidrs refuses to start instead of being dropped silently (which used to leave the operator believing a proxy network was trusted when it was not).

func WithIdentity

func WithIdentity(ctx context.Context, id Identity) context.Context

WithIdentity returns a context carrying the authenticated identity. The UI middleware calls this after a successful auth so downstream Connect handlers (audit, manage) can attribute actions to an operator.

Types

type Identity

type Identity struct {
	Subject string // "agent:<NodeID>" for agents, the UI user for UI
	Email   string // empty for agents, optional for UI
	Role    string // "agent" | "ui-operator"

	// ReadOnly marks an operator whose mutations must be refused
	// (Data Studio create/update/delete/bulk). Set from the trusted
	// proxy's role header or forced globally via UIConfig.ForceReadOnly.
	ReadOnly bool
}

Identity is the minimal set of facts the rest of the server may rely on after a request has been authenticated. Used for observability, audit attribution, and the read-only gate on Data Studio mutations.

func IdentityFromContext

func IdentityFromContext(ctx context.Context) Identity

IdentityFromContext returns the authenticated identity, or a zero Identity (Subject "") when the context carries none.

type UIConfig

type UIConfig struct {
	// BearerToken, when non-empty, lets a request authenticate by sending
	// "Authorization: Bearer <BearerToken>". The token is checked AFTER
	// trusted-proxy header pass-through.
	BearerToken string

	// AuthHeader and EmailHeader name the headers the trusted reverse
	// proxy uses to forward identity (X-Auth-User / X-Auth-Email by
	// default, configurable per Config.UIAuthHeader / UIEmailHeader).
	AuthHeader  string
	EmailHeader string

	// TrustedCIDRs is the allowlist of remote addresses whose
	// trusted-proxy headers are honoured. Empty = "127.0.0.1/32, ::1/128".
	TrustedCIDRs []string

	// ProxySecret, when non-empty, is a shared secret the trusted proxy
	// must echo in the ProxySecretHeader ("X-Auth-Proxy-Secret") for its
	// forwarded identity to be honoured. CIDR membership alone is then no
	// longer sufficient — it defends against any co-located process that
	// can source packets from a trusted CIDR but does not know the secret.
	// Empty keeps the CIDR-only behaviour.
	ProxySecret string

	// RoleHeader names the trusted-proxy header carrying the operator's
	// role (default "X-Auth-Role"). Honoured only on the trusted-proxy
	// path, together with AuthHeader. Value "viewer" / "readonly" /
	// "read-only" (case-insensitive) marks the identity read-only; any
	// other value — including absent — keeps the operator read-write.
	RoleHeader string

	// ForceReadOnly marks EVERY authenticated UI identity read-only,
	// regardless of role header or credential mode. See
	// Config.UIReadOnly.
	ForceReadOnly bool

	// InsecureOpen, when true, authenticates a credential-less request
	// whose remote address is loopback as the fixed operator
	// "insecure-open". Local-development convenience ONLY (the embedded
	// SPA cannot present a bearer, so without a header-setting reverse
	// proxy a browser can never load the UI). The server refuses to
	// start with this set on a non-loopback UI listener; see
	// Config.UIInsecureOpen.
	InsecureOpen bool
}

UIConfig groups the UI-listener auth knobs.

Jump to

Keyboard shortcuts

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