Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tech Question: Do we even Need an AUTH_API_KEY? πŸ’­ πŸ€·β€β™‚οΈ #277

Open
nelsonic opened this issue Feb 23, 2023 · 5 comments
Labels
chore a tedious but necessary task often paying technical debt discuss Share your constructive thoughts on how to make progress with this issue elixir Pull requests that update Elixir code help wanted If you can help make progress with this issue, please comment! priority-1 Highest priority issue. This is costing us money every minute that passes. question A question needs to be answered before progress can be made on this issue T1h Time Estimate 1 Hour tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written technical A technical issue that requires understanding of the code, infrastructure or dependencies

Comments

@nelsonic
Copy link
Member

Continuing on from our discussion in: #268
and with the benefit of our knowledge from Flutter and JS-land ...
Trying to think about auth from first principals ...
How are we going to enable auth in our Flutter app with the least code possible
and without the need for keeping "secrets" ... πŸ’­

Why do we have an AUTH_API_KEY in the first place?

We (I) created an AUTH_API_KEY because I thought that it was needed for identifying/verifying which App is using auth for authenticating the person. But when I think about it with my beginner's mind I'm forced to think "Why...?" πŸ€·β€β™‚οΈ

If someone is running a Phoenix App on localhost then we know they are in "Dev" mode, right? πŸ‘©β€πŸ’»
So why do they need to have an AUTH_API_KEY to identify them? πŸ€”
The AUTH_API_KEY doesn't provide the person using the app any additional security
it's just an extra step for the Dev/Engineer to setup ...

Does auth need an API_KEY or can we just do domain-based verification? πŸ’­

Can we just create an "Allowed List" for urls that are allowed to use auth and reject any other URL?
We currently require the URL to be defined for an app, e.g: https://auth.dwyl.com/apps/45

image

If we are doing a domain-based verification, then do we need an AUTH_API_KEY? πŸ’­
What real additional security is the AUTH_API_KEY giving us?
Is it just perceived security because we've been trained to think that API Keys are the "right" way to do this? πŸ€”

How will an attacker exploit a system that only has domain-based verification?

Hypothetically, if we were to completely remove the AUTH_API_KEY,
how would a malicious person ("attacker") attempt to use our auth system
to get people to login with their Google/GitHub/etc account and steal their data? πŸ’­

If the attacker can intercept a request or create a fake page that looks like our App,
and use our own auth endpoint to authenticate a person and then replay
the successful JWT back to the App they can read the person's data ...

How can we do domain-based verification on a Distributed App?

If our Flutter App is web-based or deployed to the App/Play Store,
will there be a "domain" for it? πŸ’­
And if there is no domain associated with the "Native" App, how do we verify it? πŸ€·β€β™‚οΈ
Is there a unique string associated with the iOS or Android build that cannot be spoofed?

These are the questions that are on my mind right now as I'm thinking about auth in general
and specifically gearing up to re-write auth from first principals to be an order of magnitude simpler.

Note: Please only comment if you understand the security implications of this question. πŸ™
i.e: you have done a bit of white/grey hat hacking and understand how "hackers" think about compromising systems. πŸ¦Έβ€β™€οΈ

@nelsonic nelsonic added help wanted If you can help make progress with this issue, please comment! question A question needs to be answered before progress can be made on this issue priority-1 Highest priority issue. This is costing us money every minute that passes. T1h Time Estimate 1 Hour chore a tedious but necessary task often paying technical debt discuss Share your constructive thoughts on how to make progress with this issue technical A technical issue that requires understanding of the code, infrastructure or dependencies tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written elixir Pull requests that update Elixir code labels Feb 23, 2023
@nelsonic
Copy link
Member Author

Supabase has the concept of an anon key:
https://supabase.com/docs/guides/database/api#api-url-and-keys
anon-key-in-web-context

"an anon key, which is safe to be used in a browser context."

i.e. people are putting these keys in plaintext in their web apps ...

@LuchoTurtle's recent speed-run of the Supabase + Flutter tutorial:

supabase-flutter-demo#42-adding-main-function-and-constants
image

hard-coded into the demo app:
https://github.com/dwyl/supabase-flutter-demo/blob/01a2902fb7a0950cd8af370ea0c1eeaa91e7750d/lib/main.dart#L19-L23

https://jwt.io/#debugger-io?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InltbGx1YnB0b2p4eXloZXFoZmJnIiwicm9sZSI6ImFub24iLCJpYXQiOjE2NzQ4MzU2ODksImV4cCI6MTk5MDQxMTY4OX0.DwTBckKPG63bObcqK2il-xt0uiWQXfuAxWS596RTUfk

image

Note: There's an active thread about how to disable anon key in the Supabase discussions: supabase/supabase#4547 ⏳
This is not the place to "bash" Supabase ... they have built their system how they see fit. πŸ‘
Instead I want to understand how we can do "anonymous" access to auth
without needing to have an anon key which IMO is an anti-pattern.

An anon key encourages people to put the key in-the-clear e.g. in front-end JS apps.
That means it provides exactly zero security. 0️⃣
So what's the point of having it? πŸ€·β€β™‚οΈ

@nelsonic
Copy link
Member Author

nelsonic commented Feb 25, 2023

OK, I've thought about this a lot from both the security and usability perspectives. πŸ’­
Crucially, if we're building a Native App using Flutter, πŸ“±
and there isn't a way to protect an API key in Flutter, see: dwyl/learn-flutter#82 πŸ”
So while we aren't going to completely remove the AUTH_API_KEY,
we are going to re-think it as "non-secure". πŸ”“
i.e. we won't use it as a "key" but rather as an "identifier". πŸ”‘ -> πŸ‘€
The key [breaking] change we will be making to the AUTH_API_KEY is the format:

auth.domain.com/:person_id/:public_key

Before:

88SwQD4YweF8q7iAt1RPVjwqnztrEP9Lm4XWn/88SwQGcsdq4gUpR9D69DFAXyZep/authdemo.fly.dev

After:

authdemo.fly.dev/88SwQD4YweF8q7iAt1RPVjwqnztrEP9Lm4XWn/88SwQGcsdq4gUpR9D69DFAXyZep

The change is pretty basic; on the surface ...
Instead of having the URL as the last part of the AUTH_API_KEY,
it will be at the start of the AUTH_API_KEY.
But rather than this being a boring key, it will also be a functional URL/endpoint.
i.e. visiting: authdemo.fly.dev/88SwQD4YweF8q/88SwQGcsdq4g
in a browser will show the info/stats for the client - provided you successfully authenticate.

As previously noted, this is a breaking change so we will need to release a V2 of auth_plug.

We're going to make it explicit in all our docs that the AUTH_API_KEY does not contain anything sensitive
and can safely be embedded in a front-end/Native App. The only reason to continue using environment variables to specify the key is to be able to switch between auth instances
e.g: from authdemo.fly.dev to auth.dwyl.com or auth.acme.co

I think this is as simple as we can make it.
We're always going to need an auth instance URL
so the App knows where to send people to authenticate.

So the next question is: should we rename our SingleEnvironmentVariableTM
from AUTH_API_KEY to AUTH_URL for clarity/simplicity
given that it will in fact be just a URL not an "API Key"...? πŸ’­

@LuchoTurtle
Copy link
Member

I agree with the changes. However, even though this following question might be me missing something...

I wonder if, even though the AUTH_URL is an identifier and not a key, can't it be used to impersonate other people, since the AUTH_URL is accessible by anyone in the browser?

@nelsonic
Copy link
Member Author

AUTH_URL will be restricted to the person that is allowed to see it. πŸ”
I will attempt to clarify this shortly. 🀞

@nelsonic
Copy link
Member Author

But yes, you're right. perhaps the the AUTH_API_KEY name will be clearer to people ... πŸ’­

If the AUTH_API_KEY is left in-the-clear, e.g. committed to GitHub by mistake,
it could be used to authenticate by someone that isn't the owner.
This is the same as leaking any other API Key by committing it to GitHub.
The mitigation will be:
a) Having an "Allowed List" for the URL that is allowed authenticate. i.e. only app.dwyl.com #281
b) Additional check on a new device, i.e: for people authenticating on a new phone/computer they will have to verify via 2nd factor auth. TBD

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chore a tedious but necessary task often paying technical debt discuss Share your constructive thoughts on how to make progress with this issue elixir Pull requests that update Elixir code help wanted If you can help make progress with this issue, please comment! priority-1 Highest priority issue. This is costing us money every minute that passes. question A question needs to be answered before progress can be made on this issue T1h Time Estimate 1 Hour tech-debt A feature/requirement implemented in a sub-optimal way & must be re-written technical A technical issue that requires understanding of the code, infrastructure or dependencies
Projects
None yet
Development

No branches or pull requests

2 participants