ThatAIguyA world of ideas

THE CONSCIOUSNESS ATLAS
Read. Experiment. Follow the evidence.

ConsciousnessLearn · Explore · Joseph Anady

Janady13/missionmatch / internal/platform/tenant/tenant.go

Source identity, revision, and recovered contents.

GitHub sourceSource text recovered

Source identity

FieldRecorded value
Source typeGitHub source
Original recordJanady13/missionmatch / internal/platform/tenant/tenant.go
DateNot specified in source
RepositoryJanady13/missionmatch
Revision9bde0f9a74b89d01980fa658e5253acda7528d0c
Branchper-tenant-routing
Path or archive memberinternal/platform/tenant/tenant.go
Original SHA-25631a64d002141d526f93ff67182b80530540e17601f6b80686c6699ee778d8828
Git blob SHAabeebac32108bbf1e4ad2717c3cd347d092bbb7b
Reading-copy SHA-25631a64d002141d526f93ff67182b80530540e17601f6b80686c6699ee778d8828

Original source ↗

Every recorded occurrence

These 3 records contain identical original source bytes. Their paths and revisions remain part of the archive.

Original recordBranch or archiveRevision / identifierOriginal location
Janady13/missionmatch / internal/platform/tenant/tenant.goper-tenant-routing9bde0f9a74b89d01980fa658e5253acda7528d0cOpen original
Janady13/missionmatch / internal/platform/tenant/tenant.godeploy-and-opsbdacd9d0b4d5998d25fc74bf4007f4c3ec538c7aOpen original
Janady13/missionmatch / internal/platform/tenant/tenant.goper-tenant-routing9bde0f9a74b89d01980fa658e5253acda7528d0cOpen original

Recovered source transcript

// Package tenant is the multi-tenancy correctness boundary. // // Tenant isolation is enforced by Postgres Row-Level Security, NOT by Go WHERE clauses. Every // tenant-scoped request runs inside a transaction whose `app.current_org_id` GUC is set // transaction-locally, so Postgres discards it at COMMIT/ROLLBACK and it can never leak to the next // request that reuses a pooled connection (the pgx-pool gotcha, see docs/STACK_DECISIONS.md §2). // // Two safeguards stack here: // - Go side: no validated org in context => RunInTenantTx refuses to run (fail closed). // - DB side: an unset GUC makes current_setting(...,true) NULL, so the RLS policy matches zero // rows (default deny). // // The org id MUST originate from a verified session/JWT claim resolved by auth middleware, never // from a client-supplied body, header, or query parameter. package tenant import ( "context" "errors" "fmt" "net/http" "github.com/google/uuid" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" ) // ErrNoTenant is returned when tenant-scoped DB work is attempted without a validated organization. var ErrNoTenant = errors.New("tenant: no organization_id in context (refusing to run unscoped query)") // ctxKey is an unexported context key so a client cannot spoof the org via a context-key collision. type ctxKey struct{} var orgKey = ctxKey{} // WithOrg stores the validated org id in ctx. Call this ONLY from auth middleware, with a value // taken from verified claims. func WithOrg(ctx context.Context, orgID string) context.Context { return context.WithValue(ctx, orgKey, orgID) } // OrgFromContext returns the validated org id and whether a non-empty one is present. func OrgFromContext(ctx context.Context) (string, bool) { v, ok := ctx.Value(orgKey).(string) return v, ok && v != "" } // principalCtxKey is a SEPARATE key type from ctxKey. Reusing ctxKey for the user would collide with // orgKey, because every empty struct value of the same type is equal, so the two context lookups // would return each other's value. A distinct type keeps the org and the principal independent. type principalCtxKey struct{} var principalKey = principalCtxKey{} // Principal is the authenticated actor resolved from a validated session: the user id and the role // used for authorization. Like the org, it MUST originate from auth middleware reading verified // session state, never a client supplied value. type Principal struct { UserID string Role string } // WithUser stores the validated principal in ctx. Call this ONLY from auth middleware. func WithUser(ctx context.Context, p Principal) context.Context { return context.WithValue(ctx, principalKey, p) } // UserFromContext returns the validated principal and whether one with a non-empty user id is // present. func UserFromContext(ctx context.Context) (Principal, bool) { p, ok := ctx.Value(principalKey).(Principal) return p, ok && p.UserID != "" } // Router resolves the leaf tenant DB for an organization in the database per tenant model: it acquires // that tenant's own pool (and a release the caller must invoke). The per tenant pool manager satisfies // it. A DB with a nil router is shared mode, where every request uses the one static Pool and tenant // isolation is Row Level Security; with a router the DB is per_tenant mode, where each request physically // routes to its tenant's database and RLS is defense in depth. type Router interface { Acquire(ctx context.Context, org uuid.UUID) (*DB, func(), error) } // DB wraps either a single pgxpool.Pool (shared mode, authenticating as the NOBYPASSRLS application role) // or a Router (per_tenant mode) that resolves the request's tenant pool. Pool is nil in per_tenant mode. type DB struct { Pool *pgxpool.Pool router Router } // New wraps a pool as a tenant-scoped DB (shared mode, or a leaf tenant DB the manager hands back). func New(pool *pgxpool.Pool) *DB { return &DB{Pool: pool} } // NewRouting builds a routing DB with no static pool: every access resolves the caller's tenant database // from the router using the validated org in context. This is how per_tenant mode reaches tenant data // while keeping every handler and RunInTenantTx call site unchanged. func NewRouting(r Router) *DB { return &DB{router: r} } // Close releases the underlying pool (a no op for a routing DB; the manager owns the tenant pools). func (db *DB) Close() { if db.Pool != nil { db.Pool.Close() } } // resolveLeaf returns the DB to actually run against for this request plus a release the caller MUST // invoke. In shared mode it is the DB itself (no op release). In per_tenant mode it acquires the tenant's // leaf DB by the validated org in context (fail closed when there is no validated org, so a request with // no org still reaches zero data). func (db *DB) resolveLeaf(ctx context.Context) (*DB, func(), error) { if db.router == nil { return db, func() {}, nil } orgStr, ok := OrgFromContext(ctx) if !ok { return nil, nil, ErrNoTenant } org, err := uuid.Parse(orgStr) if err != nil { return nil, nil, ErrNoTenant } return db.router.Acquire(ctx, org) } // Acquire exposes the request's leaf DB (and a release the caller MUST invoke) for the readers that touch // a pool directly: the global reference catalog reads and the stored skill matcher. In shared mode it is // a no op wrapper over the single pool; in per_tenant mode it routes to the tenant's own database. func (db *DB) Acquire(ctx context.Context) (*DB, func(), error) { return db.resolveLeaf(ctx) } // RunInTenantTx is THE correctness boundary. It: // 1. requires a validated org id (fail-closed: no org => no query, before the pool is touched), // 2. opens a transaction on a single pooled connection, // 3. sets app.current_org_id transaction-locally via set_config(..., is_local=true) so it // auto-resets at COMMIT/ROLLBACK and cannot leak across the pool, // 4. runs fn against that same tx, then commits (rolling back on any error). // // All tenant-scoped repository work MUST go through this method. func (db *DB) RunInTenantTx(ctx context.Context, fn func(ctx context.Context, tx pgx.Tx) error) (err error) { orgID, ok := OrgFromContext(ctx) if !ok { return ErrNoTenant } // In per_tenant mode this routes to the org's own database (and refuses without a validated org); // in shared mode leaf is this DB and release is a no op. The org GUC is still set below either way, // so RLS stays armed as defense in depth inside the tenant database. leaf, release, err := db.resolveLeaf(ctx) if err != nil { return err } defer release() if leaf.Pool == nil { return ErrNoTenant } tx, err := leaf.Pool.Begin(ctx) if err != nil { return fmt.Errorf("begin tenant tx: %w", err) } // Rollback is a no-op once Commit succeeds; this guarantees the connection is released on every path. defer func() { _ = tx.Rollback(ctx) }() // Transaction-local GUC, parameterized (no SQL-injection surface). is_local=true is what makes // this safe on a pooled connection. if _, err = tx.Exec(ctx, "SELECT set_config('app.current_org_id', $1, true)", orgID); err != nil { return fmt.Errorf("set tenant guc: %w", err) } if err = fn(ctx, tx); err != nil { return err // defer rolls back } if err = tx.Commit(ctx); err != nil { return fmt.Errorf("commit tenant tx: %w", err) } return nil } // Middleware resolves the org id from an already-validated request and stores it in context. // resolveOrg MUST read verified session/JWT claims, never a raw client value. A request whose org // cannot be resolved is rejected with 403 before any downstream handler runs. func Middleware(resolveOrg func(*http.Request) (string, bool)) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { orgID, ok := resolveOrg(r) if !ok { http.Error(w, "forbidden", http.StatusForbidden) return } next.ServeHTTP(w, r.WithContext(WithOrg(r.Context(), orgID))) }) } }

Search equations, builds, manuscript text, and recovered sources.