Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.

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 (I don't want to have to deal with spammers), 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 is just a rough outline of what I want to cover.

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.

Encryption Keys

  • Every "key" (device key, PUK, PTK, etc.) actually consists of three key pairs:

    • EdDSA
    • Curve25519
    • ML-KEM key - "post quantum"
  • Yubikey firmware cannot do the ML-KEM algorithms (yet?)

    • FIPS 203
    • Yubikey firmware is not upgradable - when/if future Yubikeys do support it, we'll all have to buy newer Yubikeys 😁

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 - also Max, used for "virtual hosting"
    • for people want their own FOKS server but don't want to build or maintain it
  • other servers - anybody is able to 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

Users

  • each user exists on a specific server
  • encryption: per-user key
  • per-user or per-virtual-server 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
    • bot token
    • 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
    • teams have a limit of 512 KiB until "claimed" by somebody, limit is configurable using floating_team in config.jsonnet file
  • user/team names are in the same "namespace"
    • if user xyz exists on a server, team xyz cannot be created on the same server
  • encryption: per-team key

Roles and Visibility Levels

Roles control who has access to which items within a team.

Items stored in KV have two levels associated with them - the level required to read the item, and the level required to write (or overwrite) the item. The values are encrypted using encryption keys which are specific to that level. (These keys are created the first time they're needed.)

If an operation is attempted using a client whose role isn't "high" enough, the operation will fail because the client won't have access to the necessary encryption key.

  • Owners

    • can add/remove team members and assign visibility levels
    • can delete the team
    • can access encryption keys for all levels
  • Admins

    • can add/remove team members and assign visibility levels (other than owner)
    • cannot delete the team
    • can access encryption keys for "admin" and all "member/*" items
    • cannot access encryption keys for "owner"
  • Members

    • cannot add/remove members or assign visibility levels
    • cannot delete the team
    • members have "visibility levels"
      • integer between -32768 and 32767, default 0
      • each priority level which is being used, has its own encryption key
    • can access encryption keys for visibility levels equal to or lower than their own role
    • cannot access encryption keys for visibility levels higher than their own role
      • m/0 can access m/0, m/-1, m/-2, etc.
      • m/0 cannot access m/1, m/2, etc.
      • m/* cannot access admin or owner keys
  • None

    • used for former members who were removed from the team
    • cannot access or do anything
    • this is just like if they had never been a member of the team

Other info

  • Users who publish items can choose which levels are required to read or write that value. Either level can be any level at or below their own access level.

  • The first time an item is published using a level which has not previously been used (for example, as member/100), an encryption key is created for that visibility level. This key is used to encrypt the value being stored, as well as any future values stored using the same visibility level.

High-Level Features

ℹ️ This page is just a rough outline of what I want to cover.

This page will explain the high-level features of FOKS.

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)
  • individual values can be anything, any size
    • user account storage limits based on server policy
  • values are stored as rows in database
    • large values are split into 4 MiB chunks, so a large value will occupy multiple rows
    • can values be stored in other storage? → hasn't been built yet
    • storage ideas (mine, no idea if any of these will happen or not)
      • files on server's local disk (how to monitor usage and not run out of space)
      • S3 (or compatible) bucket blobs
      • azure, google, etc.
      • dropbox, box.com, etc.
  • deleted values still count against foks kv get-usage totals
    • janitor (aka "quota reclamation") hasn't been built yet

Git Repositories

  • stored in KV, using keys under /app/git/REPONAME
  • git-remote-foks - allows git to work with foks:// URLs
  • there is no foks git delete command, but foks kv rm -R /app/git/REPONAME deletes the repo

Client Architecture

ℹ️ This page is just a rough outline of what I want to cover.

  • foks agent - runs 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
  • foks commands run in the foreground

    • communicates with agent using UNIX socket
      • ❓ document protocol over that UNIX socket
    • HTTP protocol - foks kv rest commands

Installing FOKS

ℹ️ This page is just a rough outline of what I want to cover.

Installing FOKS

The official directions have quick directions on how to install the software. Below is essentially a copy of the official directions.

  • macOS

    • If Homebrew is not installed, install it.

      /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
      
    • Install the foks package.

      brew isntall foks
      
  • Linux

    In addition to installing the software, these commands will install the apt/yum repository containing the foks software, so that normal apt/dnf/yum commands will work as expected.

    • Debian-ish: as root

      curl -fsSL https://pkgs.foks.pub/install.sh  | sh
      
    • Redhat-ish: as root

      curl -fsSL https://pkgs.foks.pub/install.sh | sh
      

    In addition, if you plan to use a Yubikey, you will need to install the pcscd software.

    • Debian-ish: as root
      apt install pcscd libpcsclite-dev
      
    • Redhat-ish: as root ❗️ not tested yet
      yum install pcscd
      
  • windows

    • Here's a nickel, kid. Get yourself a better computer.

      But seriously ... the only windows machine I own is an old laptop running "windows 7", which I haven't booted up in probably two years ... and because it's windows, I haven't connected it to any network in at least five years. (I only keep it around to program radios that CHIRP doesn't support.)

    • The official directions say to run this command.

      winget install foks
      

Upgrading FOKS

Install the new software over the existing software.

  • macOS

    brew update && brew upgrade foks
    
  • Linux

    • Debian-ish: as root
      apt update && apt upgrade foks
      
    • Redhat-ish: as root
      dnf check-update && dnf update foks
      
      • or yum check-update && dnf update foks, depending on which distro/version you're using
  • windows

    The official directions don't mention upgrading, and I don't have a windows machine to try it. I would assume that this "winget" thing has a winget update command that could be used to upgrade the software? If anybody knows, please let me know, or even better, open a pull request and update this page.

Installing on Tails

🛑 If you are seeing this, the directions below are what I think should work, but there are some permission-related issues I need to figure out first.

Last tried using Tails 6.18, note that Tails 7.0 is out now so I need to revisit this.

  • If the stick doesn't have persistent storage (have not tried this)

    • Download .deb file by hand
    • sudo apt install ./foks_n.n.n_amd64.deb
    • foks ctl start
  • If the stick does have persistent storage (tried, not successful yet)

    • as amnesia user
      • download .list and .gpg files (as amnesia user, curl doesn't seem to want to work for root)
      • edit foks.list
        • URL needs to start with tor+http
        • ❓ may need to change path to PGP key
    • as root
      • set up persistent /etc/apt/sources.list.d/
      • set up persistent /usr/share/keyrings/
        • 🛑 doesn't work, _apt user can't traverse /live/persistence/TailsData_unlocked so the symlinks are not usable
        • if there's a bind-mounted directory we can use (so symlinks aren't being followed) then we should be able to store the .gpg file there and adjust the filename in the foks.list file
      • install foks.list and .gpg files
    • reboot
    • sudo apt install foks
    • when pop-up asks if you want it to be persistent, say yes

Creating a User

ℹ️ This page is just a rough outline of what I want to cover.

Select a server

foks.app and vh.foks.app

The foks.app and vh.foks.app servers will be offered by default.

These servers are a paid service. The servers themselves are owned by Max, the primary developer of FOKS.

  • foks.app offers individual user accounts.
  • w.foks.app offers virtual hosting (i.e. using your own hostname, but hosted on the foks.app server)
  • This page explains more about how it works, and includes pricing.

Non-paid accounts are only usable for simple experimentation. Each non-paid user has a very small usage limit (3 MiB).

Other servers - list?

Building/hosting a list of other FOKS servers is on the roadmap.

❓ The whitepaper § 3.7 talks about a "beacon server", could this be used to generate a list?

If so, I'm assuming FOKS servers notify the beacon server about their existence. Some server owners may not want their server listed, is there a way to either (1) tell the beacon server not to include the server in a publicly visible list, or (2) tell this server not to send any information to the beacon server?

Build and host your own server

I am planning to document how to build a FOKS server on this site, however I haven't actually done it yet. (I've tried once, ran into a problem, and haven't had time to get back to it.)

For now, see Max's documentation in the source code.

foks signup

Once you've selected a server, run the foks signup command to create a new user account on that server.

  • foks signup

    $ foks signup
    ╔══════════════════════════════════════════════════════════╗
    ║                                                          ║
    ║ 🔑 Welcome to the Federated Open Key Service -- FOKS! 🔑 ║
    ║                                                          ║
    ╚══════════════════════════════════════════════════════════╝
    
    Let's signup
    
      🆗 Press <Enter> to get started
      ☮️  Or <Ctrl+C> or <Esc> at any time to quit
    
  • Select a server.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    └────────────────────────────────────────────┘
    
        Select a home server
    
       > 🏠 foks.app     (perfect for individuals and small teams)
         🏢 vh.foks.app  (team admins: stand-up a virtual server)
         🏄‍♂️ -            (specify a custom server)
    
  • Enter your email address. This is so the server operator has a way to contact you in case of problems.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    │ ✓ Using FOKS host: foks.app                │
    └────────────────────────────────────────────┘
    
        What's your email address?
    
    
        > xxxxx@example.com
    
       ✅ Email accepted; push <return> to continue
    
  • If you have one, enter your "invite code". I suspect this was needed at the very beginning, however this is no longer required.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    │ ✓ Using FOKS host: foks.app                │
    │ ✓ Email: xxxxx@example.com                 │
    └────────────────────────────────────────────┘
    
        Enter your optional invite code (or leave blank to skip)
    
    
        >
    
  • Choose a username on the server.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    │ ✓ Using FOKS host: foks.app                │
    │ ✓ Email: xxxxx@example.com                 │
    └────────────────────────────────────────────┘
    
        Pick a username (3-25 characters, with some Latin Unicode, hypens, periods, and underscores)
    
    
        > example123
    
       ✅ Username available; push <return> to continue
    
  • Choose a device name.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    │ ✓ Using FOKS host: foks.app                │
    │ ✓ Email: xxxxx@example.com                 │
    │ ✓ Username: example123                     │
    └────────────────────────────────────────────┘
    
        Pick a device name:
    
    
        > MyComputer
    
       ✅ Device name accepted; push <return> to continue
    
  • The user account is created, and you will see a summary.

    ┌────────────────────────────────────────────┐
    │ ✓ Using a local device key (not a yubikey) │
    │ ✓ Using FOKS host: foks.app                │
    │ ✓ Email: xxxxx@example.com                 │
    │ ✓ Username: example123                     │
    │ ✓ Device name: MyComputer                  │
    └────────────────────────────────────────────┘
    
     🔑 Welcome to FOKS 🔑
    
      Your account is now ready to use. Have fun, and remember,
      not your keys, not your data!
    
    
     Next Steps You Might Consider️:
    
        🔑 Create a backup key          foks key new
        📄 Store files and string data  foks kv put
        🔀 Host a git repository        foks git create
        🤝 Create a team                foks team create
        🌐 Setup billing via web        foks admin web
    
    
    
     ✌️  Press any key to exit.
    

Create a backup key

❗️ MAKE SURE TO CREATE A BACKUP KEY!

This is the #1 most important thing to remember about FOKS. I cannot stress this strongly enough.

Any data stored in your FOKS account is encrypted using "device keys". If you lose all of your devices, you will cryptographically lose access to all data stored in the account. There is nothing that the server owner, or Max, can do to help you regain access to your data.

If all of your devices are lost, a backup key will allow you to regain access to the account, including the data stored in the account.

If your account only has a single device key, the foks key ls command will warn you about this:

$ foks key ls
┌───────────────────────────────────────────────────────────────────────────────────┐
│ All keys for 👤 example123 @ foks.app                                             │
├────────┬────────────┬────────┬────────────┬───────────────────────────────────────┤
│ ACTIVE │ NAME       │ TYPE   │ CREATED    │ ID                                    │
├────────┼────────────┼────────┼────────────┼───────────────────────────────────────┤
│ *      │ MyComputer │ device │ 2025-09-21 │ .4FYMa91Exxxxxxxxxxxxxxxxxxxxxxxxxxxx │
└────────┴────────────┴────────┴────────────┴───────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ All profiles available on this machine               │
├────────┬────────────┬──────────┬────────┬────────────┤
│ ACTIVE │ USERNAME   │ HOSTNAME │ TYPE   │ KEY NAME   │
├────────┼────────────┼──────────┼────────┼────────────┤
│ *      │ example123 │ foks.app │ device │ MyComputer │
└────────┴────────────┴──────────┴────────┴────────────┘

 ☠️ ☠️  DATA LOSS WARNING ☠️️ ☠️

 You only have one active device; if you lose access to it, you will lose access to all
 data stored in this account. FOKS uses true end-to-end encryption, so your service provider
 does not store backup keys. Protect yourself! Try:

      🛟 foks key new

 If you prefer to YOLO it and dismiss this warning without action, the command is:

      🔥 foks notify clear-device-nag

(There's no way to show it using Markdown, but the "DATA LOSS WARNING" message will be printed in red. It's meant to get your attention.)

As you can see, there is a way to disable this warning without creating a backup key, however that is NOT a good idea.

To create a backup key ...

  • Run foks key new.

    $ foks key new
    ╔══════════════════════════════════════════════════════════╗
    ║                                                          ║
    ║ 🔑 Welcome to the Federated Open Key Service -- FOKS! 🔑 ║
    ║                                                          ║
    ╚══════════════════════════════════════════════════════════╝
    
    Let's make a new key
    
      🆗 Press <Enter> to get started
      ☮️  Or <Ctrl+C> or <Esc> at any time to quit
    

    Hit ENTER.

  • The next question is, who to create a key for. This is because it's possible for a single computer to be attached to multiple FOKS accounts, normally on different servers but possibly on the same server.

        Who needs a new key?
    
         🆕 A new user on this device
       > 👤 example123 @ foks.app <📱 device: MyComputer> [ACTIVE]
    

    Be sure to select the active account (use the ↑ and ↓ keys) before hitting ENTER. (Selecting "A new user on this device" will start the process of adding this computer as a device on an existing FOKS account. This is covered on the Working with Keys and Devices page.

  • The next screen asks what type of key you want to create. At the moment there's only one option, but if there are multiple options in the future, be sure to select "A new backup key".

    Why type of key do you want to make?
    
    > 💾 A new backup key (to write down on paper)
    
  • The new backup key will be created and printed to the screeen.

     💾 New Backup Key Activated 💾
    
      Here is your key. Please write it down and keep it in a safe place:
    
    
          evoke 3992 antenna 1804 rebel 8192 nasty 337 target 7177 burger 1010 car 5506 maze 994 rely
    
    
    
     ✌️  Press any key to exit.
    

    Save the key somewhere safe. The most common way to do this would be to write it on paper and physically store it somewhere safe, such as a bank safety deposit box.

    This is the ONLY time the backup key will be shown. Once this terminal window is gone, there is no way to show the backup key again.

Future foks key ls commands will show the backup key as a key on the account.

$ foks key ls
┌───────────────────────────────────────────────────────────────────────────────────┐
│ All keys for 👤 example123 @ foks.app                                             │
├────────┬────────────┬────────┬────────────┬───────────────────────────────────────┤
│ ACTIVE │ NAME       │ TYPE   │ CREATED    │ ID                                    │
├────────┼────────────┼────────┼────────────┼───────────────────────────────────────┤
│        │ evoke 3992 │ backup │ 2025-09-21 │ .GGIQfSnZxxxxxxxxxxxxxxxxxxxxxxxxxxxx │
│ *      │ MyComputer │ device │ 2025-09-21 │ .4FYMa91Exxxxxxxxxxxxxxxxxxxxxxxxxxxx │
└────────┴────────────┴────────┴────────────┴───────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ All profiles available on this machine               │
├────────┬────────────┬──────────┬────────┬────────────┤
│ ACTIVE │ USERNAME   │ HOSTNAME │ TYPE   │ KEY NAME   │
├────────┼────────────┼──────────┼────────┼────────────┤
│ *      │ example123 │ foks.app │ device │ MyComputer │
└────────┴────────────┴──────────┴────────┴────────────┘

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. This key acts as a "device key" on the user account.

  • A Yubikey, or more correctly, an encryption key stored in a Yubikey. This key also acts as a "device key" on the user account.

  • Bot tokens. These are similar to backup keys, but are written using a different format, and may have reduced permissions to the user account.

ℹ️ The descriptions below were written using FOKS version 0.1.2. Things may be different in later versions.

Profiles

The first time you "log into" FOKS using a given key, it creates a "profile" on disk which contains information about the key, including the key name, what kind of key it is (device, backup, bot token, or Yubikey), and the server and username who "owns" the key. Profiles do not contain any secret keys.

  • For device keys, the profile contains the key's name, user information (server and username), and information about how and where the secret key is stored on the computer. The Key Storage page has more detail about this.

  • For backup keys, the profile contains the key's name and user information. The backup key itself consists of a series of alternating words and numbers. The first word and number act as the key's name.

  • For bot tokens, the profile contains the key's name and user information. The token consists of two blocks of characters, separated by a . character. The first block is five characters, and act as the key's name.

  • For Yubikeys, the profile contains the key's name and user information, plus the Yubikey's serial number and the PIV "slot" numbers containing two encryption keys. One key is used to perform encryption operations on the Yubikey itslf, the other is used to generate the key used to perform post-quantum encryption operations on the computer.

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. Note that secret key material for other profiles may exist in memory, but it will not be used unless that profile is active.

It's also possible to have no active profile. In this case, foks will not be able to do anything (other than create or log into a user account).

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.

$ foks key ls
┌───────────────────────────────────────────────────────────────────────────────────┐
│ All keys for 👤 example123 @ foks.app                                             │
├────────┬────────────┬────────┬────────────┬───────────────────────────────────────┤
│ ACTIVE │ NAME       │ TYPE   │ CREATED    │ ID                                    │
├────────┼────────────┼────────┼────────────┼───────────────────────────────────────┤
│        │ evoke 3992 │ backup │ 2025-09-21 │ .GGIQfSnZxxxxxxxxxxxxxxxxxxxxxxxxxxxx │
│ *      │ MyComputer │ device │ 2025-09-21 │ .4FYMa91Exxxxxxxxxxxxxxxxxxxxxxxxxxxx │
└────────┴────────────┴────────┴────────────┴───────────────────────────────────────┘
┌──────────────────────────────────────────────────────┐
│ All profiles available on this machine               │
├────────┬────────────┬──────────┬────────┬────────────┤
│ ACTIVE │ USERNAME   │ HOSTNAME │ TYPE   │ KEY NAME   │
├────────┼────────────┼──────────┼────────┼────────────┤
│ *      │ example123 │ foks.app │ device │ MyComputer │
└────────┴────────────┴──────────┴────────┴────────────┘

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 key you want to sign in with.

  • If a passphrase, PIN, or other authentication is needed, you will be asked for it.

  • It the new profile's secret keys are not in memory, the key will be used to decrypt them into memory (unless the profile you activated is tied to a Yubikey).

  • If you were logged in using a different profile, any secret keys associated with the previous profile will remain in memory, so that a future foks key switch command can switch back to them, but they will not be used.

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 switch to 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 doing so can cause problems. If you need another computer to have access to your account, enroll that computer as its own device on the account, or use a "backup key" or "bot token" on that other computer.

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 again.

When you're finished using a backup key, be sure to log out. (See below.)

Bot Tokens

While logged in using a bot token, you can "switch" to a different key and then later "swtich" back to the bot token, without needing to type in the token again.

When you're finished using the bot token, 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. In this case, commands will fail with an error message like this:

$ foks key list
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 profile on the computer, but the key itself (derived from the words and numbers you typed) is never written to disk. When you "log out" of the profile, the secret key material is 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 Bot Token

To long in using a bot token ...

foks key use-bot-token [--host SERVERNAME] [--token TOKEN]

This command will ...

  • Ask you for the FOKS server name, if the --host option was not used.
  • Ask you to type in the token, if it was not supplied using the --token option or the FOKS_BOT_TOKEN environment variable.

The encryption key will be decoded from the token 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 bot token and switch to a different profile, the profile based on the bot token will remain in memory, and you can switch back to it, without having to supply the token 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 involves two key exchanges:

  • DH over Curve25519, performed by the Yubikey itself.
  • ML-KEM (aka "post quantum"), performed on the computer, using a seed calculated by the Yubikey.

The encrytion keys stored on the Yubikey are never sent to the computer.

Log Out

There are two different commands to "log out" of FOKS.

foks key lock

This command will remove the current profile's secret key material from memory, and un-select the profile. If any other profiles are available, one will be "selected" automatically.

❓ 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. FOKS did lock the Yubikey's key and made the machine's normal device key active, but foks 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".

foks clear

This command will remove the secret key material for all profiles from memory, and totally log out of FOKS. (If the machine has a device key, you can use foks key switch to log back in.)

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 the two computers physically 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 an 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 the backup key has "owner" access, which means 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 Bot Token

A bot token can be used to access a FOKS account from a computer that isn't a permanent device on the account. They are useful for "bots" or other automated processes.

Unclear what --role option does

My first guess was that each token carries a visibility level with it, so that a client using the token will have limited access to the account (and its teams). If this were true, I had written the following:

Unlike a backup key (which always has "owner" access), a bot token can be assigned any "visibility level" you like. When a client uses a bot token, they will be limited to the token's visibility level. For example, if you create a token with visiblity level "member/0", clients using that token will not be able to access items or perform operations requiring "admin" or "owner" access.

However, when I tried to create a token with anything other than owner access, it didn't work.

foks bot new [--role XXX]

The XXX value can be one of:

  • owner or o: owner access
  • admin or a: admin access
  • member/10 or m/10: member access with visibility level 10 (which is higher than m/0 but lower than m/20)

Visibility Levels

Visibility levels can be specified when adding key-value items, to control who can read or write that item. For example, if you add an item with read role m/0 and write role m/10, then a bot token with visibility level m/0 would be able to read that item but not write the item.

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, those secret keys are gone. All you can do is revoke them and set up a new Yubikey.

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.

  • 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
  • ❓ do this again, and this time write down the 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

Secret Key Storage

ℹ️ This page is just a rough outline of what I want to cover.

This page will talk about how "device keys" are stored on computers.

  • foks skm info

    • T field values - from proto/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
      )
      
    • other fields will depend on T
  • 0 = Plain text

    • is this used at all?
  • 1 = Passphrase

    • foks passphrase command
      • difference between set and change?
  • 2 = macOS Keychain

    • default on macOS
    • has f2 dictionary with Account, Service, and SecretBox keys
    • explain: item containing device key is flagged to allow foks to access it without additional authorization
      • this allows FOKS to log into acct without asking for auth
      • this also allows foks key switch without asking for auth, which can seem insecure
    • how to change this
      • find item in keychain
      • click "Access Control"
      • remove foks from list ⇒ require approval via GUI pop-up (clicking "always allow" will add foks back to the list)
      • maybe turn on "Ask for Keychain password" ⇒ when the GUI pop-up appears, it will require you to enter the "keychain password" (usually same as macOS login password) before clicking "allow" or "always allow"
  • 3 = Noise File

    • default on linux if no GUI is present
    • has f3 dictionary with Filename, and SecretBox keys
    • filename is in $HOME/.config/foks/, contains random garbage - presumably used to decrypt foks-secrets file in same directory
  • 4 = Keychain

    • linux/gnome keychain?

Working with Passphrases

ℹ️ This page is just a rough outline of what I want to cover.

Figure out

  • how/when passphrases are used
  • ❓ is a passphrase specific to just the key(s) on a single machine, or is it global to the entire account?
    • whitepaper talks about a case where if machine A changes a passphrase, the next login on machine B would need to use the new passphrase
  • the foks passphrase and foks secret-key-material commands

Yubikeys

ℹ️ This page is just a rough outline of what I want to cover.

Basics

  • Hardware
    • Yubikeys are little computers, running "apps"
    • different hardware has different connectivity options (USB-A, USB-C, Lightning, NFC)
    • firmware is loaded at the factory, cannot be upgraded
      • Yubico has a history of "making it right" in case of bugs, several years ago they sent me a replacement Yubikey Neo due to a security issue in the firmware.
  • PIV app must be enabled
  • FOKS (and common sense) requires that the PIN, PUK, and admin key cannot be default values
  • Yubikey Manager GUI program
    • deprecated after 2026-02-19
    • Yubico Authenticator is recommended, but seems to be missing functionality
  • Yubico Authenticator
    • can enable/disable PIV app
    • cannot (yet?) set PIN/PUK codes
  • ykman

Debian 12

After installing FOKS

  • apt install pcscd is necessary to interact with Yubikeys
    • this will start a background service as soon as it's installed
  • foks ctl start is necessary for FOKS to work
  • foks key use-yubikey - log into acct using Yubikey
  • foks key new - create permanent key for device and "switch" to it
  • physically remove yubikey
  • foks key remove - remvoe yubikey

Yubikey PIV app setup

Install ykman

Show high-level status of Yubikey

$ ykman info
Device type: YubiKey 5C NFC
Serial number: 12345678
Firmware version: 5.4.3
Form factor: Keychain (USB-C)
Enabled USB interfaces: FIDO, CCID
NFC transport is enabled

Applications    USB             NFC
Yubico OTP      Disabled        Disabled
FIDO U2F        Enabled         Enabled
FIDO2           Enabled         Enabled
OATH            Disabled        Disabled
PIV             Enabled         Disabled
OpenPGP         Enabled         Enabled
YubiHSM Auth    Disabled        Disabled

Enable the PIV app (if needed)

Some Yubikey devices support NFC in addition to USB. Apps can be enabled or disabled for each connection type. On my Yubikey I have the PIV app enabled for USB but disabled for NFC.

$ ykman config usb --enable piv
USB configuration changes:
  Enable PIV
Proceed? [y/N]: y
USB application configuration updated.
$ ykman config nfc --disable piv
NFC configuration changes:
  Disable PIV
Proceed? [y/N]: y
NFC application configuration updated.

Reset the PIV app

If you're not 100% sure about the app's state, and you don't have any keys stored in the app that you can't afford to lose, you can reset the app back to its factory default state.

$ ykman piv reset
WARNING! This will delete all stored PIV data and restore factory settings. Proceed? [y/N]: y
Resetting PIV data...
Reset complete. All PIV data has been cleared from the YubiKey.
Your YubiKey now has the default PIN, PUK and Management Key:
        PIN:    123456
        PUK:    12345678
        Management Key: 010203040506070801020304050607080102030405060708

Show status of the PIV app

After factory reset:

$ ykman piv info
PIV version:              5.4.3
PIN tries remaining:      3/3
PUK tries remaining:      3/3
Management key algorithm: TDES
WARNING: Using default PIN!
WARNING: Using default PUK!
WARNING: Using default Management key!
CHUID: No data available
CCC:   No data available

After changing PIN/PUK/Management key, and adding FOKS keys:

$ ykman piv info
PIV version:              5.4.3
PIN tries remaining:      3/3
PUK tries remaining:      3/3
Management key algorithm: TDES
Management key is stored on the YubiKey, protected by PIN.
CHUID: No data available
CCC:   No data available
Slot 82 (RETIRED1):
  Private key type: ECCP256

Slot 83 (RETIRED2):
  Private key type: ECCP256

Generate a new random management key

It is possible to have the Yubikey generate a random PIV management key. However if you do this, you won't know what the key is, and therefore won't be able to perform any operations which need the management key.

We're going to generate the management key on the computer first. This allows us to store the key somewhere secure (i.e. in FOKS, 1Password, or some other secure storage) in case we need it in the future.

The commands shown below will generate a random key by reading 24 bytes from /dev/urandom and converting them to hex.

$ MKEY="$( head -c24 /dev/urandom | xxd -p -c0 )"
$ echo $MKEY
6c0113005314e3f7f07255e85696e9638e9da4dd1ac819ca
$ ykman piv access change-management-key \
    --management-key     010203040506070801020304050607080102030405060708 \
    --new-management-key "$MKEY"
New management key set.

Change PIN and PUK

PUK is used to "unlock" a Yubikey after too many bad PIN attempts.

PIN and PUK must be 6-8 characters long. Any alphanumeric characters will work, however for compatibilty you may want to stick with digits.

$ ykman piv access change-pin --pin 123456 --new-pin 654321
New PIN set.
$ ykman piv access change-puk --puk 12345678 --new-puk 87654321
New PUK set.

Working with Teams

ℹ️ This page is just a rough outline of what I want to cover.

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

ℹ️ This page is just a rough outline of what I want to cover.

Background

  • namespace
  • "reserved" names (i.e. /app/, others?)
  • value types and limits
  • REST API

Procedures

  • initializing KV storage (i.e. create / directory)
  • list values
  • create directory
  • store a value (create or overwrite)
    • need --force to overwrite existing value
  • read a value
  • create a symlink
  • read a symlink
  • get usage
  • rename/move a value

Key-Value REST API

ℹ️ This page is just a rough outline of what I want to cover.

  • first added in v0.1.2
  • how to start/stop server
  • auth token
  • how to send requests using curl

Start REST server

  • explain auth tokens
$ foks kv rest start
Listening...
Port: 8080

Requests can be sent to http://127.0.0.1:8080.

  • --bind-ip 127.0.0.1: specify the IPv4 address where the REST server will listen (default is 127.0.0.1)
  • --port 8080: specify the TCP port where the REST server will listen (default is 8080
  • --team x: work on behalf of a given team (not necessary?)
  • --auth-token xxxxx: clients must supply a matching token (default: none)

Stop REST server

foks kv rest stop

API

  • show example of how to include auth token with request

GET /v0/-/path/to/a/directory/

$ curl -X GET http://127.0.0.1:8080/v0/-/app/
{"entries":[{"name":"git","write":"o","mtime":"2025-08-02T22:51:15.796337Z","ctime":"0001-01-01T00:00:00Z"}],"parent":"/app/"}

Request a list of keys under the indicated directory.

Response will be a JSON blob with the form

{
    "entries" : [
        {
            "name" : "xxx" ,
            "write" : "o" ,
            "mtime" : "2025-08-17T01:43:22.123456Z" ,
            "ctime" : "0001-01-01T00:00:00Z"
        }
    ] ,
    "next" : {
        "dir_id" : dir_id ,
        "pagination" : { "hmac" : "xxx" }
    }
}

ℹ️ In v0.1.2 the JSON structure doesn't include what kind of object each entry is (i.e. file, directory, or symlink). It looks like PR #195 adds a type item with this information. This should be present in v0.1.3.

The next item is for pagination. To read the next page, send the same GET request with page_dir_id and page_hmac query parameters. You can also send a page_entries parameter to limit the number of entries in each "page".

curl -X GET 'http://127.0.0.1:8080/v0/-/app/?page_dir_id=xxx&page_hmac=xxx'

GET /v0/-/path/to/a/key

$ curl -X GET http://127.0.0.1:8080/v0/-/xyzzy
this is a test

Read the value of a key.

The word after /v0/ can be

  • - = access the current user's KVs
  • t:TEAMNAME = access that team's KVs

PUT /v0/-/path/to/a/key

Store a value. Request body is the value to be stored.

The --mkdir-p flag is assumed, i.e. any intermediate directories which don't exist will be created.

DELETE /v0/-/path/to/a/key

Delete a value.

Working with Git Repositories

ℹ️ This page is just a rough outline of what I want to cover.

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
    • OWNER will be xxx for a username, or t:xxx for a team name
  • remove a repo
    • there is no foks git rm command (yet?)
    • foks kv rm -r /app/git/REPONAME will do the job
  • other operations (pull, push, etc.) all use the same git commands you would use for other git servers

Questions

  • primary branch name
    • git "server" assumes primary branch name main, created issue #187
    • command to set primary branch name, or brain surgery?
  • LFS support → hasn't been built yet

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 make mdbook 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.

    Github Documentation - Fork a repository

  • Make sure your fork is up-to-date with all commits from the main repo.

    Github Documentation - Syncing a fork

  • 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 appropriate mdbook 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 what make 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

    Github Documentation - Creating a pull request

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.


Generated 2025-09-22 03:40:19
74d4feb 2025-09-22 03:38:41 +0000