Repository navigation
Expand file tree
/
Copy path.env.example
More file actions
190 lines (187 loc) · 11 KB
/
Copy path.env.example
File metadata and controls
190 lines (187 loc) · 11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# Every variable here follows one rule: an empty value means unset, exactly as
# if the line were deleted. Values are trimmed. Booleans accept true/1/yes/on
# and false/0/no/off, case-insensitively; anything else falls back to the
# documented default and logs a warning. See D93 in DECISIONS.md.
DATABASE_URL=postgres://overslash:overslash@localhost:55432/overslash
HOST=0.0.0.0
PORT=3000
# Generate each with `openssl rand -hex 32`. There is deliberately no working
# value here: the API refuses placeholder, repeated-byte, patterned and short
# keys at boot anywhere OVERSLASH_ENV is set to something other than `local`
# (and warns about them on a local checkout), so a copied .env.example cannot
# start a deployment with a published vault key.
SECRETS_ENCRYPTION_KEY=
SIGNING_KEY=
# Deployment marker: unset/local (a developer checkout), dev, staging or prod.
# `prod` refuses DEV_AUTH and clamps a debug RUST_LOG to info. The container
# image defaults this to prod.
# OVERSLASH_ENV=
# Deps stay at info; overslash crates emit debug for local development.
RUST_LOG=info,overslash_api=debug,overslash_core=debug,overslash_db=debug,overslash_mcp=debug,overslash_cli=debug
APPROVAL_EXPIRY_SECS=1800
# Upstream call timeouts (D56). CALL_TIMEOUT_MS is the default when neither the
# call, the action template, the service template, nor the org says otherwise.
# CALL_TIMEOUT_MAX_MS is the hard ceiling on any resolved value and should sit
# just under whatever request cap your proxy enforces (Cloud Run and the GCLB
# both cut at 120s), so a slow call fails with our own 504 and an audit row
# rather than an anonymous proxy timeout.
CALL_TIMEOUT_MS=30000
CALL_TIMEOUT_MAX_MS=110000
# Per-chunk idle timeout for `prefer_stream: true` responses. Streaming
# deliberately does not take the call timeout as a total deadline — that would
# fail a healthy large transfer at an arbitrary elapsed time — so slowness is
# allowed and only a stall is fatal.
CALL_STREAM_IDLE_TIMEOUT_MS=30000
# Display-param resolver cache (D64). A resolver turns an opaque argument into
# something a reviewer can read, at the cost of an authenticated round trip per
# call; this caches the answer. When REDIS_URL is set the cache is shared across
# replicas via Valkey, otherwise it is process-local. Cached values are
# encrypted with SECRETS_ENCRYPTION_KEY, because what a resolver returns is
# people's names, addresses and phone numbers.
#
# Keep RESOLVE_CACHE_TTL_SECS short. A resolver that declares `scope:` decides
# which permission *grant* matches, while the call itself still targets the
# caller's raw argument — so the TTL is how long a grant may be matched against
# a stale mapping. Templates that know their mapping is immutable raise it
# per-resolver with `cache_ttl:`. Set to 0 to disable the cache entirely.
RESOLVE_CACHE_TTL_SECS=300
# How long a *failed* lookup is remembered. Stops a down provider costing every
# call the full 3s resolver timeout, without keeping approvals unreadable long
# after it recovers.
RESOLVE_CACHE_NEGATIVE_TTL_SECS=30
# Ceiling on the effective TTL for `scope:`-bearing resolvers. A template sets a
# default; the deployment sets the cap; the tighter wins.
RESOLVE_CACHE_SCOPE_TTL_MAX_SECS=300
# Budget for the cache backend itself. Exceeding it is a miss, never an error —
# the call resolves live. Sits well inside the 3s resolver budget.
RESOLVE_CACHE_TIMEOUT_MS=100
# In-memory backend only: cap on resident entries, since resolver arguments are
# caller-supplied and would otherwise grow unboundedly between sweeps.
RESOLVE_CACHE_MAX_ENTRIES=10000
# Extra key-namespace segment. Leave unset in production; set it when two
# deployments share one Valkey.
# RESOLVE_CACHE_NAMESPACE=
# Optional Valkey/Redis. Backs rate-limit counters and, when set, the resolver
# cache above. Unset means both fall back to process-local in-memory stores,
# which is correct for a single replica.
# `make local-db` starts one on 6380 (a worktree gets its own port, written to
# .env.local along with REDIS_URL and VALKEY_URL) — that is also the Valkey the
# oversla-sh integration tests talk to.
# REDIS_URL=redis://localhost:6380
# A managed Valkey with AUTH and TLS (Memorystore in prod, CASA 6.7.1) takes a
# rediss:// URL plus the AUTH string and the server CA bundle (PEM text, not a
# path) — both secrets, kept out of the URL. Setting a CA with a redis:// URL
# is refused at boot. oversla-sh reads the same as VALKEY_PASSWORD / VALKEY_CA_CERT.
# REDIS_URL=rediss://10.0.0.3:6378
# REDIS_PASSWORD=
# REDIS_CA_CERT=
# Service-template variables (D44). Every `OVERSLASH_TEMPLATE_VAR_<NAME>` here
# supplies `${<NAME>}` to a service template in services/ — nothing else in the
# environment is reachable from a template, which is what makes it safe to let
# org-authored templates use the same syntax.
#
# NON-SECRET ONLY. Any tenant who can author a template can read these back by
# referencing them and reading the resolved definition. Hostnames, base URLs —
# never a key.
#
# MAILBOX_HOST is the overfwd Mailbox Gateway host that services/email.yaml
# resolves its `servers[0]` to. It has no default on purpose: a wrong host both
# sends mail through somebody else's gateway and silently loses the platform
# gateway key (which is only ever sent to OVERSLASH_PLATFORM_GATEWAY_HOST).
# Unset ⇒ the `email` template simply doesn't load.
# dev → mailbox.dev.overslash.com
# prod → mailbox.overslash.com
# OVERSLASH_TEMPLATE_VAR_MAILBOX_HOST=mailbox.dev.overslash.com
# Self-hosted Metabase (services/metabase.yaml). Optional in a different sense
# from MAILBOX_HOST: the template writes `${METABASE_URL?}`, so leaving this
# unset does not drop the template — it ships with no host and each service
# instance is asked for its own URL instead. Set it to give every instance in
# the deployment the same default.
# OVERSLASH_TEMPLATE_VAR_METABASE_URL=http://localhost:3033
# Langfuse (services/langfuse.yaml). Optional in a third sense: the template
# writes `${LANGFUSE_URL:https://cloud.langfuse.com}`, the one D44 form with a
# literal default, because the vendor's EU cloud is a right answer for any
# deployment that does not say otherwise. Set this only to point the whole
# deployment at another Langfuse Cloud region or a self-hosted instance; a
# single service instance is re-pointed by setting its own `url`.
# EU (default) → https://cloud.langfuse.com
# US → https://us.cloud.langfuse.com
# JP → https://jp.cloud.langfuse.com
# HIPAA → https://hipaa.cloud.langfuse.com
# OVERSLASH_TEMPLATE_VAR_LANGFUSE_URL=https://us.cloud.langfuse.com
# Enables /auth/dev/token (returns a session cookie for dev@overslash.local).
# Required for the screenshot script and any non-OAuth local testing. Leave
# unset in production — or set it to 0/false/no/off, which now genuinely
# disables it (see D93; it used to be a presence check, so any value at all,
# including the empty string, turned it on).
DEV_AUTH=1
# Overslash-managed sign-in (optional). When set, corp orgs that opt in via
# `allow_overslash_managed_signin` accept authentication through these
# shared OAuth apps — admission is still gated by their `org_invites`
# allowlist, so a verified email cannot admit a stranger. Leave unset to
# require every org to register its own OAuth app.
# GOOGLE_AUTH_CLIENT_ID=...
# GOOGLE_AUTH_CLIENT_SECRET=...
# GitHub sign-in: register an OAuth App (not a GitHub App — the login flow
# relies on the read:user / user:email scopes, which GitHub Apps ignore) under
# the `overfolder` org, one per environment for secret isolation. The callback
# URL is always `<PUBLIC_URL>/auth/callback/github`:
# local → http://localhost:3000/auth/callback/github
# dev → https://api.dev.overslash.com/auth/callback/github
# prod → https://api.overslash.com/auth/callback/github
# GITHUB_AUTH_CLIENT_ID=...
# GITHUB_AUTH_CLIENT_SECRET=...
# Billing (optional — only needed when CLOUD_BILLING=true).
# Lookup keys default to overslash_seat_eur / overslash_seat_usd; set the same
# value on the matching Price in Stripe Dashboard so the server resolves the
# literal price_… ID at startup. Override only if you pick different names.
# CLOUD_BILLING=true
# STRIPE_SECRET_KEY=sk_test_...
# STRIPE_WEBHOOK_SECRET=whsec_...
# STRIPE_EUR_LOOKUP_KEY=overslash_seat_eur
# STRIPE_USD_LOOKUP_KEY=overslash_seat_usd
# Default trial length in days. Used by the instance-admin "start trial"
# endpoint (when no explicit duration is passed) and by the self-serve
# Stripe trial (subscription_data[trial_period_days]). Default 30.
# TRIAL_DEFAULT_DURATION_DAYS=30
# Transactional email (optional). Keep this block commented in dev — the API
# uses NoopMailer when EMAIL_PROVIDER is unset and boots cleanly. Setting
# EMAIL_PROVIDER without a real EMAIL_API_KEY + EMAIL_FROM trips validate_env
# and the CLI exits at startup.
# EMAIL_PROVIDER=resend
# EMAIL_FROM=no-reply@overslash.com
# EMAIL_REPLY_TO=support@overslash.com
# EMAIL_API_KEY=re_your_resend_api_key_here
# Outbound egress allow-list (self-hosted only). Every outbound request whose
# URL a caller can influence — a Mode A raw HTTP call, a service action, a
# webhook delivery, an MCP dispatch, a template import — is resolved and checked
# against a deny-list of private, loopback, link-local, CGNAT, ULA and
# metadata-range addresses, with the validated IP pinned so DNS cannot move the
# target after the check and redirects re-checked hop by hop. Leave this unset
# and Overslash can only reach the public internet, which is what a multi-tenant
# deployment wants.
#
# Set it to reach services on your OWN network: a self-hosted GitLab, a MinIO on
# a container network, a webhook consumer that never leaves the VPC. It is a
# comma-separated list of CIDR blocks, checked against the RESOLVED address, so
# a hostname that resolves outside every listed range is still refused. Be
# specific — list the ranges those services are actually on, not 10.0.0.0/8.
#
# Anyone who can make Overslash issue a request can reach what you list here,
# and on the default configuration that is every member of every org (the
# `Everyone` group holds `admin` on the `http` pseudo-service). The API logs a
# warning naming the accepted ranges at startup.
# OVERSLASH_SSRF_ALLOWED_CIDRS=10.42.0.0/16,192.168.1.0/24
# The cloud instance-metadata ranges — 169.254.0.0/16 and fd00:ec2::/32 — are
# denied BEFORE the allow-list is consulted, so no OVERSLASH_SSRF_ALLOWED_CIDRS
# entry reaches them, not even 0.0.0.0/0. That is deliberate: metadata hands out
# credentials for the instance's own service account, so a token minted there is
# not "one internal service", it is the whole deployment.
#
# This variable is the only gate past that, and it does not open anything by
# itself — it lets the allow-list cover those ranges, so reaching metadata takes
# two separate deliberate acts. You almost certainly do not want this; an
# operator reaching for 169.254.0.0/16 usually wants some other link-local
# device, which is a narrower range. Startup warns on any overlap either way,
# naming this variable and whether it is set.
# OVERSLASH_DANGER_ALLOW_METADATA_CIDR=true