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.
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 · เอกสารถูกกรองตามโปรไฟล์ · ลิงก์แชร์ไม่หลุดเนื้อหาถ้าคนที่รับไม่มีสิทธิ์
DAS_TEAM_SECRET), also fill it in when prompted. Without the correct secret, login fails with team_secret_required_or_mismatch.ds_session) with an explicit expiry. The mode badge in the topbar flips to BACKEND · LOCAL/DEV.das-signing-key.local) unless the operator rotates the key.DAS_LOGIN_RATE_LIMIT).DNS_REQUIRE_SESSION=true, mutations require your session. Notes persist server-side (no more browser-local loss on cache clear).data-ds-auth-base="none".| Sender state | Recipient without access | Recipient with access |
|---|---|---|
| visible doc | URL works for them if their profile shows visible | sees full content |
| restricted doc | sees restricted banner + metadata | sees full content + banner |
| hidden-doc / hidden-group / not-granted | sees stub page · no content leakage | sees full content |
Important: sharing is NOT gated at the HTTP layer for the original static URL unless the operator has configured a reverse-proxy rule to route through /api/access/render. Without that, a recipient who knows the direct URL may still see the file if the static host permits it. Shell-based pages still swap to stub on access denial.
team_secret_required_or_mismatch./me or /resolve call returns anonymous — effectively a lockout.das-signing-key.local and restart (invalidates all sessions).DAS_TEAM_SECRET to a new value and restart (existing sessions continue unless combined with key rotation).status: "disabled" in user_store_examples.json and restart. Their session is rejected on every verify./api/access/render (example in document-http-gating.html).DNS_REQUIRE_SESSION=true on the notes service.HttpOnly=false/Secure=false. Acceptable for a LAN/VPN team deployment only./api/access/render, HTTP-level gating does not cover all URLs.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).DAS_TEAM_SECRET to a freshly-rotated value and share via a secure channel.DAS_ALLOW_ORIGINS to the console origin (comma-separated for multi-origin).DAS_REJECT_QUERY_TOKEN=true to forbid tokens in URLs.DAS_SESSION_TTL to an appropriate value (8h–24h recommended).DAS_LOGIN_RATE_LIMIT to a non-zero value (default 5/min).user_store_examples.json — add real team emails with intended visibility; remove example users; set status: "disabled" for dormant accounts.DNS_REQUIRE_SESSION=true + DNS_ALLOW_ORIGINS=<console> on the notes service./api/access/render for true HTTP-level gating.