aboutsummaryrefslogtreecommitdiffstats
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/USERGUIDE.md37
1 files changed, 28 insertions, 9 deletions
diff --git a/docs/USERGUIDE.md b/docs/USERGUIDE.md
index abfc404..7bd695b 100644
--- a/docs/USERGUIDE.md
+++ b/docs/USERGUIDE.md
@@ -98,10 +98,10 @@ POST /v1/users/register
POST /v1/users/login
{"username": "yourname", "password": "yourpassword"}
→ {
- "access_token": "JWT (Ed25519, 1 hour validity)",
+ "access_token": "JWT (Ed25519, 4 hour validity)",
"refresh_token": "opaque 256-bit token (30 days)",
"token_type": "bearer",
- "expires_in": 3600,
+ "expires_in": 14400,
}
```
@@ -117,12 +117,20 @@ curl -s -X POST https://meshbay.org/v1/users/login \
### Token refresh
-Access tokens are valid for 1 hour. When one expires, use the refresh token to get a new one without re-entering your password:
+Access tokens are valid for 4 hours. **The web app does this for itself** — it
+renews ten minutes before expiry, on returning to the tab, and on any 401, then
+replays the request. Nobody should meet an expired token in the browser; what
+follows is for other clients.
+
+The endpoint **rotates**: it revokes the refresh token you present and returns a
+new one, so store the replacement. Presenting a revoked token is treated as
+theft and revokes the whole family, which is a full sign-out.
```
POST /v1/users/token/refresh
{"refresh_token": "your-refresh-token"}
-→ {"access_token": "new JWT", "token_type": "bearer", "expires_in": 3600}
+→ {"access_token": "new JWT", "refresh_token": "USE THIS NEXT TIME",
+ "token_type": "bearer", "expires_in": 14400}
```
```bash
@@ -131,7 +139,13 @@ curl -s -X POST https://meshbay.org/v1/users/token/refresh \
-d '{"refresh_token":"YOUR_REFRESH_TOKEN"}'
```
-Refresh tokens are valid for 30 days and can be immediately invalidated by the hub on account compromise. Revoking the refresh token means the next access token renewal will fail; any active access token expires within 1 hour at most.
+Refresh tokens are valid for 30 days — that is the session — and can be
+invalidated by the hub at once on account compromise. Revoking one means the
+next renewal fails; an access token already issued keeps working for up to 4
+hours. That window is not the whole story: the hub reloads the account on every
+request and refuses a suspended one immediately, and it pushes signed
+revocations to nodes, so suspending an account or revoking a membership takes
+effect at once regardless of the token's remaining life.
### Access token structure
@@ -146,7 +160,7 @@ The JWT payload contains:
| `groups` | The `group_id`s you are a member of, for node-side authorization |
| `scope` | `user` for a browser, `node` for a daemon |
| `iat` | Issued at (Unix timestamp) |
-| `exp` | Expires at (Unix timestamp, 1 hour from issue) |
+| `exp` | Expires at (Unix timestamp, 4 hours from issue — `[jwt] access_token_ttl`) |
The token carries **no public key of yours**. It used to carry `pk_user`, and a node
recorded that key as the uploader of a file — which meant the party issuing tokens
@@ -166,7 +180,7 @@ What deletion does:
- Releases the username — someone else may register it afterwards
- Clears the email and password hash, and drops the node linking key
- Removes group memberships, notifications and refresh tokens
-- Refuses any access token still in its hour of validity, immediately
+- Refuses any access token still within its validity, immediately
What deletion does **not** do:
@@ -867,7 +881,7 @@ Two layers:
- `jti` (UUID4) is mandatory in every token — prevents replay (Ed25519 signing is deterministic; without `jti`, two tokens issued in the same second are byte-for-byte identical) and enables individual revocation
- Nodes verify JWTs offline using the hub's cached public key — no hub roundtrip, no hub downtime dependency
-- Revocation: hub invalidates refresh token → next access token renewal fails → node access expires within 1 hour. For immediate revocation: hub adds `jti` to a denylist that nodes periodically fetch
+- Revocation: hub invalidates refresh token → next access token renewal fails → node access expires within the access token's life. For immediate revocation: hub adds `jti` to a denylist that nodes periodically fetch
### What node compromise exposes
@@ -961,7 +975,12 @@ These logs are not used for any purpose other than responding to legal requests.
**Symptom:** node returns 401, error says "expired" or "Token signature expired".
-**Fix:** your access token is over 1 hour old. Refresh it:
+In the web app this should not happen: it renews before expiry and retries once
+on a 401. If you see it there, the renewal path itself is broken — check the
+browser console rather than the token.
+
+**Fix (other clients):** your access token is over 4 hours old. Refresh it, and
+**keep the refresh token that comes back** — the one you sent is now revoked:
```bash
curl -s -X POST https://meshbay.org/v1/users/token/refresh \