medito-app icon indicating copy to clipboard operation
medito-app copied to clipboard

Find a better solution for auth.dart

Open michaelcspeed opened this issue 3 years ago • 5 comments

Currently the auth token is stored in a file networkauth.dart that is not checked into version control. This means that each new developer needs to create this file and manually paste in their config.

The file when given to other volunteers currently looks like this"

const BASE_URL = 'https://thebackendurl.medito.app/';
const INIT_TOKEN = '';
const CONTENT_TOKEN = 'Bearer a_generated_auth_token';
const SENTRY_URL = '';

The blank tokens are only used in production and are added to the project during the build pipeline.

It would be good to streamline this process somehow. Any ideas welcome.

michaelcspeed avatar May 22 '21 13:05 michaelcspeed

I guess the reason you don't want to push auth.dart is that you want to hide the endpoint and content token from public, especially bots. If someone really wants to get the endpoint and CONTENT_TOKEN, they can easily extract them from the production app or inspect them via network tools. Here are my humble opinions based on that assumption.

If we can't hide it completely and only want to protect against the crawling bots, we can add an extra but simple obstacle to prevent the bots, still allow developers generate the tokens by themselves. For example:

  1. Change the code in auth.dart to read from an asset json configuration file instead hardcoded strings
  2. Check the auth.dart into version control
  3. Encrypt the BASE_URL and CONTENT_TOKEN into strings
  4. Create a shell script to decrypt the strings and write them into the configuration json
  5. Add the json configuration file into .gitignore
  6. Check the shell script into version control
  7. Add the script in github workflow
  8. Update README with the onboarding instruction

When a new developer joins the project, they can run the script to generate the configuration file.

When you need to add a new tokens (or change a token), you will need to add them into auth.dart and add/change the encrypted strings in the generator script, everyone will get the update.

qtdzz avatar May 22 '21 17:05 qtdzz

That sounds like something that could be workable. It does need a lot of setup for new developers to take in. I would personally go for a register developer account, and provide the key in the members area of that user. Only have to register developers, not regular users to keep the barrier as low as possible.

That seems to be the most used thing to do nowadays.

noesnaterse avatar May 25 '21 14:05 noesnaterse

@noesnaterse: That also sounds like a good idea. I do have some concerns though.

I agree registering and obtaining API keys is a popular way to distribute API keys to developers. However it seems to be more suitable the use case when developers want to develop their own app connecting to the service provider. Medito App is a single client connecting to Medito server. All Medito users are using the same API keys in Production.

We are developers but we don't develop our own app/client. We are contributing to a single client Medito App. So I don't think we need register ourselves and obtain a different key for every contributor. It doesn't provide any more value in my opinion.

If I am a bad actor, I can simply decompile the production APK and take the production keys... We can't distinguish that bad actors with other normal users by just looking at the API keys.

Moreover, if we are providing the keys in a page, every time Mike wants to change/update keys, he will need to update that page. Then all the contributors will have to go to that page and manual update their keys accordingly. That is not much different than what we have now, I think.

My proposal:

Option 1: Encrypt the keys and decrypt before building the app

PoC: https://github.com/qtdzz/medito-app/pull/2

  1. Encrypt the keys and commit the encrypted keys to git
  2. Create script to decrypt that file as an json asset in assets/api_keys.json
    • We can either embed the passphrase directly in the script. This is more convenient but people might skip slack #development channel.
    • Or Provide them as an environment variable and distribute that passphrase in #development slack channel to encourage people join the slack channel before contributing.
  3. Update the Auth.dart to use that json, commit Auth.dart
  4. Create script to decrypt the keys and update keys

When a new contributor joins, they will need:

  1. Join #development slack channel
  2. Get passphrase
  3. Run MEDITO_API_KEYS_PASSPHRASE=abc ./github/scripts/decrypt_development_api_keys.sh
    • If we embedded the passphrase in the script, they can skip step 1-2
  4. Build the app

When Mike wants to update/add keys, he can:

  1. Update Auth.dart
  2. Update api_keys.json (which is gitignored)
  3. Run MEDITO_KEYS_PASSPHRASE=abc ./github/scripts/update_development_api_keys.sh to create a new encrypted keys file
  4. git commit -am "chore: update api keys" && git push
  5. Every contributors will need to run ./github/scripts/encrypt_development_api_keys.sh again after pulling the latest changes, otherwise they will get an exception telling to do so when starting the app.
  • Pros:
    • Encourage contributors to join slack channel, more engagement
    • No obvious API keys + endpoints in GitHub
    • Mike can update the keys without telling everyone to do so, they will get to know when they pull the latest change and the app can't start.
  • Cons:
    • It sounds very complex to start contributing...
    • I don't have an option right now for contributors who is using Windows to decrypt the keys without downloading additional software...

Option 2: Embed the keys as base64 encoded to avoid crawling bots

PoC: https://github.com/qtdzz/medito-app/pull/1

  1. Base64 encode the keys and endpoint
  2. Put them in Auth.dart
  3. Decode them at the first touch and cache them
  4. Create different Auth.dart implementation for different environment (dev/prod)

When a new contributor joins, they will need:

  1. Just build the app and it should just work
  2. Join #development slack channel for discussion

When Mike wants to update/add keys, he can:

  1. Encode new APIs/endpoint
  2. Update Auth.dart
  3. Commit the file
  4. Every one will get the update
  • Pros:
    • Extremely simple process, every one can contribute without any hassle
    • Mike can update the keys without telling everyone to do so, they will not even recognize it...
    • The app is completely builable from source without any intervention. (This is important for publishing in F-Droid)
  • Cons:
    • The APIs keys and endpoint are easily retrievable from source code. However, as I described above. Any bad actor can just decompile the production APK and get the keys. It still prevents the crawling bots though
    • People might skip joining the #development channel (if that matters)

Note

This issue is a blocker for releasing to F-Droid because they require to build the app from source.

qtdzz avatar Jun 12 '21 17:06 qtdzz

I have steered the discussion towards f-droid which can be discussed in a separate issue, but I thought of putting more options forward to trigger that discussion. We could get help for this issue in the process

I am a frequent user of f-droid apps and can offer some suggestions based on my knowledge in the order of complexity from the user's end starting from easy. Although not an expert myself on getting an app published, I can help in the process and learn on the way.

Pre Requisite :

Offer a flavor of the app build that follows the Inclusion Policy

Options :

  1. Creating an issue on f-droid Requests For Packaging repo to start the conversation and get more information from maintainers and contributors about the app secrets handling.
    1. Upside : Easy for users who have installed just f-droid to install medito
    2. Downside: Not and actual downside. Once new version metadata is added is that it may take a while for f-droid to build and publish the app for users to download compared to Play Store.
  2. IzzyOnDroid is also a popular f-droid repository where the curator updates apps from GitHub releases that are not present in main f-droid repo. More information on the process here and the issue tracker for submission.
    1. Upside : Repo maintainer takes care of the app management
    2. Downside: App may take more less or more time because of the human factor compared to option 1. Users will have to add the IzzyOnDroid repo to be able to download and install medito
  3. Create your own f-droid repo. I do not have much info on this right now but can look into this route if needed. Apps like NewPipe offer this approach to allow for quicker updates than the official repo.
    1. Upside : Quick updates and no external dependencies.
    2. Downside : Setting up the repository itself and adding to 2nd point is that users may or may not trust the apk or the source because it either might have not passed the high inclusion standards or could be compromised (although chances are close to less).

Alternatives (can also be done now or in addition to above) :

  • Publish the built apk to GitHub releases. GPG verified releases are recommended.

Hope this info helps!

broxmen avatar Jul 11 '21 16:07 broxmen

I assume currently its still the old solution? I have an issue getting it compiled as it seems the Slac link is outdated...

h0ru5 avatar Oct 29 '21 18:10 h0ru5