summaryrefslogtreecommitdiff
path: root/docs/PROTOCOL.md
diff options
context:
space:
mode:
authorAnders Betts <anders.betts@gmail.com>2026-09-23 10:08:44 +0200
committerAnders Betts <anders.betts@gmail.com>2026-09-23 10:08:44 +0200
commite06248ef69b33d102a57aaa31fffcde3240dad9c (patch)
treed2b82eb5a5e2918336f89e241efdeed8bed5ca95 /docs/PROTOCOL.md
parent79b27457125dc2e259783359085021eea1d26e3a (diff)
downloadbokf-e06248ef69b33d102a57aaa31fffcde3240dad9c.tar.gz
bokf-e06248ef69b33d102a57aaa31fffcde3240dad9c.zip
user.set_password: change your own password; TUI "Byt lösenord"v0.1.68
Needs the current password (wrong ones rate limited like logins) and a password session, requires at least 10 characters, closes the user's other sessions and is audited without secrets. The TUI main menu gets "Byt lösenord" with masked prompts; ^R keeps working with the new password. Masked prompt buffers are wiped before they are freed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'docs/PROTOCOL.md')
-rw-r--r--docs/PROTOCOL.md15
1 files changed, 13 insertions, 2 deletions
diff --git a/docs/PROTOCOL.md b/docs/PROTOCOL.md
index ae1098f..9ab9620 100644
--- a/docs/PROTOCOL.md
+++ b/docs/PROTOCOL.md
@@ -86,6 +86,13 @@ and returns an opaque, high-entropy session id:
- Sliding TTL, `session_ttl` default 8 h. `session.close` ends one explicitly.
- Passwords are stored as Argon2id hashes. Failed logins are rate limited per
peer (default: 5 failures per 15 minutes, then `RATE_LIMITED`).
+- A user changes their own password with `user.set_password` from a
+ password session (a token session gets `FORBIDDEN`). The current password
+ is required — 5 wrong ones per 15 minutes give `RATE_LIMITED` — and the
+ new one must have at least 10 characters and differ from it. On success
+ every other session of the user is closed (`sessions_closed`); the call's
+ own session stays. The audit entry (`user.set_password`, also for a wrong
+ current password) carries no password.
- Token lookups compare SHA-256 hashes in constant time. Token values are
shown exactly once at creation and are never logged.
@@ -97,7 +104,7 @@ and returns an opaque, high-entropy session id:
- Tokens are the intended mechanism for agents and for accountant/viewer
access. They can be revoked immediately (`token.revoke`). Scopes are
enforced for every command, including admin commands: `backup.snapshot`
- and `user.*` need a token with the `admin` scope.
+ and `user.create`/`user.list` need a token with the `admin` scope.
### 4.3 Roles and permissions
@@ -115,6 +122,7 @@ Scopes on a token can narrow but never widen the user's role.
| `payroll.agi` (decrypted personnummer), `payroll.tax_tables_fetch/import` | | | ● | |
| `org.member_*`, `token.create` for others | | | ● | |
| `user.create`, any org | | | | ● |
+| `user.set_password` (own password) | ● | ● | ● | ● |
| `backup.snapshot` | | | ● | ● |
Any authenticated user may create a new org (config `allow_org_create`,
@@ -295,6 +303,7 @@ Arguments are shown abbreviated; `describe` is authoritative.
| `board.add` / `board.update` / `board.remove` | `name`,`title?` / `id`,`name?`,`title?` / `id` | owner; audited |
| `user.create` | `username`, `password`, `display_name`, `is_admin?` | `user` (system admin) |
| `user.list` | — | `items[]` (system admin) |
+| `user.set_password` | `current_password`, `new_password` | `sessions_closed` (own password; password session only) |
| `token.create` | `label`, `scopes[]`, `org`, `expires_at?` | `token` (shown once), `id` |
| `token.list` / `token.revoke` | — / `id` | `items[]` / `{}` |
@@ -826,6 +835,7 @@ Args: `name:type(values)[!][=default]`, `!` = required.
| `session.whoami` | viewer | no | no | no | — |
| `session.list_orgs` | viewer | no | no | no | — |
| `session.use_org` | viewer | no | no | no | `org:int!` |
+| `user.set_password` | viewer | no | yes | no | `current_password:string!`, `new_password:string!` |
| `org.create` | viewer | no | yes | yes | `name:string!`, `org_nr:string`, `fiscal_year_start_month:int=1`, `moms_period:enum(month\|quarter\|year)=month`, `framework:enum(K2\|K3)=K2` |
| `org.list` | viewer | no | no | no | — |
| `org.get` | viewer | yes | no | no | — |
@@ -935,7 +945,8 @@ Args: `name:type(values)[!][=default]`, `!` = required.
commands. Implemented screens (0.1.0-dev):
- **Inloggning** — server, user, password; org picker when several exist.
- **Byt bolag** in the main menu reopens the picker during the session.
+ **Byt bolag** in the main menu reopens the picker during the session;
+ **Byt lösenord** calls `user.set_password`.
- **Dashboard** — status line with org, fiscal year, role and user.
- **Verifikat** — list and detail view (rows with column headers, an
underlag section separated by a rule, hash, link to corrected voucher); `c`