pd4d10 / unpub

Self-hosted private Dart Pub server for Enterprise
https://pub.dev/packages/unpub
MIT License
441 stars 135 forks source link

fine grained access permissions #55

Open bsutton opened 2 years ago

bsutton commented 2 years ago

the 2.15 changes got me thinking about fine grain access control.

How would we feel about passing a user identifier to each of the meta and file store api calls?

The email addresses obtained from the access token probably makes sense.

If there is interest I might be able to find time to contribute the change.

Thoughts?

talisk commented 2 years ago

@bsutton

Fine. There're some issues are also looking for solution about fine grain access control. Like #54 .

If you have a good plan, welcome to discuss it together.

leoshusar commented 2 years ago

I think it would be great to have the ability to restrict access to only allowed users (list of allowed emails? allowed domains wildcard?), so you can have public facing but still secure unpub. And also hide frontend behind login.

Did your idea include something like this? If yes, I'm 100% interested.

I was also thinking about an option to use custom OAuth2 server instead of Google. What do you think about this? It would mainly cut the need of using Google account, but also allowed "IdP level access restriction" (when used with e.g. self hosted IdP).

bsutton commented 2 years ago

I've had a look at this and my schedule and its going to be a large chunk of work which I can't commit to at the moment.

So sorry I'm going to have to step out of this one.

talisk commented 2 years ago

@leoshusar

I think it would be great to have the ability to restrict access to only allowed users (list of allowed emails? allowed domains wildcard?), so you can have public facing but still secure unpub. And also hide frontend behind login.

Did your idea include something like this? If yes, I'm 100% interested.

I was also thinking about an option to use custom OAuth2 server instead of Google. What do you think about this? It would mainly cut the need of using Google account, but also allowed "IdP level access restriction" (when used with e.g. self hosted IdP).

Support for custom oauth2 servers is planned for unpub soon. When deploying the unpub service, pass in the OAuth2 configuration and use the unpub_auth tool to guide users finish the authentication process.

leoshusar commented 2 years ago

@talisk Thanks for the info! In fact I've been chatting with the Dart team on their Discord about hosted Pub servers and one of my questions was about auth, like if they are maybe somehow planning to integrate custom OAuth2 into the Pub client or if users should use some_auth_app | dart pub token add xxx...

And their idea for this is to have web UI with login where users can generate their tokens. I don't know if you are planning something like this or how much temporary is the unpub_auth app. But I agree that this would be the best way.

Quote:

Regarding updating tokens:

https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md If you read the repository specification it says that when authentication fails, you can return WWW-Authenticate header with a custom message.

I would suggest creating a private pub server such that you do:

dart pub get
.... authentication failed error message
Custom message:
  Go to https://my-pubserver.com/manage-tokens to get a token

So create a custom message that says something like: "go to https://my-pubserver.com/manage-tokens to create a token" So your custom pub server should just have a webinterface where users can:

  1. sign-in using whatever sign-in mechanism you want (consider supporting various SSO systems)
  2. Once signed in, the user can create / delete / activate / deactivate tokens
  3. User will then create a token, and copy it to dart pub token add

Tokens should have expiration of 30 days or 1 year, or just never expire. Ideally, when creating a token, the user would give it a description, so they can remember what computer they've authenticated using said token.

Also here is an example how it works on GitLab. You create new token, give it name, maybe expiration, username wouldn't be needed here since, and scopes - for unpub read and write should be enough. Now the API would be accessible using only this token and OAuth2 token would be for webAPI. image

And side note: unpub now isn't even checking the token audience, so any random Google token would also work on any random unpub instance.

I've been playing with this for a few afternoons, but unfortunately this is going to be rather big update which sadly I don't have time to finish, I wanted to add just simple auth middleware but I already ended up with twice as much code than I started with, haha

Next thing that should be done is to "convert" uploaders from email to user ID, because while on Google you cannot change your email, with other OAuth2 providers you can, so the only reliable identifier will be the ID.

I can however give you my unfinished code, if you want. My latest working version had auth middleware with OAuth2 token checking (Google, custom JWT and introspected opaque). Then I wanted to add custom generated tokens for API routes and that's where I have ended.

I can however share my unfinished code. I don't know how far you are with it already, but you can use anything you want from there, if you like something from there; you don't have to, if you don't :) I didn't want to publish half baked temporary solutions, that's why I didn't PR the first OAuth2 working thing.

ebsangam commented 1 year ago

For now is there any way to make unpub hosted repo private? (private in sense that unauthorized user can't access). I didn't find any documentation about this.