From the early days of ChatGuessr, we told people to use an OAuth token generator to allow ChatGuessr to receive whispers. In v1.1.0-alpha.0 and v2.0.0, we also used this OAuth token to authenticate with ChatGuessr servers, which did this to verify identity:
This approach is nice and simple, but it has a major problem. While we only use it for verifying identity, these OAuth tokens:
give a lot of access (including moderation access if the account has it);
are permanently valid, because they are intended for people who connect to Twitch chat with an IRC client.
Both of these are very bad if we're sending them over the wire! We know that we don't abuse it but that is unproveable (even if the server was open source, there is no guarantee that the servers actually run that code and not something else entirely). And for users, trusting that an application on their computer is well-behaved is a different beast from trusting that this remote server is well-behaved and will be well-behaved into the future.
Using these tokens was very convenient for the ChatGuessr application in the past because it didn't really have to deal with authentication that much, it could just assume that the thing was valid and run with it. We could avoid a lot of the complexity that a login system typically requires. But now that we have to authenticate with our own servers, that complexity is no longer optional.
This patch reworks it so Twitch tokens are never sent. It uses Supabase just like the ChatGuessr map does, and uses the Supabase access token for authentication instead of the Twitch OAuth token. This means:
we no longer get any access to Twitch accounts on the server side, nor does anyone else (including Supabase)
the OAuth tokens used by the ChatGuessr application only have the bare minimum permissions
the OAuth tokens used by the ChatGuessr application are only valid for a short time, so even if they are leaked, the chances of an attacker actually getting to use it is small
ChatGuessr will show up as "ChatGuessr-App" in twitch connection settings, instead of the cryptic "Twitch Chat OAuth Token Generator", so it is easier for people to revoke the access if they want to
Because the tokens are only briefly valid, we need to go through the authentication flow every time we try to connect to chat to get a fresh token. This is done in a separate window that stays hidden as long as user interaction is not required.
This implementation is still a bit janky and I would like to improve it (eg. by pulling all the authentication code into a class in its own module). Different parts of the authentication flow are spread out across the codebase too much. However it's more important to get it out the door than to perfect it.
I tried to put most of the Twitch-specific code into a TwitchBackend class here, in the future we could add different Backend classes for other streaming services supported by Supabase, or even things like Discord.
From the early days of ChatGuessr, we told people to use an OAuth token generator to allow ChatGuessr to receive whispers. In v1.1.0-alpha.0 and v2.0.0, we also used this OAuth token to authenticate with ChatGuessr servers, which did this to verify identity:
This approach is nice and simple, but it has a major problem. While we only use it for verifying identity, these OAuth tokens:
Both of these are very bad if we're sending them over the wire! We know that we don't abuse it but that is unproveable (even if the server was open source, there is no guarantee that the servers actually run that code and not something else entirely). And for users, trusting that an application on their computer is well-behaved is a different beast from trusting that this remote server is well-behaved and will be well-behaved into the future.
Using these tokens was very convenient for the ChatGuessr application in the past because it didn't really have to deal with authentication that much, it could just assume that the thing was valid and run with it. We could avoid a lot of the complexity that a login system typically requires. But now that we have to authenticate with our own servers, that complexity is no longer optional.
This patch reworks it so Twitch tokens are never sent. It uses Supabase just like the ChatGuessr map does, and uses the Supabase access token for authentication instead of the Twitch OAuth token. This means:
Because the tokens are only briefly valid, we need to go through the authentication flow every time we try to connect to chat to get a fresh token. This is done in a separate window that stays hidden as long as user interaction is not required.
This implementation is still a bit janky and I would like to improve it (eg. by pulling all the authentication code into a class in its own module). Different parts of the authentication flow are spread out across the codebase too much. However it's more important to get it out the door than to perfect it.
I tried to put most of the Twitch-specific code into a TwitchBackend class here, in the future we could add different Backend classes for other streaming services supported by Supabase, or even things like Discord.