config

package
v0.5.5 Latest Latest
Warning

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

Go to latest
Published: Jul 11, 2026 License: AGPL-3.0 Imports: 9 Imported by: 0

Documentation

Overview

Package config loads akari-server configuration.

The server is a container workload, so it reads its configuration from the environment by convention. (The akari client, by contrast, uses a config file and defines no environment variables of its own; see docs/DESIGN.md.)

Index

Constants

View Source
const (
	// DefaultAnalyticsSnapshotFreshness keeps programmatic Server construction
	// aligned with LoadServer.
	DefaultAnalyticsSnapshotFreshness = time.Minute
	// DefaultAnalyticsSnapshotStaleFor keeps programmatic Server construction
	// aligned with LoadServer.
	DefaultAnalyticsSnapshotStaleFor = 15 * time.Minute
	// DefaultAnalyticsSnapshotLimit keeps programmatic Server construction aligned
	// with LoadServer.
	DefaultAnalyticsSnapshotLimit = 256
	DefaultPasswordWorkers        = 2
	DefaultPasswordQueueDepth     = 32
	DefaultPasswordQueueTimeout   = 3 * time.Second
)
View Source
const (

	// DefaultOAuthRegistrationsPerHour is exported for programmatic Server
	// construction, which otherwise bypasses LoadServer's environment defaults.
	DefaultOAuthRegistrationsPerHour = 1000
)
View Source
const MachineEnvVar = "AKARI_MACHINE"

MachineEnvVar overrides the machine identity a client reports for its sessions. It is the only environment variable akari itself defines (the agent root overrides discovery honors belong to the agents). It wins over the config's machine field, which in turn wins over the OS hostname; see ResolveMachine.

Variables

This section is empty.

Functions

func DefaultClientPath

func DefaultClientPath() (string, error)

DefaultClientPath returns the platform-standard config file path: ~/.config/akari/config.toml on Linux, ~/Library/Application Support/akari/config.toml on macOS, %AppData%\akari\config.toml on Windows.

func NormalizePublicOrigin added in v0.5.5

func NormalizePublicOrigin(raw string) (string, error)

NormalizePublicOrigin turns an external URL into the exact origin browsers send in Origin. HTTP handlers use the same normalization for request headers, so default ports and host casing cannot create false mismatches. Rejecting paths and other URL components keeps the value usable as both the OAuth issuer and the CSRF trust boundary.

func ResolveMachine added in v0.2.7

func ResolveMachine(cfg Client, env func(string) string, hostname func() (string, error)) string

ResolveMachine determines the machine identity a client reports for its sessions. Ephemeral and containerized hosts (CI jobs, autoscaled workers, throwaway dev containers) each get a distinct one-off hostname, so a fleet of them otherwise pollutes the machine facet with thousands of single-use values. An explicit identity lets that fleet share one stable logical machine (for example "ci" or "sandbox-pool").

Precedence, highest first:

  1. the AKARI_MACHINE environment variable, for a per-run override without touching the config, the natural fit for ephemeral hosts, which set an env var far more easily than they write a config file;
  2. the machine field in the client config, set at login for a stable per-host or per-fleet name;
  3. the OS hostname, the historical default.

A blank env var or config value falls through rather than reporting an empty machine, and surrounding whitespace is trimmed. hostname is injected (pass os.Hostname) so the fallback is testable; its error is ignored exactly as the bare `machine, _ := os.Hostname()` call sites it replaces did.

func SaveClient

func SaveClient(path string, c Client) error

SaveClient writes the config to path (creating parent directories) with protected per-user permissions since it holds an API token. Unix grants only the owner; Windows also retains SYSTEM and local-administrator recovery access. The temporary file is protected at creation and atomically renamed, so a crash or write error cannot truncate or expose an existing config.

Types

type Client

type Client struct {
	// ServerURL is the base URL of the akari server, e.g. https://akari.example.
	ServerURL string `toml:"server_url"`
	// Token is an API token (ingest or full scope) used as a Bearer credential.
	Token string `toml:"token"`
	// Machine is the logical machine name reported for every session this client
	// uploads. Empty falls back to the OS hostname. Set it (at login or by hand)
	// to give a fleet of ephemeral or containerized hosts one stable identity
	// instead of leaking a distinct one-off hostname per run. AKARI_MACHINE
	// overrides it per run; see ResolveMachine.
	Machine string `toml:"machine"`
	// ExtraRoots are additional session directories to discover beyond each
	// agent's standard roots.
	ExtraRoots []ExtraRoot `toml:"extra_roots"`
	// Excludes are glob patterns of paths to skip during discovery, applied to
	// both `akari sync` and `akari watch`. Patterns match the full path with
	// forward slashes and `*`/`**` span separators (see discover.Excluder), so
	// `**/tmp/**` ignores any path with a `tmp` segment. Empty means discover
	// everything.
	Excludes []string `toml:"excludes"`
}

Client holds the akari client configuration. All of it lives in one TOML file at the platform per-user config location; the client keeps no other on-disk state and defines a single environment variable of its own (AKARI_MACHINE, see ResolveMachine).

func LoadClient

func LoadClient(path string) (Client, error)

LoadClient reads and validates the client config. An empty path uses DefaultClientPath. A missing file is a usable error directing the user to log in.

func ReadClient

func ReadClient(path string) (cfg Client, exists bool, err error)

ReadClient decodes the config without checking required values. It reports whether the file existed (a missing file is not an error: callers like login start from a blank config), but rejects malformed TOML and unknown keys. A misspelled exclusion or root setting must not silently weaken backup policy.

type ExtraRoot

type ExtraRoot struct {
	Agent string `toml:"agent"` // claude | codex | pi
	Path  string `toml:"path"`
	// FollowRootLink opts this root into resolving a symlink or, on Windows, a
	// directory junction at the root itself before walking, for when Path is
	// only reachable through such a link (for example a Windows user who
	// relocated their session directory with `mklink /J`). The default (false)
	// rejects a linked root outright with a clear error: the same closed
	// symlink policy that governs everything discovered inside the walk also
	// governs the root, so following it is an explicit opt-in, not something a
	// stray link should silently grant itself. This setting never weakens the
	// no-follow policy applied to paths found inside the walk.
	FollowRootLink bool `toml:"follow_root_link"`
}

ExtraRoot is a user-configured session directory for one agent.

type Server

type Server struct {
	// DatabaseURL is the Postgres connection string (AKARI_DATABASE_URL).
	DatabaseURL string
	// Listen is the address the HTTP server binds (AKARI_LISTEN), e.g. ":8080".
	Listen string
	// CookieSecure marks session cookies Secure. Defaults true; set
	// AKARI_COOKIE_INSECURE=1 for plain-HTTP local development.
	CookieSecure bool
	// PublicURL is the externally reachable base URL of the server (scheme and
	// host, no trailing slash), e.g. "https://akari.example.com". It is the OAuth
	// issuer and the base of every absolute URL the MCP authorization flow
	// advertises (the discovery documents, the authorize and token endpoints, the
	// MCP resource identifier). Read from AKARI_PUBLIC_URL, falling back to
	// AKARI_URL (which eph already exports for the dev stack). When neither is set,
	// it is empty and the OAuth handlers derive the base from each request's scheme
	// and Host header, which is correct for a single-origin deployment behind a
	// well-behaved proxy.
	PublicURL string
	// MCPResponseBudgetBytes caps the encoded CallToolResult body
	// (AKARI_MCP_RESPONSE_BUDGET_BYTES). The default is 8 MiB.
	MCPResponseBudgetBytes int
	// SweepInterval is how often the server reclaims orphaned CAS blobs
	// (AKARI_SWEEP_INTERVAL, a Go duration like "1h"). Defaults to 1h; set "0" to
	// disable the background sweep (for example to run it only via the subcommand).
	SweepInterval time.Duration
	// OGCacheTTL is how long a rendered Open Graph preview card is served from the
	// cache before the next request re-renders it (AKARI_OG_CACHE_TTL, a Go duration
	// like "1h"). A published overview's card is rendered lazily on first request and
	// cached; once it ages past this TTL a later request renders a fresh one in its
	// place. Defaults to 1h and must be positive (the card is always cached).
	OGCacheTTL time.Duration
	// OGCleanupInterval is how often the server sweeps expired preview cards from the
	// cache (AKARI_OG_CLEANUP_INTERVAL, a Go duration). Each pass deletes cards older
	// than OGCacheTTL, so a card for an overview nobody shares does not linger. It is
	// pure housekeeping: a live share re-renders its card on demand regardless.
	// Defaults to 24h; set "0" to disable the sweep.
	OGCleanupInterval time.Duration
	// ProxyAuthHeader is the request header a trusted reverse proxy sets to the
	// authenticated username (AKARI_PROXY_AUTH_HEADER, e.g.
	// "X-Auth-Request-Preferred-Username"). Setting it turns on proxy-header auth:
	// the server trusts the header's value as the signed-in user and provisions the
	// account on first sight. It is empty (disabled) by default, because trusting a
	// header is only safe when akari is reachable ONLY through the proxy that sets
	// it. Leave it unset for a direct deployment. See auth.go's proxyPrincipal and
	// the deployment notes in docs/development.md.
	ProxyAuthHeader string
	// ProxyAuthSecret, when set (AKARI_PROXY_AUTH_SECRET), is a shared secret the
	// proxy must echo in ProxyAuthSecretHeader for the identity header to be
	// trusted. It is defense in depth for when network isolation alone is not
	// enough: a client that reaches akari directly cannot forge an identity without
	// also knowing the secret. Empty means the identity header is trusted on
	// network isolation alone.
	ProxyAuthSecret string
	// ProxyAuthSecretHeader is the header carrying ProxyAuthSecret
	// (AKARI_PROXY_AUTH_SECRET_HEADER). Defaults to "X-Akari-Proxy-Secret". Only
	// consulted when ProxyAuthSecret is set.
	ProxyAuthSecretHeader string
	// SignalsSettleInterval is how often the parse worker's maintenance tick fires
	// (AKARI_SIGNALS_SETTLE_INTERVAL). The tick backstops the wake-driven rebuild
	// drain and grades sessions that settled between rebuilds: a rebuild grades a
	// session only once it is settled or terminal, so a session whose last rebuild
	// ran while it was live is graded here, once, after it has been idle past the
	// abandoned threshold. Defaults to 5m; set "0" to disable the tick (rebuilds
	// then run only on ingest wakes, and settle grading only via the subcommand).
	SignalsSettleInterval time.Duration
	// ParseWorkers is how many sessions the parse worker rebuilds concurrently
	// (AKARI_PARSE_WORKERS). Distinct sessions rebuild in parallel; two rebuilds
	// of one session serialize on its row locks. Defaults to 4.
	ParseWorkers int
	// InsightsRefreshInterval is how often the fleet /insights snapshot recomputes in
	// the background (AKARI_INSIGHTS_REFRESH_INTERVAL, a Go duration). Every trailing
	// window recomputes together in one pass, so the range views cannot drift apart.
	// Defaults to 1h; set "0" to disable the background loop, in which case the
	// snapshot computes once on first request and then only when a fleet reparse
	// completes.
	InsightsRefreshInterval time.Duration
	// RequestBudgetCapacity is the process-wide weighted capacity shared by
	// expensive public request classes (AKARI_REQUEST_BUDGET_CAPACITY). One unit is
	// approximately 8 MiB of bounded memory or an equivalent database work share.
	// Defaults to 16 and must be at least 12 so the heaviest class can run once.
	RequestBudgetCapacity int
	// RequestBudgetWaitTimeout bounds how long expensive work waits for admission
	// (AKARI_REQUEST_BUDGET_WAIT_TIMEOUT). Defaults to 5s. Requests that exceed it
	// receive a retryable 503 response.
	RequestBudgetWaitTimeout time.Duration
	// OAuthRegistrationsPerHour is the database-coordinated ceiling for successful
	// dynamic client registrations (AKARI_OAUTH_REGISTRATIONS_PER_HOUR). It applies
	// across every server replica and defaults to the abuse-only threshold 1000.
	OAuthRegistrationsPerHour int
	// AnalyticsSnapshotFreshness is how long a completed user or project analytics
	// snapshot is considered fresh (AKARI_ANALYTICS_SNAPSHOT_FRESHNESS). Requests
	// after this interval coalesce behind one refresh. Defaults to 1m.
	AnalyticsSnapshotFreshness time.Duration
	// AnalyticsSnapshotStaleFor is the additional interval an expired analytics
	// snapshot may be served when its refresh fails
	// (AKARI_ANALYTICS_SNAPSHOT_STALE_FOR). Defaults to 15m.
	AnalyticsSnapshotStaleFor time.Duration
	// AnalyticsSnapshotLimit bounds the process-local analytics snapshot cache
	// (AKARI_ANALYTICS_SNAPSHOT_LIMIT). Least-recently-used entries are evicted.
	// Defaults to 256.
	AnalyticsSnapshotLimit int
	// PasswordWorkers is the maximum number of request-triggered Argon2 hashes or
	// verifications that may run at once (AKARI_PASSWORD_WORKERS).
	PasswordWorkers int
	// PasswordQueueDepth bounds password requests waiting behind active workers
	// (AKARI_PASSWORD_QUEUE_DEPTH). A full queue fails closed without allocating
	// another waiter.
	PasswordQueueDepth int
	// PasswordQueueTimeout bounds how long admitted password work may wait for a
	// worker (AKARI_PASSWORD_QUEUE_TIMEOUT).
	PasswordQueueTimeout time.Duration
}

Server holds the akari-server runtime configuration.

func LoadServer

func LoadServer() (Server, error)

LoadServer reads server configuration from the environment, applying defaults and validating required values.

Jump to

Keyboard shortcuts

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