Understanding the Keybase Filesystem
(For a gentler introduction to KBFS, see our launch announcement.)
Overview
The Keybase filesystem (KBFS) is a distributed filesystem with end-to-end encryption and a global namespace. The KBFS code is open source.
“Distributed” means you can access it from any device.
“Filesystem” means that there is no sync model -- files stream in and out on demand. Among other things, that means that by default files on KBFS don’t permanently take up space on your devices. (KBFS does use the local disk for temporary and transient data; see the "Local disk usage policy" section below for more details. You may also opt-in to permanent local disk storage for some folders or files; see the "Syncing data for offline access" section below for more details.)
“End-to-end encryption” means that all data stored in KBFS have guaranteed integrity and authentication, and also confidentiality when desired, and that only the people intended to read or write a piece of data can do so. In particular, we (Keybase) cannot change, read, or even know the names of your private files.
“Global namespace” means that each file on KBFS has a single unique path, regardless of the device from which you access it.
The Keybase namespace
A Keybase path has the form
/keybase/public/canonical_top_level_folder_name/subpath
or
/keybase/private/canonical_top_level_folder_name/subpath
. Files and
folders under /keybase/public
are signed, and files and folders under
/keybase/private
are encrypted in addition to being signed.
A top-level folder (TLF) is a subdirectory of either /keybase/public
or /keybase/private
. A canonical name for a public folder is in the
form writer1,writer2,...
, and a canonical name for a private folder
is either writer1,writer2,...
or
writer1,writer2,...#reader1,reader2,...
, where each writer or reader
is a keybase username, and the list of writers and readers are
alphabetized separately. The writers for a TLF can both read and write
to that TLF, whereas readers can only read.
The canonical name for a TLF encodes which keybase users can read or write to it. For a public folder, it is guaranteed that only the writers for that folder have written to it. This is verified by the keybase client, which checks the signatures of the updates to that folder against the writers’ public keys.
For a private folder, it is guaranteed that only the writers for that folder have written to it, and only the writers and readers for that folder can read it. This is also verified by the keybase client.
For further details on the crypto design of KBFS, see https://keybase.io/docs/kbfs-crypto.
You can also access keybase files through paths with non-canonical TLF names. The simplest example of a non-canonical TLF name is one where the order of the writers or reader is not alphabetical, but more useful examples involve using assertions instead of usernames. See https://keybase.io/docs/command_line for assertion syntax.
Example assertions:
akalin
trivially resolves to the Keybase userakalin
.fakalin@twitter
resolves to the Keybase user who has proven ownership of thefakalin
account at Twitter.fakalin@twitter+akalin@github
resolves to the Keybase user who has proven ownership of thefakalin
account at Twitter as well as theakalin
account at GitHub.
At the filesystem level, each non-canonical TLF name resolves as a symlink to the canonical TLF name.
Security Model
At a high level, end-user devices are trusted and Keybase/KBFS/other servers are untrusted. On desktops, we run all KBFS processes as the current user and use OS-level secret stores, but we don’t attempt to protect against other processes owned by the same user or root.
The KBFS client doesn’t trust any data coming from Keybase or KBFS servers, and verifies any received data against the relevant users’ public keys. For the nitty-gritty details, see the KBFS crypto doc. In particular, the KBFS servers cannot see into the contents or structure of your (non-public) files.
That having been said, the KBFS servers know what users can access which data, and will only serve data to an authorized reader of a TLF with a valid session. Furthermore, they will only serve historical (archived) data to writers of a TLF, even public ones.
Each TLF is backed by an "implicit" Keybase team, and the private keys required to access the TLF are managed by this team; see the Keybase team docs for more details. When you provision a new device to your account, it automatically gains access to these keys, and thus the TLF data. When you revoke a device, a new key is created for the TLF and used to encrypt all future data written to the TLF, to ensure that the device cannot read the new data. Old data is not re-encrypted (though our servers won’t serve it to revoked devices).
Filesystem semantics
There are no guarantees as to the relative ordering of operations in two different TLFs.
A TLF is best thought of as a linear sequence of changes. If only a single device is operating on a TLF, then each change it makes appends to this sequence, which is called the “master branch”. However, if there are multiple devices, then a change from another device may be added to the master branch before one from the current device. In that case, a separate branch exclusive to the local device is forked off. In this state (called “staged”), operations on the local device aren’t normally visible to any other devices, although they’re still persisted locally (or, with journaling turned off, on KBFS servers) in case of process or device restarts. Then a background process periodically attempts to merge this branch into the master branch, resolving conflicts as necessary. When this succeeds, the changes from the local device are visible to everyone else (but see the section on conflict resolution below).
Within a single device, KBFS then behaves more or less like a normal (i.e., POSIX-compliant) filesystem, except for the exceptions listed below. However, it’s difficult to make general statements about the relative ordering and visibility of operations in a TLF between two different devices. But in general, once an application does an fsync that is sent to the KBFS servers successfully from a device, all the previously-written data will eventually be visible to a second device. Note that a file write is a purely local operation---writes to a file on a device will be invisible to a second device until the next sync or close, and after the sync they will eventually be visible to a second device. There is also a background process that frequently syncs file data, in case the application does not sync or close the files.
By default, KBFS requires network connectivity, and no offline reads are possible unless the data being read happens to be cached in memory. In theory offline writes are possible, and will be queued up on your local disk until network access is available. However, writing often involves reading first, especially for updating the directory that contains the file, so in practice the lack of offline reads could hinder offline writes. (See the "Syncing data for offline access" section below for more options for offline access.)
Durability
For performance reasons, when KBFS receives a write call (either a file write or a directory modification), KBFS buffers the write in memory and responds successfully, before the new data is persisted on disk or on the servers. This is POSIX-compliant, but due to the latencies involved, KBFS holds data in memory for longer than most mounted file systems. By default, it holds data for up to 1 second (or until 100 operations, or 25 MB of file data, have been buffered).
Any fsync
call causes all buffered data to be flushed immediately
and synchronously to either the local disk or the KBFS server,
depending on the journal configuration (see below). KBFS doesn't
currently have any optimizations for syncing individual files -- it's
all or nothing.
Applications may inspect the currently-buffered data in the special
.kbfs_status
file that can be read within your TLF (e.g., cat /keybase/private/me,you/.kbfs_status
or keybase fs read /keybase/private/me,you/.kbfs_status
). In that file, there is a list
of "DirtyPaths", indicating which files and directories have data that
is held only in memory.
Journaled writes
By default, KBFS uses a persistent journal on your local disk to store any changes you make to a TLF temporarily, until they can be saved on our servers. This makes the writes faster, decouples your network latency from your file system latency, and provides KBFS opportunities for rolling several changes together and saving you bandwidth. This applies both to file writes and directory updates. Note that all data in this journal are encrypted before being written to disk.
The use of a journal means that a sync or close of a file does NOT
ensure the data has made it to our KBFS servers and will soon be
visible to other devices. Data in the journal are flushed to the
servers in the background. Your Keybase app icon will change to
include an up arrow while data is uploading from the journal. You can
check the status of the changes that the journal is uploading (and an
estimated time for when the uploads will finish) using the keybase fs uploads
CLI command. Furthermore, in the .kbfs_status
file (see
above), you can also see which local directory is being used for the
journal; see the "Local disk usage policy" section below for more
details.
If you want stronger semantics, or if you want to avoid using any disk space for KBFS data even temporarily, you can disable journaling altogether, or on a per-TLF basis. For example, on Linux and macOS you can do the following:
- Persistently turn off all journaling for TLFs accessed in the
future:
echo 1 > /keybase/.kbfs_disable_auto_journals
. This doesn't affect TLFs that might already be using journaling; you'll have to disable each of those manually.) - Turn off journaling for one TLF:
echo 1 > /keybase/private/me,you/.kbfs_disable_journal
. This only works if the journal is empty.
In comparison to sync-based systems like Dropbox, the use of a journal
gives stronger ordering guarantees between file system operations on
the same device, since KBFS strictly uploads data in the order it was
written. If you know there will only be one device at a time writing
to a particular TLF, this means it's fairly safe to run something like
git
in a KBFS folder, even if other devices can be reading from it
at the same time, since you're not at risk of repo corruption if the
read happens at the wrong time or the device stalls or fails. (Of
course, Keybase also offers encrypted git
repositories
directly as a service, which are also based on KBFS but offer the
usual git safety guarantees even when multiple devices are committing
at the same time.)
Conflict resolution
Our conflict resolution strategy is similar to Dropbox's, but because we have stronger filesystem semantics than they do, we're able to do things in a slightly different way that more closely match the behavior of a local FS when two users are updating it concurrently (only relevant for corner cases). Here is roughly what the resolutions look like:
- When both devices do make non-conflicting changes to the same directory, those will get merged trivially.
- When both devices write to the same file, the "loser" file will
get copied to a new name, marked with the name of the user who did
the write, and the time at which the resolution happened. So if
both users with to file
a/b.txt
, but user "bob" loses the race, after resolution you should seea/b.txt
anda/b.conflicted (bob’s macbook copy 2015-11-24).txt
, where “bob” is the name of the user who wrote the file, and “macbook” is the public name of the device on which bob wrote the file. KBFS does not currently attempt to merge the contents of the two copies, for any type of file. - When both devices create a file with the same name, the same resolution as above will happen.
- When both devices create a directory with the same name, they will be intelligently merged (dealing with children conflicts recursively).
- If one device creates a directory, and another creates a file,
using the same name, the file is always renamed with the
.conflicted...
suffix mentioned above, in order to preserve the directory structure as best as possible. - Unlike Dropbox, if "alice" creates a file
a/foo
, but "bob" doesmv a b
, the resolution should only have the fileb/foo
. That is, the updates to a directory follow that directory across renames. This is the same way it works in the terminal, if you're in a directory and someone moves that directory out from under you. - If the devices cause a rename cycle, it's resolved with
symlinks. So for example, "alice" does
mv b/ a/
and bob doesmv a/ b/
. If alice wins the initial race, the resolution will look likea/b/a
, where the seconda
is a symlink pointing to../
. - One weirdness is when alice does
mv a/ b/
and bob concurrently doesmkdir b
. Ideally, we would merge those two directories, but implementing that is very tricky and expensive, so right now the code treats it as a conflict.
Folders stuck in conflict mode
In rare cases where KBFS has a bug in its conflict resolution process,
or resource pressures on the device prevent conflict resolution from
completing, a device might get permanently stuck with its local
branched view of a folder, and other devices won't ever see that data.
If this is the case, the .kbfs_status
file in the TLF (see above)
will show IN_CONFLICT_AND_STUCK
for its ConflictStatus
. If you
notice one of your TLFs in this state, please use keybase log send
to bring it to our attention as soon as possible.
You can revert the stuck TLF to the "master" view by using the
keybase fs clear-conflicts
command. This moves the local view aside
under a new, read-only path name such as /keybase/team/mycompany (local conflicted copy 2019-09-25)
, while making the "master" view
accessible under the normal path. Data can then be manually copied
from the stuck view into the normal view. Once any required data has
been restored, the conflict view can be removed (and the corresponding
local disk space reclaimed) with the keybase fs finish-resolving-conflicts
command.
Deviations from POSIX
Permissions are determined entirely by the TLF name, and so there are no POSIX-style permissions.
Hard links are not supported. Symbolic links are supported, but will only be globally meaningful if they refer to other KBFS paths.
O_EXCL
and O_APPEND
are not supported, although they may work if
the file is operated on only from a single device. In particular,
nothing that does file locking (like git) should be used from multiple
devices yet, and appending to a single shared file (e.g., a log file)
from multiple devices should be avoided. We may support either or both
of these in the future.
KBFS does not support atime, since that turns a read into a write and would require all readers to also be writers. Also, it'd be slow.
Typical POSIX attributes like file owner, group, and permissions don't make much sense in KBFS. KBFS sets the owner of all files and directories to the UID of the local user that is running the KBFS process. Read and write permissions are set based on whether the user has read or write access to the TLF. For example:
- Non-executable files in writable private TLF:
0600
(-rw-------
) - Executable files in writable private TLF:
0700
(-rwx------
) - Private subdirectories:
0700
(drwx------
) - Public subdirectories that user has write access to:
0700
(drwx------
) - Read-only public subdirectories:
0500
(-dr-x------
)
Note that permissions and ownership of a TLF itself may be incorrect until one has accessed the TLF.
Any requests to change the owner or group (e.g., via chown
) or to
set permissions (excluding the executable bit) will appear to succeed,
but the change will not be saved or propagated to other clients.
Ideally we would fail these calls, but too many applications (such as
mv
or unzip
) fail miserably when those calls fail. In addition,
any attribute change request that doesn't result in a real change to
the underlying KBFS metadata (including setting the executable bit
when it is already set, for example) does not update the corresponding
ctime for the directory entry. This is a violation of POSIX, but it's
an important optimization for some common workloads (e.g., rsync
).
Symbolic links can lead outside a TLF
The Keybase client allows symbolic links that lead outside a TLF. This is by design, and we envision a variety of great use cases:
- a subfolder of your public folder, where you link to friends' public folders you endorse
- storing private links to all your favorite private folders
- a link entirely outside KBFS to another global filesystem you endorse. For example, to something in IPFS.
You should therefore take care to consider the possibility of blindly
following a symbolic link - without noticing - by someone you don't
trust. As an example, if you ran a webserver and naively served
content in someone's /keybase/public/
folder - with your server
configured to follow symbolic links - a user could trick you into
serving your own secret files back out.
Storage, Quotas and History
The KBFS servers store your data in opaque blobs called blocks. Both files and directories within a TLF are stored as blocks, and the servers can't tell which block belongs to which file or directory within the TLF. The data in these blocks are encrypted, and their size is increased (i.e., padded) to avoid leaking information to our servers.
Each user has a quota, expressed in a number of bytes. Whenever you
write to a file or change a TLF’s structure, only the blocks that you
change count against your quota. The complete size of each block
(including encryption and padding) is what counts towards your quota.
Note that due to KBFS internal data structures, changing a file or
directory also changes all of the directories on the path back to the
root of the TLF. So, for example, if you edit a file at
/keybase/private/you/a/b/c/foo
, you've ended up changing at least
five blocks: the TLF root directory block for /keybase/private/you
,
the subdirectory blocks for a
, a/b
, and a/b/c
, and the file
block for a/b/c/foo
.
You can check your quota usage using keybase fs quota
, or df
on
Linux and macOS. Note that du
also works (though it might be very
slow) - however, du
only counts the plaintext size of the files, and
includes data written by any user, not just you.
Blocks that are deprecated due to a new change (e.g., if you overwrite a previous version of a file, or add a new directory entry) are marked for cleanup, and a background process on each client cleans up these old blocks after about two weeks, though this could be delayed if all clients currently accessing that folder go offline. These deprecated blocks don't count towards your quota.
Time travel
You can view, and recover data from, old versions of your TLF within the two-week window before old, archived data is cleaned up.
Every time you change something in a KBFS TLF (at the root level or in
any subdirectory), you create a new version, or revision, of that
TLF. Each revision is assigned a monotonically increasing revision
number. You can see the current revision number in the Revision
field of the .kbfs_status
file for the TLF (see below). You can
also find the revision number of the newest version of the folder to
have been cleaned up (and thus is NOT accessible anymore) in the
LastGCRevision
field of that same file. When viewing old versions
of the TLF, you choose one of those revisions to browse. They are
read-only, but you can copy data from them into the current copy of
the TLF.
There are multiple ways to view old data. Within the keybase fs
suite of commands, you can access old data with the ls
, stat
, and
read
commands, and for the source paths of the cp
command, using
the following flags:
-
-time
: This specifies a date and time for when the data was available to all devices from the KBFS servers. It can take many different formats, such as:- "Sun Jul 29 11:46:18 PDT 2018"
- "July 29, 2018 11:46:18 PM PST"
- "July 29, 2018"
- "2018-07-18 13:13:43 +0800"
Note that if no timezone is given, it uses UTC (and not the local timezone), in order to provide consistent behavior when copy/pasting commands between users/devices that may be in different timezones. Dates in formats where the month and day are ambiguous (such as "4/3/18" or "04-03-2018" are treated as if the month comes first, and then the day, as in typical US date formats.
-
-reltime
: This specifies a relative time in the past, using unit suffixes, such as "5m" for five minutes ago or "5h3m2s" for five hours, three minutes and two seconds ago. Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h". Of course, this would not be copy/paste-able as the relative revisions could change according to the current time. -
-rev
: This specifies the exact revision number of the TLF you're browsing, and is probably most useful for Keybase developers.
For example, to view the TLF as it was five minutes ago (and the current date is July 29th 2018 at 11:51:00 am in San Francisco):
$ keybase fs ls -reltime 5m /keybase/private/you
- or -
$ keybase fs ls -time "Sun Jul 29 11:46:00 PDT 2018" /keybase/private/you
You can also browse old versions of the TLF directly inside the KBFS mount, using these special directories at the root of the TLF:
.kbfs_archived_time=<t>
: As with the-time
flag above, you can substitute any time for<t>
. This actually just acts as a symlink to the corresponding revision for that time (see below)..kbfs_archived_rev=<r>
: As with the-rev
flag above, you can specify an exact revision here as<r>
..kbfs_archived_reltime=<r>
: Unlike this above two version, this isn't a directory. It's a file, whose contents contains the directory name of the revision directory corresponding to the relative time. This is to avoid copy/paste issues across time.
For the same examples above, you can do this in the mount directory instead:
$ ls "/keybase/private/you/.kbfs_archived_time=Sun Jul 29 11:46:00 PDT 2018/
- or -
$ cd /keybase/private/you
$ ls `cat .kbfs_archived_reltime=5m`
If you're interested in browsing the revisions of a specific file or
directory, you can list them using the keybase fs stat
command. The
-show-archived
flag shows you the stat info for five previous
revisions of the file, scattered throughout the archive history. For
example:
$ keybase fs stat --show-archived /keybase/private/you/tmp/foo
/private/you/foo
69403) 2018-08-01 11:22:50 PDT FILE 444 foo you
69393) 2018-08-01 11:22:29 PDT FILE 404 foo you
69387) 2018-08-01 11:22:20 PDT FILE 380 foo you
69369) 2018-08-01 11:21:53 PDT FILE 308 foo you
69295) 2018-08-01 11:20:00 PDT FILE 12 foo you
The first number in each row is the revision number. You can pass
that to other commands, such as keybase fs read
or keybase fs recover
, to access that exact revision of the file.
Another option is the -show-last-archived
flag, which shows exactly
the last five revisions of the file. You can use this to iterate all
of the revisions, if desired. For example:
$ keybase fs stat --show-last-archived /keybase/private/you/foo
/private/you/foo
69403) 2018-08-01 11:22:50 PDT FILE 444 foo you
69402) 2018-08-01 11:22:48 PDT FILE 440 foo you
69401) 2018-08-01 11:22:47 PDT FILE 436 foo you
69400) 2018-08-01 11:22:45 PDT FILE 432 foo you
69399) 2018-08-01 11:22:44 PDT FILE 428 foo you
$ ./keybase fs stat --show-last-archived -rev 69399 /keybase/private/you/foo
/private/you/foo
69399) 2018-08-01 11:22:44 PDT FILE 428 foo you
69398) 2018-08-01 11:22:42 PDT FILE 424 foo you
69397) 2018-08-01 11:22:41 PDT FILE 420 foo you
69396) 2018-08-01 11:22:39 PDT FILE 416 foo you
69395) 2018-08-01 11:22:38 PDT FILE 412 foo you
keybase fs recover
provides a simple helper command to recover the
specific revision of a file or directory back into the TLF. It takes
the same -time
, -reltime
and -rev
flags as the above commands,
and just forcibly overwrites the current data in the folder with the
data from the specified revision. It recovers directories
recursively. It does not delete new files that weren't in the old
versions of the directories.
A neat property of KBFS recovery is that you can restore a
consistent view of the TLF. That is, all the versions of the files
within a specific revision all existed exactly that way, at the same
time. So it's guaranteed that if you wrote file a
, and then wrote
file b
, that in the future when you browse a revision of the TLF and
see that version of b
, you'll also the see the same version of a
that existed at the time you wrote b
. This can be important for
recovering certain types of applications that write to multiple files,
such as databases and repositories.
An important caveat, though, as mentioned above, is that using
keybase fs recover
on a directory (including the root of the TLF
itself) could leave behind new files that didn't exist at the time
from which you are recovering. If exact recovery is needed for a full
directory, one option is to recover via the file system's special
.kbfs_archived
directories, using rsync --delete
.
Currently the limit for recovering data is about two weeks in the past, though we might improve this in the future.
Local disk usage policy
As mentioned above, KBFS streams data into and out of your device on demand, and doesn't store data permanently on your disk by default. However, for performance reasons, KBFS does use your local disk in two different ways, limiting the amount of space it uses based on the amount of disk space currently available on the disk partition storing your local home directory. (This only applies to desktop devices at the moment, since KBFS is not yet available on mobile devices.) All data stored to disk is first encrypted.
- Temporary local writes: After files are written to KBFS, but before they are uploaded to the servers, they will temporarily use disk space on your device -- see the "Journaled writes" section above. We limit this usage to 85% of your available disk space, up to a maximum of 170 GB. These files will be deleted as soon as they sync successfully to the KBFS servers.
- On-disk transient cache: KBFS also stores data in a transient cache on disk to improve performance. This is limited to 10% of your available disk space, up to a maximum of 20 GB. If other applications start using more of your disk space, data will be evicted from this cache automatically to maintain the overall usage percentage.
If you want to adjust these limits, see the "Running on a resource-constrained system" section below. There is currently no way to adjust the locations of the directories.
In addition, the KBFS process writes log files to your Keybase log directory. The KBFS logs are limited to about 400 MB total.
Syncing data for offline access
KBFS does not store TLF data permanently on your local device by default. This is because KBFS gives you access to a very large amount of data (e.g., every Keybase user's public files!), and so syncing all that data before accessing it is infeasible. This comes at the cost of not being able to access the data while offline, however.
KBFS now offers a way for you to opt-in to "syncing" the data in specific TLFs, or in specific subdirectories or files within a TLF, to your local device, so that the most up-to-date version of the data possible will be accessible quickly, even when offline. This process works by storing the encrypted blocks in a local database (similar to the "transient cache" above), and making the data available through the normal KBFS mount point. It does not "sync" the data in decrypted form to/from a folder on your local file system the way Dropbox and others do. The synced files are not available when KBFS is not running.
Right now this feature is only supported on non-mobile devices, and
the only way to enable this feature is via the command line. To
enable syncing, use the keybase fs sync enable
command as follows:
# Sync an entire TLF
$ keybase fs sync enable /keybase/private/me
# Sync just a subdirectory of a TLF
$ keybase fs sync enable /keybase/private/me,you/tax_docs
# Sync just a particular file
$ keybase fs sync enable /keybase/team/mycompany/passwords.txt
There is also a disable
subcommand to turn off the syncing (the data
is deleted slowly in the background), and a show
command for showing
sync configuration and progress (including an estimated time when the
sync will finish) for the all synced TLFs, or for a particular TLF.
Note that, unlike for the transient cache described above, KBFS will use as much local storage as necessary to store this data. Therefore if you try to sync more data than you have in available disk space, you will fill up your disk.
GUI and mobile support for file syncing will be coming soon.
Favorites
Each Keybase user has their own list of "favorites" that appear under
/keybase/private
and /keybase/public
. Whenever you access a new
directory (e.g., you run ls /keybase/public/malgorithms@twitter
), it
will be added to your favorites list under its canonical name (e.g.,
/keybase/public/chris
).
You can remove entries from your favorites list using rmdir
for the
canonical TLF name (e.g., rmdir /keybase/public/chris
), or choosing
to ignore the folder in the Keybase GUI application.
Mountpoints
On macOS and Linux, the official Keybase packages support multiple local users of a computer all using KBFS at the same time (presumably signed into different Keybase accounts, but that's not a requirement). We do that by mounting KBFS onto your file system for each user in a unique location.
- macOS: For a user with local macOS account name
user
, KBFS is mounted at/Volumes/Keybase (user)
. - Linux: If the user (with Linux account name
user
) has$XDG_RUNTIME_DIR
set in their environment, KBFS is mounted at$XDG_RUNTIME_DIR/keybase/kbfs
. Otherwise, we mount it at/home/user/.config/keybase/kbfs
.
Notably, we don't create a ~/keybase
directory, like other file
storage applications do, because KBFS is a real mountpoint and gives
you access to team and public directories, and so it slows down
programs that crawl your home directory like backup software, du
, or
find
. (A Linux user without $XDG_RUNTIME_DIR
set will still have
this issue, unfortunately.)
You can figure out your current mountpoint with keybase status | grep mount
.
Root redirector
So, how does the magic /keybase
path work, if it's not the KBFS
mountpoint? We mount what we call a root redirector there, which
shows different symlinks to the per-user mounts, depending on which
user is asking. This allows our users to send and post global paths
to KBFS files that will work for all Linux and macOS users (and
Windows users, via the keybase fs
command set), all while supporting
multiple local users.
Note that on fresh Keybase installs on macOS 10.15 or later, the
operating system does not allow the creation of new mount points at
the root level of the file system. In that case, the root redirector
is mounted at /Volumes/Keybase
instead.
We recognize that not everyone would want to run the root redirector.
In particular it runs with root permissions on your computer (via a
root-suid binary on Linux, and via a root helper process on macOS),
and it also makes a directory at the root of your local file system,
either of which might be unwelcome. So if you'd rather access KBFS
directly via the per-user mountpoints, you can turn off the root
redirector by creating a root-level Keybase config file at
/etc/keybase/config.json
with the following contents:
{
"disable-root-redirector": true
}
Then on Linux, do:
sudo killall keybase-redirector
sudo chmod a-s /usr/bin/keybase-redirector
On macOS, you can do this:
keybase uninstall -c redirector
After that the redirector should stay off permanently, even across upgrades.
Custom mountpoints
If you don't like the default mountpoint location, you can override it
with keybase config set mountdir </a/better/location>
, and then
restart Keybase.
The root redirector mountpoint cannot currently be changed.
Windows
Currently only one Windows user may use Keybase, and KBFS, at a time.
We mount to the K:\
drive if possible, picking another available
drive letter if needed. You can customize the drive letter with
keybase config set mountdir X:
.
Running on a resource-constrained system
On desktops and laptops, KBFS makes liberal use of memory in order to cache recently-read data for performance. It also uses CPU and networking resources to pre-fetch data you are likely to access in the near future, such as recently-edited files or subsequent data blocks to data that was just requested. These optimization tradeoffs might not be desired on systems that don't have any extra RAM or CPU to spare. Starting with Keybase 4.6.0, we allow users to configure their desktops and laptops to run the same way mobile devices do, which disables these optimizations. To do so, run the following command:
keybase config set kbfs.mode constrained
and then restart KBFS. The default behavior can be restored with:
keybase config set kbfs.mode --clear
followed by a restart.
A few other configuration options can be set via keybase config set
as well:
kbfs.block_cache.mem_max_bytes
(integer, must be set using the-i
flag): The maximum number of bytes that the in-memory data cache can hold at once. The default for this number is 512 MB or 1/8 of the total RAM on the device, whichever is smaller. Making this number smaller can help reduce KBFS's memory footprint.kbfs.block_cache.disk_max_fraction
(float, must be set using the-f
flag): The fraction of the available bytes of the local disk that can be used for the on-disk transient cache. If the usage goes above this fraction, blocks will be evicted from the cache until it fits within the fraction again. The default value for this fraction is 0.10 (10%, as discussed above).kbfs.block_cache.sync_max_fraction
(float, must be set using the-f
flag): The fraction of the available bytes of the local disk that can be used for synced-for-offline-access data. Data is never evicted from this cache; if its size exceeds the configured fraction of the disk, then background syncs will fail until more space becomes available. The default fraction for his fraction is 1.00 (100%).
KBFS must be restarted for any of these options to take effect.
Debugging
For most users, keybase log send
should suffice. This packages up
some log files and sends them to Keybase admins. Log files may
contain metadata (sizes, etc.) about your files, though file and
directory names are obfuscated and cannot be inferred from the logs.
For the more curious, on macOS, the easiest way to access the KBFS logs
is via [Console.app](https://en.wikipedia.org/wiki/Console_(OS_X)). On
the left under FILES, it should be under ~/Library/Logs
as
keybase.kbfs.log
. keybase.service.log
may also be useful. You can
then either copy and paste a portion of the displayed lines, or drag
and drop the “keybase.kbfs.log” to attach the entire file, or
right-click and select “Reveal in Finder” to find the actual file.
There are a number of special invisible KBFS files that either have
debugging info or turns on and off KBFS settings. They all start with
.kbfs_
, and KBFS won’t let you create files with that prefix.
Since these files aren’t listed by default, you’ll need to use the terminal to access these.
From any folder, the following files are accessible:
.kbfs_error
: contains a list of the last few errors and their stack traces..kbfs_metrics
: contains a list of some metrics (mostly RPC-related)..kbfs_profiles/
: contains files representing Golang profiles.
From within a TLF the following additional files are also accessible:
.kbfs_status
: lists some status info about the current TLF..kbfs_update_history
: shows a JSON-formatted list of all the revisions for this TLF, including what operations were done when, and by which authorized TLF writer. This fetches all revisions from the server, and may be very slow for TLFs with long histories. It contains a lot of internal debugging information and may be hard to read by someone who's not a KBFS developer; making a friendlier version is future work..kbfs_fileinfo_XXX
(where XXX is the name of a file or directory in that TLF subdirectory): shows some debugging information about the given file, including who last claimed to have written it (this is shown without explicit cryptographic verification -- verification is done at the TLF-level, not at the individual file level).