Skip to content

Restrict default OAuthScope to "read:org" #39

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

Merged
merged 2 commits into from
Jul 11, 2015

Conversation

sirosen
Copy link
Contributor

@sirosen sirosen commented Jul 6, 2015

The default scope for OAuth should arguably be as restricted as possible. The older default of "repo,read:org" requested push access to all of a user's repositories. For many users of the plugin, this was considered a deal-breaker before configurable OAuth Scopes, so there's no reason to assume that most users would want this moving forward.

For admins who prefer setting these values through the web UI, it's better to start with a more restricted scope, as it means that the admin doesn't need to share push privileges with Jenkins at any point during server configuration. This is also a better default for novice users who are not familiar with the GitHub OAuth docs and OAuth scoping.

This is, of course, a follow-up to discussions that we had with #35

The default scope for OAuth should arguably be as restricted as possible. The
older default of "repo,read:org" requested push access to all of a user's
repositories. For many users of the plugin, this was considered a deal-breaker
before configurable OAuth Scopes.
For admins who prefer setting these values through the web UI, it's better to
start with a more restricted scope, as it means that the admin doesn't need to
share push privileges with Jenkins at any point during server configuration.
Plus, this is a better default for novice users who are not familiar with the
GitHub OAuth docs and OAuth scoping.
@samrocketman
Copy link
Member

That makes sense to me +1. I'll let others weigh in.

@samrocketman samrocketman self-assigned this Jul 6, 2015
@samrocketman
Copy link
Member

cc @jhoblitt

@s0undt3ch
Copy link

Is there a way to not even have org in there? By disabling certain parts of the plugin which require it?

I'm just using the plugin for authentication, I really don't want nothing to do with my users org's...

@jhoblitt
Copy link
Member

jhoblitt commented Jul 6, 2015

@s0undt3ch github will issue an oauth token without a scope so in theory it should work -- have you tried it?

@s0undt3ch
Copy link

That's what I was using and got a traceback because of the missing read:org, my guess is that this plugin always tries to pull org info? Because of its org based permissions feature? I'm not using that though hence me asking about not eve trying to fetch that data....

@samrocketman
Copy link
Member

@s0undt3ch I confirm that at a minimum read:org is required. I set the scope value to (no scope) from the list of acceptable scopes which gives access only to public information. However, when you log into the application you're presented with a stack trace.

WARNING: Error while serving http://localhost:8080/securityRealm/finishLogin
java.lang.reflect.InvocationTargetExceptio.....
...
Caused by: java.io.IOException: {"message":"You need at least read:org scope or user scope to list your organizations.","documentation_url":"https://developer.github.com/v3/orgs/#list-your-organizations"}
...
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://api.github.com/user/orgs
...
Caused by: java.io.IOException: Server returned HTTP response code: 403 for URL: https://api.github.com/user/orgs
...

For now, read:org is the minimum required scope.

@s0undt3ch
Copy link

Can't the plugin extend the required codes to include read:org only if org based permissions are enabled? Yes this can be considered a feature requiesy, unless, GitHub imposes that perm just for authentication?

@samrocketman
Copy link
Member

It's not because of a limitation on GitHub. It's how the OAuth plugin is getting the access token. Here's the actual stack trace.

Caused by: java.io.IOException: {"message":"You need at least read:org scope or user scope to list your organizations.","documentation_url":"https://developer.github.com/v3/orgs/#list-your-organizations"}
        at org.kohsuke.github.Requester.handleApiError(Requester.java:496)
        at org.kohsuke.github.Requester._to(Requester.java:245)
        at org.kohsuke.github.Requester.to(Requester.java:191)
        at org.kohsuke.github.GitHub.getMyOrganizations(GitHub.java:331)
        at org.jenkinsci.plugins.GithubAuthenticationToken.<init>(GithubAuthenticationToken.java:106)
        at org.jenkinsci.plugins.GithubSecurityRealm.doFinishLogin(GithubSecurityRealm.java:440)
        ... 73 more

Notice the last two lines in that stack trace: GithubSecurityRealm.java:440 and GithubAuthenticationToken.java:106. Specifically, GithubAuthenticationToken.java:106 is the cause because it is attempting to loop over the org membership. This should probably be patched. Keep in mind that the default scope should be one which allows the authorization strategy to work (that is read:org) is required. However, if not using the authorization strategy at all then the scope (no scope) should be an acceptable value. Feel free to open a bug report on it and someone may patch it for you. At the moment, I'm only maintaining releases and pull requests.

@jenkinsadmin
Copy link
Member

Thank you for a pull request! Please check this document for how the Jenkins project handles pull requests

@samrocketman
Copy link
Member

@s0undt3ch the patch for GithubAuthenticationToken.java:106 would basically need to check for one of the following scopes existing in Jenkins.instance.getSecurityRealm().oauthScopes (Groovy code).

  • read:org
  • admin:org

It needs to be something along the lines of:

import jenkins.model.Jenkins;
...
        if(Jenkins.instance.getSecurityRealm() instanceof GithubSecurityRealm
           && (Jenkins.instance.getSecurityRealm().oauthScopes.indexOf("read:org") >= 0
           || Jenkins.instance.getSecurityRealm().oauthScopes.indexOf("admin:org") >= 0)) {
            for (String name : gh.getMyOrganizations().keySet()) {
                authorities.add(new GrantedAuthorityImpl(name));
            }
        }

I tried writing my own patch but I'm still too new to plugin development to write something that could compile. I'm not sure how to access the current security realm instance to pull out oauthScopes.

@samrocketman
Copy link
Member

@michaelneale
Copy link
Member

the less permissions to operate the better, asking for a lot is a real roadblock for some people, so 👍 to concept (not sure of limitations or compatibility problems though).

@jhoblitt
Copy link
Member

jhoblitt commented Jul 7, 2015

As a data point, I'm using read:org in "production" without issue so it should be safe as the default. The desire to be able to do so was the main motivation for #35 .

@jhoblitt
Copy link
Member

jhoblitt commented Jul 7, 2015

Per #39 (comment), I've opened PR #40 to fix a wide range of whitespace and formatting issues.

@jhoblitt jhoblitt mentioned this pull request Jul 7, 2015
The GitHub default OAuth Scope lives in two places -- in the
GithubSecurityRealm definition, and in the jelly file used to build the web UI
for setting scope. In addition to restricting it to read:org in the class
definition, it needs to be restricted as such in the jelly.
@sirosen
Copy link
Contributor Author

sirosen commented Jul 7, 2015

I'm also using "read:org" on a live server, so I know that it works.
I'm not at all against the idea of trying to make this work with an unscoped token, or at least one that can't read organizational memberships, but I think that's a distinct issue from the more critical one of removing the "repo" scope from the defaults.

To me, the inclusion of "repo" is a clear and obvious mistake, while whether or not "read:org" should be the default (which could be removed by the admin after the fact, of course) is up for debate.

@s0undt3ch
Copy link

I'm mostly after the required support to just have user:email

@samrocketman
Copy link
Member

@s0undt3ch I believe the read:org is the minimum permissions we can bargain for because you need at least that in order to use the GitHub authorization strategy (in addition to the authentication). Otherwise, it won't be able to query for permissions on a project in that case. Feel free to correct me if I'm wrong. I think it still starts with patching that file as I mentioned.

@s0undt3ch
Copy link

That's my point, I'm not using it, so, I should not be forced to use read:org an patching every release is also not the solution.

If an admin chooses to use the GH authorization strategy, and he does not have that perm, he'll see the traceback, or, that component adds that perm to the list. Basically, it needs to be configurable...

@samrocketman
Copy link
Member

@s0undt3ch it's already configurable with #35. The sane default should be read:org. If you don't need/want that then you can configure it to be more restrictive. If we make it more restrictive by default then functionality won't work out of the box unless you have that bit of knowledge to change it. I think it should simply be documented as a recommended step for limiting access if you're not using the authorization strategy. Showing a user a stack trace as a result of them enabling authorization is not a good user experience and should be avoided I think. Stack traces aren't meant to be a feature in that regard.

Nobody said anything about patching every release. Patch it and create a pull request.

@samrocketman
Copy link
Member

@s0undt3ch there's two issues that I want to clarify. I think they're both distinct.

  1. The minimal required access for the entire plugin to work out of the box if a user uses all features of it. That minimal access is read:org and what this pull request is recommending (which I agree with).
  2. The fact that you can't be more restrictive with the scope to (no scope) or user:email when not making use of the functionality that requires organization access. This is a bug in GithubAuthenticationToken.java:106. A separate pull request needs to be created to address it. That's the patch I keep referring.

@s0undt3ch
Copy link

Agreed on both.

@sirosen
Copy link
Contributor Author

sirosen commented Jul 10, 2015

I want to make sure I'm not blocking this getting merged.
Since the jelly conf is now fixed, there's nothing else I know of that's outstanding.

As far as I can tell, the conclusion of the discussion here between @s0undt3ch and @samrocketman is that supporting more restrictive scopes is an issue, but not to be addressed here.

Anything I've missed?

@samrocketman
Copy link
Member

@sirosen nope, I think you're good. I'll merge it the next chance I get.

@samrocketman samrocketman merged commit 3594a7c into jenkinsci:master Jul 11, 2015
samrocketman added a commit that referenced this pull request Jul 11, 2015
samrocketman added a commit that referenced this pull request Jul 24, 2015
If using the GitHub OAuth plugin for authentication only, then it
doesn't make sense to query GitHub for Organization membership since it
will not be using GitHub OAuth for authorization.

This stems from a discussion in pull request #39.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants