Fossil SCM

fossil-scm / www / caps / index.md
1
# Administering User Capabilities (a.k.a. Permissions)
2
3
Fossil includes a powerful [role-based access control system][rbac]
4
which affects which users have which capabilities(^Some parts of the
5
Fossil code call these “permissions” instead, but since there is [a
6
clear and present risk of confusion](#webonly) with operating system
7
level file permissions in this context, we avoid using that term for
8
Fossil’s RBAC capability flags in these pages.) within a given
9
[served][svr] Fossil repository. We call this the “caps” system for
10
short.
11
12
Fossil stores a user’s caps as an unordered string of ASCII characters,
13
one capability per, [currently](./impl.md#choices) limited to
14
[alphanumerics][an]. Caps are case-sensitive: “**A**” and “**a**” are
15
different user capabilities.
16
17
This is a complex topic, so some sub-topics have their own documents:
18
19
1. [Login Groups][lg]
20
2. [Implementation Details](./impl.md)
21
3. [User Capability Reference](./ref.html)
22
23
[an]: https://en.wikipedia.org/wiki/Alphanumeric
24
[avs]: ./admin-v-setup.md
25
[lg]: ./login-groups.md
26
[rbac]: https://en.wikipedia.org/wiki/Role-based_access_control
27
28
29
## <a id="ucat"></a>User Categories
30
31
Before we explain individual user capabilities and their proper
32
administration, we want to talk about an oft-overlooked and
33
misunderstood feature of Fossil: user categories.
34
35
Fossil defines four user categories. Two of these apply based on the
36
user’s login status: **nobody** and **anonymous**. The other two act
37
like Unix or LDAP user groups: **reader** and **developer**. Because we
38
use the word “group” for [another purpose][lg] in Fossil, we will
39
avoid using it that way again in this document. The correct term in
40
Fossil is “category.”
41
42
Fossil user categories give you a way to define capability sets for four
43
hard-coded situations within the Fossil C source code. Logically
44
speaking:
45
46
> *(developer* &or; *reader)* &ge; *anonymous* &ge; *nobody*
47
48
When a user visits a [served Fossil repository][svr] via its web UI,
49
they initially get the capabilities of the “nobody” user category. This
50
category would be better named “everybody” because it applies whether
51
you’re logged in or not.
52
53
When a user logs in as “anonymous” via [`/login`](/help?name=/login) they
54
get all of the “nobody” category’s caps plus those assigned to the
55
“anonymous” user category. It would be better named “user” because it
56
affects all logged-in users, not just those logged in via Fossil’s
57
anonymous user feature.
58
59
When a user with either the “reader” ([**u**][u]) or “developer”
60
([**v**][v]) capability letter logs in, they get their [individual user
61
caps](#ucap) plus those assigned to this special user category. They
62
also get those assigned to the “anonymous” and “nobody” categories.
63
64
Because “developer” users do not automatically inherit “reader” caps,
65
it is standard practice to give both letters to your “developer” users:
66
**uv**. You could instead just assign cap **u** to the “developer”
67
category.
68
69
Fossil shows how these capabilities apply hierarchically in the user
70
editing screen (Admin → Users → name) with the `[N]` `[A]` `[D]` `[R]`
71
tags next to each capability check box. If a user gets a capability from
72
one of the user categories already assigned to it, there is no value in
73
redundantly assigning that same cap to the user explicitly. For example,
74
with the default **ei** cap set for the “developer” category, the cap
75
set **ve** is redundant because **v** grants **ei**, which includes
76
**e**.
77
78
We suggest that you lean heavily on these fixed user categories when
79
setting up new users. Ideally, your users will group neatly into one of
80
the predefined categories, but if not, you might be able to shoehorn
81
them into our fixed scheme. For example, the administrator of a
82
wiki-only Fossil repo for non-developers could treat the “developer”
83
user category as if it were called “author,” and a forum-only repo could
84
treat the same category as if it were called “member.”
85
86
There is currently no way to define custom user categories.
87
88
[svr]: ../server/
89
90
91
## <a id="ucap"></a>Individual User Capabilities
92
93
When one or more users need to be different from the basic capabilities
94
defined in user categories, you can assign caps to individual users. You
95
may want to have the [cap reference][ref] open when doing such work.
96
97
It is useful at this time to expand on the logical
98
expression [above](#cat), which covered only the four fixed user categories.
99
When we bring the individual user capabilities into it, the complete
100
expression of the way Fossil implements user power becomes:
101
102
> *setup* &ge; *admin* &ge; *moderator* &ge; *(developer* &or; *reader)* &ge; *[subscriber]* &ge; *anonymous* &ge; *nobody*
103
104
The two additions at the top are clear: [setup is all-powerful][apsu],
105
and since admin users have [all capabilities][ref] except for Setup
106
capability, they are [subordinate only to the setup user(s)][avsp].
107
108
The moderator insertion could go anywhere from where it’s shown now down
109
to above the “anonymous” level, depending on what other caps you give to
110
your moderators. Also, there is not just one type of moderator: Fossil
111
has [wiki][l], [ticket][q], and [forum][5] moderators, each
112
independent of the others. Usually your moderators are fairly
113
high-status users, with developer capabilities or higher, but Fossil
114
does allow the creation of low-status moderators.
115
116
The placement of “subscriber” in that hierarchy is for the
117
sort of subscriber who has registered an account on the repository
118
purely to [receive email alerts and announcements][7]. Users with
119
additional caps can also be subscribers, but not all users *are* in fact
120
subscribers, which is why we show it in square brackets. (See [Users vs
121
Subscribers](../alerts.md#uvs).)
122
123
[apsu]: ./admin-v-setup.md#apsu
124
[avsp]: ./admin-v-setup.md#philosophy
125
126
127
## <a id="new"></a>New Repository Defaults
128
129
Fossil creates one user account in new repos, which is named after your
130
OS user name [by default](#defuser).
131
132
Fossil gives the initial repository user the [all-powerful Setup
133
capability][apsu].
134
135
Users who visit a [served repository][svr] without logging in get the
136
“nobody” user category’s caps which default to
137
**[g][g][j][j][o][o][r][r][z][z]**: clone the repo, read the wiki,
138
check-out files via the web UI, view tickets, and pull version archives.
139
This default is suited to random passers-by on a typical FOSS project’s
140
public web site and its code repository.
141
142
Users who [prove they are not a bot][bot] by logging in — even if only
143
as “anonymous” — get the “nobody” capability set plus
144
**[h][h][m][m][n][n][c][c]**: see internal hyperlinks, append to
145
existing wiki articles, file new tickets, and comment on existing
146
tickets. We chose these additional capabilities as those we don’t want
147
bots to have, but which a typical small FOSS project would be happy to
148
give anonymous humans visiting the project site.
149
150
The “reader” user category is typically assigned to users who want to be
151
identified within the repository but who primarily have a passive role
152
in the project. The default capability set on a Fossil repo adds
153
**[k][k][p][p][t][t][w][w]** caps to those granted by “nobody” and
154
“anonymous”. This category is not well-named, because the default caps
155
are all about modifying repository content: edit existing wiki pages,
156
change one’s own password, create new ticket report formats, and modify
157
existing tickets. This category would be better named “participant”.
158
159
Those in the “developer” category get the “nobody” and “anonymous” cap
160
sets plus **[e][e][i][i]**: view
161
sensitive user material and check in changes.
162
163
[bot]: ../antibot.wiki
164
165
166
## <a id="pvt"></a>Consequences of Taking a Repository Private
167
168
When you click Admin → Security-Audit → “Take it private,” one of the
169
things it does is set the user capabilities for the “nobody” and
170
“anonymous” user categories to blank, so that users who haven’t logged
171
in can’t even see your project’s home page, and the option to log in as
172
“anonymous” isn’t even offered. Until you log in with a user name, all
173
you see is the repository’s skin and those few UI elements that work
174
without any user capability checks at all, such as the “Login” link.
175
176
Beware: Fossil does not reassign the capabilities these users had to
177
other users or to the “reader” or “developer” user category! All users
178
except those with Setup capability will lose all capabilities they
179
inherited from “nobody” and “anonymous” categories. Setup is the [lone
180
exception][apsu].
181
182
If you will have non-Setup users in your private repo, you should parcel
183
out some subset of the capability set the “nobody” and “anonymous”
184
categories had to other categories or to individual users first.
185
186
187
## <a id="read-v-clone"></a>Reading vs. Cloning
188
189
Fossil has two capabilities that are often confused:
190
[**Read**](./ref.html#o) and [**Clone**](./ref.html#g).
191
192
The **Read** capability has nothing to do with reading data from a local
193
repository, because [caps affect Fossil’s web interfaces
194
only](#webonly). Once you’ve cloned a remote repository to your local
195
machine, you can do any reading you want on that repository irrespective
196
of whether your local user within that repo has <b>Read</b> capability.
197
The repo clone is completely under your user’s power at that point,
198
affected only by OS file permissions and such. If you need to prevent
199
that, you want to deny **Clone** capability instead.
200
201
Withholding the **Read** capability has a different effect: it
202
prevents a web client from viewing [embedded documentation][edoc],
203
using [the file browser](/help?name=/dir),
204
exploring the [history](/help?name=/timeline) of check-ins,
205
and pulling file content via the [`/artifact`](/help?name=/artifact),
206
[`/file`](/help?name=/file), and [`/raw`](/help?name=/raw) URLs.
207
It is common to withhold **Read** capability from low-status visitors
208
on private or semi-private repos to prevent them from pulling individual
209
elements of the repo over the web one at a time, as someone may do when
210
denied the bulk **Clone** capability.
211
212
[edoc]: ../embeddeddoc.wiki
213
214
215
## <a id="defuser"></a>Default User Name
216
217
By default, Fossil assumes your OS user account name is the same as the
218
one you use in any Fossil repository. It is the [default for a new
219
repository](#new), though you can override this with [the `--admin-user`
220
option][auo]. Fossil has other ways of overriding this in other contexts
221
such as the `name@` syntax in clone URLs.
222
223
It’s simplest to stick with the default; a mismatch can cause problems.
224
For example, if you clone someone else’s repo anonymously, turn off
225
autosync, and make check-ins to that repository, they will be assigned
226
to your OS user name by default. If you later get a login on the remote
227
repository under a different name and sync your repo with it, your
228
earlier “private” check-ins will get synced to the remote under your OS
229
user name!
230
231
When such problems occur, you can amend the check-in to hide the
232
incorrect name from Fossil reports, but the original values remain in
233
the repository [forever][shun]. It is [difficult enough][fos] to fix
234
such problems automatically during sync that we are unlikely to ever do
235
so.
236
237
[auo]: /help?name=new
238
[fos]: ./impl.md#filter
239
[shun]: ../shunning.wiki
240
241
242
243
## <a id="utclone"></a>Cloning the User Table
244
245
When cloning over HTTP, the initial user table in the local clone is set
246
to its “[new state:](#new)” only one user with Setup capability, named
247
after either your OS user account, per the default above, or after the
248
user given in the clone URL.
249
250
There is one exception: if you clone as a named Setup user, you get a
251
complete copy of the user information. This restriction keeps the user
252
table private except for the only user allowed to make absolutely
253
complete clones of a remote repo, such as for failover or backup
254
purposes. Every other user’s clone is missing this and a few other
255
items, either for information security or PII privacy reasons.
256
257
When cloning with file system paths, `file://` URLs, or over SSH, you
258
get a complete clone, including the parent repo’s complete user table.
259
260
All of the above applies to [login groups][lg] as well.
261
262
263
## <a id="webonly"></a>Caps Affect Web Interfaces Only
264
265
Fossil’s user capability system only affects accesses over `http[s]://`
266
URLs. This includes clone, sync/push/pull, the [UI pages][wp], and [the
267
JSON API][japi]. For everything else, the user caps aren’t consulted at
268
all.
269
270
The only checks made when working directly with a local repository are
271
the operating system’s file system permissions. This should strike you
272
as sensible, since if you have read access to the repository file, you
273
can do anything you want to that repo DB including giving your user’s
274
record the [**Setup**][s] capability, after which Fossil’s user
275
capability system is effectively bypassed. (Or, create another Setup
276
user, with the same end effect.) If you’re objecting that you need
277
*write* access to the DB file to achieve this, realize that you can copy
278
a read-only file to another location, giving yourself write access to
279
it.
280
281
This is why the `fossil ui` command
282
gives you Setup permissions within Fossil UI: it can’t usefully prevent
283
you from doing anything through the UI since only the local file system
284
permissions actually matter, and you can’t start `fossil ui` without
285
having at least read access to that file.
286
287
What may be more surprising to you is that this is also true when
288
working on a *clone* done over a local file path, except that there are
289
then two sets of file system permission checks: once to modify the
290
working check-out’s repo clone DB file, then again on [sync][sync] with
291
the parent DB file. The Fossil capability checks are effectively
292
defeated because your user has [**Setup**][s] capability on both sides
293
of the sync. Be aware that those file checks do still matter, however:
294
Fossil requires write access to a repo DB while cloning from it, so you
295
can’t clone from a read-only repo DB file over a local file path.
296
297
Even more surprising to you may be the fact that user caps do not affect
298
cloning and syncing over SSH! (Not unless you go [out of your way][sshfc]
299
to patch around it, at any rate.) When you make a change to such a
300
repository, the stock Fossil behavior is that the change first goes to the
301
local repo clone where file system
302
permissions are all that matter, but then upon sync, the situation is
303
effectively the same as when the parent repo is on the local file
304
system. The reason behind this is that if you can log into the remote
305
system over SSH and that user has the necessary file system permissions
306
on that remote repo DB file to allow clone and sync operations, then
307
we’re back in the same situation as with local files: there’s no point
308
trying to enforce the Fossil user capabilities when you can just modify
309
the remote DB directly, so the operation proceeds unimpeded by any user
310
capability settings on the remote repo.
311
312
Where this gets confusing is that *all* Fossil syncs are done over the
313
HTTP protocol, including those done over `file://` and `ssh://` URLs,
314
not just those done over `http[s]://` URLs:
315
316
* For `ssh://` URLs, Fossil pipes the HTTP conversation through a
317
local SSH client to a remote instance of Fossil running the
318
[`test-http`](/help?name=test-http) command to receive the tunneled
319
HTTP connection. [This interface is intentionally permissionless][sxycap].
320
321
* For `file://` URLs — as opposed to plain local file paths —
322
the “sending” Fossil instance writes its side of
323
the HTTP conversation out to a temporary file in the same directory
324
as the local repo clone and then calls itself on the “receiving”
325
repository to read that same HTTP transcript file back in to apply
326
those changes to that repository. Presumably Fossil does this
327
instead of using a pipe to ease portability to Windows.
328
329
Despite use of HTTP for these URL types, the fact remains that
330
checks for capabilities like [**Read**][o] and [**Write**][i] within the
331
HTTP conversation between two Fossil instances only have a useful effect
332
when done over an `http[s]://` URL.
333
334
[sshfc]: ../server/any/http-over-ssh.md
335
[sxycap]: /file?ci=ec5efceb8aac6cb4&name=src/main.c&ln=2748-2752
336
337
338
## <a id="pubpg"></a>Public Pages
339
340
In Admin → Access, there is an option for giving a list of [globs][glob]
341
to name URLs which get treated as if the visitor had [the default cap
342
set](#defcap). For example, you could take the [**Read**][o] capability
343
away from the “nobody” user category, who has it by default, to prevent
344
users without logins from pulling down your repository contents one
345
artifact at a time, yet give those users the ability to read the project
346
documentation by setting the glob to match your [embedded
347
documentation][edoc]’s URL root.
348
349
350
## <a id="defcap"></a>Default User Capability Set
351
352
In Admin → Access, you can define a default user capability set, which
353
is used as:
354
355
1. the default caps for users newly created by an Admin or Setup user
356
2. the default caps for self-registered users, an option in that same UI
357
3. the effective caps for URIs considered [public pages](#pubpg)
358
359
This defaults to [**Reader**][u].
360
361
362
<!-- add padding so anchor links always scroll ref’d section to top -->
363
<div style="height: 75em"></div>
364
365
[ref]: ./ref.html
366
367
[a]: ./ref.html#a
368
[b]: ./ref.html#b
369
[c]: ./ref.html#c
370
[d]: ./ref.html#d
371
[e]: ./ref.html#e
372
[f]: ./ref.html#f
373
[g]: ./ref.html#g
374
[h]: ./ref.html#h
375
[i]: ./ref.html#i
376
[j]: ./ref.html#j
377
[k]: ./ref.html#k
378
[l]: ./ref.html#l
379
[m]: ./ref.html#m
380
[n]: ./ref.html#n
381
[o]: ./ref.html#o
382
[p]: ./ref.html#p
383
[q]: ./ref.html#q
384
[r]: ./ref.html#r
385
[s]: ./ref.html#s
386
[t]: ./ref.html#t
387
[u]: ./ref.html#u
388
[v]: ./ref.html#v
389
[w]: ./ref.html#w
390
[x]: ./ref.html#x
391
[y]: ./ref.html#y
392
[z]: ./ref.html#z
393
394
[2]: ./ref.html#2
395
[3]: ./ref.html#3
396
[4]: ./ref.html#4
397
[5]: ./ref.html#5
398
[6]: ./ref.html#6
399
[7]: ./ref.html#7
400
401
[glob]: https://en.wikipedia.org/wiki/Glob_(programming)
402
[japi]: https://docs.google.com/document/d/1fXViveNhDbiXgCuE7QDXQOKeFzf2qNUkBEgiUvoqFN4/view#heading=h.6k0k5plm18p1
403
[sp]: ../sync.wiki
404
[sync]: /help?name=sync
405
[wp]: /help#webpages
406

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button