No description
Find a file
Alec Perkins 99f810d043 Harden auth, invites and deployment after security review
- Signed-out visitors get the same login redirect for missing and
  private projects, so the redirect no longer reveals private ones.
- Production refuses the console email backend; sign-in codes must
  never reach the logs.
- Database cache shared by all workers for allauth rate limits; invite
  sending throttled per sender and per recipient.
- Email invite links are claimed on first use and the token rotated,
  so a token copied from request logs is worthless.
- allauth password URLs removed; adding an email requires a fresh code
  and notifies existing addresses.
- Markdown drops remote images until uploads exist.
- Project and org slugs lowercased; only superusers can grant staff
  status or permissions in the admin.
- Container runs as a non-root user; CI actions pinned to commits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-27 08:42:19 -04:00
.forgejo/workflows Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
bin Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
config Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
docs Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
intent Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
static Add projects and features with revision history (Phase 2) 2026-10-27 07:58:16 -04:00
templates Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
tests Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
.dockerignore Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
.env.example Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
.gitignore Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
.python-version Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
compose.yaml Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
Dockerfile Harden auth, invites and deployment after security review 2026-10-27 08:42:19 -04:00
fly.toml Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
litestream.yml Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
manage.py Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
pyproject.toml Add projects and features with revision history (Phase 2) 2026-10-27 07:58:16 -04:00
README.md Scaffold Phase 0: Django project, deploy config, base layout 2026-10-27 06:59:34 -04:00
uv.lock Add projects and features with revision history (Phase 2) 2026-10-27 07:58:16 -04:00

Intent

Track the why behind features, across implementations. See docs/concept.md and docs/plan.md.

Local development

With uv:

uv sync
uv run python manage.py migrate
uv run python manage.py runserver

Or with Docker:

docker compose up --build

Then open http://localhost:8000. Data lives in data/ (uv) or the data volume (Docker).

Checks:

uv run ruff check . && uv run ruff format --check . && uv run pytest

Production

Fly.io, one machine with a volume at /data. bin/start restores the database from B2 if the volume is empty, runs migrations, and starts gunicorn under Litestream.

Secrets (fly secrets set):

Name Purpose
DJANGO_SECRET_KEY Django secret key
LITESTREAM_BUCKET, LITESTREAM_ENDPOINT, LITESTREAM_ACCESS_KEY_ID, LITESTREAM_SECRET_ACCESS_KEY B2 backup bucket
BUCKET_NAME, AWS_* Tigris uploads; set by fly storage create
SENTRY_DSN Optional error reporting

Restore drill: create a fresh volume, deploy, and confirm bin/start logs a restore before migrating.