Accounts and access

Reading time 7 min

Admin > Users manages authenticated writers, not public-reader memberships. An administrator searches/selects an account and uses Access, Account, Sessions and Activity tabs. On phones, Back to users returns from detail with a discard decision for unsaved access edits.

Actual V2 Admin account access screen with fictional accounts

The sample writer has one synthetic section assignment. The image shows a real local V2 interface with fictional accounts, not a production user database.

Permission matrix

Action Admin Editor
Root content Yes No
Assigned descendants Yes Yes
Other section content Yes No
Top section folder changes Yes No
Publication Yes No
Global/account management Yes No
Own password Yes Yes

“Assigned descendants” means authorized read/write/create/rename/delete inside the physical assigned top-level folder. An editor cannot rename/delete/write the top-level section folder itself or move content to another section. The sidebar title/generated URL is not the assignment key.

The server enforces content path/realpath/role checks. Invalid or outside-content paths have their own rejection; outside an editor’s assignments normally answers 404 rather than exposing another section’s names. A disabled account cannot sign in. Admin has broad content access, so operator trust still matters.

Editor authentication does not protect generated reading. Hidden sections still build/search; published index/media can reveal content. If Field Guide is private, configure and test a separate reader gate covering every artifact path.

Account model and limits

Field Contract
Name 2-32 characters; starts lowercase letter/digit
Other name chars Lowercase letters/digits, dot, underscore, dash
Role admin or editor; not later editable here
Sections Valid physical top-level names, deduplicated
Disabled Blocks sign-in; not document deletion
Forced password Next sign-in must change before ordinary APIs
Auth version Persistent value used to invalidate older sessions
Timestamps Creation and actual successful sign-in

Exact account-name pattern is ^[a-z0-9][a-z0-9._-]{1,31}$. UI trims/lowercases a new name; server/store validation still matters. Role/name are read-only after creation; V2 has no account-rename, role-edit or delete-user management action. Choose ownership/role carefully before creation.

Section names use ^[a-z0-9][a-z0-9_-]*$. A section is a real direct folder under content, not a symlink assignment, root file or arbitrary nested path. Missing assigned folders remain labeled in Access instead of silently removing permission records. Investigate runtime/tree/rename/deletion before clearing them.

Passwords must be text, 12-256 JavaScript string characters and not one of the pin’s exact common weak values compared case-insensitively. This is not a general breached-password lookup or enforced composition policy. Hashing uses scrypt with salt/parameters in stored hash and NFKC normalization. Never publish passwords, hashes, tokens or users files. Security and privacy explains wider perimeter/password boundaries.

Create a fictional writer

  1. Verify intended server, protected runtime, account owner and existing sections.
  2. Open Add user. New form defaults editor with no assignments.
  3. Choose valid fictional username and initial password in the private form.
  4. Select intended sections for editor; admin has global access and no assignment list.
  5. Submit and wait for success before treating account as created.
  6. Confirm list/selected account and intended role/sections.
  7. Use a separate session/profile to test allowed and denied writing scope.

Creation accepts the chosen initial password and does not automatically set forced-change state. Browser reset has that separate behavior. Do not call the initial password a one-time system-generated credential unless you actually use reset afterward.

Success clears username/password and closes create dialog, then reloads users. Errors display in the form for review. If a response is lost, inspect current list before resubmitting; duplicate name error can mean first creation succeeded. Do not invent a second account to bypass uncertainty.

Deliver credentials through an approved private process, never public documentation, activity notes or issue. This sample is a workflow, not authority to create a real person’s account or disclose their password.

Access drafts and saving

State/action Result
Toggle Local access draft, not server grant
Select all/none Changes visible draft checks, including labeled missing assignments
Save changes Sends selected list; controls gated while saving
Save success Draft clears; affected sessions invalidated
Save error Edits remain and “Not saved” is shown
Discard Re-renders selected account’s loaded assignments
Select another user Unsaved discard confirmation
Switch detail tab Access draft remains for later save/discard

Changing assignments bumps persistent auth version and ends affected sessions. Ask writers to save intended work first and expect fresh login. A checked row on screen is not evidence the server changed. After success, recheck account and role-session allowed/denied paths.

Account actions may require discarding unsaved access first. Sign out everywhere requires save/discard before proceeding. While access save is active, selection/back/actions are gated. Browser leaving/area changes follow unsaved guards; these are local workflow controls, not permission enforcement.

Access does not have a general content revision merge system. Another operator/account command can change state. Refresh/reconcile current assignments before overwriting unexpected changes; users store protects cross-process writes but cannot infer intended concurrent policy.

Account state actions

Action Effect and limit
Disable Blocks account; sessions end, source remains
Enable Account becomes usable; version changes
Disable self Refused by server; UI also disables action
Last active admin Store refuses disabling it
Browser reset Editor accounts only; not admin recovery
Shell admin reset Selected admin recovery with hidden new password

Enable/disable asks for confirmation. Do not disable an account to delete its documents or remove browser drafts. Keeping one enabled admin is a guard, not a full recovery plan; back up protected runtime and retain operator access.

Browser reset generates 20 random characters grouped with hyphens, shows the temporary password once, sets forced-change and ends sessions. It does not automatically enable a disabled editor. Copy/deliver privately before closing; losing display does not justify guessing the password. Another deliberate reset produces a different credential and invalidates prior one.

The next sign-in can access only the forced-change flow’s permitted APIs until password is changed. An ordinary document request failing at that point is not a section-grant failure. Current/new/confirmation fields belong to private password handling, not Markdown drafts.

Administrator shell recovery uses npm run editor:reset-admin -- --user NAME with correct MARKSTACK_USERS_FILE. It sets a new password, enables that admin, clears forced-change and invalidates old sessions on subsequent requests without needing restart. A wrong users path can look like a missing admin; inspect it before creating/resetting elsewhere.

Sessions tab

Display/action Meaning
Signed-in time Current-process session creation
Last active Session activity time, not a permanent device log
No sessions No current valid entries; restart can explain it
Sign out everywhere Confirmation, version bump and current-session removal
Self selection Includes current session; returns to sign-in

Session summaries omit token hashes/CSRF/secrets and do not refresh idle timer. They filter the selected account’s current auth version. Session store is in memory, so restart ends sessions. Refresh account to see current state; a loaded list is not a live stream.

Persistent last-sign-in remains after restart and updates only after an actual successful login, not opening a users row. Clearing sessions does not clear browser Markdown recovery drafts. A fresh sign-in does not automatically publish or recover source.

Account Activity

The Activity tab shows up to 50 retained target-matching events from the bounded audit store, with event/time. It is not all past account activity, full document version history or proof of authorship for failed login names. Full exact filters/cursor are in Security and history.

An audit-write warning can follow a completed account operation. Check actual account/version/session state before repeating reset/disable/save. Repair protected storage/disk and record missing evidence separately; successful later logging does not reconstruct the gap.

Completion checks

Verify Evidence
Correct account Actual selected name, role and owner decision
Saved scope Current server assignments, not draft checks
Writer session Allowed synthetic section and outside/root/Admin denied
State Enabled/disabled/forced-change as intended
Sessions Expected invalidation and fresh sign-in
Privacy No credentials/runtime bytes in public output
Recovery Protected backup and admin shell path rehearsed

Use disposable content for negative permission tests. UI screenshots/tests are not a production account deployment or a full security certification. Validation limits and Private team editor separate measured engine behavior from host/operator work.