-
Notifications
You must be signed in to change notification settings - Fork 37
Expand file tree
/
Copy path.env.example
More file actions
102 lines (95 loc) · 4.97 KB
/
.env.example
File metadata and controls
102 lines (95 loc) · 4.97 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
# =============================================================================
# Access keys (OPTIONAL: drives the invite-link `?share=<id>` flow)
# =============================================================================
#
# Leave SHARED_API_KEYS unset and the demo runs in BYOK-only mode: every
# visitor brings their own provider key via the in-app Model Picker, and
# the stream goes browser-direct (never through this server). This is
# the easiest setup if you only need it for yourself.
#
# Set SHARED_API_KEYS to skip BYOK and let non-technical viewers chat
# without pasting a key. Each entry maps a share id to an api key, a
# model handle, and a per-IP lifetime cap on chat turns. Visitors land
# on `?share=<id>` and the server pays for the LLM under your account.
# Requests without a recognized `?share=<id>` still return 401 and the
# client falls back to BYOK.
#
# Shape (per share id):
#
# {
# "<share_id>": {
# "api_key": "<provider api key>",
# "model": "<anthropic_haiku_4_5 | deepseek_v4_flash>",
# "rate_limit_turns_lifetime": 20
# }
# }
#
# Each share id has its own per-IP lifetime counter. With REDIS_URL set
# (see below), counters survive restarts and are shared across containers.
# Without REDIS_URL, counters live in memory per container (fine for
# single-instance / BYOK-only deployments). The reserved id "__default__"
# is rejected at parse time. Example with two invites on two providers:
#
# SHARED_API_KEYS='{"preview-alice":{"api_key":"sk-ant-...","model":"anthropic_haiku_4_5","rate_limit_turns_lifetime":5},"customer-acme":{"api_key":"sk-...","model":"deepseek_v4_flash","rate_limit_turns_lifetime":100}}'
#
# Visitors then open `http://localhost:3001/?share=preview-alice` (or
# the equivalent on your hosted domain).
#
# -----------------------------------------------------------------------------
# Base64 fallback (recommended for hosted deploys)
# -----------------------------------------------------------------------------
# Some hosts (DigitalOcean App Platform, Render, fly.io app specs) mangle
# embedded or surrounding quotes when storing JSON-shaped env vars. The
# parser accepts a base64-encoded payload as an alternative: plain JSON
# is tried first, base64-then-JSON second. Either works.
#
# Portable one-liner (macOS + Linux):
#
# printf '%s' '{"preview-alice":{"api_key":"sk-ant-...","model":"anthropic_haiku_4_5","rate_limit_turns_lifetime":5}}' | base64 | tr -d '\n'
#
# Paste the resulting ASCII-only string as the value, with no surrounding
# quotes. The parser also auto-strips one wrapping pair of single or
# double quotes if your host shell-escapes the value into the env.
SHARED_API_KEYS=
# =============================================================================
# Client configuration
# =============================================================================
# SimplePDF company identifier. The subdomain piece of
# <companyIdentifier>.simplepdf.com that serves the embedded editor.
# Exposed to the browser (VITE_ prefix) because the iframe src is built
# client-side. REQUIRED: the app throws at startup if unset.
#
# `spdf-copilot` is the public demo workspace and whitelists
# `http://localhost:3001`, so the iframe loads as-is for local dev. To
# host this on your own domain, set this to your own SimplePDF
# Premium company identifier and whitelist your serving origin in the
# SimplePDF dashboard.
VITE_SIMPLEPDF_COMPANY_IDENTIFIER=spdf-copilot
# Optional. Gates the TanStack Router devtools panel + chatty monitoring
# logs. Leave unset in production / CI; set to "true" for local dev.
# VITE_ENABLE_DEVTOOLS=true
# =============================================================================
# Rate-limit storage (optional; required for multi-container deployments)
# =============================================================================
# Connection URL to a Redis-protocol-compatible instance (Valkey, Redis,
# KeyDB, etc.). Required for hosted deployments where you want
# per-(share, IP) lifetime counters to survive restarts AND be shared
# across multiple containers. Without it, counters live in memory per
# container (fine for local dev, single-instance hosts, or BYOK-only
# deployments).
#
# DO Managed Caching for Valkey: $15/mo single-node, drop-in protocol-
# compatible. The dashboard returns a `rediss://default:<password>@<host>:25061/0`
# URL. The password is INSIDE the URL, so this value is a secret and must
# be stored as such (the deploy.template.yaml at the repo root marks it
# `type: SECRET`).
# REDIS_URL=rediss://default:<password>@<host>:25061/0
# REQUIRED when REDIS_URL is set (the server refuses to boot otherwise).
# Salts the SHA-256 IP hash used in Redis keys (rl:<share>:<hash>).
# Without a salt, a leak of the Redis snapshot lets anyone brute-force the
# ~4B IPv4 space in minutes. With a salt, the brute force needs the
# server-side secret too. Optional in BYOK-only mode (no REDIS_URL set),
# since hashes never persist beyond the process.
#
# Generate with: openssl rand -hex 32
# IP_HASH_SALT=