← Console
Console/Planning/Document Team Usage
RESOLVING…
Prod candidate →

Document Team Usage · Internal Guide

How your team uses the document platform day-to-day · login · notes · share · access states · what happens when someone follows a link they shouldn't · honest internal-production candidate state
Team guide Live Batch 13 · v1.0 Planning A-owned Internal production candidate · NOT internet-ready

Your session · session ของคุณ

Overview

This guide explains how a team member uses the document platform end-to-end. After Batch 13 the platform is a production-candidate for internal/team use: signed sessions with optional team secret, persistent signing key, rate-limited login, server-delivered HTML render path, and notes backend with optional session-gated mutations. It is NOT yet public-internet ready — TLS, real auth, and reverse-proxy route protection are still pending.

Key Point

Team members log in with their email (+ optional team secret), stay signed in across restarts, and see documents filtered by their profile. Share links work — recipients without access see the stub, not the content.
สมาชิกทีมใช้อีเมล (+ team secret ถ้าเปิด) · session อยู่ข้าม restart · เอกสารถูกกรองตามโปรไฟล์ · ลิงก์แชร์ไม่หลุดเนื้อหาถ้าคนที่รับไม่มีสิทธิ์

Login flow

  1. Go to any shelled document (e.g. Document Groups).
  2. In the "User · Access" panel at the top, type your registered email.
  3. If the operator has set a team secret (DAS_TEAM_SECRET), also fill it in when prompted. Without the correct secret, login fails with team_secret_required_or_mismatch.
  4. The server issues a signed session cookie (ds_session) with an explicit expiry. The mode badge in the topbar flips to BACKEND · LOCAL/DEV.
  5. Session persists across server restarts (because the signing key is persistent in das-signing-key.local) unless the operator rotates the key.
  6. Login is rate-limited to 5/minute/IP by default (DAS_LOGIN_RATE_LIMIT).

Daily use

  • Read: visible documents render normally. Restricted documents show a sticky banner. Hidden/not-granted show a stub page.
  • Notes: submit via the Notes tab at the bottom of any shelled doc. With DNS_REQUIRE_SESSION=true, mutations require your session. Notes persist server-side (no more browser-local loss on cache clear).
  • Share: 🖨 Print / PDF always available for visible docs. 🔗 Copy link copies the URL. 📤 Share opens the OS share sheet on supported browsers.
  • Switch profile: use the user panel. Previous session is revoked on logout.
  • Mode badge: BACKEND (green) when backend is reachable; OFFLINE (rose) falls back to browser-local; DISABLED if the shell is configured with data-ds-auth-base="none".

When access is denied · things your team will see

  • No profile (anonymous): groups the operator marked public remain visible; everything else shows the stub.
  • Wrong team secret: login rejected with team_secret_required_or_mismatch.
  • Disabled profile: login may succeed once; every subsequent /me or /resolve call returns anonymous — effectively a lockout.
  • Expired session: the next API call returns anonymous; the shell flips the mode badge. Re-login to resume.
  • Rate-limited: HTTP 429 · retry after the window.
  • Server-rendered hidden: if the operator has wired the reverse-proxy to /render, the recipient sees the stub page and no content.

For the operator

  • Env vars: access deployment.md + notes deployment.md
  • Rotate signing key: delete das-signing-key.local and restart (invalidates all sessions).
  • Rotate team secret: set DAS_TEAM_SECRET to a new value and restart (existing sessions continue unless combined with key rotation).
  • Disable a user: set status: "disabled" in user_store_examples.json and restart. Their session is rejected on every verify.
  • Enforce HTTP gating: add a reverse-proxy rule that routes protected document paths through /api/access/render (example in document-http-gating.html).
  • Require notes mutations to be signed-in: set DNS_REQUIRE_SESSION=true on the notes service.
  • Debug surfaces: access debug · notes debug

Honest limits

  • No TLS · cookie is HttpOnly=false/Secure=false. Acceptable for a LAN/VPN team deployment only.
  • No real password / OAuth / SSO. Login is email (+ optional shared team secret). Not strong enough for public internet.
  • Without reverse-proxy rule to /api/access/render, HTTP-level gating does not cover all URLs.
  • Notes backend is single-writer. Concurrent team editing will lose updates.
  • No audit log of auth or note events. Session activity is not traceable.
  • In-memory rate limit and revocation — multi-instance needs Redis.

Go-live checklist (internal / team)

  • Pick deployment perimeter — LAN / VPN-only. NOT public internet.
  • Generate and store signing key: python3 -c "import secrets;print(secrets.token_hex(32))" → set as DAS_SIGNING_KEY in your secret manager OR let das-signing-key.local be auto-generated (ensure it's gitignored).
  • Set DAS_TEAM_SECRET to a freshly-rotated value and share via a secure channel.
  • Set DAS_ALLOW_ORIGINS to the console origin (comma-separated for multi-origin).
  • Set DAS_REJECT_QUERY_TOKEN=true to forbid tokens in URLs.
  • Set DAS_SESSION_TTL to an appropriate value (8h–24h recommended).
  • Set DAS_LOGIN_RATE_LIMIT to a non-zero value (default 5/min).
  • Review user_store_examples.json — add real team emails with intended visibility; remove example users; set status: "disabled" for dormant accounts.
  • Set DNS_REQUIRE_SESSION=true + DNS_ALLOW_ORIGINS=<console> on the notes service.
  • Smoke-test the mandatory use cases (login · disabled user denied · expired session · direct URL gated · notes persist · share fallback).
  • Document incident response — who rotates the signing key when a session is compromised.
  • Document rollback — stop the services and the static site remains legacy (Batch 9 scaffold behaviour).
  • OPTIONAL but recommended: wire nginx/Cloudflare to route protected paths through /api/access/render for true HTTP-level gating.
  • If going to anything bigger than team-internal: stop. Real password/OAuth + TLS + audit + Redis-backed sessions are required. See Production Candidate for the remaining gap list.

Notes