Overview
Kayra is three concerns wired onto one gin engine by
apiserver.Build, each in its own
package-by-domain directory — no shared models/controllers split, no
layer that doesn’t own its own types, etcd persistence and HTTP handlers
together:
request → middleware.Authenticator (or SysadminGate) → route handler
│ │
authn + authz + oidc + crypto rbac / catalog
│ │
└───────────── internal/store ──────────┘
Configuration#
One kayra.yaml, two things resolved from it:
app:— flattened byconfig.AppConfig.ToVariablesand handed to infrapi/lib’s ownlibconfig.NewConfigFromMap/GetAppConfig, which still owns theINFRAPI_APP_*validation rules (required fields,oneof/fqdn/http_url/hostname_port): name, platform, region, listen address. Every package that needs “this instance’s own platform/region” (API registration addressing, the sysadmin group name) reads the resolvedAppConfig, never a request.- Everything else — Kayra’s own config: the
storage backend,
authentifications.<name>(how a bearer token is verified and whose claim is the user id) andauthorizations.<name>(LDAP or a dev fixture, how a user id resolves to attributes/groups).
See Getting started for a runnable pair of files.
Storage#
Everything — RBAC & Auth’s objects, the catalog
resources below, the PAT keypair, every cache — goes through one
store.Store interface: a real etcd cluster in
production, a directory of files for the dev: local: backend. One
Keys builder gives every package’s etcd layout a single source of truth,
and store.Store.Watch (etcd’s native MVCC watch, or a polling fallback
locally) is what lets a component react to changes instead of polling the
API.
Catalog#
The business domain: cluster-wide API registrations, per-tenant namespaces, and the subscriptions linking them — ported from the legacy Postgres/GORM tool, now etcd-backed. Split across three pages, since each has its own management story:
- API registrations — records declaring that an API group exists and who owns it; Kayra never implements the API itself.
- Namespaces — the legacy model’s “Tenant”.
- Subscriptions & reconciliation — the link between
them, plus
kayra reconciler, the controller that activates and reconciles everything above.
internal/catalog depends on rbac for exactly one
check (rbac.RequireClusterRBAC); rbac has no knowledge of catalog at all.
Authentication & authorization#
See RBAC & Auth for the full story: how a bearer token
(JWT or PAT) is verified and resolved to a user, how the privileged
$platform-core-sysadmin bootstrap credential is produced and checked, and
how Kayra’s own stored Group/Role/RoleBinding objects decide who can
manage what.
Operational processes#
Two independent invocations of the one binary, not one process doing both jobs:
kayra serve # the HTTP API
kayra reconciler # the catalog reconcile controller
See the CLI reference and Subscriptions & reconciliation for why they’re kept apart.