mirror of
https://github.com/block/buzz.git
synced 2026-08-18 06:50:31 +02:00
This change requires a valid signed Blossom authorization request and current relay membership for every media GET and HEAD request. It removes the unauthenticated compatibility path and updates desktop reads to send the required authorization. This blocks anonymous retrieval and access after relay-membership revocation. It does not yet bind a blob to its originating channel, so someone removed from a private channel can still read a known blob while remaining a relay member. That channel-ACL follow-up remains required before closing the full finding. ## Testing - `git diff --check origin/main...codex/security-media-read-auth` - Rebased onto `origin/main` at `5c98932` - Full CI pending Originating Buzz thread: `buzz://message?channel=3928fe05-df61-4b5d-b9c7-d623b9b10ea1&id=3c6c02312f763fbe0d2bfc33a6c1a362f91d0354f3d18b039cf7a0558c1439d1` --------- Signed-off-by: Jordan Mecom <jm@squareup.com> Signed-off-by: Alex Rosenzweig <arosenzweig@squareup.com> Signed-off-by: Eli Foster <efoster@squareup.com> Co-authored-by: Eli Foster <efoster@squareup.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
253 lines
12 KiB
Bash
253 lines
12 KiB
Bash
# =============================================================================
|
||
# Buzz Backend — Local Development Environment
|
||
# =============================================================================
|
||
# Copy this file to .env and adjust as needed:
|
||
# cp .env.example .env
|
||
#
|
||
# All defaults here work with `docker compose up` out of the box.
|
||
#
|
||
# Service ports (defaults):
|
||
# Postgres → localhost:5432
|
||
# Redis → localhost:6379
|
||
# Typesense → localhost:8108
|
||
# Adminer → localhost:8082 (DB browser UI)
|
||
#
|
||
# Note: If port 8082 conflicts, change the adminer port in docker-compose.yml
|
||
# =============================================================================
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Database (Postgres 17)
|
||
# -----------------------------------------------------------------------------
|
||
DATABASE_URL=postgres://buzz:buzz_dev@localhost:5432/buzz
|
||
# Optional read-replica URL; unset/blank keeps all reads on the writer.
|
||
# READ_DATABASE_URL=postgres://buzz:buzz_dev@localhost:5433/buzz
|
||
PGHOST=localhost
|
||
PGPORT=5432
|
||
PGUSER=buzz
|
||
PGPASSWORD=buzz_dev
|
||
PGDATABASE=buzz
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Redis 7
|
||
# -----------------------------------------------------------------------------
|
||
REDIS_URL=redis://localhost:6379
|
||
# Max connections in the relay's shared Redis pool (default 16).
|
||
# BUZZ_REDIS_POOL_SIZE=16
|
||
|
||
# Max connections in each of the relay's Postgres pools — writer and, when
|
||
# READ_DATABASE_URL is set, reader (default 50).
|
||
# BUZZ_DB_POOL_SIZE=50
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Typesense (search)
|
||
# -----------------------------------------------------------------------------
|
||
TYPESENSE_API_KEY=buzz_dev_key
|
||
TYPESENSE_URL=http://localhost:8108
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Relay (WebSocket server)
|
||
# -----------------------------------------------------------------------------
|
||
# Bind address for the relay (host:port)
|
||
BUZZ_BIND_ADDR=0.0.0.0:3000
|
||
# Public WebSocket URL — used in NIP-42 auth challenges
|
||
RELAY_URL=ws://localhost:3000
|
||
# Stable relay signing key. Set this in dev if you want REST-created forum posts
|
||
# to keep resolving to the original author across relay restarts.
|
||
# BUZZ_RELAY_PRIVATE_KEY=<32-byte hex private key>
|
||
# Optional: path to the web UI dist directory. When set, the relay serves
|
||
# the web frontend at / for browser requests. Leave unset for local dev
|
||
# (use `just web` for Vite HMR instead).
|
||
# BUZZ_WEB_DIR=./web/dist
|
||
|
||
# Shared Redis-backed admission limits. Defaults shown below; each value must
|
||
# be a positive integer.
|
||
# BUZZ_RATE_LIMIT_HUMAN_MESSAGES_PER_MIN=60
|
||
# BUZZ_RATE_LIMIT_HUMAN_API_CALLS_PER_MIN=300
|
||
# BUZZ_RATE_LIMIT_HUMAN_WS_EVENTS_PER_SEC=10
|
||
# BUZZ_RATE_LIMIT_AGENT_STANDARD_MESSAGES_PER_MIN=120
|
||
# BUZZ_RATE_LIMIT_AGENT_STANDARD_API_CALLS_PER_MIN=600
|
||
# BUZZ_RATE_LIMIT_AGENT_ELEVATED_MESSAGES_PER_MIN=300
|
||
# BUZZ_RATE_LIMIT_AGENT_PLATFORM_MESSAGES_PER_MIN=600
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Git (NIP-34 bare repositories)
|
||
# -----------------------------------------------------------------------------
|
||
# Root directory for ephemeral Git workspaces and the disposable pack cache.
|
||
# Default: ./repos (relative to CWD).
|
||
# BUZZ_GIT_REPO_PATH=./repos
|
||
# BUZZ_GIT_MAX_PACK_BYTES=524288000
|
||
# BUZZ_GIT_MAX_REPO_BYTES=1048576000
|
||
# Process-local immutable pack/index cache. Zero disables retention.
|
||
# BUZZ_GIT_PACK_CACHE_PATH=./repos/.pack-cache
|
||
# BUZZ_GIT_PACK_CACHE_MAX_BYTES=5368709120
|
||
# BUZZ_GIT_PACK_CACHE_MAX_CONCURRENT_POPULATIONS=2
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# S3-Compatible Object Storage (media + Git/CAS)
|
||
# -----------------------------------------------------------------------------
|
||
# The local MinIO container is reachable from host processes at localhost:9000.
|
||
# Path style keeps the bucket in the URL path and is required by this local DNS
|
||
# setup. Use `virtual` only when the provider requires bucket-as-subdomain URLs.
|
||
BUZZ_S3_ENDPOINT=http://localhost:9000
|
||
BUZZ_S3_ACCESS_KEY=buzz_dev
|
||
BUZZ_S3_SECRET_KEY=buzz_dev_secret
|
||
BUZZ_S3_BUCKET=buzz-media
|
||
BUZZ_S3_REGION=us-east-1
|
||
BUZZ_S3_ADDRESSING_STYLE=path
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Media Upload Admission
|
||
# -----------------------------------------------------------------------------
|
||
# Bound image/video parser and storage work admitted by one relay process.
|
||
# BUZZ_MEDIA_MAX_CONCURRENT_UPLOADS=8
|
||
# BUZZ_MEDIA_MAX_CONCURRENT_UPLOADS_PER_PUBKEY=2
|
||
# BUZZ_MEDIA_UPLOADS_PER_MINUTE=30
|
||
# GET/HEAD /media/* always require Blossom t=get auth and relay membership.
|
||
# BUZZ_REQUIRE_MEDIA_GET_AUTH and BUZZ_REQUIRE_MEDIA_READ_AUTH are no longer
|
||
# read; setting either (including to false) changes nothing and the relay warns
|
||
# about it at startup.
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Ephemeral Channels (TTL testing)
|
||
# -----------------------------------------------------------------------------
|
||
# Override the TTL for all ephemeral channels (in seconds). When set, any
|
||
# channel created with a TTL tag will use this value instead of the
|
||
# client-provided one. Unset to use the client-provided TTL.
|
||
# BUZZ_EPHEMERAL_TTL_OVERRIDE=60
|
||
|
||
# How often the reaper checks for expired ephemeral channels (default: 60s).
|
||
# BUZZ_REAPER_INTERVAL_SECS=5
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# Logging / Tracing
|
||
# -----------------------------------------------------------------------------
|
||
RUST_LOG=buzz_relay=debug,buzz_datastore=info,buzz_db=debug,buzz_auth=debug,buzz_pubsub=debug,tower_http=debug
|
||
# Optional OpenTelemetry-only target filter. This is deliberately independent
|
||
# from RUST_LOG so log verbosity changes cannot break trace parentage.
|
||
# BUZZ_OTEL_FILTER=buzz_relay=info,buzz_datastore=info
|
||
|
||
# OTLP tracing endpoint (optional — leave unset to disable)
|
||
# OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317
|
||
|
||
# -----------------------------------------------------------------------------
|
||
# ACP (Agent Communication Protocol — buzz-acp harness)
|
||
# -----------------------------------------------------------------------------
|
||
# The ACP harness bridges Buzz events to AI agents. Each env var below maps
|
||
# to a CLI flag of the same name (lowercase, hyphens → underscores). All values
|
||
# are optional unless noted; defaults are shown in comments.
|
||
#
|
||
# Quick start:
|
||
# BUZZ_PRIVATE_KEY=<hex> BUZZ_RELAY_URL=ws://localhost:3000 buzz-acp
|
||
|
||
# ── Identity & auth ──────────────────────────────────────────────────────────
|
||
# Nostr private key (hex or bech32). REQUIRED — identifies the agent on the relay.
|
||
# BUZZ_PRIVATE_KEY=<32-byte hex or nsec1… private key>
|
||
|
||
# Relay WebSocket URL the harness connects to.
|
||
# Note: the relay itself uses RELAY_URL (above); this is the ACP harness's
|
||
# connection target — they happen to point at the same place in local dev.
|
||
# BUZZ_RELAY_URL=ws://localhost:3000
|
||
|
||
# ── Agent subprocess ─────────────────────────────────────────────────────────
|
||
# Binary to spawn as the AI agent (e.g. "goose", "codex-acp", "claude-code").
|
||
# BUZZ_ACP_AGENT_COMMAND=goose
|
||
|
||
# Comma-separated arguments passed to the agent binary.
|
||
# Goose default: "acp". Codex/Claude default: "" (empty).
|
||
# BUZZ_ACP_AGENT_ARGS=acp
|
||
|
||
# Binary for an optional MCP server sidecar (e.g. buzz-dev-mcp for buzz-agent).
|
||
# BUZZ_ACP_MCP_COMMAND=
|
||
|
||
# Number of parallel agent subprocesses (1–32).
|
||
# BUZZ_ACP_AGENTS=1
|
||
|
||
# Desired LLM model ID. Applied to every new ACP session.
|
||
# Use `buzz-acp models` to discover available model IDs.
|
||
# BUZZ_ACP_MODEL=
|
||
|
||
# ── Timeouts & sessions ──────────────────────────────────────────────────────
|
||
# Max seconds per agent turn before timeout (default 320 = ~5 min).
|
||
# BUZZ_ACP_TURN_TIMEOUT=320
|
||
|
||
# Max turns per session before proactive rotation. 0 = disabled (rotate only
|
||
# on MaxTokens / MaxTurnRequests). Recommended: 50 for long-running agents.
|
||
# BUZZ_ACP_MAX_TURNS_PER_SESSION=0
|
||
|
||
# ── Prompts ──────────────────────────────────────────────────────────────────
|
||
# System prompt injected into every agent session (inline text).
|
||
# BUZZ_ACP_SYSTEM_PROMPT=
|
||
|
||
# Path to a file containing the system prompt (mutually exclusive with above).
|
||
# BUZZ_ACP_SYSTEM_PROMPT_FILE=
|
||
|
||
# Message sent to the agent immediately after session creation.
|
||
# BUZZ_ACP_INITIAL_MESSAGE=
|
||
|
||
# ── Heartbeat ────────────────────────────────────────────────────────────────
|
||
# Seconds between heartbeat prompts. 0 = disabled. Must be 0 or ≥10.
|
||
# Recommended: 60 for long-running agents to prevent idle session timeouts.
|
||
# BUZZ_ACP_HEARTBEAT_INTERVAL=0
|
||
|
||
# Heartbeat prompt text (inline). Mutually exclusive with file variant.
|
||
# BUZZ_ACP_HEARTBEAT_PROMPT=
|
||
|
||
# Path to a file containing the heartbeat prompt.
|
||
# BUZZ_ACP_HEARTBEAT_PROMPT_FILE=
|
||
|
||
# ── Desktop development ──────────────────────────────────────────────────────
|
||
# DEV-only: replay first-run onboarding and the Welcome Team kickoff on each
|
||
# app launch while keeping the current identity and relay data.
|
||
# VITE_BUZZ_FORCE_FRESH_ONBOARDING=true
|
||
|
||
# ── Subscription & filtering ─────────────────────────────────────────────────
|
||
# Subscribe mode: "mentions" (default), "all", or "config" (rule-based).
|
||
# BUZZ_ACP_SUBSCRIBE=mentions
|
||
|
||
# Comma-separated event kind numbers to subscribe to (overrides mode defaults).
|
||
# BUZZ_ACP_KINDS=
|
||
|
||
# Comma-separated channel UUIDs to limit subscription scope.
|
||
# BUZZ_ACP_CHANNELS=
|
||
|
||
# Set to true to disable the @-mention filter in mentions mode.
|
||
# BUZZ_ACP_NO_MENTION_FILTER=false
|
||
|
||
# Path to TOML config file for rule-based subscriptions (config mode).
|
||
# BUZZ_ACP_CONFIG=./buzz-acp.toml
|
||
|
||
# ── Dedup & self-ignore ──────────────────────────────────────────────────────
|
||
# How to handle duplicate events: "queue" (default) or "drop".
|
||
# BUZZ_ACP_DEDUP=queue
|
||
|
||
# Set to true to process the agent's own messages (default: ignore self).
|
||
# BUZZ_ACP_NO_IGNORE_SELF=false
|
||
|
||
# ── Context ──────────────────────────────────────────────────────────────────
|
||
# Max context messages fetched for thread replies and DMs (0–100). 0 = disabled.
|
||
# BUZZ_ACP_CONTEXT_MESSAGE_LIMIT=12
|
||
|
||
# ── Presence & typing ────────────────────────────────────────────────────────
|
||
# Set to true to disable automatic online/offline presence status.
|
||
# BUZZ_ACP_NO_PRESENCE=false
|
||
|
||
# Set to true to disable typing indicators while the agent is processing.
|
||
# BUZZ_ACP_NO_TYPING=false
|
||
|
||
# ── Advanced tuning ──────────────────────────────────────────────────────────
|
||
# Event channel buffer capacity (WebSocket → harness). Increase for
|
||
# high-throughput agents. Minimum 1.
|
||
# BUZZ_ACP_EVENT_BUFFER=256
|
||
|
||
# ── Legacy aliases ───────────────────────────────────────────────────────────
|
||
# These are accepted for backward compatibility but the canonical names above
|
||
# are preferred:
|
||
# BUZZ_ACP_PRIVATE_KEY → BUZZ_PRIVATE_KEY
|
||
|
||
# Optional relay join policy. Markdown is served by the relay so every join
|
||
# surface can present the same documents. Each document and the independent age
|
||
# attestation are optional; configuring any one enables policy acceptance.
|
||
# BUZZ_TERMS_OF_SERVICE_MARKDOWN="# Terms of Service\n\nFull terms here."
|
||
# BUZZ_PRIVACY_POLICY_MARKDOWN="# Privacy Policy\n\nFull policy here."
|
||
# BUZZ_AGE_ATTESTATION_REQUIRED=true
|