Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 43 additions & 11 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,35 @@
# ---------------------------------------------------------------------
# Required: secrets resolver
# ---------------------------------------------------------------------
# SECRET_PROVIDER selects which cloud secret store the resolver fetches
# from. Default `aws` matches the email factory's default backend
# (internal/email/factory.go) — using a value the email factory does
# not understand (e.g. `env`) makes app startup fail because email
# init runs unconditionally. For local dev that doesn't actually call
# email or secret-store paths, `aws` is a safe placeholder.
# aws | gcp | azure
SECRET_PROVIDER=aws
# SECRET_PROVIDER selects which secret store the resolver fetches from.
# aws | gcp | azure — production: real Secrets Manager / Key Vault
# env — local dev: resolve secret names to env vars
# In `env` mode, every secret-ref var (ADMIN_PASSWORD_SECRET,
# API_KEY_SECRET_ARN, etc.) holds the NAME of another env var whose
# value is the actual secret. See `internal/secrets/env_resolver.go`.
# Pairs with EMAIL_ENABLED=false so the email factory's no-op sender
# kicks in (see PR #333) — otherwise `env` is not a recognised email
# backend and the factory would fail dispatch.
SECRET_PROVIDER=env

# ---------------------------------------------------------------------
# Required: scheduled-task auth mode (no default — must be explicit)
# ---------------------------------------------------------------------
# Selects how the internal /api/scheduled/* endpoints authenticate.
# oidc — production: verify Google-issued OIDC ID tokens
# bearer — shared-secret token in Authorization header
# disabled — local dev: no auth check
# Required by `internal/server/scheduledauth/config.go`; app refuses
# to start when unset.
SCHEDULED_TASK_AUTH_MODE=disabled

# ---------------------------------------------------------------------
# Required: email gate (factory short-circuit, see PR #333)
# ---------------------------------------------------------------------
# When `false`, internal/email/factory.go returns a no-op sender that
# logs each invocation at debug level instead of dispatching to a
# cloud-specific backend. Pair with SECRET_PROVIDER=env for local dev.
EMAIL_ENABLED=false

# ---------------------------------------------------------------------
# Required: credential encryption key
Expand All @@ -35,9 +56,20 @@ CREDENTIAL_ENCRYPTION_ALLOW_DEV_KEY=1
# CREDENTIAL_ENCRYPTION_KEY=<64-hex-chars>

# ---------------------------------------------------------------------
# Required for production: admin auth + API
# ---------------------------------------------------------------------
ADMIN_EMAIL=admin@example.com
# Required: admin auth + API
# ---------------------------------------------------------------------
# With SECRET_PROVIDER=env, the *_SECRET / *_SECRET_ARN vars hold the
# NAME of another env var whose value is the actual secret. The matched
# env var must then be defined below. Two reasons for the indirection:
# (1) production uses the same var name pointing at a real ARN/name;
# (2) the dev value is co-located with its lookup key so future readers
# can trace the chain in one file.
ADMIN_EMAIL=admin@cudly.local
ADMIN_PASSWORD_SECRET=ADMIN_PASSWORD_DEV
ADMIN_PASSWORD_DEV=LocalDev!Pass123
API_KEY_SECRET_ARN=ADMIN_API_KEY_DEV
ADMIN_API_KEY_DEV=cudly-local-dev-api-key-not-for-prod
Comment thread
coderabbitai[bot] marked this conversation as resolved.
# Production examples (override SECRET_PROVIDER and these):
# ADMIN_PASSWORD_SECRET=arn:aws:secretsmanager:us-east-1:000000000000:secret:cudly-admin-password-PLACEHOLDER
# API_KEY_SECRET_ARN=arn:aws:secretsmanager:us-east-1:000000000000:secret:cudly-api-key-PLACEHOLDER

Expand Down
25 changes: 22 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,29 @@ services:
DB_AUTO_MIGRATE: "true"
DB_MIGRATIONS_PATH: /app/internal/database/postgres/migrations

# Secret provider (use aws with empty credentials for local dev)
SECRET_PROVIDER: aws
# Email disabled for local development (no SNS topic)
# Secret provider — "env" reads secrets from env vars (local-dev only).
# Production uses "aws" / "azure" / "gcp" with real Secrets Manager.
SECRET_PROVIDER: env

# Admin password secret: the EnvResolver looks up the env var whose
# NAME equals ADMIN_PASSWORD_SECRET. Here it points at ADMIN_PASSWORD_DEV.
ADMIN_PASSWORD_SECRET: ADMIN_PASSWORD_DEV
ADMIN_PASSWORD_DEV: "LocalDev!Pass123"
ADMIN_EMAIL: admin@cudly.local

# API-key secret: same pattern — name → env var that holds the value.
# Frontend asks for this in the admin-setup modal.
API_KEY_SECRET_ARN: ADMIN_API_KEY_DEV
ADMIN_API_KEY_DEV: "cudly-local-dev-api-key-not-for-prod"

# Credential encryption: dev key (all-zero) is gated behind this flag.
CREDENTIAL_ENCRYPTION_ALLOW_DEV_KEY: "1"

# Email disabled for local development (no SNS topic / SES creds)
EMAIL_ENABLED: "false"
# Scheduled-task auth: OIDC for prod, disabled for local dev so the
# internal /api/scheduled/* endpoints don't require Google ID tokens.
SCHEDULED_TASK_AUTH_MODE: disabled

# Application settings
ENVIRONMENT: development
Expand Down