feather-reader 0.2.2

A minimalist, atproto-native RSS/Atom reader in Rust — your feed subscriptions live in your own PDS.
Documentation
# FeatherReader atproto OAuth sidecar — environment.
# Copy to .env (dev) or set these in the container/compose environment.

# --- networking ---
SIDECAR_HOST=127.0.0.1
SIDECAR_PORT=8081

# The sidecar's own externally-reachable base URL. Determines client_id,
# redirect_uri (= ${SIDECAR_PUBLIC_URL}/callback), and where client-metadata.json
# and jwks.json are published.
#   dev:   http://127.0.0.1:8081        (localhost dev-client, no PKI)
#   prod:  https://feather-reader.com/oauth   (fronted at /oauth path)
SIDECAR_PUBLIC_URL=http://127.0.0.1:8081

# Force the atproto localhost dev-client rules on/off (PKI shape only).
# Auto-detected from a localhost PUBLIC_URL when unset. NOTE: this flag ALSO acts
# as the explicit dev opt-in for the fail-loud secret/enc-key guards below — a
# localhost PUBLIC_URL alone does NOT relax those guards; only SIDECAR_DEV=true does.
# SIDECAR_DEV=true

# --- storage ---
SIDECAR_DB=oauth-sidecar.db

# At-rest encryption key for stored OAuth tokens/DPoP keys + the signing JWK.
# REQUIRED in production (≥32 bytes); deliver via `fly secrets set SIDECAR_ENC_KEY=…`
# and NEVER write it to the volume — a raw volume/snapshot read is then useless.
# Generate: `openssl rand -base64 32`. May be unset ONLY with SIDECAR_DEV=true
# (dev then stores tokens/JWK in plaintext, loudly warned).
SIDECAR_ENC_KEY=change-me-openssl-rand-base64-32

# --- Rust <-> sidecar internal API ---
# Shared secret the Rust server sends as `X-Internal-Secret` on /internal/*.
# REQUIRED in production: must be ≥32 bytes and NOT the dev default, else the
# sidecar refuses to boot. A dev bypass requires an explicit SIDECAR_DEV=true.
SIDECAR_INTERNAL_SECRET=change-me-to-a-long-random-value

# --- session TTLs / reaper (defaults shown; dormant refresh tokens are reaped) ---
# SIDECAR_SESSION_ABS_TTL_MS=7776000000   # absolute lifetime (90d)
# SIDECAR_SESSION_IDLE_TTL_MS=2592000000  # idle lifetime (30d)
# SIDECAR_REAPER_INTERVAL_MS=3600000      # reaper sweep cadence (1h)

# Where the browser is redirected after a successful login, with ?session_id=...
# This is the Rust app's OAuth callback route.
#   dev:  http://localhost:8080/oauth/callback
#   prod: https://feather-reader.com/oauth/callback
SIDECAR_APP_CALLBACK_URL=http://localhost:8080/oauth/callback

# --- atproto resolution (defaults are fine) ---
SIDECAR_HANDLE_RESOLVER=https://bsky.social
SIDECAR_PLC_DIRECTORY=https://plc.directory
SIDECAR_SCOPE=atproto transition:generic