Documentation
¶
Overview ¶
Package config loads runtime settings via koanf in the layered pattern: struct defaults → settings.toml → CHESHMHAYASH__* environment variables.
Env keys use `__` as the path separator (e.g. CHESHMHAYASH__SERVER__PORT). `[]NATS` entries are addressed by their array index — koanf can't merge a numeric-keyed env map into a TOML-loaded slice, so slice paths are overlaid manually after the struct is unmarshalled.
Index ¶
Constants ¶
const ( AuthModeOIDC = "oidc" AuthModeJWT = "jwt" )
Auth mode identifiers (auth.mode).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AccessRule ¶ added in v0.10.0
type AccessRule struct {
AllowedEmails []string `json:"allowed_emails,omitempty" koanf:"allowed_emails"`
AllowedDomains []string `json:"allowed_domains,omitempty" koanf:"allowed_domains"`
AllowedGroups []string `json:"allowed_groups,omitempty" koanf:"allowed_groups"`
}
AccessRule is an email/domain/group allowlist triple. Used for the write-access (admin) tier; the same matching logic as the sign-in allowlist, scoped to a narrower set of identities.
func (AccessRule) IsEmpty ¶ added in v0.10.0
func (r AccessRule) IsEmpty() bool
IsEmpty reports whether the rule matches nobody (all three slices empty).
type Auth ¶ added in v0.8.0
type Auth struct {
Enabled bool `json:"enabled" koanf:"enabled"`
// Mode selects how a request is authenticated when Enabled:
// "oidc" (default) — cheshmhayash runs the OIDC login flow itself and
// issues an HMAC-signed session cookie.
// "jwt" — no login flow. Every request must carry an
// `Authorization: Bearer <jwt>` access token minted
// by auth.oidc.issuer (a "builtin oauth" gateway in
// front of cheshmhayash). The token's signature /
// issuer / expiry are verified and its claims drive
// the same allowlist + admin/readonly roles.
Mode string `json:"mode,omitempty" koanf:"mode"`
OIDC AuthOIDC `json:"oidc" koanf:"oidc"`
Access AuthAccess `json:"access" koanf:"access"`
Session AuthSession `json:"session" koanf:"session"`
JWT AuthJWT `json:"jwt,omitzero" koanf:"jwt"`
MCPKeys []MCPKey `json:"mcp_keys,omitempty" koanf:"mcp_keys"`
MCPOAuth AuthMCPOAuth `json:"mcp_oauth,omitzero" koanf:"mcp_oauth"`
MCPJWT AuthMCPJWT `json:"mcp_jwt,omitzero" koanf:"mcp_jwt"`
}
Auth gates the HTTP API behind OIDC. When Enabled is false the API stays open (backward-compatible default). MCP HTTP is gated by MCPKeys independently: leave the slice empty to keep /mcp open like before.
func (Auth) ModeOrDefault ¶ added in v0.13.0
ModeOrDefault returns the configured auth mode lower-cased, defaulting to "oidc" when unset so existing configs keep their cookie-login behaviour.
type AuthAccess ¶ added in v0.8.0
type AuthAccess struct {
AllowedEmails []string `json:"allowed_emails,omitempty" koanf:"allowed_emails"`
AllowedDomains []string `json:"allowed_domains,omitempty" koanf:"allowed_domains"`
AllowedGroups []string `json:"allowed_groups,omitempty" koanf:"allowed_groups"`
GroupsClaim string `json:"groups_claim,omitempty" koanf:"groups_claim"`
Admin AccessRule `json:"admin,omitzero" koanf:"admin"`
}
AuthAccess is the post-login allowlist. At least one of the three sign-in slices must be populated when auth is enabled — otherwise any account in the IdP can sign in, which is almost never what you want.
The sign-in slices (AllowedEmails/Domains/Groups) decide who may open the dashboard at all; everyone who passes them gets at least read-only access. Admin carries a second, write-access allowlist: a signed-in user who additionally matches it gets the "admin" role (full read + write). When Admin is empty every signed-in user is an admin, which preserves the pre-role behaviour where any allowed account had full access.
type AuthJWT ¶ added in v0.13.0
type AuthJWT struct {
// Audiences, when non-empty, restricts accepted tokens to those whose
// `aud` carries one of these values (RFC 8707). Empty accepts any token
// the issuer signed — fine when the gateway is the sole ingress and
// strips a client-supplied Authorization header.
Audiences []string `json:"audiences,omitempty" koanf:"audiences"`
}
AuthJWT tunes the "jwt" auth mode (auth.mode = "jwt"), where cheshmhayash validates an access-token JWT presented on every request instead of running its own login flow. The token is verified against auth.oidc.issuer.
type AuthMCPJWT ¶ added in v0.15.0
type AuthMCPJWT struct {
Enabled bool `json:"enabled" koanf:"enabled"`
}
AuthMCPJWT is the third /mcp auth path (besides static mcp_keys and the OIDC-verified mcp_oauth): accept a bearer JWT and read its identity claims WITHOUT verifying the token at all — no signature, issuer, audience, or expiry check. The claims still run through the auth.access allowlists to resolve a role, but anyone who can reach /mcp can forge them, so only enable this when a trusted gateway in front of cheshmhayash has already validated the token and untrusted clients can't hit the endpoint directly.
type AuthMCPOAuth ¶ added in v0.11.0
type AuthMCPOAuth struct {
Enabled bool `json:"enabled" koanf:"enabled"`
// Resource is the canonical URI of this MCP server (RFC 8707), e.g.
// "https://cheshmhayash.example.com/mcp". Advertised in the metadata
// document and used as the default accepted token audience.
Resource string `json:"resource" koanf:"resource"`
// AuthorizationServers overrides the metadata's authorization_servers
// list. Defaults to [auth.oidc.issuer] when empty.
AuthorizationServers []string `json:"authorization_servers,omitempty" koanf:"authorization_servers"`
// Audiences is the set of `aud` values accepted on inbound access
// tokens. Defaults to [Resource] when empty. Keycloak must be configured
// (audience mapper / client scope) to mint tokens carrying one of these.
Audiences []string `json:"audiences,omitempty" koanf:"audiences"`
// SkipAudienceCheck accepts any token the issuer signed, regardless of
// `aud` (signature, issuer and expiry are still enforced, and the
// subject still has to pass the access allowlist). This drops the
// RFC 8707 confused-deputy protection — only set it when the IdP can't
// mint resource audiences (e.g. a Keycloak client without an audience
// mapper) and the issuer is trusted for this realm.
SkipAudienceCheck bool `json:"skip_audience_check,omitempty" koanf:"skip_audience_check"`
}
AuthMCPOAuth turns the /mcp HTTP transport into an OAuth 2.0 resource server per the MCP authorization spec (2025-06-18): the server advertises Protected Resource Metadata (RFC 9728) pointing at the same OIDC issuer as the dashboard, and validates Keycloak-issued access-token JWTs presented as `Authorization: Bearer`. Requires auth.enabled (it reuses the OIDC provider and the auth.access allowlists). Static auth.mcp_keys keep working as a fallback alongside it. Off by default — backward-compatible.
type AuthOIDC ¶ added in v0.8.0
type AuthOIDC struct {
Issuer string `json:"issuer" koanf:"issuer"`
ClientID string `json:"client_id" koanf:"client_id"`
ClientSecret string `json:"-" koanf:"client_secret"`
RedirectURL string `json:"redirect_url" koanf:"redirect_url"`
Scopes []string `json:"scopes" koanf:"scopes"`
}
AuthOIDC holds the OpenID Connect provider coordinates for the login flow.
type AuthSession ¶ added in v0.8.0
type AuthSession struct {
Secret string `json:"-" koanf:"secret"`
TTLSeconds int `json:"ttl_seconds" koanf:"ttl_seconds"`
CookieName string `json:"cookie_name" koanf:"cookie_name"`
Secure bool `json:"secure" koanf:"secure"`
}
AuthSession configures the HMAC-signed cookie that carries the session.
func (AuthSession) TTL ¶ added in v0.8.0
func (a AuthSession) TTL() time.Duration
TTL is the cookie lifetime as a duration. Falls back to 12 h when unset.
type MCPKey ¶ added in v0.8.0
MCPKey is one bearer token accepted on the /mcp HTTP transport. Name is human-readable for log lines / revocation; Value is the secret.
type NATS ¶
type NATS struct {
Name string `json:"name" koanf:"name"`
URL string `json:"url" koanf:"url"`
CredsFile string `json:"creds_file,omitempty" koanf:"creds_file"`
User string `json:"user,omitempty" koanf:"user"`
// Password is redacted on the startup log; the JSON tag matters only
// for that single pretty-print.
Password string `json:"-" koanf:"password"`
RequestTimeoutMS int `json:"request_timeout_ms,omitempty" koanf:"request_timeout_ms"`
DiscoveryTimeoutMS int `json:"discovery_timeout_ms,omitempty" koanf:"discovery_timeout_ms"`
}
NATS describes one configured cluster connection.
func (NATS) DiscoveryTimeout ¶
DiscoveryTimeout is the deadline for multi-responder discovery requests (e.g. SERVER.PING), defaulted when unset.
func (NATS) RequestTimeout ¶
RequestTimeout is the per-request NATS deadline, defaulted when unset.
type Notify ¶ added in v0.6.0
type Notify struct {
Provider string `json:"provider" koanf:"provider"` // slack | mattermost | matrix
URL string `json:"-" koanf:"url"` // redacted in startup log
Channel string `json:"channel,omitempty" koanf:"channel"`
Username string `json:"username,omitempty" koanf:"username"`
}
Notify describes one outbound chat webhook. The provider field selects the JSON shape and target API.
type Settings ¶
type Settings struct {
Server Server `json:"server" koanf:"server"`
NATS []NATS `json:"nats" koanf:"nats"`
Notify []Notify `json:"notify,omitempty" koanf:"notify"`
Auth Auth `json:"auth" koanf:"auth"`
}
Settings is the fully-resolved runtime configuration (defaults → TOML → env), returned by Load and consumed by main.