Documentation
¶
Overview ¶
Package iam exposes an in-process entry point for the Hanzo IAM server, mirroring the shape used by github.com/hanzoai/tasks/pkg/tasks.
Embed lets a parent binary (e.g. a fused `hanzo` daemon that runs base + iam + kms + tasks together) boot the IAM Beego server in the same address space, reuse its http.Handler, and shut it down via context. The standalone iamd binary is now a thin wrapper around Embed plus signal handling.
Beego carries non-trivial global state (web.BeeApp, sync.Once init hooks, beego.AppPath). For that reason Embed is documented as safe to call AT MOST ONCE per process. A second call returns ErrAlreadyEmbedded — the parent should reuse the original handle.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrAlreadyEmbedded = errors.New("iam.Embed: already embedded in this process")
ErrAlreadyEmbedded is returned by a second Embed call in the same process. Beego's web.BeeApp is a singleton; multiple Embeds would share state in confusing ways.
Functions ¶
This section is empty.
Types ¶
type EmbedConfig ¶
type EmbedConfig struct {
// DataDir is where IAM persists its Base/SQLite database.
// Empty → "/data/iam" (production default).
DataDir string
// HTTPAddr is the bind address for the HTTP server.
// Empty → ":8000". Use ":0" for an ephemeral port (tests).
HTTPAddr string
// JWTKeySource is the JWKS URL used when IAM acts as a relying
// party (e.g. to validate inbound service tokens). Empty →
// "https://hanzo.id/.well-known/jwks". Stored as env var
// IAM_JWT_KEY_SOURCE so downstream config readers see it.
JWTKeySource string
// AppConfPath is an optional absolute path to a Beego app.conf.
// Empty → Beego picks up ./conf/app.conf relative to the binary,
// matching the standalone iamd behaviour.
AppConfPath string
// SkipListen, when true, runs the Beego bootstrap but does NOT
// bind a TCP listener. Use this when the parent binary serves the
// returned HTTPHandler() over its own listener (e.g. mounted
// behind hanzoai/gateway). Tests use this flag.
SkipListen bool
// Logger is the structured log target. nil → slog.Default().
Logger *slog.Logger
// ShutdownTimeout caps how long Stop will wait for in-flight
// requests to drain. 0 → 10s.
ShutdownTimeout time.Duration
}
EmbedConfig configures the in-process IAM server.
Zero values resolve to production-safe defaults that match the canonical iamd container image (DataDir=/data/iam, HTTPAddr=:8000).
type Embedded ¶
type Embedded struct {
// contains filtered or unexported fields
}
Embedded is the handle to a running in-process IAM server.
func Embed ¶
func Embed(ctx context.Context, cfg EmbedConfig) (*Embedded, error)
Embed boots the IAM Beego server in-process and returns a handle.
Embed is safe to call AT MOST ONCE per process. A second call returns ErrAlreadyEmbedded.
The provided ctx is used for cancellation; if ctx is cancelled before Stop is called, Embed will trigger a graceful shutdown automatically.
func (*Embedded) HTTPAddr ¶
HTTPAddr returns the bound listen address. Returns "" when SkipListen=true.
func (*Embedded) HTTPHandler ¶
HTTPHandler returns the Beego http.Handler. The fused binary mounts this behind its own listener (e.g. hanzoai/gateway).
func (*Embedded) Stop ¶
Stop gracefully shuts down the IAM server. Idempotent.
Stop does NOT clear the singleton lock — Beego's process-globals (logger registration, flag registration, init hooks) are not reset by Stop, so a fresh Embed in the same process would still panic. The "one Embed per process" contract is enforced for the lifetime of the process, not the lifetime of the running server.