Jenkins DSL Authorization Matrix loop

Authorization Matrix is one of my favorite Jenkins functionality. It allows managing permissions per Project what gives enough granularity. But when you have a lot of Projects, you can find Jenkins DSL Plugin very helpful. Especially when you start your adventures with Jenkins, those two plugins can make your life easier. As you use Jenkins, I suppose you are in love with automation. You try to automate and optimize everything. And if you read this post, it’s more than certain that you faced the same problem I had faced in my work. How to create a Jenkins DSL Authorization Matrix loop? I found a way, so please take a look below.

What is the problem?

Jenkins DSL has many solutions ready to use. Let assume I want to specify which users should have which permissions to a job. Then I can look into the Job DSL API Viewer and find out, that I can use the following code:

So, for example, it can be something like this:

And everything is fine, but… What if I want to create multiple permissions’ sets for multiple users? Moreover, what if each job has each own permissions sets? Oh my god, what a mess! No, it must be another way. And that way exists – we can create a function with a list of permissions as an argument. We can use a configure block for this purpose. Please take a look at that code:

In the case above we grant Read and Build permissions to user username for job Example. Please note, that in this method we don’t use an array or another similar structure. We list of functions instead of invoking a function with a list as an argument. It allows us to create loops in our DSL scripts.

How to create a Jenkins DSL Authorization Matrix loop?

It’s very simple. Let’s assume we need a job named “MyJob”. Alice and Bob should have a Read and Build permissions and they both should have access to the Workspace. But only Alice should be able to Cancel running job – Bob shouldn’t be able to do that. At first, let’s create a map variable with the proper permissions.

Easy, doesn’t it? Ok, so when we finally have our permissions map, we should create a loop which will be iterate through the individual elements. To be honest, we actually need a nested loop. First of them will be iterate over user key (to ensure that each user will be created in configuration XML file), and then the second loop will iterate over the permissions lists. If it’s not clear enough, just let take a look at this code:

It’s of course only the loop part. We can place that code in every job, but it will better if we store this in one, central place. For example in the one class and call the method whenever we need that. Please take a look at the following code:

It will create a class named MyPermissions and a method named JobPermissions. We must pass a map with the specified permissions as the method’s arguments. After executing the DSL script, we will receive an XML such that:

As you can see, permissions were set correctly, exactly as we wanted. Now, we can call that method in every job or folder configuration, where we want to set permissions. The map with permissions can be created either for each job separately or as the global variable, available for each job.

What about inheritance?

In my example, I used a global inheritance strategy, but if you would prefer another one, you should just simply change a part of my code. There are two different ways to achieve this:

  • add a new parameter “inheritance”
  • remove inheritanceStrategy outside of method and call the method inside the configuration block

And that’s all. Hope this post can help you with your problem. It doesn’t matter whether you are using the Jenkinsfile flow with pipelines or just simple Freestyle jobs – authorization is useful in both ways of administering your jobs. And Jenkins DSL is almost “must have” functionality.

4 Replies to “Jenkins DSL Authorization Matrix loop”

    1. What do you exactly mean? You can update permissions by DSL and manually, at the project level in the configuration of the project, or globally – inside the Security section of Jenkins configuration. Does it answer your question?

  1. Hi, Great article,
    Is there a way to specify whether the authorization entity we give access to is a group or a user?

    In the XML code I can specify as
    USER:hudson.model.Item.Configure:deployuser
    GROUP:hudson.model.Item.Read:anonymous

    Is there a way to specify it in the DSL:

    pipelineJob(‘__job_name__’) {
    authorization {
    blocksInheritance()
    permission(‘hudson.model.Item.Configure’,deployuser’)
    permission(‘hudson.model.Item.Read:anonymous’)
    }

    There is an comment in https://stackoverflow.com/questions/70454192/jenkins-ambiguous-permission which answers my question but not sure how to implement it.
    Thanks.

    1. Hi, thanks a lot! Yeah, to be honest, I now use only groups and I can specify them in the DSL like users. But I use configure block, so I can specify something like this (in my case it’s Authorization Matrix compatible with Azure AD, but schema is exactly the same for classic AM, it’s just another class):

      configure {
      it / ‘properties’ / ‘com.microsoft.jenkins.azuread.AzureAdAuthorizationMatrixProperty’ {
      inheritanceStrategy(class: ‘org.jenkinsci.plugins.matrixauth.inheritance.InheritGlobalStrategy’)
      permission(‘hudson.model.Item.Read:username’)
      permission(‘hudson.model.Item.Read:groupname’)
      }
      }
      And it works perfectly.

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.