identityserver

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Jun 15, 2026 License: AGPL-3.0 Imports: 36 Imported by: 0

Documentation

Overview

Package identityserver is identity's embeddable public API. It lets a Go program import identity and mount it into an existing server instead of running the dedicated container.

Two mount surfaces are exposed, both backed by one service-layer wiring:

srv, err := identityserver.New(ctx, identityserver.OptionsFromEnv())
mux.Handle("/", srv.Handler())   // Connect (gRPC, gRPC-Web, Connect)
srv.RegisterGRPC(grpcServer)     // native registration on a *grpc.Server
srv.Start(ctx)                   // background workers (audit, sweeper, signer reload)
defer srv.Shutdown(ctx)

Handler returns the full middleware chain (CORS, auth, rate-limit, metrics, health, JWKS) wrapping the Connect handler — mount it on any HTTP/2 (or h2c) server. RegisterGRPC bridges identity's Connect service implementation onto a host *grpc.Server; the host owns the listener and any gRPC-side auth interceptors.

cmd/identity is a thin shim over this package: it calls New with OptionsFromEnv and serves Handler, so the container behaves identically to embedding identity over HTTP.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Migrate added in v0.15.0

func Migrate(opts Options) error

Migrate applies any pending Postgres schema migrations using opts.Config, then returns. It requires GATEWAY_POSTGRES_DSN (opts.Config.PostgresDSN) to be set.

This is the programmatic entry point behind the `identity migrate` subcommand. Embedders can call it before New/Start to migrate the schema as an explicit deploy step rather than via GATEWAY_POSTGRES_AUTO_MIGRATE. It is idempotent and safe to run from multiple instances concurrently (the runner holds a Postgres advisory lock).

Types

type Config

type Config = config.Config

Config is the full identity configuration, re-exported so embedding programs can build it field-by-field without importing internal packages. It is the same struct cmd/identity loads from the environment; OptionsFromEnv populates it the same way the container binary does.

type Options

type Options struct {
	// Config holds every env-driven setting (ports, tenant, JWT,
	// revocation mode, OAuth credentials, OTel, sweeper, etc.). Required.
	Config Config

	// Logger receives identity's structured logs. nil installs a no-op
	// logger; the container passes a zap production logger.
	Logger *zap.Logger

	// MetricsRegistry is where identity records its Prometheus RED
	// metrics. nil uses prometheus.DefaultRegisterer (what the container
	// wants). Tests pass an isolated registry to avoid collisions.
	MetricsRegistry prometheus.Registerer

	// Signer mints and verifies access tokens. nil builds the
	// Config.JWTSigner backend (file or kms_aws), including the dev
	// fallback key when no keys file is configured.
	Signer jwt.Signer

	// Repo and DB are the persistence adapters. They must be supplied
	// together: either both nil (New builds them from Config.RepoDriver)
	// or both set (New uses them and skips driver construction).
	Repo service.Repository
	DB   service.DB

	// EmailTransport delivers outbound mail. nil builds a transport from
	// the SMTP settings in Config (falling back to log-only).
	EmailTransport email.Transport

	// SMSSender delivers outbound SMS for phone verification. nil builds a
	// sender from the GATEWAY_SMS_* settings in Config (log-only when SMS
	// is disabled).
	SMSSender sms.Sender

	// OAuthRegistry holds the per-provider exchangers. nil builds one
	// from the OAuth client credentials in Config.
	OAuthRegistry *oauth.Registry

	// IDVProvider drives document/selfie identity verification. nil
	// builds the Config.IDVProvider backend (which may itself be
	// disabled, leaving the IDV RPCs Unimplemented).
	IDVProvider idv.Provider

	// CaptchaVerifier gates the unauthenticated auth endpoints. nil builds
	// the Config.CaptchaProvider backend (the no-op verifier when CAPTCHA
	// is disabled).
	CaptchaVerifier captcha.Verifier

	// DNSResolver is the TXT-lookup boundary VerifyDomain uses to confirm a
	// custom domain's ownership challenge. nil defaults to net.DefaultResolver
	// — the production behaviour. A host (or a full-stack test) supplies its
	// own resolver to verify domains without touching real DNS. Has effect
	// only on the postgres control-plane driver, where the DomainService is
	// wired; other drivers leave the domain RPCs Unimplemented.
	DNSResolver service.DNSResolver
}

Options is the programmatic form of the configuration plus the adapters identity needs to run. The zero value is not usable; supply at least a Config (via OptionsFromEnv, or a hand-built one) and either let New build the persistence/signer adapters from Config (the container path) or inject your own.

Two construction modes:

  • Env/container parity: take OptionsFromEnv() and tweak fields. New builds the EntDB/Postgres repository, the JWT signer, the WebAuthn service, the IDV provider, and OpenTelemetry from Config exactly as cmd/identity does.

  • Injected adapters: set Repo+DB (and optionally Signer, Passkeys, EmailTransport, OAuthRegistry, IDVProvider). New uses whatever is supplied and only builds the adapters left nil. This is how a host that already owns a database, or a test, mounts identity without a real EntDB.

func OptionsFromEnv

func OptionsFromEnv() Options

OptionsFromEnv loads Options from the environment exactly as the container binary does: it reads every GATEWAY_* variable into Config and leaves all adapter fields nil so New builds them from that Config. This keeps cmd/identity a thin shim and gives env-driven deployers an identical entry point.

type Server

type Server struct {
	// contains filtered or unexported fields
}

Server is a constructed, mountable identity service. Build it with New, expose it via Handler and/or RegisterGRPC, run its background workers with Start, and tear everything down with Shutdown.

func New

func New(ctx context.Context, opts Options) (*Server, error)

New assembles the identity service from opts. It builds the persistence, signer, WebAuthn, IDV and OpenTelemetry adapters that are not already injected, validates the configuration, and wires the service layer. It does NOT start background workers or bind any listener — call Start once you are ready to serve and Shutdown to drain.

ctx scopes the construction-time setup (EntDB dial, AWS config load, OTel exporter init); it is not retained.

func (*Server) Handler

func (s *Server) Handler() http.Handler

Handler returns the identity HTTP handler: the full middleware chain wrapping the Connect-RPC mux. It serves the Connect, gRPC, and gRPC-Web protocols, plus /health, /readyz and /.well-known/jwks.json. Mount it on any HTTP/2 (or h2c) server.

func (*Server) RegisterGRPC

func (s *Server) RegisterGRPC(reg grpc.ServiceRegistrar)

RegisterGRPC registers identity onto an existing *grpc.Server (any grpc.ServiceRegistrar). The host owns the listener and any gRPC-side interceptors. The registered service delegates to the same Connect service implementation Handler serves, so both surfaces share one wiring.

Note: the HTTP middleware chain (CORS, rate-limit, the JWT auth middleware that populates X-Authenticated-User-Id, health, JWKS) is HTTP-only. Over native gRPC the host is responsible for authentication — supply a server interceptor that verifies the bearer token and forwards identity's expected metadata (see docs/embedding.md).

func (*Server) Shutdown

func (s *Server) Shutdown(ctx context.Context) error

Shutdown drains the background workers and releases every resource New acquired (signer watcher, EntDB client, OTel exporter), in reverse order. It is safe to call without a preceding Start and safe to call more than once. The first non-nil release error is returned after all releases run.

func (*Server) Start

func (s *Server) Start(_ context.Context) error

Start launches the background workers: the async audit flusher, the expired-row sweeper, and (for the file signer) SIGHUP-driven key reload. It is idempotent. ctx is accepted for symmetry and future use; the workers manage their own lifetimes and stop on Shutdown.

Jump to

Keyboard shortcuts

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