app

package
v1.6.0 Latest Latest
Warning

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

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

Documentation

Overview

Package app builds the identity service HTTP handler from injected dependencies. It is shared by the production binary (cmd/identity) and the integration test harness (tests/integration), so that both exercise the exact same wiring code: middleware chain, audit logger, service layer, and Connect-RPC handler registration.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Built added in v0.9.0

type Built struct {
	Handler        http.Handler
	ConnectHandler *identityconnect.IdentityHandler
	// contains filtered or unexported fields
}

Built is the result of New: the assembled identity service, ready to mount and run. It separates construction (no goroutines) from the background-worker lifecycle so the embedding consumer — the container binary or a host server — controls when workers run via Start/Stop.

  • Handler is the full middleware chain wrapping the Connect-RPC handler; mount it on any HTTP/2 (or h2c) server.
  • ConnectHandler is the Connect service implementation. The native gRPC bridge registers against this so both mount surfaces share one service-layer wiring.
  • Start launches the background workers (audit flusher, sweeper); it is idempotent. Stop drains them; safe to call multiple times.

func New

func New(deps Deps) (*Built, error)

New assembles the identity service from injected dependencies. It builds the middleware chain, the Connect-RPC service handler, and the background workers — but does NOT start the workers; the caller starts them with (*Built).Start once it is ready to serve, and drains them with (*Built).Stop on shutdown. Configuration errors (e.g. invalid CORS origins) are returned before any worker is constructed.

func (*Built) Start added in v0.9.0

func (b *Built) Start()

Start launches the background workers. Calling it more than once is a no-op. It is separate from New so the audit flusher and sweeper goroutines never start until the consumer is ready to run them.

func (*Built) Stop added in v0.9.0

func (b *Built) Stop()

Stop drains the background workers. Safe to call multiple times and safe to call without a preceding Start.

type Deps

type Deps struct {
	Config   *config.Config
	Logger   *zap.Logger
	Signer   jwt.Signer
	Repo     service.Repository
	DB       service.DB
	Passkeys *passkeys.WebAuthnService
	TOTPKey  []byte

	// ProjectResolver resolves a request's control-plane project from its
	// credential key or Host header (see middleware.NewProjectResolver).
	// Non-nil only for the postgres driver; when nil the project-resolution
	// middleware pins every request to the configured default project. The
	// production binary wires the postgres control-plane store; tests pass
	// a fake or nil.
	ProjectResolver service.ProjectResolver

	// TenantAutoFormer auto-forms a company tenant from a new user's email
	// domain at signup. Non-nil only for the postgres driver (the only one
	// with a governance plane); when nil, signup does not auto-form tenants.
	TenantAutoFormer service.TenantAutoFormStore

	// DomainStore, TenantStore and MembershipStore back the tenant
	// domain-verification RPCs (CreateDomain / VerifyDomain /
	// ListTenantDomains). All three are non-nil ONLY for the postgres
	// driver (the only one with a governance plane); when any is nil the
	// DomainService is not constructed and those RPCs return Unimplemented.
	DomainStore     service.DomainStore
	TenantStore     service.TenantStore
	MembershipStore service.MembershipStore

	// InvitationStore backs the tenant-invitation RPCs
	// (CreateTenantInvitation / AcceptTenantInvitation /
	// ListTenantInvitations). Non-nil ONLY for the postgres driver; when nil
	// (together with the membership/tenant stores) the MembershipService is
	// not constructed and the membership RPCs return Unimplemented.
	InvitationStore service.InvitationStore

	// ControlPlaneStore is the project write-store backing the control-plane
	// admin RPCs (AdminCreateProject and friends). Non-nil ONLY for the
	// postgres driver; when nil (together with the tenant/membership stores)
	// the ControlPlaneAdminService is not constructed and the admin RPCs
	// return Unimplemented. Even when wired, the surface stays disabled until
	// Config.AdminAPISecret is set.
	ControlPlaneStore service.ControlPlaneProjectStore

	// PlatformAdminStore backs the zero-config first-admin bootstrap
	// (CreateFirstPlatformAdmin). Non-nil ONLY for the postgres driver; when
	// nil the bootstrap RPC returns Unimplemented. Unlike the other admin
	// RPCs the bootstrap is NOT gated on Config.AdminAPISecret — it is the
	// one path a fresh deployer uses before any secret is configured, and it
	// self-secures by closing once any admin exists.
	PlatformAdminStore service.PlatformAdminStore

	// LoginPolicyStore backs the operator LoginPolicy-authoring admin RPCs
	// (UpsertLoginPolicy / GetLoginPolicy / DeleteLoginPolicy) — the write
	// side of the policy the login path enforces. Non-nil ONLY for the
	// postgres driver; when nil those RPCs return Unimplemented.
	LoginPolicyStore service.LoginPolicyStore

	// LoginGovernance is the read-side bundle the login path consults to
	// enforce a claimed tenant's LoginPolicy. Non-nil only for the postgres
	// driver (the only one with a governance plane); when nil, login imposes
	// no policy restriction.
	LoginGovernance *service.LoginGovernance

	// DNSResolver is the TXT-lookup boundary VerifyDomain uses to confirm a
	// domain's ownership challenge. nil defaults to net.DefaultResolver
	// (production). The embedding API threads a custom resolver through here
	// so a full-stack test can publish the deterministic challenge without
	// touching real DNS.
	DNSResolver service.DNSResolver

	// TOTPRecoveryPepper is the HMAC-SHA-256 key used to hash and
	// verify recovery codes. Must be >= totp.MinRecoveryPepperBytes
	// bytes long; the binary refuses to start otherwise.
	TOTPRecoveryPepper []byte

	// EmailTransport delivers outbound mail. If nil, New constructs a
	// transport from cfg via buildEmailTransport (so production code
	// only needs to populate this when a test wants a custom recorder).
	EmailTransport email.Transport

	// SMSSender delivers outbound SMS for phone verification. If nil, New
	// constructs a sender from cfg via buildSMSSender — a log-only sender
	// when GATEWAY_SMS_ENABLED is false, otherwise the configured
	// provider (Twilio / SNS / Azure).
	SMSSender sms.Sender

	// OAuthRegistry holds the per-provider Exchangers used for OAuth
	// login. May be nil — in that case OAuthLogin returns
	// ErrOAuthDisabled. When nil, New builds a registry from the
	// config's GATEWAY_*_CLIENT_ID/SECRET env vars (only providers
	// with both credentials set are registered).
	OAuthRegistry *oauth.Registry

	// IDVProvider drives identity-verification (document + selfie).
	// May be nil — in that case BeginIdentityVerification returns
	// CodeUnimplemented. Production deployments wire an Azure or
	// other real provider; tests typically pass an idv.StubProvider.
	IDVProvider idv.Provider

	// CaptchaVerifier gates the unauthenticated auth endpoints. May be
	// nil — in that case New builds one from Config (the no-op verifier
	// when CAPTCHA is disabled). Tests inject a fake to drive pass/fail
	// without network calls.
	CaptchaVerifier captcha.Verifier

	// MetricsRegistry is the Prometheus registry the server records
	// RED metrics into. May be nil — in that case the default
	// registry is used (which is what production wants). Tests pass an
	// isolated registry so they can read counters without colliding
	// with other tests in the same process.
	MetricsRegistry prometheus.Registerer
}

Deps groups the injectable dependencies required to build the identity HTTP handler. It lets the production main.go pass real adapters and the integration test harness pass in-memory fakes, without duplicating the wiring code.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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