Skip to content

Strip API Surface

Strip API Surface

Strip is a Fiber HTTP server that renders Templ pages and serves HTMX-style JSON fragments. It has no direct DB writes for domain entities — every business read or mutation is forwarded to sirloin over gRPC.

Topology

flowchart LR
Browser -->|HTTPS| Strip[Strip Fiber<br/>:8080]
Strip -->|Clerk SDK / cookie| Clerk[(Clerk)]
Strip -->|gRPC| Sirloin[(sirloin StripService<br/>v5)]
Strip -->|HTTPS| OpenRouter[(OpenRouter LLM)]
Strip -->|HTTPS| Brisket[(brisket links)]

See apps/strip/cmd/app/main.go startFiberServer (line 330+).

Middleware Stack (in order)

Registered in cmd/app/main.go:

  1. requestid.New() — request ID for trace correlation.
  2. recover.New(EnableStackTrace: true) — panic recovery, returns 500.
  3. helmetMiddlewareForStage — security headers (CSP varies by stage).
  4. limiter.New (globalRateLimitMax) — IP-keyed global rate limit. Asset paths (/assets, /assets/...) are skipped via shouldSkipGlobalRateLimit.
  5. compress.New — gzip/brotli on dynamic responses.
  6. Static file serving for /assets.

A stricter authLimiter is layered onto /login, /auth/refresh, and /auth/clerk/callback.

Auth Surface

Auth is enforced by two middlewares (apps/strip/internal/app/middleware/):

  • AuthMiddleware.RequireAuth — verifies a Clerk session cookie or __session token; populates c.Locals("userId" | "userEmail" | "sessionToken").
  • AuthorizationMiddleware.RequirePermission(perm) — RBAC, fails with 403. HTMX requests get a JSON body + HX-Reswap: none, otherwise the forbidden Templ page.

Two dev-only bypass paths exist and emit SECURITY WARNING logs:

  • X-Auth-Bypass: <uuid> header (or ?auth=<uuid>) matching STRIP_AUTH_BYPASS_UUID.
  • Stage == development with clerkService == nil.

Permission catalog (internal/app/authorization/authorization.go): view:dashboard, view:users, manage:credits, view:characters, create:character, update:character, delete:character, manage:nsfw, view:media, delete:media, view:audit_logs, view:dataset, view:examples, create:users, manage:roles, manage:admins.

Public Routes

MethodPathHandlerNotes
GET/healthinlineliveness, no auth
GET/loginHandleLoginClerk login page
POST/loginHandleLoginPostauthLimiter
POST/auth/refreshHandleRefreshTokenauthLimiter
POST/auth/clerk/callbackHandleClerkCallbackauthLimiter
GET/sso-callbackHandleSSOCallback
GET/createRootHandlerredirects per session state

Protected Pages (RequireAuth)

PathHandlerExtra perm
GET /dashboardHandleDashboard
GET /ask-stripHandleAskStripview:audit_logs
GET /usersHandleUsers
GET /charactersHandleCharactersPage
GET /dataset-gallery[/load-more]HandleDatasetGallery
GET /media[/load-more]HandleListMedia
GET /media/gallery[/load-more]HandleMediaGallery
GET /popular-examples[/load-more]HandlePopularExamplesGallery
GET /shop-vi[/load-more]HandleShopVIListing
GET /auditlogsHandleAuditLogsview:audit_logs
GET /rolesHandleRolesPagemanage:roles
DELETE /api/media/:idHandleDeleteMediadelete:media
POST /logoutHandleLogout

Protected JSON / HTMX API (/api/*, RequireAuth)

MethodPathHandlerPerm
GET/api/auth/mcp-tokenHandleMCPToken
GET/api/users/searchHandleUserSearch
GET/api/command-palette/searchHandleCommandPaletteSearch
GET/api/search/previewHandleSearchPreview
GET/api/activity-feedHandleActivityFeed
POST/api/ask-strip/support-briefHandleAskStripSupportBriefview:audit_logs
POST/api/ask-strip/chatHandleAskStripChatview:audit_logs
GET/api/users/:idHandleUserDetails
GET/api/users/:id/panelHandleUserPanel
POST/api/users/:id/creditsHandleAddCreditsmanage:credits
POST/api/users/:id/charactersHandleCreateCharactercreate:character
POST/api/users/createHandleCreateClerkUsercreate:users
GET/api/characters/:idHandleCharacterDetails
GET/api/characters/:id/panelHandleCharacterPanel
POST/api/characters/:id/updateHandleUpdateCharacterupdate:character
POST/api/characters/:id/bypass-onboarding-checksHandleBypassCharacterOnboardingChecksupdate:character
DELETE/api/characters/:idHandleDeleteCharacterdelete:character
GET/api/media/:id/panelHandleMediaPanel
GET/api/auditlogs/:idHandleAuditLogDetailsview:audit_logs
GET/api/rolesHandleListRolesmanage:roles
POST/api/rolesHandleSetRolemanage:roles
DELETE/api/roles/:userIdHandleDeleteRolemanage:roles

Templ Pages

Templ files render every protected page above. They live under apps/strip/internal/app/strip/templates/ and are compiled by templ generate into *_templ.go siblings. The strip Fiber handlers call templates.<Page>(...).Render(ctx, c) rather than c.Render. See services/strip-datatable/ and services/strip-filters/ for the shared render primitives.

Downstream gRPC Calls

Strip embeds the generated client at apps/strip/internal/pkg/pb/sirloin/v5/. The proto contract is proto/sirloin/v5/strip.proto, service sirloin.v5.StripService. RPCs called by handlers include:

  • StripListUsers, StripUpdateUser
  • StripListCharacters, StripCreateCharacter, StripUpdateCharacter, StripDeleteCharacter, StripBypassCharacterOnboardingChecks
  • StripListMedia, StripFailMedia
  • StripListPopularExamples, StripListPopularCategories
  • StripListDatasetImages
  • StripLogAudit, StripListAuditLogs, StripGetAuditLog
  • StripGetUserRole, StripListUserRoles, StripSetUserRole, StripDeleteUserRole (proto/sirloin/v5/strip.proto:33-36)
  • StripCreateClerkUser (proto/sirloin/v5/strip.proto:39)
  • StripFoxy360CreateThread, StripFoxy360SendMessage, StripFoxy360GetRun, StripFoxy360ListMessages, StripFoxy360ListArtifacts (proto/sirloin/v5/strip.proto:42-46)
  • StripGetDashboardStats, StripGetSchema, StripRunReadonlyQuery (proto/sirloin/v5/strip.proto:28-30)
  • StripListAvailableCharacters (proto/sirloin/v5/strip.proto:49). Credits surface as fields on StripListUsers / character responses (credits_min, remaining_credits, standard_credits, full_access_credits) — no dedicated credits RPC.

The keepalive client is created in cmd/app/main.go (grpcKeepaliveTime=30s, grpcKeepaliveTimeout=10s) and reused for the process lifetime.