Introduction
This site is meant to serve as user-facing documentation for FOKS, the Federated Open Key Service.
If you're just learning about FOKS, you should probably start with the Background page. It explains several concepts that will make the rest of the site, make more sense.
ℹ️ Just Getting Started
If you're seeing this message, this "book" is in the very early stages. I'm still trying to figure out what pages need to exist, how they should be structured, and how much detail they should go into.
For now you can expect to see pages which don't exist yet, or which exist but have little or no real content. You will also see a lot of ❓ marks as well. Hopefully these will be filled in over time.
It's possible that the pages within the book may be renamed, re-arranged, or deleted as time goes by, and if this happens, the URLs of the individual pages will change. If you're going to save bookmarks, I recommend you save just the URL for the site itself, rather than any individual page.
If you're interested in helping to write or edit the book, start by reading the Working on this Book page, which walks through the basics of how to use mdbook.
Links
https://foks.pub/
- Main site- First blog post announcing the service
- White Paper - includes details about how the cryptography works
https://w.foks.app/
- FOKS Hosting Service- free accounts exist, but they're meant to be used to try it out before upgrading to a paid account or standing up your own server
- minimal storage (maybe 3 MiB?)
- Github
foks-proj/go-foks
- Source code for the client and server - Github
foks-proj/book
- Source code for this "book" web site
Chat
I've created the foks_book team on Keybase, and plan to use its "team chat" channel as a place for people to coordinate with each other and make sure we aren't duplicating each others' efforts.
If you're interested in working on this book, please join that team. The team is not fully open, but any Keybase user is able to ask to join, and I will try to approve people as quickly as possible (while I'm awake ... I'm physically in Florida, US, and regardless of what you may have heard, I do sometimes sleep at night. 😁)
If you have questions about FOKS that the book doesn't cover, also please join that team. Knowing what questions people are asking helps us to know what the book needs to cover, and if your question is answered, having the answer in the chat room's history can make it a easier when adding the information to the book.
Obviously, if FOKS adds a similar "chat room" functionality in the future, I'll create a team in FOKS and move the conversation there.
About this Site
This site is generated using mdbook, with some customizations from this repo.
The initial content, and the skeleton of the site, were written by John Simpson.
Please let me know if you have any ideas for how to improve this book, or even better, if you're willing and able to help write it (see the Working on this Book page).
Concepts
This page will contain information that will hopefully make it easier to understand FOKS.
For now this is just a list of what I think would be useful to cover.
Servers
foks.app
- default server, run by Max- offers paid accounts
- free accounts only allow a few MiB of data to be stored - enough for basic testing, then
foks admin web
to log in and convert to paid account
vh.foks.app
- other servers - anybody can stand up their own FOKS server
- source code is in the same repo with
foks
client - can be free or paid, the
foks.app
server is using it
- source code is in the same repo with
Users
- each user exists on a specific server
- encryption: per-user key
- per-user storage limit (depending on server policy)
Devices
- each user account can have multiple devices
- computers can access multiple FOKS accounts, only one is active at a time
- key types
- device key
- backup key
- Yubikey
- encryption: per-device key is used to decrypt per-user and per-team keys, which are then used to decrypt
Profiles
- "profiles" contain per-user settings associated with a device/backup/yubikey
- ❓ TBD
Teams
- groups of users
- team exists on one server
- every team must have at least one owner - user who creates a team is the initial owner
- team owner/admin must be on same server as the team, but team members may be on different servers
- adding members
- closed server: invite/accept/(inbox,admit) process
- open server: ❓
- users can create teams (count can be limited by server policy)
- team storage consumes a user's storage limit
foks.app
: limit for teams not linked to a user?
- user/team names are in the same "namespace"
- if user
xyz
exists on a server, teamxyz
cannot be created on the same server
- if user
- encryption: per-team key
Roles
- control who has what access within a team
- owner, admin, member, none
- member priority values
- integer between
-32768
and32767
, default0
- each priority level being used has its own key
- how/when are priority-level keys created?
- members can access content encrypted using any member key whose priority is equal or lower than their own role, but not member keys whose priority is higher than their own role
- users who publish items can choose which "level" will have access to the item (any level at or below their own access)
- admins and owners can read all "member/*" items
- integer between
High-Level Features
This page will explain the high-level features of FOKS.
For now this is just a list of what I think would be useful to cover.
Key-Value Storage
- user KV vs team KV
- key namespace looks like unix path
- first character must be
/
, 0+ "directories" separated by/
, then a non-empty "file" name foks kv ls
output shows names within each "directory", but not whether each name is a file or directory- newly created accounts don't have a
/
key until at least one other key is created (or a git repo is created, which creates/
,/app
and/app/git
if they don't already exist, so it can create/app/git/REPONAME
)
- first character must be
- individual values can be anything, any size
- user account storage limits based on server policy
- values are stored ... ?
- as files on disk?
- as rows in a database table?
- either/or depending on size?
- can values be stored in other storage?
- S3 (or compatible) bucket blobs
- azure blob storage
- deleted values still count against
foks kv get-usage
totals- not sure how this will be handled, but there needs to be a way to reclaim the storage, both to prevent the server from running out of space, and to not charge paying users for deleted data
Git Repositories
- stored in KV, using keys under
/app/git/REPONAME
git-remote-foks
- allowsgit
to work withfoks://
URLs- there is no
foks git delete
command, butfoks kv rm -R /app/git/REPONAME
deletes the repo
Client Architecture
-
foks agent
running in the background- holds state, including secret key material for the "active" profile
- listening on a UNIX socket
- macOS:
${HOME}/Library/Caches/foks/foks.sock
- Linux:
${XDG_RUNTIME_DIR:-${HOME}/.config}/foks/foks.sock
- macOS:
-
foks
commands run in the foreground- communicates with agent using UNIX socket
- ❓ protocol over that UNIX socket
- HTTP protocol proposed ⇒ #180
Installing FOKS
Creating a User
-
Select a server
- defaults
foks.app
andvh.foks.app
will be offered- these are a paid service, w.foks.app, offers virtual hosting (i.e. your own hostname, hosted on the
foks.app
server) - also usable for simple experimentation, each user has a very small usage limit (3 MiB)
- these are a paid service, w.foks.app, offers virtual hosting (i.e. your own hostname, hosted on the
- other servers - list?
- build/host your own server
- defaults
-
foks signup
- walk through what the process looks like
-
Create a backup key
- explain why having a backup key is important
-
Note about macOS Keychain ⇒ Key Storage page
Working with Keys and Devices
On this page, unless otherwise specified, the term "key" refers to any of ...
- Device keys. These are encryption keys stored on a computer.
- Backup keys. These are collections of words and numbers which encode an encryption key.
- A Yubikey, or more correctly, an encryption key stored in a Yubikey.
ℹ️ The descriptions below were written using FOKS version 0.1.1. Things may be different in later versions.
Profiles
The first time you "log into" FOKS using a given key, it creates a "profile" linked to that key. Each profile contains information about the key, including the key name, what kind of key it is (device, backup, or Yubikey), and other information about the key.
-
For device keys, the profile contains information about how and where they key is stored on the computer. The Key Storage page has more detail about this.
-
For backup keys, the profile contains the secret itself. The profile only exists in RAM (in the
foks agent
process) and is never written to disk. -
For Yubikeys, the Yubikey's serial number and the PIV "slots" containing the two encryption keys.
Only one profile can be active at a time. Any operations done by FOKS will be done "as" the device (and therefore the user) contained in that profile.
It's also possible to have no active profile. In this case, foks
will not be able to do anything involving encrypted data.
Commands
Note that several foks
keys have multiple commands which do the same thing. For example, foks key list
and foks key ls
are "aliases" for each other, and end up running the same code within the client.
List Keys/Profiles
foks key list
foks key ls
This command will print two lists:
- A list of all keys attached to the user account. If there is no active profile, this list will not be printed.
- A list of profiles on this machine.
Options exist to show just the keys or just the profiles, use foks key list -h
for more information.
Log Into FOKS
These sections cover how to log into an existing FOKS account. See the Creating a User page for information about how to create a new FOKS account.
Log In Using an Existing Profile
foks key switch
This command will show a menu containing the profiles on the local machine, other than the currently active profile.
Select the profile linked to the device key you want to sign in with.
-
If a passphrase is needed, you will be asked for it.
-
If you were logged in using a different profile, this will delete any secret keys associated with that profile from memory. (❓ not true if switching from a backup key)
-
It then uses the device key to decrypt the other keys it needs memory.
Device Keys
It is possible to have multiple device keys for the same computer, if you have multiple FOKS user accounts. In this case, this device's keys for the other user accounts will be shown on the list, so you can sign into those accounts.
You cannot "select" a device key whose secret keys are not present on the current machine. Device keys only exist on the device where they were created. (It may be possible to copy device keys from one computer to another, but this is not part of how FOKS was designed, and may cause problems if you don't do it correctly.)
Backup keys
While logged in using a backup key, you can "switch" to a different key and then later "swtich" back to the backup key, without needing to type in the list of words and numbers. (❓ not sure if this is intended behaviour or not)
When you're finished using a backup key, be sure to log out. (See below.)
Yubikeys
If you "select" a Yubikey profile but the Yubikey isn't physically plugged into the computer, the foks key switch
command will say it succeeded but you won't be able to access anything until the Yubikey is inserted.
$ foks key ls
Error: credentials are locked by Yubikey and unlocked credentials are required
Log In Using a Backup Key
To log in using a backup key ...
foks key use-backup
This command will ...
- Ask you for the FOKS server name
- Ask you to type in the backup key (the list of words and numbers)
The encryption key will be decoded from that list and used to decrypt the other keys associated with the user account and any teams it may be a member of.
This will create a temporary profile on the computer, which is never written to disk. When you "log out" of the profile, the secret key material and the profile are removed from memory.
❗️ Switching vs Logging Out
If you're logged in using a backup key and switch to a different profile, the profile based on the backup key will remain in memory, and you can switch back to it, without having to type in the list of words and numbers again.
If this is not what you want, be sure to log out (see below) when you're finished using a backup key.
Log In Using a Yubikey
To log in using a Yubikey ...
foks key use-yubikey
This command will ...
- Scan the computer to list all attached Yubikeys and ask you to select one
- Ask you for the FOKS server name
- Ask you for a "slot number" on the Yubikey
- Ask you to confirm you want to use this Yubikey to log into the user account
The encryption key stored on the Yubikey will be used to decrypt the PUK (per-user key) and PTK's (per-team keys) for any teams the user is a member of. This decryption is performed by the Yubikey itself. The encrytion keys on the Yubikey are never sent to a computer.
Log Out
There are two different commands to "log out" of FOKS. I don't fully understand the differences between them yet, below is what seems to me to be happening, based on the -h
messages and my own experimentation.
foks clear
This command will remove the secret key material for all profiles, from memory, and un-selects whatever profile is active.
foks key lock
This command will remove the secret key material for the current profile, from memory.
❓ I tried this command while logged in using a Yubikey, on a computer which also has its own device key, stored in the macOS Keychain, with the
foks
utility having permission to read the item without manual authentication, FOKS did lock the Yubikey's key, but it also made the machine's normal device key active, but didn't change the active profile (sofoks key ls
showed the device key active, with the Yubikey profile active.)I'm not sure if this is the expected behaviour. Until I know more, I plan to use
foks clear
whenever I need to "log out".
Add A Computer
Adding a computer to your account requires approval from an existing key. This can only be done using a device which is logged in using a key on the account.
Add A Computer Using An Existing Device
This requires a computer logged into the FOKS account using an existing key, in addition to the computer you're adding. You will need to be able to read from one screen and type into the other, so it may be helpful to have them close to each other. You can also SSH into one from the other, so you can copy and paste a temporary code from one window to the other.
-
On the existing device
foks key assist
This command will print a series of words and numbers on the screen, then ask for a different code.
Don't do anything, just leave it on the screen for now.
-
On the new device
foks key new
This command will walk you through the process.
- "Press Enter to get started"
- Select "A new user on this device"
- Select or enter the FOKS server for the user account.
- Enter your username.
- Enter the device name you want to use for the new device.
This will also print a series of words and numbers on the screen, and then ask for a different code.
-
On either device
Type in the series of words and numbers from the other device's screen.
After a few seconds, it should report that the device was added, and both computers will return to a command prompt.
Add A Computer Using A Backup Key
This can be done using only the computer you're adding to the account.
-
Log the computer into your FOKS account using the backup key. (See above.)
-
Add the computer as a permanent device on the account.
foks key new
This command will recognize that FOKS is logged in using a backup key and walk you through the process of adding a permanent device key for this computer.
❓ exact steps
Add A Computer Using A Yubikey
This can be done using only the computer you're adding to the account.
-
Log the computer into your FOKS account using the Yubikey. (See above.)
-
Add the computer as a permanent device on the account.
foks key new
This command will recognize that FOKS is logged in using a Yubikey and walk you through the process of adding a permanent device key for this computer.
❓ exact steps
Add a Backup Key
A backup key can be used to access your account from a computer that isn't a permanent device on your account. Using a backup key doesn't make the computer a device on your account, although it can be used to add devices to your account.
Before running this command ...
- Make sure the computer is logged into the FOKS account you're adding the backup key to.
foks key new
This command will walk you through the following steps:
Press <Enter> to get started
.- Select the
[ACTIVE]
profile for the user you want to create a backup key for. - Select
A new backup key
. - The command will print a series of words and numbers.
These words and numbers encode an encryption key which has the same access as any other device on your account.
WRITE THE WORDS AND NUMBERS DOWN ON PAPER AND STORE IT SOMEWHERE SECURE. This is the only time FOKS will ever print it. If you don't save it, there is no way to recover it (although as long as you have access to the FOKS account, you can revoke the backup key and/or create another one).
Note that the first word and number will be used as the name of the backup key.
Add a Yubikey
Like a backup key, a Yubikey can be used to access your account from a computer that isn't a permanent device on your account. Using a Yubikey doesn't make the computer a device on your account, although it can be used to add devices to your account.
Unlike a backup key, the actual secret keys are generated by the Yubikey itself, and stored in a "secure element" within the Yubikey itself. This means that ...
- There is no way to download the actual secret keys that it generates.
- There is no way to back up the scret keys to a second Yubikey.
- If you physically lose the Yubikey, the secret keys are gone.
Before running this command ...
- Make sure the Yubikey's PIV app is enabled, and the PIN/PUK codes and admin key have been changed from the default values. The Yubikeys page explains this.
- Make sure the computer is logged into the FOKS account you're adding the backup key to.
- Make sure the Yubikey is plugged into the computer.
foks key new
This command will make the Yubikey generate two encryption keys and store them in "slots" within the PIV app. One of these keys will be added to your FOKS user account as a "key", the same way a device key or user key is added.
Press <Enter> to get started
- Select the
[ACTIVE]
profile for the user you want the Yubikey to be linked to A new key on my Yubikey
- ❓ exact steps
The command will make the Yubikey generate two encryption keys, and add one of them as a "device" on your account.
❓ not sure what the other encryption key is used for, need to re-read that part of the whitepaper
Remove a Key from your Account
foks key revoke
This command will revoke an existing key from your account. This adds an entry in the account's "blockchain" which says that the key should no longer be used. It also starts a process which re-encrypts any data which were previously accessible using the now-revoked key.
❓ haven't done this yet - try it and take notes
Key Storage
This page will talk about how "device keys" are stored on computers.
-
foks skm info
T
field values - fromproto/lib/common.go
const ( SecretKeyStorageType_PLAINTEXT SecretKeyStorageType = 0 SecretKeyStorageType_ENC_PASSPHRASE SecretKeyStorageType = 1 SecretKeyStorageType_ENC_MACOS_KEYCHAIN SecretKeyStorageType = 2 SecretKeyStorageType_ENC_NOISE_FILE SecretKeyStorageType = 3 SecretKeyStorageType_ENC_KEYCHAIN SecretKeyStorageType = 4 )
-
macOS Keychain authorization
- explain: item containing device key is flagged to allow
foks
to access it without additional authorization- allows FOKS to log into acct without asking for auth
- allows
foks key switch
without asking for auth
- how to change this
- find item in keychain
- click "Access Control"
- remove
foks
from list ⇒ require approval via GUI pop-up - maybe turn on "Ask for Keychain password" ⇒ the GUI pop-up will require you to enter the "keychain password" (usually same as macOS login password)
- explain: item containing device key is flagged to allow
Working with Passphrases
Yubikeys
- PIV app must be enabled
- PIN must not be default
123456
- PUK must not be default
12345678
- Admin key must not be default
- Yubikey Manager
- deprecated after 2026-02-19
- Yubico Authenticator is recommended, but
- Yubico Authenticator
- can enable/disable PIV app
- cannot (yet?) set PIN/PUK codes
- ykman
Working with Teams
Background
- roles (owner, admin, member, none)
- who can be a member
- owner/admin must be on the same server
- members can be on other servers
Procedures
- create a team
- add a user to a team
- change a user's role
- remove a user
- ❓
Questions
Working with Key Value Storage
Background
- namespace
- "reserved" names (i.e.
/app/
, others?) - value types and limits
Procedures
- initializing KV storage (i.e. create
/
directory) - list values
- create directory
- store a value (create or overwrite)
- need
--force
to overwrite existing value
- need
- read a value
- create a symlink
- read a symlink
- get usage
- rename/move a value
Questions
Working with Git Repositories
Background
- repos are stored in KV, under
/app/git
- owned by user vs owned by team
Procedures
- create repo
foks git create
- If content doesn't exist yet
git init
- Either way
git remote add
git commit
if needed (repo must contain at least one commit before push)git push --all
git push --tags
- clone a repo
git clone foks://SERVER/OWNER/REPONAME
- remove a repo
foks kv rm -r /app/git/REPONAME
- other operations (pull, push, etc.) all use the same
git
commands you would use for other git servers
Questions
- primary branch name
- does git "server" assume a certain branch name (
master
,main
, etc.) or does it use the name of the first branch pushed into? - command to set primary branch name, or brain surgery?
- does git "server" assume a certain branch name (
- LFS support
Setting Up a Server
Working on this Book
This page covers the "workflow" around how to work with this site.
The site itself is a collection of static HTML, CSS, and Javascript pages, generated by mdbook. The "source code" for each page is a Markdown file. This is all stored in a Github repo.
mdbook includes a web server, meant for use while working on content. When you're working on the Markdown source files, it can show you what the finished site will look like, in a browser on your local machine. This works by running a simple web server and watching the source files. When it sees a file change whose contents affect the site, it sends a signal to the browser, telling it to reload.
ℹ️ Coordination
I've created the foks_book team on Keybase, and plan to use its "team chat" channel as a place for people to coordinate with each other and make sure we aren't duplicating each others' efforts.
If you're interested in working on this book, please join that team. If you have questions about FOKS that the book doesn't cover, also please join that team. Knowing what questions people are asking helps us to know what the book needs to cover.
Obviously, if FOKS adds a similar "chat room" functionality in the future, I'll create a team in FOKS and move the conversation there.
Repo Structure
The repo contains a collection of files which are involved in building the site. The files you'll be working with if you edit the book's content are:
-
src/
- This directory contains the Markdown source files for every page. -
src/SUMMARY.md
- This file contains the Table of Contents for the site, and is used to build the panel on the left. It is a markdown file, however it only supports a limited set of tags.If you're using mdbook's live preview feature, if you add a new page to the list in this file and save it, mdbook will create the associated Markdown file if it doesn't already exist.
-
book/
- This directory contains the generated HTML, CSS, and other files which make up the rendered site. The book is "published" to a web server by copying this directory to the site's document root directory.This directory is not meant to be checked into the git repo, so it's listed in the repo's
.gitignore
file. -
book.toml
- This file sets the overall properites of the book. This includes any custom steps to be performed in the rendering process.
This repo contains some customizations which aren't in normal mdbook books. These include a CSS stylesheet which adds horizontal lines above section headers (which I personally think makes it easier to read), as well as a script which is run during the rendering process to add the git commit information to the bottom of each page.
I do the same thing in a few dozen other "books" that I write and maintain. I created this repo to use as a starting point for new books, it contains more information about how the customizations work.
Pre-requisites
The only thing you really need in order to work on the site is a text editor.
Editorconfig
Your text editor should support Editorconfig. If it requires a plugin, it should be installed and enabled.
If your editor doesn't have a way to support editorconfig at all (such as nano
), you should manually follow the rules laid out in the .editorconfig
file, and use editorconfig-checker to check your files before committing them.
Live Preview
If you want to use mdbook's "live preview" feature, the following things will need to be installed on your workstation.
-
mdbook - the program which reads the Markdown files and generates the HTML, CSS, and other files which make up the final web site.
-
jq - a tool for working with JSON files. This is needed by the
version-commit
script, which sets things up to makemdbook
include the commit information at the bottom of every page. -
A web browser, to preview the changes as you save them.
These are explained in more detail here, in the mdbook-template
repo.
Workflow
This is the overall workflow to use while working on the book.
Setup
-
If you haven't already, "fork" the repo into your own Github account. You'll be making your changes in your own copy of the repo.
-
Make sure your fork is up-to-date with all commits from the main repo.
-
If you haven't already, clone your copy of the repo to your workstation.
cd ~/git/ git clone https://github.com/USERNAME/REPONAME foks-book
-
cd
into the directory where you cloned the repo, and make sure it's up to date with the Github repo.cd ~/git/foks-book/ git fetch -p git checkout main git pull
-
Create a new branch to contain the changes you're working on.
This is not strictly required, since you're working in your own repo. I find it helps to work on different tasks in different branches, especially at
$DAYJOB
where I might be working on a dozen or more different things at the same time.cd ~/git/foks-book/ git checkout -b new-branch-name
Edit
-
If you want to see the live preview while you're working, run
make serve
(or the appropriatemdbook serve
command). This will render the book from Markdown into HTML, start a web server on your workstation, and open a browser pointing to that web server.This web server normally listens on
http://127.0.0.1:3000/
, which means the pages it's serving will only be accessible from the same machine.The IP address and port number can be changed if needed. For example, if you make it listen on
0.0.0.0
(which is whatmake serve-all
does), any machine which can access your workstation will be able to view the pages. You will obviously want to be careful with this.Leave this command running while you're working.
-
Edit the files under the
src/
directory as needed.If you're using the live preview feature, visit the page(s) you're updating in the browser and make sure your changes are correct. Each time you save a file, the browser should automatically reload. (If you find this is not happening, manually reload the browser window and it should start automatically reloading again.)
Commit, Push, and Create a Pull Request
After you're happy with the proposed changes ..,
-
If you're using the live preview feature, go back to the window where the mdbook web server is running, and hit CONTROL-C to stop it.
-
Run
editorconfig-checker
to make sure the Markdown files are properly formatted.$ cd ~/git/foks-book/src/ $ editorconfig-checker -v . ... 0 errors found 16 files checked
If any problems are found, fix them before committing.
-
Commit your changes and push the new branch to your repo.
cd ~/git/foks-book/ git add src/ git commit -m 'Update information about XYZ' git push -u origin new-branch-name
ℹ️ Commit Messages
When your PR is merged into the main repo, your commits will become part of the main repo's history.
I've seen dozens of different web pages claiming to tell you how to create a "perfect" commit messages. The important thing is that your commit messages should explain what they're doing.
The other "rules" I follow, which are motly habits I've picked up over the years, are ...
- Assume that the first line of the commit will have "This commit will" before it, and make it make sense.
- If the commit message needs more detail than just one sentence, use multiple lines. Just make sure there's a blank line after the first line, since not including the blank line will confuse tools that other people might use.
- Try not to use more than 72 characters per line. There are people who still use 80-column terminals.
Commit messages don't have to be perfect, but they should be informative.
-
The output from the
git push
command should contain a URL to create a pull request. Visit that URL to create a pull request.In the grey bar above "Add a title", make sure that ...
- "base repository" points to the
foks-proj/book
repo - "base" points to
main
(the branch you want to merge into) - "head repository" points to your repo
- "compare" points to the branch containing the changes in your repo
- "base repository" points to the
Review and Merge
-
At this point, other Github users will be able to see the pull request, and offer comments on it.
-
If you want to update your proposed changes, create and push another commit to the same branch in your repo. When you push the new commit(s), Github will automatically update the pull request to include those changes.
-
People can also "approve" the pull request. This simply means that they've looked over the changes and don't see any problems with them.
-
When the repo owners decide that they're good with the changes, they can merge the pull request. This adds the commits from your branch, to the primary repo.
-
Within a few minutes after this happens, the web site containing the rendered book will be updated automatically.
❗️ The mechanics of making this happen have not been set up yet.