How to user Mastodon's built-on oauth provider as the authentication provider for WriteFreely
Mastodon is an amazingly flexible application, including exposing an oauth API that can be used by other applications as an authentication source. Wrtefreely is a very clean, minimalist, fediverse-native blogging platform. One thing it doesn't do, though, is handle authentication well. For example, there is no provision for verifying the email address of a person signing up, nor provisions for multifactor authentication. But it does support oauth authentication providers. Enter Mastodon.
Writefreely is one of the more common requests of people on infosec.exchange, and I am all in on the fediverse, hoping to show the possibilities and value of the fediverse. And I like the technical challenge that comes with setting these things up and administering them, somewhat at scale.
What is NOT clear, and not well documented for the uninitiated is exactly how to configure WriteFreely to use Mastodon for authentication. Hopefully this writeup helps others.
I recommend that you follow these steps before you try to log in for the first time. WriteFreely sets the first login as the administrator, and it's a PITA to change it.
The first step is to create an application on your Mastodon instance. Obviously, substitute infosec.exchange for your own (or use infosec.exchange – that's ok, too). Run this command from a unixy shell:
curl -X POST -F 'client_name=Login with Infosec.Exchange' -F 'redirect_uris=https://infosec.press/oauth/callback/generic' -F 'scopes=read: accounts' -F 'website=https://infosec.exchange' https://infosec.exchange/api/v1/apps'
This will return a string that looks like:
{"id":"62724","name":"Login with Infosec.Exchange","website":"https://infosec.exchange","redirect_uri":"https://infosec.press/oauth/callback/generic","client_id":"<clientIDstring>","client_secret":"<clientSecretString>","vapid_key":"<VapidKeyString>"}
There will be key values in where the <> is in the above example. You will use <clientIDstring>
and <clientSecretString>
, but will not use <VapidKeyString>
.
Next, in the config.ini file you created, find this section at the end of the file and delete everything below:
[oauth.generic]
Then, copy/paste the follow:
client_id = <clientIDstring>
client_secret = <clientSecretString>
host = https://infosec.exchange
display_name = Infosec.Exchange
token_endpoint = /oauth/token
inspect_endpoint = /api/v1/accounts/verify_credentials
auth_endpoint = /oauth/authorize
scope = read: accounts
allow_disconnect = false
map_user_id = id
Making the necessary substitutions for the key and the Mastodon instance you're authenticating against.
If you want to only permit logins through oauth (this is my recommendation), also change this value:
disable_password_auth = false
to
disable_password_auth = true
Once done, run systemctl restart writefreely.service
or whatever you named your system unit file and you should be in business.