-
Notifications
You must be signed in to change notification settings - Fork 369
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
Add support for GitHub app authentication #269
Changes from all commits
a277a71
96bfe13
5225a5d
42e6826
8010d4d
9415745
df39f0c
262f07e
cd4b795
9e7de1c
e2c9374
c311b36
ad2e0ca
07dc6a6
4ad286e
5b1c3df
91e4bf4
ff0327a
d33000a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
= GitHub app authentication guide | ||
|
||
This guide is targeted to users who want to use a link:https://developer.github.com/v3/apps/[GitHub app] | ||
to authenticate to Jenkins. | ||
|
||
== Why? | ||
|
||
- the link:https://developer.github.com/apps/building-github-apps/understanding-rate-limits-for-github-apps/[rate limit] | ||
for a GitHub app scales with your organization size, whereas a user based token has a limit of 5000 regardless of | ||
how many repositories you have, | ||
- for organization's that have 2fa enforced - no need to manage 2fa tokens for a 'bot' user | ||
timja marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- to improve and tighten security: the Jenkins GitHub app requires a minimum, controlled set of privileges compared to a service user and its personal access token which has a much wider set of privileges | ||
|
||
== Getting started | ||
|
||
Before you get started make sure you have the required permissions: | ||
|
||
=== GitHub | ||
|
||
You'll need the permission to create a GitHub app, if you're creating it on a personal account then you can skip this section, | ||
otherwise: | ||
|
||
- organization owner | ||
|
||
or | ||
|
||
- permission to manage GitHub apps has been | ||
link:https://help.github.com/en/github/setting-up-and-managing-organizations-and-teams/adding-github-app-managers-in-your-organization[delegated to you]. | ||
|
||
=== Jenkins | ||
|
||
You'll need the permission to create a new credential and update job configuration, the specific permissions are: | ||
|
||
- Credentials/Create | ||
- Job/Configure | ||
|
||
== Creating the GitHub app | ||
|
||
link:https://developer.github.com/apps/building-github-apps/creating-a-github-app/[Follow the GitHub guide for creating an app] | ||
|
||
The only fields you need to fill out (currently) are: | ||
|
||
- Github App name - i.e. `Jenkins - <team name>` | ||
- Homepage URL - your company domain or a github repository | ||
- Webhook URL - your jenkins instance, i.e. `https://<jenkins-host>/github-webhook/` | ||
timja marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
Permissions this plugin uses: | ||
|
||
- Commit statuses - Read and Write | ||
- Contents: Read-only (to read the `Jenkinsfile` and the repository content during `git fetch`). You may need "Read & write" to update the repository such as tagging releases | ||
- Metadata: Read-only | ||
- Pull requests: Read-only | ||
- Webhooks (optional) - If you want the plugin to manage webhooks for you, Read and Write | ||
|
||
|
||
Click 'Create GitHub app' | ||
|
||
You now need to generate a private key authenticating to the GitHub app | ||
|
||
Click the 'generate a private key' option. | ||
|
||
After a couple of seconds the key will be downloaded to your downloads folder. | ||
|
||
Now you need to convert the key into a different format that Jenkins can use: | ||
|
||
[source,shell] | ||
---- | ||
openssl pkcs8 -topk8 -inform PEM -outform PEM -in key-in-your-downloads-folder.pem -out converted-github-app.pem -nocrypt | ||
---- | ||
|
||
== Install the GitHub app | ||
|
||
- From the install app section of newly created app, install the app to your organization. | ||
|
||
== Adding the Jenkins credential | ||
|
||
=== UI | ||
|
||
- From the Jenkins main page click 'Credentials' | ||
- Pick your credential store, normally `(global)` | ||
- Click 'Add credentials' | ||
|
||
Fill out the form: | ||
|
||
- Kind: GitHub app | ||
- ID: i.e. github-app-<team-name> | ||
- App ID: the github app ID, it can be found in the 'About' section of your GitHub app in the general tab. | ||
- API endpoint (optional, only required for GitHub enterprise this will only show up if a GitHub enterprise server is configured). | ||
- Key: click add, paste the contents of the converted private key | ||
- Passphrase: do not fill this field, it will be ignored | ||
- Click OK | ||
|
||
=== link:https://github.com/jenkinsci/configuration-as-code-plugin[Configuration as Code Plugin] | ||
|
||
[source,yaml] | ||
---- | ||
credentials: | ||
system: | ||
domainCredentials: | ||
- credentials: | ||
- gitHubApp: | ||
appID: "1111" | ||
description: "GitHub app" | ||
id: "github-app" | ||
# apiUri: https://my-custom-github-enterprise.com/api/v3 # optional only required for GitHub enterprise | ||
privateKey: "${GITHUB_APP_KEY}" | ||
---- | ||
|
||
== Configuring the github organization folder | ||
|
||
See the link:https://docs.cloudbees.com/docs/admin-resources/latest/plugins/github-branch-source[main documentation] | ||
for how to create a GitHub folder. | ||
|
||
- Load the folders configuration page | ||
- Select the GitHub app credentials in the 'Credentials field drop down | ||
- If you are using GitHub enterprise make sure the API url is set to your server, | ||
(note you currently need to set the API url on both the credential and the job). | ||
|
||
After selecting the credential you should see: | ||
|
||
[quote] | ||
---- | ||
GHApp verified, remaining rate limit: 5000 | ||
---- | ||
|
||
- Click save | ||
- Click 'Scan organization now' | ||
- Click 'Scan organisation log' | ||
|
||
Verify at the bottom of the scan log it says: | ||
|
||
[quote] | ||
---- | ||
Finished: SUCCESS | ||
---- | ||
|
||
=== Help? | ||
|
||
Raise an issue on link:https://issues.jenkins-ci.org/[Jenkins jira] | ||
setting the 'component' to be `github-brance-source-plugin` |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,11 +76,8 @@ | |
import org.apache.commons.lang.StringUtils; | ||
import org.jenkinsci.plugins.gitclient.GitClient; | ||
import org.jenkinsci.plugins.github.config.GitHubServerConfig; | ||
import org.kohsuke.accmod.Restricted; | ||
import org.kohsuke.accmod.restrictions.NoExternalUse; | ||
import org.kohsuke.github.GitHub; | ||
import org.kohsuke.github.GitHubBuilder; | ||
import org.kohsuke.github.HttpConnector; | ||
import org.kohsuke.github.RateLimitHandler; | ||
import org.kohsuke.github.extras.OkHttpConnector; | ||
|
||
|
@@ -198,13 +195,23 @@ public static FormValidation checkScanCredentials(@CheckForNull Item context, St | |
GitHub connector = Connector.connect(apiUri, credentials); | ||
try { | ||
try { | ||
boolean githubAppAuthentication = credentials instanceof GitHubAppCredentials; | ||
if (githubAppAuthentication) { | ||
int remaining = connector.getRateLimit().getRemaining(); | ||
return FormValidation.ok("GHApp verified, remaining rate limit: %d", remaining); | ||
} | ||
|
||
return FormValidation.ok("User %s", connector.getMyself().getLogin()); | ||
} catch (IOException e){ | ||
return FormValidation.error("Invalid credentials"); | ||
} catch (Exception e) { | ||
return FormValidation.error("Invalid credentials: %s", e.getMessage()); | ||
} | ||
} finally { | ||
Connector.release(connector); | ||
} | ||
} catch (IllegalArgumentException | InvalidPrivateKeyException e) { | ||
String msg = "Exception validating credentials " + CredentialsNameProvider.name(credentials); | ||
LOGGER.log(Level.WARNING, msg, e); | ||
return FormValidation.error(e, msg); | ||
} catch (IOException e) { | ||
// ignore, never thrown | ||
LOGGER.log(Level.WARNING, "Exception validating credentials {0} on {1}", new Object[]{ | ||
|
@@ -512,7 +519,7 @@ static boolean isCredentialValid(GitHub gitHub) { | |
return true; | ||
} else { | ||
try { | ||
gitHub.getMyself(); | ||
gitHub.getRateLimit(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This text need to change: https://github.com/jenkinsci/github-branch-source-plugin/pull/269/files#diff-61948c4cd4e480f18c6e572cf88a055bR511 This should be fixed in github-api as well. Not your problem, I'll fill an issue over there. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This works because invalid credentials return There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
return true; | ||
} catch (IOException e) { | ||
if (LOGGER.isLoggable(FINE)) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good call here. 💯