openshift / jenkins-openshift-login-plugin

A plugin for integrating OpenShift OAuth into Jenkins
Apache License 2.0
22 stars 53 forks source link

openshift-login

A Jenkins plugin which lets you login to Jenkins with your account on an OpenShift installation.

This plugin requires use of the global matrix authorization strategy in Jenkins.

Primary scenario

This plugin can function with no additional configuration within Jenkins, but you must be running in an OpenShift Pod and against v1.4+ of OpenShift/Origin (https://github.com/openshift/origin/tree/release-1.4).

When running against a sufficient level of OpenShift/origin, and the plugin is installed in your Jenkins instance, the authentication mechanism (the "Security Realm") established within your Jenkins instance is as follows:

NOTE: When this plugin manages authentication, the predefined admin user in the default Jenkins user database for the OpenShift Jenkins image is now ignored. Unless there is an admin user defined within OpenShift with sufficient permissions to the project Jenkins is running in, you will not be able to do anything with Jenkins by logging in as admin.

Running in an OpenShift Pod against v1.4 or later of OpenShift/Origin with OPENSHIFT_ENABLED_OAUTH=true is hence the primary scenario for this plugin.

A quick reminder on OpenShift identity providers: if, for example, the default OpenShift identity provider Allow All is used, you can provide any non-empty string as the password for any valid user for the OpenShift project Jenkins is running in. Otherwise, if Allow All is not used as the identity provider, then valid credentials stored with your identity provider must be provided.

Browser access

When attempting to log into the Jenkins console when this plugin controls Jenkins authentication, you'll first see a prompt with both Jenkins and OpenShift icons, explaining that you can proceed to log into Jenkins with your OpenShift credentials. You will then be redirected to an OpenShift login page, where you provide those credentials. Once the credentials as provided, you will then be asked about allowing the associated service account the ability to check access for you. If you allow this, the authentication process will occur within the OpenShift master, and if successful, you will be logged into Jenkins and redirected to the URL you originally supplied in the browser..

Specifics on the redirect flow during browser login

On the OAuth redirect flow during login from a browser, the construction of the redirect URL back to Jenkins when authentication is successful examines the following elements in this order:

Non-browser access

For non-browser, direct HTTP or HTTPS access to Jenkins when the plugin manages authentication, a HTTP bearer token authentication header must be supplied with an OpenShift token which has sufficient permissions to access the project that Jenkins is running in. A suggested token to use is a token associated with the service account for the project Jenkins in running in. If you started Jenkins using the example jenkins-ephemeral or jenkins-persistent templates, the commands to display the token are:

$ oc describe serviceaccount jenkins
$ oc describe secret <serviceaccount secret name>

This token can be extracted, Base64 decoded, and passed along as a bearer token when communicating with Jenkins such as validating Jenkinsfiles:

$ JENKINS_TOKEN=$(oc get secret <serviceaccount secret name> -o=jsonpath={.data.token} | base64 -D)
$ curl --silent -X POST -H "Authorization: Bearer ${JENKINS_TOKEN}" -F "jenkinsfile=<Jenkinsfile" "<Jenkins URL>/pipeline-model-converter/validate"

OpenShift role to Jenkins permission mapping

Once authenticated, OpenShift roles determine which Jenkins permissions you have. Any user with the OpenShift admin role for the OpenShift project Jenkins is running in will have the same permissions as those assigned to an administrative user within Jenkins. Users with the edit or view roles for the OpenShift project Jenkins is running in will have progressively reduced permissions within Jenkins.

For the view role, the Jenkins permissions are:

For the edit role, in addition to the permissions available to view:

Users authenticated against OpenShift OAuth will be added to the Jenkins authorization matrix upon their first successful login.

Now, with v1.0.10 of this plugin, you can change

By default, this plugin looks for a ConfigMap named "openshift-jenkins-login-plugin-config" in the namespace that Jenkins is running in. You can override this behavior by specifying an environment variable named CONFIG_MAP_NAME that points to a well formatted ConfigMap that contains your custom configuration.

Typically, when running Jenkins in an OpenShift Pod, it will look in the namespace that Jenkins is running in. Otherwise, it looks in the namespace specified in the "client ID" as explained in "Secondary Scenarios" down below.

If this plugin finds and can read in that ConfigMap, it then:

Finally, permissions for users in Jenkins, and OpenShift to Jenkins permission mapping, can be changed in OpenShift after those users are initially established in Jenkins. The OpenShift Login plugin polls the OpenShift API server for permissions and will update the permissions stored in Jenkins for each Jenkins user with the permissions retrieved from OpenShift. Technically speaking, you can change the permissions for a Jenkins user from the Jenkins UI as well, but those changes will be overwritten the next time the poll occurs.

Some permission like Lockable Resources contains spaces. In order to configure them using config map, the space must be replaced by an '_'.

For example Lockable_Resources-Unlock: 'view,edit'

You can control how often the polling occurs with the OPENSHIFT_PERMISSIONS_POLL_INTERVAL environment variable. The default polling interval when no environment variable is set is 5 minutes.

Using custom Roles

If you would like to use a custom role such as 'jenkins-admin' then you need to first create a role:

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: jenkins-admin (1)
  namespace: jenkins (2)
rules:
  - verbs:
      - jenkins-admin (3)
    apiGroups:
      - build.openshift.io (4)
    resources:
      - jenkins (5)
  1. Name of the role doesn't actually matter, but for consistancy suggest aligning with (3)
  2. Namespace of the role needs to be either in the namespace Jenkins is running in or this needs to be a ClusterRole not bound to a namespace
  3. The verb is the key bit, and is what you will use in your openshift-jenkins-login-plugin-config ConfigMap as the role OpenShift role name
  4. This currently has to be build.openshift.io
  5. This currently has to be jenkins

Then you can create a RoleBinding between your user(s) or group(s) to the Role. For example:

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: user42-jenkins-admin (1)
  namespace: jenkins (2)
subjects: (3)
  - kind: User
    apiGroup: rbac.authorization.k8s.io
    name: user42
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: jenkins-admin (4)
  1. RoleBinding name does not matter, use something descriptive
  2. Namespace must be the namespace Jenkins is running in
  3. Subjects should be any user(s) or group(s) want to give the role to
  4. roleRef Name should be the name of the Role created previously

Then finally update your openshift-jenkins-login-plugin-config ConfigMap to use the custom role/verb.

kind: ConfigMap
apiVersion: v1
metadata:
  name: openshift-jenkins-login-plugin-config
  namespace: jenkins
data:
  Overall-Administer: 'jenkins-admin' (1)
  1. where the OpenShift role referenced here is actually a verb on the build.openshift.io apiGroup jenkins resource that a set of users has access to via a RoleBinding to a Role that grants access to that verb.

Secondary scenarios

This plugin can be explicitly configured from within the Jenkins console to manage the login/authentication process for Jenkins. Examples for wanting to do this might be for development of this plugin, or perhaps for running within a pre-existing Jenkins installation that runs outside of an OpenShift Pod.

Even though Jenkins is not running in OpenShift, you should define a project in the same fashion as the jenkins-ephemeral or jenkins-persistent templates do, including defining a service account. Permissions and authorization levels for users within that project then dictate the level of authorization the users have with Jenkins. And the service acccount participates both in the authentication flows for the user logging in, as well as performs the OAuth self-SAR to determine authorization levels.

Once this project and related settings are defined in OpenShift, you can then go to the Jenkins console to enable the plugin as the "Security Realm". Once logged into Jenkins, go to "Manage Jenknins", then "Configure Global Security", and then select "Login with OpenShift" as the security realm. Some details on the various configuration fields (where only the first three are required):

JVMs

This plugin has been developed and tested almost exclusively with the OpenJDK JVM. However, user testing has confirmed that it can run inside an IBM JDK if -Dcom.ibm.jsse2.overrideDefaultTLS=true is supplied as a JVM argument when starting Jenkins.