Skip to content

Backend Configuration

The backend is configured entirely through environment variables, loaded at startup with kelseyhightower/envconfig (see internal/config). This page is the canonical reference for every variable. The authoritative source is backend/.env.example in the repo — copy it to backend/.env for local development (make backend-run-dev does this automatically if .env is missing).

  • Values come from the process environment. There is no config file format; in local dev the Makefile exports the contents of backend/.env.
  • Variables are read once at boot. Most are optional and have safe defaults; optional integrations stub out cleanly when left empty.
  • A handful are hard requirements — the service fails to start without them.
VariableDefaultRequiredPurpose
PORT8080NoHTTP listen port.
LOG_LEVELinfoNodebug | info | warn | error. Use debug locally.
LOG_FORMATjsonNojson (structured, for aggregators) or text (human-readable).
SERVICE_VERSIONdevNoVersion tag attached to metrics/traces.
VariableDefaultRequiredPurpose
DB_HOSTlocalhostYesPostgres host. Use postgres with Docker Compose.
DB_PORT5432YesPostgres port.
DB_USERvibexp_appYesDatabase user.
DB_PASSWORDlocal_passwordYesDatabase password. Change for any real deployment.
DB_NAMEvibexp_ioYesDatabase name.

See Database & Migrations for pooling and migration behaviour.

VariableDefaultRequiredPurpose
ENCRYPTION_KEYYesAES-256 key for encrypting sensitive data at rest. Must be exactly 32 bytes.
API_KEY_COMMONNoShared API key for the common API surface.
BACKOFFICE_ADMIN_API_KEYNoAdmin key for back-office endpoints (/bo/*). Separate from JWTs and regular API keys.

Selects and configures the web-login identity provider. See Authentication for the full model.

VariableDefaultRequiredPurpose
AUTH_PROVIDER(empty)Noworkos, oidc, or empty (auto-detect: WorkOS if its credentials are set, else a no-op stub).
SIGNIN_ALLOWED_EMAILS(empty)NoComma-separated allowlist. Empty means open registration.
DEV_LOGIN_ENABLEDfalseNoEnables /api/v1/auth/dev/login (bypasses the IdP). Local development only.

WorkOS AuthKit (AUTH_PROVIDER=workos or auto-detected)

Section titled “WorkOS AuthKit (AUTH_PROVIDER=workos or auto-detected)”
VariableDefaultRequiredPurpose
WORKOS_API_KEY(empty)When using WorkOSWorkOS API key.
WORKOS_CLIENT_ID(empty)When using WorkOSWorkOS Client ID.
WORKOS_COOKIE_PASSWORDdev valueWhen using WorkOS32-byte hex string deriving the AES-GCM key that encrypts the vx_session cookie. Generate with openssl rand -hex 32.
WORKOS_REDIRECT_URIhttp://localhost:8080/api/v1/auth/callbackWhen using WorkOSOAuth callback registered in WorkOS.

Works with any OIDC-compliant issuer (Keycloak, Authentik, Zitadel, Auth0, Google).

VariableDefaultRequiredPurpose
OIDC_ISSUER_URL(empty)When using OIDCIssuer for discovery (/.well-known/openid-configuration appended).
OIDC_CLIENT_ID(empty)When using OIDCOAuth client ID.
OIDC_CLIENT_SECRET(empty)When using OIDCOAuth client secret.
OIDC_REDIRECT_URIhttp://localhost:8080/api/v1/auth/callbackWhen using OIDCCallback URI registered with the provider.

The /mcp/v1/common endpoint is an OAuth 2.1 resource server delegating to AuthKit. See MCP Server.

VariableDefaultRequiredPurpose
MCP_OAUTH_ISSUER(empty)To enable MCPAuthKit issuer URL. JWKS fetched from <issuer>/oauth2/jwks. Empty disables the endpoint (rejects all tokens with 401).
MCP_RESOURCE_URI(empty)To enable MCPCanonical MCP resource identifier and required token audience (RFC 8707). No default.

When set, /api/v1/* accepts AuthKit bearer JWTs (mobile / native PKCE clients) alongside session cookies and API keys.

VariableDefaultRequiredPurpose
API_OAUTH_ISSUER(empty)NoAuthKit issuer URL. Empty rejects non-API-key bearer tokens with 401.
API_OAUTH_AUDIENCES(empty)NoOptional comma-separated aud allow-list. Default accepts any audience except the MCP resource URI.
VariableDefaultRequiredPurpose
FRONTEND_BASE_URLhttp://localhost:5173NoPublic URL of the web app (redirects, email links).
CORS_ALLOWED_ORIGINS(empty)NoComma-separated allowed origins. Empty allows only localhost dev origins.
VariableDefaultRequiredPurpose
GCS_RESOURCE_ATTACHMENTS_BUCKET(empty)NoGCS bucket for attachments. Empty disables attachments (upload/download/delete return 503).

Embeddings are generated in-process by an async event-bus worker: text is chunked in Go, embedded via the active provider, and stored in pgvector. There is no external AI service and no message broker.

VariableDefaultRequiredPurpose
EMBEDDING_MODELgemini-embedding-001NoThe model_id tag written on every row and used as the search filter. Set to the model your provider serves.
EMBEDDING_CHUNK_SIZE1000NoRune-based chunk size for the in-Go chunker.
EMBEDDING_CHUNK_OVERLAP200NoOverlap between chunks (must be smaller than the chunk size).
VariableDefaultRequiredPurpose
EMAIL_PROVIDERsmtpNosmtp, mailgun, postmark, or sendgrid.
EMAIL_FROM_ADDRESSdev@vibexp.localRequired for non-smtp providersSender address. Falls back to SMTP_USERNAME for smtp.
CONTACT_RECIPIENT_ADDRESS(empty)NoInbox for contact/support emails. Falls back to EMAIL_FROM_ADDRESS, then SMTP_USERNAME.

SMTP (EMAIL_PROVIDER=smtp). Dev defaults point at Mailpit (UI at http://localhost:8025).

VariableDefaultPurpose
SMTP_HOSTlocalhostSMTP host.
SMTP_PORT1025SMTP port.
SMTP_USERNAMEdevSMTP username.
SMTP_PASSWORDdevSMTP password.

Mailgun (EMAIL_PROVIDER=mailgun).

VariableDefaultPurpose
MAILGUN_DOMAINmg.example.comMailgun sending domain.
MAILGUN_SENDING_KEYMailgun private API key.
MAILGUN_BASE_URL(empty)Region base URL; empty uses the US default.

Postmark (EMAIL_PROVIDER=postmark).

VariableDefaultPurpose
POSTMARK_SERVER_TOKENPostmark Server API token.
POSTMARK_MESSAGE_STREAMoutboundMessage stream to send on.

SendGrid (EMAIL_PROVIDER=sendgrid).

VariableDefaultPurpose
SENDGRID_API_KEYSendGrid API key with the “Mail Send” permission.

Optional. Leave empty for local dev (the provider stubs out).

VariableDefaultRequiredPurpose
GITHUB_APP_ID(empty)NoApp ID from your GitHub App settings.
GITHUB_APP_PRIVATE_KEY(empty)NoBase64-encoded private key. A non-empty but invalid value fails startup on PEM parsing.
GITHUB_CLIENT_ID(empty)NoOAuth Client ID for user authorization.
GITHUB_CLIENT_SECRET(empty)NoOAuth Client Secret.
GITHUB_WEBHOOK_URLhttps://api.example.com/webhooks/githubNoPublic URL GitHub sends events to.
GITHUB_WEBHOOK_SECRET(empty)NoSecret used to verify webhook payloads.
VariableDefaultRequiredPurpose
HUBSPOT_CRM_ACCESS_KEY(empty)NoHubSpot Private App access token for contact sync. Empty disables the integration.

Async event processing (embeddings, analytics, HubSpot sync). All optional with production-tuned defaults; values are validated and capped.

VariableDefaultMaxPurpose
EVENT_BUS_WORKER_COUNT201000Concurrent event workers.
EVENT_BUS_BUFFER_SIZE50010000Event queue buffer size.
EVENT_BUS_MAX_RETRIES310Max retry attempts per event.
EVENT_BUS_RETRY_BACKOFF200ms5sBase retry delay; exponential, capped at 30s per attempt.
EVENT_BUS_RETRY_JITTERtrueRandomize backoff (±10%) to avoid thundering herd.
VariableDefaultRequiredPurpose
OTEL_EXPORTER_OTLP_ENDPOINTlocalhost:4317NoOTLP collector endpoint (gRPC host:port, no scheme).
OTEL_METRIC_EXPORT_INTERVAL60sNoMetric export interval.
OTEL_ENVIRONMENT(empty)NoDeployment environment (e.g. development, production). Takes precedence over ENVIRONMENT/ENV/DEPLOYMENT_ENVIRONMENT. Defaults to production if none set.
GCP_PROJECT_ID(empty)NoUsed only for observability (trace/log correlation).
VariableDefaultRequiredPurpose
A2A_DEFAULT_TIMEOUT5mNoMax time to wait for agent-to-agent HTTP responses.

Abuse-hardening backstops; all have safe defaults.

VariableDefaultPurpose
MAX_BODY_SIZE_BYTES10485760 (10 MiB)Global request-body cap. Contact form and webhooks cap at 64 KiB.
AUTH_RATE_LIMIT_PER_MINUTE10Per-IP limit on /api/v1/auth/*.
CONTACT_RATE_LIMIT_PER_MINUTE5Per-IP limit on the contact form.
API_RATE_LIMIT_PER_MINUTE100Per-IP limit on the authenticated API surface.
VariableDefaultPurpose
ERROR_TYPE_BASE_URIabout:blankRFC 9457 error type base URI. Set to a public URL documenting your error codes (joined as <base>/<code>).

OIDC auth for internal job endpoints (/internal/jobs/*), e.g. Cloud Scheduler. Unrelated to embeddings; leave empty for local dev.

VariableDefaultPurpose
PUBSUB_PUSH_AUDIENCE(empty)Public HTTPS URL the OIDC caller targets; the token’s audience must match it.
PUBSUB_PUSH_SERVICE_ACCOUNT_SUFFIX(empty)Optional. Restrict accepted tokens to a service-account domain.