In this exercise, we are going to create a small script that will help us safeguard the security of the information in the spaces of our Confluence Server or Datacenter. To do this, we will create a “Job” in Scriptrunner within our Jira Server or Datacenter. Adaptavist Scriptrunner is required in order to complete this exercise.

As you well know, Confluence Server and Datacenter can be configured to have different levels of access. For example, we can give more open access to the internal people of our company and on the other hand, we can have more limited access for external people or outsourcers.

To maintain that security we use Confluence groups.

What is the problem?

The Confluence spaces are managed by their own Space Administrators, the Confluence admins defer responsibility to the space managers. This can lead to information leakage problems and for this we need to create mechanisms that inform us of possible leaks, in such a way that the Security Office of our company can take action.

What do we need to start?

To start with, we are going to create a scheduled script (a “Job”) that will check for any leaks in Confluence every day. If there is a leak, the script will send an email to the Security Office and also will send a message to a Slack channel. In this exercise you will see 2 ways to make REST calls abroad and you will also see how to send an email from code.

You will see two REST calls. In one of them we will use CURL, that means that your Jira System Administrator must install CURL in the system. CURL exists and is used since 1998! It is my favorite tool for integrations, they are a legend!

In the other REST call, we’ll send a message through Slack and use the RESTClient class to invoke a WebHook from our Slack channel.

Let us begin!

For the recipe we need:

– A limited access level user (belonging to the Confluence group of external or outsourcer) for when we call CURL to see what the user can see in Confluence: “user:password” encoded in base64 will be necessary.

– Know the access URL to the REST access point of our Confluence. Example:

– An email where we will send the Security alert when it occurs

– A Slack WebHook. See more in: How to create a Slack Bot in 5 minutes

And now the Job script code 🙂

Here the script:

import groovy.json.JsonSlurper; 
import com.atlassian.jira.issue.comments.CommentManager
import com.atlassian.jira.user.util.UserManager
import com.atlassian.jira.component.ComponentAccessor
import groovy.json.JsonBuilder
import groovy.transform.BaseScript


import com.atlassian.mail.Email
import com.atlassian.mail.server.MailServerManager
import com.atlassian.mail.server.SMTPMailServer

MailServerManager mailServerManager = ComponentAccessor.getMailServerManager()
SMTPMailServer mailServer = mailServerManager.getDefaultSMTPMailServer()

def sout = new StringBuilder(), serr = new StringBuilder()
def proc = ""
proc = ("curl -H 'Authorization: Basic BASE64-ENCODED-USER:PASS' -H 'Accept: application/json' -H 'Content-Type: application/json'") 
def proc2 = [ 'bash', '-c', proc].execute()
proc2.consumeProcessOutput(sout, serr)
def result = sout.toString()
def error = serr.toString(); 
def jsonSlurper = new JsonSlurper()
def seleccion = jsonSlurper.parseText(result)
//TotalSize must be 4
def size = seleccion.totalSize
def spaces =
log.debug("Size=" + size + " :: " + spaces)
def today = new Date().format('yyyy-MM-dd');
if (size  != 2) {
    try {
    	log.debug("Sending email to Security Office")
    	Email email = new Email("")
 		email.setSubject("ALERT POSSIBLE CONFLUENCE SPACE LEAK! " + today);	
    } catch (Exception e) {

    final String webhookURL = ""
    final String channelOrUserId = "#event-alerts"
    def baseUrl = ComponentAccessor.applicationProperties.getString(APKeys.JIRA_BASEURL)
    def message = "ALERT POSSIBLE CONFLUENCE SPACE LEAK! " + today + " " + spaces.toString()
    def client = new RESTClient("")
    def data = [:]

    data.put("channel", channelOrUserId)
    data.put("text", message)
    data.put("iron_emoji", ":ghost:")
    log.debug("Sent to Slack")
    def response =
        path: new URIBuilder(webhookURL).path,
        contentType: ContentType.HTML,
        body: data,
        requestContentType: ContentType.JSON) as HttpResponseDecorator

    assert response.status == 200 : "Request failed with status $response.status. $response.entity.content.text"

I will do another post to do something similar in Jira
I hope it was a useful exercise

A hug
MrAddon by TecnoFor

Posted by:.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s