Plan: Private Notes & Browse Auth
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_publicfield on Note model - [x]
is_publicin NoteCreate, NoteUpdate, NoteOut schemas - [x]
issue-xss-safe-filteralready 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-foundationDepends 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-1note exists withis_public=false, visible only when logged in. Convention note documents the workflow. - [ ] Phase 3: All 40+ notes reviewed,
is_publicset 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
Related
project-pal-e-docs— parent projectplan-2026-02-24-public-docs-and-templates— deferred plan that included public CSS/Funnel workissue-xss-safe-filter— related security concern