gradio-app / gradio

Build and share delightful machine learning apps, all in Python. 🌟 Star to support our work!
http://www.gradio.app
Apache License 2.0
30.69k stars 2.28k forks source link

Limit oauth logins #8405

Closed pngwn closed 1 month ago

pngwn commented 1 month ago

Received this question about logging in with HF on discord. Posting here for visibility:

Can you limit the list of allowed logins (usernames) with huggingface for gradio spaces so you can limit who can log into it?

I wondered if this might be possible with some kind of middleware or by using gr.Request.

Cc @Wauplin

Wauplin commented 1 month ago

Wow, haven't thought about this kind of feature no :astonished:

We could introduce callbacks on login/logout calls so that gradio users can define specific rules (so kinda middleware logic indeed) but I'm wondering how impactful this would be -compared to the added complexity-.

abidlabs commented 1 month ago

This should be possible already no -- once a user logs in, you have access to their username in the gr.OAuthProfile object, so you could do something like this:

import gradio as gr

def hello(profile: gr.OAuthProfile) -> str:
    if profile in ["abidlabs"]:
        return f"Hello {profile.username}"
    return "Not authorized."

with gr.Blocks() as demo:
    gr.LoginButton()
    m = gr.Markdown()
    demo.load(hello, None, m)

demo.launch()
abidlabs commented 1 month ago

You can make disable entire parts of the demo if someone's username is not allowed, etc. Of course, the code is still available and someone could duplicate it and change the list of authorized usernames, but that's a separate issue

pngwn commented 1 month ago

That looks great. I'll close this now, we can review if there are any follow ups.

Thanks folks.

matdmiller commented 1 month ago

Thank you for the quick answer! One quick follow up question - is gr.OAuthProfile data obtained securely in a way so the requestor wouldn't be able to simply modify the header to add the profile string? I was reading your docs (https://www.gradio.app/guides/sharing-your-app#o-auth-with-external-providers) and noticed this section:

In this example, only requests that include a "user" header will be allowed to access the Gradio app. Of course, this does not add much security, since any user can add this header in their request.

and I just wanted to confirm this wouldn't be relatively trivial to bypass.

The use case I'm thinking of is where the space calls an API where the API key is stored securely in the space secrets so if they cloned it they would not be able to make requests using your API key. They would be able to add their own API key and re-use the space code which would be fine.

pngwn commented 1 month ago

That section is an example of how not to do it before explaining the OAuth integration. The OAuth integration utilises the full OAuth flow and is very secure and does not suffer from the issue mentioned in your quote.

The scenario you mentioned in the final paragraph is also safe. And is something we recommend. Duplicating spaces, even when secrets are used, is perfectly secure. The user duplicating needs to create their own secrets.