svcorg

package
v1.47.2 Latest Latest
Warning

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

Go to latest
Published: Jul 15, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package svcorg resolves — and memoizes — the organization a verified service token acts on behalf of (cloud-api → commerce per-org billing).

WHY THIS EXISTS (money-critical, incident 2026-07-04):

The service-token auth branch used to call org.GetOrCreate("Name=", slug) on EVERY request, on the caller's cancelable HTTP request context. Under concurrent load (many orgs, e2e first-touch of NEW orgs, the 15-min auto-recharge cron all sharing commerce's single SQLite writer), that read-then-maybe-create serialized behind the writer; when the wait exceeded cloud-api's request deadline the query returned "context canceled", the auth branch fell through to the legacy per-org-token path, tried to Peek the 64-hex service token as a JWT ("Invalid Segments"), and 401'd — so cloud-api's balance gate fail-secured to 402 and real customers could not run paid inference.

This package removes the per-request datastore hit from the steady state and decouples resolution from the caller's deadline:

  • CACHE: an LRU keyed by org slug with a short TTL. A hit does ZERO datastore work — the common path (org already exists) touches no SQLite at all.
  • SINGLEFLIGHT: a cache miss for a slug collapses concurrent resolvers into ONE datastore GetOrCreate, so a burst of first requests for a brand-new org (the e2e create-storm) performs exactly one create, not N contending writes.
  • DETACHED + BOUNDED: resolution runs on a fresh context.Background() with its OWN timeout, so a slow resolve fast-fails inside commerce instead of being canceled mid-create by an upstream deadline (which is what left the writer wedged and cascaded to the confusing 401).

It memoizes ONLY the (slug → *Organization) mapping. It does not change org derivation, permissions, or per-org isolation — the caller still scopes every downstream query by the returned org's Name. The money gate is untouched.

Index

Constants

This section is empty.

Variables

View Source
var ErrResolveFailed = errors.New("svcorg: could not resolve organization for service token")

ErrResolveFailed wraps any failure to resolve/provision the org for a verified service token. Callers MUST treat it as retryable (HTTP 503) — never as a bad credential — because the service token itself was already verified; only the backing store hiccuped.

Functions

func Invalidate

func Invalidate(slug string)

Invalidate drops a slug from the cache so the next Resolve re-reads it. Call after mutating an org's identity fields (Name/Enabled/Live) so a change is not masked by the TTL window. Safe to call for an absent slug.

func Resolve

func Resolve(slug string) (*organization.Organization, error)

Resolve returns the organization named slug for a VERIFIED service-token request, creating it if it does not yet exist. The slug MUST already be validated by the caller (non-empty, not bearer-shaped) — this function trusts it and never re-derives policy from it.

Steady state (slug cached, unexpired) does NO datastore work. A miss resolves under singleflight on a detached, bounded context so concurrent misses for the same slug share one GetOrCreate and a slow store fast-fails with ErrResolveFailed instead of blocking on the caller's deadline.

Types

This section is empty.

Jump to

Keyboard shortcuts

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