config

package
v1.3.2 Latest Latest
Warning

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

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

Documentation

Overview

Package config loads kafkito runtime configuration from a YAML file (optional) and environment variables (prefix KAFKITO_).

Resolution order (later wins):

  1. Built-in defaults
  2. YAML file (if --config is given or KAFKITO_CONFIG is set)
  3. Environment variables with the KAFKITO_ prefix
  4. $PORT (Cloud Foundry / Heroku style): when set and non-empty it overrides server.addr with ":$PORT", regardless of where server.addr came from.
  5. A convenience shortcut: if no clusters are defined but KAFKITO_KAFKA_BROKERS is set, a single cluster named "local" is synthesized from that comma-separated list.

Index

Constants

View Source
const (
	LogLevelDebug = "debug"
	LogLevelInfo  = "info"
	LogLevelWarn  = "warn"
	LogLevelError = "error"

	LogFormatJSON = "json"
	LogFormatText = "text"
)

Log levels and formats accepted by LogConfig.

View Source
const (
	MaskTargetValue   = "value"
	MaskTargetKey     = "key"
	MaskTargetHeaders = "headers"
)

Record parts a MaskingRule can target.

View Source
const AdhocClusterPrefix = "__adhoc_"

AdhocClusterPrefix starts the internal registry name of every private cluster: the kafka package registers a header-provided configuration under this prefix plus a fingerprint. It is the only definition of the prefix. Configured clusters may not use it (see Validate), and the HTTP layer never accepts such a name from a client.

View Source
const AuthModeOIDC = "oidc"

AuthModeOIDC is the Mode value selecting the generic OIDC validator.

View Source
const DefaultAddr = ":37421"

DefaultAddr is the listen address used when neither server.addr nor $PORT is set.

View Source
const DefaultAuthMode = "off"

DefaultAuthMode is the auth mode used when auth.mode (KAFKITO_AUTH_MODE) is empty. Only devauth builds can serve it; other builds refuse to start.

View Source
const DefaultFrameAncestors = "'none'"

DefaultFrameAncestors is the CSP frame-ancestors source list used when server.frame_ancestors is unset: the UI must not be framed.

View Source
const DefaultIdentityHeader = "X-Kafkito-User"

DefaultIdentityHeader is the HTTP header used to carry the request principal when no custom header is configured under rbac.identity.header.

View Source
const DefaultTestConnectionTimeout = 15 * time.Second

DefaultTestConnectionTimeout is the budget of the user-driven "Test connection" probe when server.test_connection_timeout is unset or zero.

View Source
const PrivateClusterSentinel = "__private__"

PrivateClusterSentinel is the URL cluster-name segment reserved for per-request private clusters. When this value appears in the URL path, the request must also carry a valid X-Kafkito-Cluster header; the cluster configuration is read from that header rather than the static config.

Variables

View Source
var ErrNoSuchCluster = errors.New("cluster not configured")

ErrNoSuchCluster is returned by lookups on an unknown cluster name.

Functions

func ClusterLogName added in v1.3.0

func ClusterLogName(name string) string

ClusterLogName returns how logs name the cluster with registry name name. A private cluster is "private-" and 12 hex digits of a SHA-256 over its registry name: the same on every log line of that cluster while the process runs, so the lines correlate, without the registry name itself. Any other name is returned unchanged.

func IsAdhocClusterName added in v1.3.0

func IsAdhocClusterName(name string) bool

IsAdhocClusterName reports whether name is in the internal namespace of private clusters.

func PublicClusterName added in v1.3.0

func PublicClusterName(name string) string

PublicClusterName returns the cluster name a client uses for the registry name name: PrivateClusterSentinel for a private cluster, name itself otherwise. Responses and error messages name clusters with it.

Types

type AppAuthConfig

type AppAuthConfig struct {
	Mode string         `koanf:"mode"`
	OIDC OIDCAuthConfig `koanf:"oidc"`
}

AppAuthConfig is the top-level authentication configuration for kafkito itself (distinct from per-cluster SASL auth). Mode comes from auth.mode in the YAML file or from KAFKITO_AUTH_MODE, and Load sets it to DefaultAuthMode when both are empty. A set but empty KAFKITO_AUTH_MODE overrides the YAML value, so it also yields DefaultAuthMode. Every build registers "off", "mock" and "oidc" ("off" can only be served by devauth builds); tagged builds may register additional IdP-specific modes, such as "xsuaa" in btp builds. See internal/auth.Register.

type AuthConfig

type AuthConfig struct {
	Type     string `koanf:"type" json:"type"`
	Username string `koanf:"username" json:"username"`
	Password string `koanf:"password" json:"password"`
}

AuthConfig is per-cluster authentication. Type "" or "none" disables SASL. Valid types: "none", "plain", "scram-sha-256", "scram-sha-512".

func (AuthConfig) LogValue

func (a AuthConfig) LogValue() slog.Value

LogValue implements slog.LogValuer so that AuthConfig is always logged with its password field masked, no matter which call site emits it.

type ClusterConfig

type ClusterConfig struct {
	Name           string               `koanf:"name" json:"name"`
	IsProd         bool                 `koanf:"is_prod" json:"is_prod"`
	Brokers        []string             `koanf:"brokers" json:"brokers"`
	Auth           AuthConfig           `koanf:"auth" json:"auth"`
	TLS            TLSConfig            `koanf:"tls" json:"tls"`
	SchemaRegistry SchemaRegistryConfig `koanf:"schema_registry" json:"schema_registry"`
	DataMasking    []MaskingRule        `koanf:"data_masking" json:"data_masking"`
}

ClusterConfig describes one Kafka cluster kafkito can connect to.

The json tags are load-bearing, not decoration: ad-hoc ("private") clusters arrive as JSON — base64 in the X-Kafkito-Cluster header, or inline as a copy request's dest_cluster_config — and encoding/json's fallback case-insensitive field matching does NOT ignore underscores. Without a json tag every multi-word key (is_prod, schema_registry, insecure_skip_verify, data_masking) is silently dropped, which previously left private clusters unable to use a Schema Registry and made them invisible to the is_prod production-confirmation gate.

func (ClusterConfig) LogValue

func (c ClusterConfig) LogValue() slog.Value

LogValue implements slog.LogValuer so that ClusterConfig never leaks embedded credentials when dumped via slog.Any.

func (ClusterConfig) Redacted

func (c ClusterConfig) Redacted() ClusterConfig

Redacted returns a copy of the cluster config safe to log or expose via API. Secrets (password) are replaced with "***" if non-empty.

type Config

type Config struct {
	Server   ServerConfig    `koanf:"server"`
	Clusters []ClusterConfig `koanf:"clusters"`
	RBAC     RBACConfig      `koanf:"rbac"`
	Auth     AppAuthConfig   `koanf:"auth"`
	Log      LogConfig       `koanf:"log"`

	PrivateClusters PrivateClustersConfig `koanf:"private_clusters"`
}

Config is the root configuration struct.

func Defaults

func Defaults() Config

Defaults returns the built-in default configuration.

func Load

func Load(path string) (Config, error)

Load merges defaults, an optional YAML file and KAFKITO_* env vars. path may be empty; if empty, KAFKITO_CONFIG is consulted.

func (Config) ClusterByName

func (c Config) ClusterByName(name string) (ClusterConfig, bool)

ClusterByName returns the cluster with the given name, or false.

func (Config) LogValue

func (c Config) LogValue() slog.Value

LogValue implements slog.LogValuer for the root Config. Emits a summary that is safe to include in startup or diagnostic logs.

func (Config) Validate

func (c Config) Validate() error

Validate returns an error for structurally invalid configurations. It is intentionally lenient: zero clusters is allowed (kafkito still starts, but cluster-scoped endpoints will report unavailable).

type IdentityConfig

type IdentityConfig struct {
	Header        string `koanf:"header"`
	AnonymousRole string `koanf:"anonymous_role"`
}

IdentityConfig controls how the request principal is resolved.

type LogConfig

type LogConfig struct {
	Level  string `koanf:"level"`
	Format string `koanf:"format"`
}

LogConfig controls the process logger. Populated from KAFKITO_LOG_LEVEL and KAFKITO_LOG_FORMAT (or log.level / log.format in YAML). Values are case-insensitive; empty means the default (info, json).

func (LogConfig) FormatName

func (l LogConfig) FormatName() string

FormatName returns the normalized output format ("json" or "text").

func (LogConfig) SlogLevel

func (l LogConfig) SlogLevel() slog.Level

SlogLevel returns the slog level for Level. Unknown values map to info; Validate rejects them before this is reached in normal startup.

type MaskingRule

type MaskingRule struct {
	Topics      []string    `koanf:"topics" json:"topics"`
	Fields      []string    `koanf:"fields" json:"fields"`           // JSONPath expressions
	Regex       []RegexMask `koanf:"regex" json:"regex"`             // regex-based replacements applied on the raw string
	Replacement string      `koanf:"replacement" json:"replacement"` // default replacement for Fields; empty = "***"
	Targets     []string    `koanf:"targets" json:"targets"`
	Headers     []string    `koanf:"headers" json:"headers"`
}

MaskingRule applies masking to a subset of topics on the cluster. At least one of Fields or Regex must be populated. Topics is a list of topic name patterns (Go regex); the rule triggers when any pattern matches the topic. If Topics is empty, the rule matches all topics.

Targets selects the record parts the rule masks (MaskTargetValue, MaskTargetKey, MaskTargetHeaders); empty means the value only. Headers narrows the headers target to header keys matching any of its patterns (Go regex); empty means every header.

func (MaskingRule) MaskTargets

func (r MaskingRule) MaskTargets() []string

MaskTargets returns the record parts r masks: its Targets, or the value alone when Targets is empty.

func (MaskingRule) Validate

func (r MaskingRule) Validate() error

Validate reports the first problem that would keep r from compiling: an unknown target, a headers selector without the headers target, or a malformed topic/header pattern, JSONPath or regex.

type OIDCAuthConfig added in v1.3.0

type OIDCAuthConfig struct {
	// IssuerURL is the exact expected "iss" claim and the base for OpenID
	// Connect discovery. Required in oidc mode.
	// Env: KAFKITO_AUTH_OIDC_ISSUER_URL.
	IssuerURL string `koanf:"issuer_url"`
	// Audience is the value the token's "aud" claim must contain: the
	// identifier of the kafkito API, not the client of the auth proxy.
	// Required in oidc mode. Env: KAFKITO_AUTH_OIDC_AUDIENCE.
	Audience string `koanf:"audience"`
	// JWKSURL is the signing-key endpoint. When empty it is discovered from
	// <IssuerURL>/.well-known/openid-configuration at startup.
	// Env: KAFKITO_AUTH_OIDC_JWKS_URL.
	JWKSURL string `koanf:"jwks_url"`
	// RequiredTyp, when set, is the "typ" header every token must carry
	// (for example "at+jwt"). Empty disables the check.
	// Env: KAFKITO_AUTH_OIDC_REQUIRED_TYP.
	RequiredTyp string `koanf:"required_typ"`
	// AllowedAZP, when non-empty, lists the "azp" claim values a token may
	// carry; tokens without azp are then rejected. Empty disables the check.
	// Env: KAFKITO_AUTH_OIDC_ALLOWED_AZP (comma-separated).
	AllowedAZP []string `koanf:"allowed_azp"`
}

OIDCAuthConfig configures the generic "oidc" auth mode. kafkito only validates bearer JWTs; login is handled by an upstream auth proxy. The settings are ignored in other modes.

type PermissionConfig

type PermissionConfig struct {
	Resource string   `koanf:"resource"`
	Actions  []string `koanf:"actions"`
}

PermissionConfig binds a resource to a set of actions. Resource is "*", a resource type ("topic", covering every topic) or "type:pattern", where pattern is "*", a prefix ending in "*" or an exact name. Names are matched literally, so a resource named "*" is only covered by the pattern "*".

type PrivateClusterMode added in v1.3.0

type PrivateClusterMode string

PrivateClusterMode says who may use private clusters, the clusters a user defines in the browser and sends per request (see PrivateClusterSentinel).

const (
	// PrivateClustersOn lets every user use private clusters. It is the
	// default.
	PrivateClustersOn PrivateClusterMode = "on"
	// PrivateClustersOff disables private clusters.
	PrivateClustersOff PrivateClusterMode = "off"
	// PrivateClustersRole limits private clusters to RBAC subjects with the
	// permission private_cluster:use. It requires rbac.enabled.
	PrivateClustersRole PrivateClusterMode = "role"
)

The values of PrivateClustersConfig.Mode.

type PrivateClustersConfig added in v1.3.0

type PrivateClustersConfig struct {
	// Mode is on, off or role, case-insensitive; empty means on. Load also
	// accepts a YAML boolean: true is on, false is off.
	Mode PrivateClusterMode `koanf:"mode"`
	// AllowPlainWithoutTLS lets a private cluster use SASL/PLAIN without
	// TLS. By default such a definition is rejected, because PLAIN sends
	// the password in clear text. Configured clusters are not affected.
	AllowPlainWithoutTLS bool `koanf:"allow_plain_without_tls"`
}

PrivateClustersConfig is the private_clusters block. Settings for private clusters are fields of this block next to Mode.

func (PrivateClustersConfig) EffectiveMode added in v1.3.0

func (p PrivateClustersConfig) EffectiveMode() PrivateClusterMode

EffectiveMode returns Mode trimmed and lowercased, PrivateClustersOn when Mode is empty.

type RBACConfig

type RBACConfig struct {
	Enabled     bool            `koanf:"enabled"`
	DefaultRole string          `koanf:"default_role"`
	Identity    IdentityConfig  `koanf:"identity"`
	Roles       []RoleConfig    `koanf:"roles"`
	Subjects    []SubjectConfig `koanf:"subjects"`
}

RBACConfig is the top-level RBAC configuration block.

type RegexMask

type RegexMask struct {
	Match       string `koanf:"match" json:"match"`
	Replacement string `koanf:"replacement" json:"replacement"`
}

RegexMask describes a single regex substitution.

type RoleConfig

type RoleConfig struct {
	Name        string             `koanf:"name"`
	Permissions []PermissionConfig `koanf:"permissions"`
}

RoleConfig defines a named role with its permissions.

type SchemaRegistryConfig

type SchemaRegistryConfig struct {
	URL                string `koanf:"url" json:"url"`
	Username           string `koanf:"username" json:"username"`
	Password           string `koanf:"password" json:"password"`
	InsecureSkipVerify bool   `koanf:"insecure_skip_verify" json:"insecure_skip_verify"`
}

SchemaRegistryConfig is an optional per-cluster Confluent-/Apicurio-compatible Schema Registry endpoint. When URL is empty, SR features are disabled for that cluster.

func (SchemaRegistryConfig) LogValue

func (s SchemaRegistryConfig) LogValue() slog.Value

LogValue implements slog.LogValuer so that SchemaRegistryConfig is always logged with its password field masked.

type ServerConfig

type ServerConfig struct {
	// Addr is the bind address, e.g. ":37421". Empty means DefaultAddr.
	// A non-empty $PORT always wins over this (Load rewrites Addr to
	// ":$PORT"), to stay Cloud-Foundry friendly.
	Addr string `koanf:"addr"`
	// TestConnectionTimeout bounds the "Test connection" probe of
	// POST /api/v1/clusters/_test. Env: KAFKITO_TEST_CONNECTION_TIMEOUT
	// (Go duration, e.g. "30s"). Zero means DefaultTestConnectionTimeout.
	TestConnectionTimeout time.Duration `koanf:"test_connection_timeout"`
	// FrameAncestors is the source list of the Content-Security-Policy
	// frame-ancestors directive, i.e. which origins may embed the UI in a
	// frame. Env: KAFKITO_SERVER_FRAME_ANCESTORS. Empty means
	// DefaultFrameAncestors ('none').
	FrameAncestors string `koanf:"frame_ancestors"`
}

ServerConfig controls the HTTP server.

type SubjectConfig

type SubjectConfig struct {
	User  string   `koanf:"user"`
	Roles []string `koanf:"roles"`
}

SubjectConfig maps a user identity to one or more roles.

type TLSConfig

type TLSConfig struct {
	Enabled            bool `koanf:"enabled" json:"enabled"`
	InsecureSkipVerify bool `koanf:"insecure_skip_verify" json:"insecure_skip_verify"`
}

TLSConfig enables TLS for the cluster connection. When Enabled is true, franz-go uses the system trust store unless InsecureSkipVerify is set.

Jump to

Keyboard shortcuts

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