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 ¶
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.
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
// NativeOAuthProjects is the control-plane project-by-id lookup
// NativeOAuthLogin uses to validate a product→project id. Non-nil ONLY for
// the postgres driver; nil on drivers without a control plane, where native
// login accepts only the product that resolves to the default project.
NativeOAuthProjects service.NativeOAuthProjectStore
// 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
// NativeOAuthVerifier verifies native mobile-SDK ID tokens for
// NativeOAuthLogin. May be nil — in that case New builds one from config
// via buildNativeOAuthVerifier (which returns nil, leaving the RPC
// disabled, unless GATEWAY_NATIVE_OAUTH_ENABLED and audiences are set).
// Tests inject a verifier pointed at a mock JWKS through this override,
// mirroring OAuthRegistry.
NativeOAuthVerifier *oauth.NativeVerifier
// 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.