Saturday, September 1, 2018

Jenkins role based access control (RBAC) with Azure AD Plugin - Step by Step

In this blog I wanted to detail out steps in enabling role based access control (RBAC) in Jenkins using Azure AD Plugin and that too without having enterprise edition of Jenkins (Cloudbees).

Here are few scenarios where this will be useful

  • When you want to control access to your Jenkins only for designated users within your organization. Only users in certain group can create, delete jobs but other can see build console outputs, trigger a new build etc.
  • You want to ensure that project team members can access only their own jobs, logs etc. 
  • Note: You don't need to expose Jenkins endpoint externally unless you want to have webhooks configured from your git repositories (if they are hosted and accessible over internet
  • and many more

  1. Have Jenkins latest version installed. I had Jenkins running on Ubuntu 16.04 Azure VM and the DNS is configured to be myjenkins on VMs public IP. Thus your Jenkins Fully Qualified Domain name would be http://myjenkins.<region>
  2. Install Azure AD plug-in installed from available plugins in your jenkins instance (Manage Jenkins -> Manage Plugins -> Available tab -> Search for Azure AD)

  3. Azure AD Plugin

  4. You have valid Azure Subscription and have privileges to create service accounts in the Azure AD that you are planning to use. If you do not have access, you can request your administrator to create a service account as per the instructions provided below
  5. In addition, to test Role based access control (RBAC), you will need permissions to create couple of groups and few user accounts to be able to login to Jenkins who are assigned in those different groups.
  1. Create Service Account in Azure AD- This service account is used by Jenkins to query user profile and group memberships
    • Navigate to Azure Active Directory from the left navigation once you login on Azure Portal (
    • Click on App Registrations -> New Application Registration
    Creating new Azure AD Service Account

    • Enter Name (e.g. in my case I named it as Jenkins) for your service account
    • Select Application Type as Web App / API
    • Enter Sign-On URL as your home page URL for your Jenkins instance (as mentioned in pre-requisites i.e. http://myjenkins.<region>
    Azure AD Service Account Creation for Jenkins - Initial Settings

    • Click Create, and take a note of Application ID (this is your Client Id) once service account creation is succ 

    • Also take a note of your Directory ID (this is your Tenant ID). You will find this when you navigate to Azure Active Directory menu on the left hand side and go to properties and copy the Directory ID
    Extracting Azure AD Tenant ID / Directory ID

  2. Configure Azure AD Service Account 
    • Configure ReplyURL - This is the URL where Azure AD posts the ID token once the user is authenticated and is in the format http://<Jenkins-dns>.<region> i.e in our case it would be as shown below

    • Configure App ID URI - This is unique App ID URI and can be same as Reply URL as configured above
    • Configure Home Page URL - This is the root url of your jenkins (i.e. Please note, no securityRealm/finishLogin appended in the URL. Both these settings are shown below
    Configuring Azure AD App ID and Home Page URL for Jenkins Service Account

    • Edit Manifest to include group memberships as part of your claims when Azure AD posts the ID token to your Jenkins application. You do this by changing gropuMembershipClaims value from null to "All". Without this your group memberships will not be issued as claims and you cannot get role based access control working. 
    Editing Azure AD Service Account Manifest

    Including Group Membership Claims for Azure AD Service Account

    • Next we need to Assign Permissions to this service account to be able to Read Directory Data and and read user profile information. You do this by navigating to settings -> Required Permissions for the service account as shown below. Please note the last step once you have selected the appropriate permissions - you need to Grant Permissions (last image in this step)
    Assigning Permissions to Azure AD Service Account for Jenkins

    Read Directory Data Permissions to Azure AD Service Account for Jenkins

    Sign-in and Read User Profile Permissions to Azure AD Service Account for Jenkins

    Grant Selected permissions to Azure AD Service Account for Jenkins

  3. Creating Azure AD Users
    • Create couple of Active Directory Users (or use the existing ones) by navigating to Azure Active Directory -> Users -> New User. Also take a note of the user name, this includes the name of your active directory. 
    • You can also choose to assign AD groups at this point (if you already have some AD Groups that you want to use) but we will do this in the next step (we will create JenkinsAdmins and JenkinsReader groups).
    • Also take a note of the temporary password. It is better to change the temporary password when you login first time to azure portal using instead of getting this prompt during authentication process of Jenkins
    • In this exercise let us say we created two users jadmin@<yourdirectory>.com and jreader@<yourdirectory>.com
    Azure AD - Create New Users

    Azure AD - Create New User - Properties

  4. Creating Azure AD Groups and Adding Users
    • Create JenkinsAdmins Group and add one of the user(s) created earlier (jadmin)
    • Create JenkinsReader Group and add a different user(s) (e.g. jreader) than the one added in JenkinsAdmins group.
    • We will be using these 2 different users in 2 different groups to see if authorizations are really working in Jenkins
  5. Configure Jenkins
    • One other important thing to change in Jenkins installation is to change the jenkins.model.JenkinsLocationConfiguration.xml configuration to include your FQDN so that when user is trying to access Jenkins, and it is being redirected by Jenkins to Azure AD for authentication, it correctly sends the redirect_uri that matches with the reply URL we configured in the Azure AD Service account. 
Changin jenkins.model.JenkinsLocationConfiguration.xml

    • If we don't do this, by default jenkinsURL in the above configuration will use the public IP address of your VM and this will not match with your service account reply URL and you will face issue mentioned in this Jira ticket. i.e.  

java.lang.IllegalStateException: Invalid nonce in the response at at at 
java.lang.invoke.MethodHandle.invokeWithArguments( at org.kohsuke.stapler.Function$MethodFunction.invoke( 

Enabling RBAC, Adding Roles and Assigning Permissions in Jenkins

  1. Configuring Global Security
    • Navigate to Manage Jenkins -> Configure Global Security
    • Check "Enable Security"
    • Select Access Control -> Security Realm -> Azure Active Directory
    • Configure the Client ID, Client Secret and Tenant ID which we noted down during the Service account creation steps above. This is shown below
    Manage Jenkins - Configure global security - Azure AD

    Manage Jenkins - Configure global security - Azure AD - Service Account Configuration
    • Save above changes. Without Saving above changes, you will not be able to add roles based on Azure AD Group and assign permissions

  2. Configuring Jenkins Roles and Permissions
    • Under Configure Global Security, navigate to Authorization section
    • Select Azure Active Directory Matrix-based Security
    • Now when you start typing in Azure user / group to add, you will Azure AD roles being populated in the list.
    • Add desired roles (in our case JenkinsAdmins and JenkinsReader) and assign necessary permissions.
    • In my case, for JenkinsAdmin, I just granted the Overall Admin permissions and for JenkinsReader, I granted only overall read, Build permissions under Agent, Build Cancel Discover and Read permissions for Jobs, Replay permissions in Run, Read permissions in View. This is shown in below pictures
Adding roles in Jenkins Azure Active Directory Matrix-based Security

Granting Permissions in Jenkins Azure Active Directory Matrix-based Security

    • If you want to configure project level roles and permissions, you can navigate to a particular job (assuming you are logged in as administrator) and enable project-based security. You will get the same interface as in Global Security, where you can configure required permissions for your project specific roles.
Jenkins RBAC - enabling project level authorization

Testing RBAC in Jenkins

  • To test the authorizations, I suggest using in-cognito mode of your preferred browser. 
  • First login with the user who has administrative permissions in Jenkins. To do this, hit the Jenkins url, this will automatically redirect you to azure ad authentication page, login with your administrative account (i.e. in our case jadmin@<yourad>.com) and once authenticated successfully, you will be taken to Jenkins home page.
  • Logout and close the incognito window
  • Now open new in-cognito instance of your browser and in similar way, login with your other account who has only read permissions (i.e. in our case jreader@<yourad>.com). You should see you do not have permissions to manage Jenkins and neither you have permissions to create new jobs. You can build existing jobs, look at the console logs etc.

Let me know what you think of this blog and you were able to configure Jenkins for RBAC with Azure AD plugin without any issues

Happy Deployments !!

Saturday, September 22, 2012

Visual Studio 2012 - Not everything works

Issues with Visual Studio 2012 RTM Ultimate edition, extensions and Nuget pkgs.

Recently, I started using Visual Studio 2012 through my MSDN subscription and due to lack of disk space (as I my laptop has 120 GB SSD) I had to un-install Visual Studio 2010, thinking Visual Studio 2012 should be good enough to do whatever i wanted to do.

Only after doing this, I realized, there are heck of problems

Problem 1:
In one of my project, I was trying to make my WCF service claims aware and wanted to test it with local STS. Unlike VS 2010, there is no Add STS Reference menu any more. What you get is Identity and Access Tools as shown below, and if you don't have this action available, go and install it it through your extension manager

Refer this post by Vittorio which refers to new tooling for "Local STS".
Problem is, this works with only ASP.NET web forms project !!
When I do this for WCF Service role (Windows Azure), the Local STS does not start. Unfortunately, all the posts refer to the old Add STS Reference way of establishing trusts between your RP and IDP. I still dont have a solution to resolve this, but once I have it, I will post it in my blog
Problem 2:
There is no concept of Recipe now in RTM, which was there in Beta. With Recipe features Phil Haack has created a nuget package to convert MVC views to mobile views, which was known as "MvcHaack.ViewMobilizer". This is also referred in MVC 4 hands on lab here. Hence that lab will not work.  When I asked this to Phil, he told me that this will not work any more because Recipe feature does not exit in RTM, and hence he removed it from Nuget library
My idea was to develop a cloud based app and showcase the MVC 4 capability for various devices.. but its unfortunate that lot of that i need to do it myself now :), though this is depicted as one of the features of ASP.NET MVC 4 :(
 I am just hoping that there are not many such issues in VS 2012.

Happy cloud-ing..

Cloud Kotecha