jms1.pub - Keybase Sites

Keybase Sites offers a way to host web sites whose content is stored in Keybase private or team directories, using URLs which are in other domains (such as domains you may own already). It works by using the Keybase user "kbpbot" to retrive the files as they are requested.

In addition, the first time somebody retrieves a page in a new hostname, kbpbot will automatically request an SSL certificate from Let's Encrypt, and use that to answer the request (and any future requests for the same site). This means the first time you try to visit the site after setting it up, it may take an extra 10-30 seconds before you see the page.

These are some very simple sites I created under the jms1.net domain, whose contents are stored in Keybase in different ways.

Site Location
jms1.pub /keybase/public/jms1/
kb-public.jms1.net /keybase/public/jms1/kb-public.jms1.net/
kb-shared.jms1.net /keybase/private/jms1#kbpbot/kb-shared.jms1.net/
kb-team.jms1.net /keybase/team/jms1team.sites/kb-team.jms1.net/
kb-git.jms1.net keybase://team/jms1team.sites/kb.jms1.net/ - "master" branch
kb-git-other.jms1.net keybase://team/jms1team.sites/kb.jms1.net/ - "other" branch

Details

⚠️ Everything below this point is a work in progress.

As in, I'm writing it whenever I have time ($DAYJOB eats almost all of my available brain-cycles). Please understand if something is incomplete or missing, but at the same time, please let me know if you notice anything which is just plain wrong.

Most of this is already documented, however it took me a bit of experimentation to get my first site working. I'm writing this page (well, adding this information to the page which already existed here) because I personally would have found things easier to understand if it had been written this way. Please don't think I'm trying to disparage the official documentation.

There are three primary tasks involved in setting up a web site using Keybase Sites:

These are explained in more detail below.

Create the content and store it in Keybase

Creating the content is up to you. Feel free to use whatever tools you like - for example, I'm using BBEdit, a text editor for macOS, to write the text you're reading right now.

The only requirements are:

Storing the files in Keybase can be done in one of several ways.

Public directory

This is probably the simplest way to do it.

ℹ️ I'm using my own Keybase username, jms1, for the following examples. You will obviously want to substitute your own username.

Shared private directory

This involves storing the files in a private directory where you and the kbpbot user both have access. Normally you would use a directory name which only allows the kbpbot user to have read access.

Team directory

This involves storing the files in a team directory, and making the kbpbot user a member of the team. Normally you would make them a "reader", so they only have read access.

Team git repository

This involves storing the files in a git repo under a team, and making the kbpbot user a member of the team. Normally you would make them a "reader", so they only have "pull" access, and can't push new commits into the repo.

Tell the world that the site is hosted using Keybase Sites

Site's hostname is within a domain

If the site's name will be within another domain, such as "www.example.com", create a CNAME record pointing to "kbp.keybaseapi.com".

In the steps below which talk about adding DNS records...

Site's hostname is the root of a domain

If the site's name will be the same as the root of a domain, such as "example.com" ... things get tricky because of the rules around CNAME records.

I've seen documentation about this which says you can use a "DNS ALIAS record", but I've searched through RFC 1035 and all 28 of its updates (which define the DNS record types), and there is no such record type defined.

As near as I can figure, some specific DNS providers (such as AWS "Route53") offer these as "virtual records", where instead of returning an IP from a "zone file" or a database, the authoritative nameserver will do a recursive lookup of the target name and return the results of that query, as if they were the actual results of the original ALIAS lookup. Basically, instead of the IPs being fixed in a database or zone file, the IPs are looked up at the time the query is received.

If you're using a DNS provider who offers such a thing, and you're sure you're going to stick with them, then create an "ALIAS record" pointing to the name "kbp.keybaseapi.com". (I have no way to try this myself, so if it doesn't work, keep reading.)

Otherwise, you can manually look up the set of IP(s) that the name kbp.keybaseapi.com points to, and create an A or AAAA record pointing to each of those IPs. Currently there's only one IPv4 address, 18.214.166.21, which belongs to AWS.

If you do this, you will need to periodically re-check the list of IPs that kbp.keybaseapi.com points to, and update your A and AAAA records to match those changes. (I doubt the list of IPs will change very often, unless Keybase decides to add IPv6 support, migrate from AWS to some other cloud provider, or set up services in other parts of the world for various legal reasons.)

Tell kbpbot where to find the site's content

Telling kbpbot where to find the content is done by creating another DNS record. This needs to be a TXT record, with the name "_keybase_pages." followed by the site's custom hostname. The content of the record depends on where the site's files are stored.

Hosted in a public directory

In this case, the files need to be stored in or under a /keybase/public/xxx directory. I say "in or under" becuase you can set up multiple "web sites" under the same Keybase public directory by pointing each web site to a different sub-directory within the public directory.

For my jms1.pub site, the files are stored in /keybase/public/jms1/.

Steps

Create and populate the directory containing the content.

(jms1@imac27) 34 /keybase/public/jms1 $ ls -laF total 4 drwx------ 1 jms1 wheel 201 Jul 7 22:18 ./ drwx------ 1 jms1 wheel 208 Jul 7 22:23 ../ -rw------- 1 jms1 wheel 705 Jul 8 18:22 index.html

Add the DNS record.

Hosted in a shared private directory

In this case, the files need to be stored in a /keybase/private/xxx directory, where xxx includes your Keybase username, kbpbot, and possibly others.

⚠️ Be careful with the directory name.

If the list of users in the directory name contains a "#" instead of a comma, any usernames after that will have read-only access. The name you use will depend on what permissions you want to assign:

For my kb-shared.jms1.net site, the files are stored in /keybase/private/jms1#kbpbot/kb-shared.jms1.net/.

Steps

Create and populate the directory containing the content.

(jms1@imac27) 34 /keybase/private/jms1#kbpbot/kb-shared.jms1.net $ ls -laF total 4 drwx------ 1 jms1 wheel 201 Jul 7 22:18 ./ drwx------ 1 jms1 wheel 208 Jul 7 22:23 ../ -rw------- 1 jms1 wheel 705 Jul 8 18:22 index.html

Add the DNS record.

Hosted in a team directory

In this case, the files need to be stored in a /keybase/team/xxx directory, where xxx is the name of a team, and kbpbot is a member of that team.

For my kb-team.jms1.net site, the files are stored in /keybase/team/jms1team.sites/kb-team.jms1.net/.

Steps

If it isn't already a member, add Keybase user kbpbot to the team. In my case, I made it a reader, so if there's a bug in the software it wouldn't be able to make any changes.

keybase team add-member -r reader -u kbpbot jms1team.sites

Create and populate the directory containing the content.

(jms1@imac27) 31 /keybase/team/jms1team.sites/kb-team.jms1.net $ ls -laF total 4 drwx------ 1 jms1 wheel 238 Jul 7 08:25 ./ drwx------ 1 jms1 wheel 475 Jul 7 23:30 ../ -rw------- 1 jms1 wheel 703 Jul 8 18:17 index.html

Add the DNS record.

Hosted in a team git repo, in master branch

In this case, the files are stored in a git repo, owned by a team that the kbpbot user is a member of. The files are stored in a branch called "master" within the repo.

For my kb-git.jms1.net repo, the files are in the repo keybase://team/jms1team.sites/kb-git.jms1.net, in the master branch.

Steps

If it isn't already a member, add Keybase user kbpbot to the team. In my case, I made it a reader, so if there's a bug in the software it wouldn't be able to make any changes.

keybase team add-member -r reader -u kbpbot jms1team.sites

Create the repo on your workstation. The site's files will need to be in a branch called "master", so it makes sense to use this name as the initial branch. (This means the literal word "master", not a term for "the repo's primary branch".)

mkdir ~/git/kb.jms1.net cd ~/git/kb/jms1.net git init -b master

Set up the content.

(master u=)(jms1@imac27) 36 ~/git/kb.jms1.net $ ls -laF total 16 drwxr-xr-x 5 jms1 staff 160 Jul 8 18:20 ./ drwxr-xr-x 44 jms1 staff 1408 Jul 7 21:23 ../ drwxr-xr-x 13 jms1 staff 416 Jul 8 18:21 .git/ -rw-r--r-- 1 jms1 staff 14 Jul 7 21:24 .gitignore -rw-r--r-- 1 jms1 staff 702 Jul 8 18:21 index.html

Add the files and commit them.

git add -A git commit

If it doesn't already exist, create the empty Keybase git repo.

keybase git create --team jms1team.sites kb.jms1.net

Set the local working directory's origin upstream to point to the new Keybase git repo.

git remote add origin keybase://team/jms1team.sites/kb.jms1.net

Push the repo "up" to Keybase.

git push -u origin master

Add the DNS record.

Hosted in a team git repo, in other branch

This is just like the case above - the files are stored in a git repo, owned by a team that the kbpbot is a member of. The difference is, in this case the files we're using for the web site are stored in a branch with name other than "master". I'm using the name "other" for this example, obviously feel free to use whatever name you like for your site.

Keybase Sites wasn't designed to use branches other than master when dealing with a git repo. In order to make it work, we're actually setting it up to read from a team directory, but the directory name we're going to point it to is a "magic" directory whose contents "contain" the HEAD of a branch within a Keybase-hosted git repo.

ℹ️ The "magic" filename which points to a branch within a team repo is ...
/keybase/team/TEAM/.kbfs_autogit/REPO/.kbfs_autogit_branch_BRANCH

I want to publicly thank Keybase user "dxb" for telling me about this. This is not something I would have figured out on my own. The "magic" filenames in KBFS are not clearly documented, and to be honest it never occurred to me to search through the client code to figure them out for myself - although now that I'm looking at the code, I want to make a list of these "magic" names and document them. I know I would find such a list useful, and I suspect others would as well.

So ... thank you dxb! 😎

For my kb-git-other.jms1.net site, the files are in the repo keybase://team/jms1team.sites/kb-git.jms1.net, in a branch called "other". This is the same git repo I'm using for kb-git.jms1.net, just a different branch. If you're curious, the commit history looks like this:

(master u=)(jms1@imac27) 42 ~/git/kb.jms1.net $ git log --oneline --all --graph --no-show-signature * 5a3513d (origin/other, other) Added `kb-public` site, changed from list to table, in `other` branch. * 7beba3a Added 'other' branch | * 8229f3f (HEAD -> master, origin/master) Added `kb-public` site, changed from list to table | * 475d1ed Added link to kb-git-other site |/ * b0e841c removed link to "this" page * f771f89 updated page to match others * 01c645c (tag: initial) initial commit, testing keybase sites hosting via keybase git repo

Steps

Clone the repo on your workstation, and make sure your repo control files are up to date with the "server" (i.e. the repo stored in Keybase).

cd ~/git git checkout keybase://team/jms1team.sites/kb.jms1.net cd kb.jms1.net git fetch -p

Create or check out the desired branch.

Set up the content.

(other u=)(jms1@imac27) 36 ~/git/kb.jms1.net $ ls -laF total 16 drwxr-xr-x 5 jms1 staff 160 Jul 8 18:20 ./ drwxr-xr-x 44 jms1 staff 1408 Jul 7 21:23 ../ drwxr-xr-x 13 jms1 staff 416 Jul 8 18:21 .git/ -rw-r--r-- 1 jms1 staff 14 Jul 7 21:24 .gitignore -rw-r--r-- 1 jms1 staff 702 Jul 8 18:21 index.html

If you've added or changed any files, commit the changes and push them. (Use the "-u" option if the branch doesn't exist in Keybase yet.)

git add -A git commit git push -u origin other

Add the DNS record.