Authoritative reference for sirloin configuration. Source of truth is
apps/sirloin/internal/app/config/config.go and the SirloinXxx constants
under apps/sirloin/internal/pkg/env/. Cross-cuts:
deployment-env for staging and Railway,
security-model for secret handling,
auth-model for token issuers.
All vars are namespaced SIRLOIN_*. Defaults shown match config.go. “Source”
indicates where the value typically comes from in production.
Core
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_PORT | no | :50051 | Railway / compose | gRPC + gRPC-Web listen address |
SIRLOIN_STAGE | yes | — | Railway | development | sandbox | production; gates dev-only RPCs |
SIRLOIN_URL | yes | — | Railway | Public URL of sirloin (used in webhooks, links) |
SIRLOIN_GRPC_HOST | n/a | — | — | Not read by sirloin itself; consumed by clients (e.g. STRIP_SIRLOIN_GRPC_HOST in apps/strip/internal/pkg/env/variables.go:13) |
SIRLOIN_GRPC_URL | n/a | — | — | Not read by sirloin itself; consumed by clients pointing at sirloin (see compose env for brisket/round services) |
SIRLOIN_TESTER_IDS | no | — | Railway | Comma-separated user IDs given test perks |
SIRLOIN_NSFW_PROCESSOR_TESTER_IDS | no | - | Railway | Comma-separated NSFW processors demo accounts |
Database
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_DATABASE_URL | yes | — | Neon (prod), local Postgres (rump) in compose | BUN ORM Postgres DSN; missing → startup error |
SIRLOIN_DATABASE_POOLED_URL | no | falls back to SIRLOIN_DATABASE_URL | Neon | Pooled runtime DSN (split read path); when set, used as DatabaseRuntimeURL (apps/sirloin/internal/app/config/config.go:144, :449) |
Local compose default: postgres://sirloin:sirloin@rump:5432/rump?sslmode=disable
(see docker-compose.yml).
Auth (Clerk)
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_CLERK_API_KEY | yes | — | secret | Verify Clerk session JWTs (see auth-model) |
Brain & Round (gRPC peers)
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_BRAIN_HOST | yes | brain:3000 (compose) | Railway | gRPC dial target for brain |
SIRLOIN_BRAIN_API_KEY | yes | — | secret | Static token for brain |
SIRLOIN_ROUND_HOST | yes | round:8080 (compose) | Railway | gRPC dial target for round |
Flank (legacy / being retired)
Under T-Bone the workflow engine and storage moved into brain, which now owns
workflows, adapters, secrets, and executions over HTTP; flank is now only the
visual workflow editor pointed at brain. The sirloin-hosted
FlankStorageService/FlankMCP surfaces these variables configure are superseded.
TODO(@law): drop these vars once the legacy flank storage/MCP wiring is removed.
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_FLANK_HOST | optional | — | Railway | (legacy) Flank gRPC host; empty disables flank execution |
SIRLOIN_FLANK_SERVICE_TOKEN | optional | — | secret | (legacy) Auth for FlankStorageService and FlankResolveSecrets |
FLANK_ENCRYPTION_KEY | optional | — | secret | (legacy) Encrypts flank secret payloads at rest in sirloin; empty disables FlankStorageService |
SIRLOIN_FLANK_MCP_ENABLED | no | false | Railway | (legacy) Enables flank MCP route on port 8086 |
SIRLOIN_FLANK_MCP_BASE_PATH | no | /flank | Railway | (legacy) Mount path for flank MCP |
Chargebee
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_CHARGEBEE_API_KEY | yes (prod) | — | secret | Chargebee API key |
SIRLOIN_CHARGEBEE_SITE | yes (prod) | — | Railway | Chargebee site name (<site>.chargebee.com) |
SIRLOIN_CHARGEBEE_WEBHOOK_USERNAME | recommended | — | Railway | Basic auth user for webhook intake |
SIRLOIN_CHARGEBEE_WEBHOOK_PASSWORD | recommended | — | secret | Basic auth pw; if either missing, webhooks rejected |
Primer
Primer environment is auto-detected from API key prefix.
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_PRIMER_API_KEY | optional | — | secret | Empty → Primer checkout disabled |
SIRLOIN_PRIMER_WEBHOOK_SECRET | recommended | — | secret | HMAC secret; empty → Primer webhooks rejected |
Storage (S3-compatible)
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_S3_ENDPOINT | yes | — | Railway | S3 endpoint (Cloudflare R2 in prod) |
SIRLOIN_S3_ACCESS_KEY | yes | — | secret | — |
SIRLOIN_S3_SECRET_KEY | yes | — | secret | — |
SIRLOIN_S3_BUCKET | yes | — | Railway | Object bucket |
SIRLOIN_S3_HMAC_KEY | yes | — | secret | Signed-URL HMAC |
SIRLOIN_S3_PUBLIC_URL | yes | — | Railway | Public CDN base |
SIRLOIN_IMAGE_CGI_URL | optional | — | Railway | On-the-fly image transform endpoint |
KYC (Ondato)
All optional; required only when KYC is enabled.
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_ONDATO_CLIENT_ID | conditional | — | secret | OAuth client id |
SIRLOIN_ONDATO_CLIENT_SECRET | conditional | — | secret | OAuth secret |
SIRLOIN_ONDATO_CLIENT_SETUP_ID | conditional | — | Railway | Setup id |
SIRLOIN_ONDATO_AUTH_URL | conditional | — | Railway | OAuth token endpoint |
SIRLOIN_ONDATO_KYC_BASE_URL | conditional | — | Railway | KYC API |
SIRLOIN_ONDATO_IDV_API_BASE_URL | conditional | — | Railway | IDV API |
SIRLOIN_ONDATO_REDIRECT_BASE_URL | conditional | — | Railway | User-facing redirect target |
SIRLOIN_ONDATO_SCOPES | conditional | — | Railway | Space-separated scopes |
SIRLOIN_ONDATO_WEBHOOK_SECRET | conditional | — | secret | Shared secret for /webhooks/ondato/verification-status |
Email
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_EMAIL_HOST | yes | — | Railway | SMTP host |
SIRLOIN_EMAIL_PORT | yes | — | Railway | SMTP port |
SIRLOIN_EMAIL_USER | yes | — | secret | SMTP user |
SIRLOIN_EMAIL_PASSWORD | yes | — | secret | SMTP password |
SIRLOIN_EMAIL_SENDER | yes | — | Railway | From header |
Analytics & Marketing
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_POSTHOG_API_KEY | recommended | — | secret | Server-side PostHog |
SIRLOIN_KLAVIYO_API_KEY | optional | — | secret | Klaviyo events |
SIRLOIN_CINDER_API_KEY | optional | — | secret | Cinder fraud signals |
SIRLOIN_GOOGLE_CREDENTIALS | optional | — | secret | Google services creds |
Observability
OpenTelemetry is enabled when SIRLOIN_AXIOM_TOKEN is set. See
observability.
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_AXIOM_TOKEN | recommended | — | secret | Axiom API token; enables OTLP export |
SIRLOIN_AXIOM_DATASET | yes if token set | — | Railway | Traces + logs dataset (axiom:events:v1) |
SIRLOIN_AXIOM_METRICS_DATASET | yes if token set | — | Railway | Metrics dataset (otel:metrics:v1) |
SIRLOIN_SENTRY_ENABLED | no | false | Railway | Toggle Sentry init; only TRUE (case-insensitive) enables it (apps/sirloin/internal/pkg/env/env.go:30, apps/sirloin/internal/app/config/config.go:206) |
Slack Notifications
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_SLACK_WEBHOOK_URL_PAYMENTS | optional | — | secret | Payment notifications |
SIRLOIN_SLACK_WEBHOOK_URL_SUBSCRIPTIONS | optional | — | secret | Subscription notifications |
SIRLOIN_SLACK_WEBHOOK_URL_NEW_CHARACTERS | optional | — | secret | Character-creation feed |
SIRLOIN_SLACK_WEBHOOK_URL_CS_REPORTS | optional | — | secret | CS-team reports |
SIRLOIN_SLACK_WEBHOOK_URL_ITEAM_ALERTS | optional | — | secret | Internal-team alerts |
Monitor Probe
| Var | Required | Default | Source | Purpose |
|---|
SIRLOIN_MONITOR_ENABLED | no | false | Railway | Synthetic generation probe |
SIRLOIN_MONITOR_GENERATION_INTERVAL | no | 2m | Railway | Probe trigger cadence |
SIRLOIN_MONITOR_CHECK_INTERVAL | no | 30s | Railway | Probe poll cadence |
SIRLOIN_MONITOR_MAX_PENDING_AGE | no | 10m | Railway | Pending-job age threshold |
Foxy360 MCP Runtime
Disabled by default. Required only when SIRLOIN_FOXY360_ENABLED=true.
| Var | Default | Purpose |
|---|
SIRLOIN_FOXY360_ENABLED | false | Master switch |
SIRLOIN_FOXY360_HTTP_PORT | :8086 | MCP HTTP listen |
SIRLOIN_FOXY360_BASE_PATH | /foxy360 | Mount path |
SIRLOIN_FOXY360_CLERK_API_KEY | — | Clerk verification for MCP |
SIRLOIN_FOXY360_ANTHROPIC_API_KEY | — | LLM provider |
SIRLOIN_FOXY360_OPENAI_API_KEY | — | LLM provider |
SIRLOIN_FOXY360_GEMINI_API_KEY | — | LLM provider |
SIRLOIN_FOXY360_GOOGLE_CREDENTIALS_JSON | — | Google services creds |
SIRLOIN_FOXY360_AXIOM_API_TOKEN | — | Foxy360-scoped Axiom token |
SIRLOIN_FOXY360_AXIOM_DATASET | — | Foxy360 dataset |
SIRLOIN_FOXY360_PRIMER_API_KEY | — | Primer connector |
SIRLOIN_FOXY360_META_ADS_ACCESS_TOKEN | — | Meta Ads connector |
SIRLOIN_FOXY360_META_AD_ACCOUNT_IDS | — | Comma-separated ad accounts |
SIRLOIN_FOXY360_MCP_AXIOM_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_AXIOM_AUTH_HEADER | — | Full Authorization header value |
SIRLOIN_FOXY360_MCP_CHARGEBEE_DATA_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_CHARGEBEE_DATA_BEARER_TOKEN | — | Raw token (no Bearer prefix) |
SIRLOIN_FOXY360_MCP_CHARGEBEE_KB_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_INTERCOM_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_INTERCOM_BEARER_TOKEN | — | — |
SIRLOIN_FOXY360_MCP_POSTHOG_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_POSTHOG_AUTH_HEADER | — | Full Authorization header value |
SIRLOIN_FOXY360_MCP_SENTRY_URL | — | MCP connector URL |
SIRLOIN_FOXY360_MCP_SENTRY_COMMAND | — | stdio command (alternate transport) |
SIRLOIN_FOXY360_MCP_DB_DSN | — | Read-only DB DSN |
Resolved
SIRLOIN_DATABASE_RUNTIME_URL does not exist as a sirloin env var. The
runtime-only DSN comes from optional SIRLOIN_DATABASE_POOLED_URL; when
unset, sirloin reuses SIRLOIN_DATABASE_URL
(apps/sirloin/internal/app/config/config.go:144, :449,
apps/sirloin/internal/pkg/env/variables.go:10).
SIRLOIN_SENTRY_ENABLED defaults to false. Config.SentryEnabled is set
via IsTrue() which only matches case-insensitive "TRUE", so any other
value (including unset) disables Sentry across stages
(apps/sirloin/internal/app/config/config.go:206,
apps/sirloin/internal/pkg/env/env.go:30).
- Ondato required-when-enabled vars (those that block
ondato.NewClient):
SIRLOIN_ONDATO_CLIENT_ID, SIRLOIN_ONDATO_CLIENT_SECRET,
SIRLOIN_ONDATO_CLIENT_SETUP_ID, SIRLOIN_ONDATO_AUTH_URL,
SIRLOIN_ONDATO_IDV_API_BASE_URL, SIRLOIN_ONDATO_KYC_BASE_URL. The rest
(SCOPES, REDIRECT_BASE_URL, WEBHOOK_SECRET) are optional but the
webhook secret is required to accept Ondato webhooks
(apps/sirloin/internal/pkg/ondato/client.go:43-:62,
apps/sirloin/internal/app/config/config.go:289-:302).
SIRLOIN_GRPC_HOST and SIRLOIN_GRPC_URL are not read by sirloin —
see Core table notes. They are client-side conventions used by other
services to dial sirloin.
TODO(@zen)
- None outstanding for env in this pass.