summaryrefslogtreecommitdiff
path: root/www/json-api/api-auth.md
diff options
context:
space:
mode:
authorcashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
committercashmere <cashmere@autistici.org>2026-09-04 09:05:24 +0200
commit4f49b16079b27d7ce633619e4cddfdf2bffbc952 (patch)
treec296c1e7f3c3e2f6859c6d3a1b1b208779b89679 /www/json-api/api-auth.md
downloadrelic-master.tar.gz
initial commitHEADmaster
Diffstat (limited to 'www/json-api/api-auth.md')
-rw-r--r--www/json-api/api-auth.md271
1 files changed, 271 insertions, 0 deletions
diff --git a/www/json-api/api-auth.md b/www/json-api/api-auth.md
new file mode 100644
index 0000000..96854da
--- /dev/null
+++ b/www/json-api/api-auth.md
@@ -0,0 +1,271 @@
+# JSON API: X
+([&#x2b11;JSON API Index](index.md))
+
+Jump to:
+
+* [Introduction](#intro)
+* [Capabilities (Access Rights)](#capabilities)
+* [Login](#login)
+ * [Anonymous User Logins](#login-anonymous)
+* [Logout](#logout)
+* [Whoami](#whoami)
+
+---
+
+<a id="intro"></a>
+# Introduction
+
+**FIXME:** Ross found a bug:
+[](/info/479aadb1d2645601)
+(sending the authToken via `POST.envelope` isn't working. It should be.)
+
+The authentication-related operations are described in this section
+(ordered alphabetically by operation name).
+
+The JSON API ties in to/piggybacks on fossil's existing cookie-based
+login mechanism, but we must also keep in mind that not all JSON-using
+clients support cookies. Cookie-capable clients can rely on cookies for
+authentication, whereas non-cookie-aware clients will need to keep track
+of the so-called "auth token" which is created via a login request, and
+pass it in with each request (either as a GET parameter or a property of
+the top-level POST request envelope) to prove to fossil that they are
+authorized to access the requested resources. For most intents and
+purposes, the "auth token" and the "login cookie" are the same thing (or
+serve the same purpose), and the auth token is in fact just the value
+part of the login cookie (which has a project-specific key).
+
+Note that fossil has two conventional user names which can show up in
+various responses but do not refer to specific people: nobody and
+anonymous. The nobody user is anyone who is not logged in. The anonymous
+user is logged in but has no persistent user data (no associated user
+name, email address, or similar). Normally the guest (nobody) user has
+more access restrictions. The distinction between the two is largely
+historical - it is a mechanism to keep bots from following the
+multitudes of links generated by the HTML interface (especially the ZIP
+files), while allowing interested users to do so by logging in as the
+anonymous user (which bots have (or *had*, at the time) a harder time
+doing because the password is randomly generated and protected from
+brute-force attacks by hashing). In the JSON API, the distinction
+between anonymous and nobody is not expected to be as prominent as it is
+in the HTML interface because the reasons for the distinction don't
+apply in *quite* the same ways to the JSON interface. It is possible,
+however, that a given repo locks out guest access to, e.g. the wiki or
+tickets, while still allowing anonymous (logged in) access.
+
+<a id="capabilities"></a>
+# Capabilities (Access Rights)
+
+The "cap" request returns information about the so-called "capabilities"
+(access rights) of the currently logged in user. This command is
+basically the same as the "whoami" command, but returns capabilities in
+a more exanded form (same data, different representation) and does not
+include the authToken in the response.
+
+TODO: consider combining this and [whoami](#whoami) into a single
+whoami response. We don't need both. We also don't really need the
+permissionFlags member - the same info is already \[in a more cryptic form\]
+in the capabilities string.
+
+**Status:** implemented 201109xx.
+
+**Required privileges:** none
+
+**Request:** `/json/cap`
+
+In CLI mode, permissions are not used/honored, and this command will
+report that the caller has all permissions (which he effectively does).
+
+**Response payload example:**
+
+```json
+{
+"userName":"json-demo",
+"capabilities":"hgjorxz", /* raw fossil permissions list */
+"permissionFlags":{ /* Same info in a somewhat friendlier form */
+ "setup": false,
+ "admin": false,
+ "delete": false,
+ "password": false,
+ "query": false,
+ "checkin": false,
+ "checkout": true,
+ "history": true,
+ "clone": false,
+ "readWiki": true,
+ "createWiki": false,
+ "appendWiki": false,
+ "editWiki": false,
+ "readTicket": true,
+ "createTicket": false,
+ "appendTicket": false,
+ "editTicket": false,
+ "attachFile": false,
+ "createTicketReport": false,
+ "readPrivate": false,
+ "zip": true,
+ "xferPrivate": false
+ }
+}
+```
+
+**FIXME:** several new permissions have been added to fossil since
+this API was implemented.
+
+
+<a id="login"></a>
+# Login
+
+**Status:** implemented 20110915 (anonymous login 20110918)
+
+**Required privileges:** none
+
+**Request:** (see below for Anonymous user special case)
+
+- `/json/login?name=...&password=...`
+- `/json/login?n=...&p=...` (for symmetry with existing login mechanism)
+
+Or `POST.payload`: `{ "name": ..., "password": ...}`
+
+(POST is highly preferred because it keeps the password out of web
+server logs!)
+
+**Response payload example:** (structure changed 20111001)
+
+```json
+{
+"authToken":"...",
+"name":"json-demo",
+"capabilities":"hgjorxz",
+"loginCookieName": "fossil-XXXXX" /*project-specific cookie name*/
+/* TODO: add authTokenExpiry timestamp (cookie expiry time) */
+}
+```
+
+We "should" be able to inherit fossil's `REMOTE_USER` handling without
+any special support, but that is untested so far. (If you happen to test
+this, please update this doc with (or otherwise report) your results!)
+
+The response *also* sets the conventional fossil login cookie (for
+clients which can make use of cookies), using fossil's existing
+mechanism for this.
+
+Further requests which require authentication must include the
+`authToken` (from the returned payload value) in the request (or it must
+be available via fossil's standard cookie) or access may (depending on
+the request) be denied. The `authToken` may optionally be set in the
+request envelope or as a GET parameter, and it *must* be given if the
+request requires restricted access to a resource. e.g. if reading
+tickets is disabled for the guest user then all non-guest users must
+send authentication info in their requests in order to be able to fetch
+ticket info.
+
+Cookie-aware clients should send the login-generated cookie with each
+request, in which case they do not need to explicitly include the
+`authToken` in the JSON envelope/GET arguments. If submitted, the
+`authToken` is used, otherwise the cookie, if set, is used. Note that
+fossil uses a project-dependent cookie name in order to help thwart
+attacks, so there is no simple mapping of cookie *name* to auth
+token. That said, the cookie's *value* is also the auth token's value.
+
+> Special case: when accessing fossil over a local server instance
+which was started with the `--localauth` flag, the `authToken` is ignored
+(neither validated nor used for any form of authentication).
+
+
+<a id="login-anonymous"></a>
+## Anonymous User Logins
+
+The Anonymous user requires special handling because he has a random
+password.
+
+First fetch the password and the so-called "captcha seed" via this
+request:
+
+`/json/anonymousPassword`
+
+It will return a payload in the form:
+
+```json
+{
+"seed": a_32_bit_unsigned_integer,
+"password": "1234abcd" /*hexadecimal STRING*/
+}
+```
+
+The "seed" and "password" values of the response payload must be set as
+the "anonymousSeed" and "password" fields (respectively) of the
+subsequent login request. The login request is identical to
+non-anonymous login except that extra "anonymousSeed" property is
+required.
+
+The password value *may* be time-limited, and *may* eventually become
+invalidated due to old age. This is unspecified.
+
+***Potential***** (low-probability) bug regarding the seed value:** from
+what I hear, some unusual JSON platforms don't support full 32-bit
+precision. If absolutely necessary we could chop off a bit or two from
+the seed value (*if* it ever becomes a problem and if DRH blesses it).
+Or we could just make it a double.
+
+
+<a id="logout"></a>
+# Logout
+
+**Status:** implemented 20110916
+
+**Required privileges:** none, but must be logged in
+
+**Request:**
+
+ - `/json/logout?authToken=...token fetched by /login`
+
+Or: set the `authToken` property of the POST envelope (as opposed to the
+`POST.payload`)
+
+Or: fossil's normal cookie mechanism is the fallback for the auth token.
+
+**Response payload:** The same as the "whoami" response, containing the
+info for the "nobody" user.
+
+This request requires the authentication token, and subsequent logouts
+without an intervening login will fail with the "auth token not
+provided" error. In effect this request removes the login entry from the
+user account, making the token invalid for future requests. In HTTP
+mode, on success fossil's login cookie is unset by this call.
+
+
+<a id="whoami"></a>
+# Whoami
+
+This request fetches the current user's login name, capabilities, and
+auth token. This can be used to check whether a login is active when the
+client has not explicitly logged in (e.g. was logged in automatically
+via a pre-existing cookie).
+
+**Status:** implemented 20110922
+
+**Required privileges:** none
+
+**Request:** `/json/whoami`
+
+**Response payload example:**
+
+```json
+{
+"name": "nobody",
+"capabilities": "o",
+"authToken": "fossil auth token (only for logged-in users)"
+}
+```
+
+The reason authToken is included in the response is because it gives
+client-side JavaScript code a way of fetching/checking for the auth
+token at app startup. The token is normally sent as a cookie but parsing
+the cookies in the browser is tedious, and fossil has a
+project-dependent cookie name (which complicates parsing a bit). If
+client code digs the cookie out of the browser, the app still wouldn't
+know if the token is still valid, whereas whoami won't (or shouldn't!)
+return an expired auth token. If the request does not include
+authentication info (via the cookie, GET param, or request envelope)
+then the response will not contain the authToken property and the user's
+name will be "nobody".