Plan: Private Notes & Browse Auth

plan-2026-02-25-private-notes-auth Plan

plan completed

Plan: Private Notes & Browse Auth

Vision

pal-e-docs is the single coordination hub for the pal-e AI agency. The browse frontend at https://pal-e-docs.tail5b443a.ts.net/browse/ is publicly accessible via Tailscale Funnel. Personal/private notes must be invisible to unauthenticated visitors and only visible to approved logged-in users.

Projects & Repos Touched

Project/Repo Platform Role in this plan
pal-e-docs Forgejo Auth implementation, frontend filtering, migration
pal-e-docs-mcp Forgejo No changes — API stays unauthenticated (Tailscale-only)

Context

The browse frontend is public via Tailscale Funnel. The Note model already has an is_public field, but it is not enforced — all notes are visible to all visitors regardless of this flag. There is no auth system. Forgejo issue #2 tracks auth integration.
User wants a private project for personal notes (poems, reflections, private thoughts) with a simple workflow: "hey claude private note" → creates a numbered note in the private project.
What's already done:
  • [x] is_public field on Note model
  • [x] is_public in NoteCreate, NoteUpdate, NoteOut schemas
  • [x] issue-xss-safe-filter already flagged as open issue
  • [x] Auth system (PR #27 merged)
  • [x] Browse frontend filters by is_public
  • [x] Users table with bcrypt hashing
  • [ ] Private project and convention not yet created

Previous Plan

plan-2026-02-24-docs-foundation

Depends On

None — can proceed independently.

Decisions Made

Decision Rationale
SQLite for users table, not Postgres pal-e-docs already uses SQLite; single-user/small-group auth doesn't need Postgres
Session cookies, not JWT Browse frontend is server-rendered Jinja2; cookies are the natural fit. No SPA, no need for JWT.
passlib + bcrypt for password hashing Industry standard, arch-level security
itsdangerous for signed cookies Already a Starlette dependency; simple and secure
API stays unauthenticated Only accessible via Tailscale (MCP server, agents). Adding auth would break all MCP tooling for no benefit.
<code>priv-</code> slug prefix for private notes Clear namespace, easy to identify
Private project slug: <code>private</code> Simple, clear

Phases

Phase 1 — Auth system + browse filtering ✅

  • Slug: phase-2026-02-25-1-auth-and-filtering
  • Goal: Full auth flow — users table, login/logout, and is_public filtering on browse frontend. One deployable unit.
  • Owner: Agent (code change)
  • Status: COMPLETE
  • Deliverables:

Phase 2 — Private project & first note

  • Slug: phase-2026-02-25-2-private-project
  • Goal: Create the private project, first private note, and establish the convention
  • Owner: Main session (docs)
  • Steps:

Phase 3 — Audit existing notes

  • Slug: phase-2026-02-25-3-note-audit
  • Goal: Review all 40+ notes and confirm is_public is set correctly for each
  • Owner: Main session (docs)
  • Steps:

Key Files

Phase File Repo Change
1 src/pal_e_docs/models.py pal-e-docs Add User model
1 src/pal_e_docs/auth.py pal-e-docs New — auth helpers
1 src/pal_e_docs/config.py pal-e-docs Add SECRET_KEY
1 alembic/versions/ pal-e-docs New migration for users table
1 pyproject.toml pal-e-docs Add passlib[bcrypt]
1 src/pal_e_docs/templates/login.html pal-e-docs New — login form
1 src/pal_e_docs/templates/base.html pal-e-docs Add login/logout nav button
1 src/pal_e_docs/routes/frontend.py pal-e-docs Login/logout routes + is_public filtering

Verification

  • [x] Phase 1: Visit /browse/ unauthenticated — private notes invisible. Log in at /browse/login — private notes appear. Log out — they disappear. Direct URL to private note redirects to login. Open redirect blocked. Linked notes filtered. 3 QA rounds passed.
  • [ ] Phase 2: priv-1 note exists with is_public=false, visible only when logged in. Convention note documents the workflow.
  • [ ] Phase 3: All 40+ notes reviewed, is_public set correctly, verified from unauthenticated browser.

Next Plan Seeds

  • XSS sanitization (issue-xss-safe-filter) — must address before auth gives false sense of security on content injection
  • API auth — if API is ever exposed beyond Tailscale, it needs token auth too (Forgejo issue #2)
  • Note graph visualization — Obsidian-style interactive graph of note connections on landing page
  • Frontend redesign — separate presentation layer (pal-e-docs-server?), better mermaid rendering, professional styling
  • CSRF protection on login form
  • project-pal-e-docs — parent project
  • plan-2026-02-24-public-docs-and-templates — deferred plan that included public CSS/Funnel work
  • issue-xss-safe-filter — related security concern