Skip to content

Connect Jenkins to Team Server, install the Runtime Sensor on every build agent, and wrap each protected pipeline with Endura start and stop commands.

Object Mapping

JenkinsTeam Server
Executable jobPipeline
BuildBuild

Discover executable jobs before instrumenting them. Folders and multibranch parents are containers; each executable child, including each branch job, becomes a pipeline. Full slash-delimited job names distinguish pipelines across folders; leaf names group recurring builds for protection status.

Prerequisites

  • Operator or Administrator access to Team Server
  • Jenkins access that can create an API token and edit jobs
  • Root access to the controller when it runs builds and to every protected agent host

Configure the Integration

Credentials and Permissions

Use a dedicated Jenkins service account with these permissions:

PermissionScopeTeam Server use
Overall/ReadJenkins controllerAccess the API and test the integration.
Job/ReadEvery required folder and executable jobTraverse folders, discover jobs, and read their build history. Grant it through a containing folder only when the authorization strategy inherits that permission to every required descendant.

Jenkins API tokens do not have independent scopes. The token receives the service account’s permissions, so do not grant build, configure, credential, or administrative access. Under the account’s Configure page, create an API token, set a rotation owner, and store the value with its username in a secrets manager.

Add Jenkins to Team Server

  1. Open Integrations, then Jenkins under Discover.
  2. Select Get Started or Create.
  3. Enter the Jenkins base URL, service-account username, and API token.
  4. Select Test, then Save.

Executable jobs appear under Pipelines. Nested jobs retain their folder hierarchy in the displayed pipeline name. Use separate integrations for separate controllers or credentials. For a private address or internal CA, configure Team Server outbound HTTP policy.

Schedule Discovery

Add these jobs to scheduler.jobs:

jenkins_pipelines:
  run: "jenkins_sync mode:pipelines trigger:scheduled"
  schedule: "0 6 * * * * *"
jenkins_builds:
  run: "jenkins_sync mode:builds trigger:scheduled"
  schedule: "0 9,24,39,54 * * * * *"

Keep statistics_calculate and status_reconcile enabled. Restart Team Server after changing configuration; see Scheduler.

Manage Sync and Deletion

Use Start Sync for an immediate run. See sync controls and deletion.

Install the Runtime Sensor on Agents

Install the Sensor on every eligible Linux x86-64 agent and any controller running builds. Use the Jenkins label to select Sensor-enabled agents; include it in cloud images/provisioning.

Keep license, token, and Team Server URL in root-only host configuration; build steps need only unprivileged job commands. Verify endura sensor status and root-only endura sensor hooks on each agent.

Instrument a Declarative Pipeline

Use a first stage for job start and post { always { ... } } for cleanup:

pipeline {
    // Select a Sensor-enabled build agent.
    agent { label 'endura' }

    // Defer source checkout until protection starts.
    options {
        skipDefaultCheckout(true)
    }

    stages {
        // Start protection before source checkout.
        stage('Start Endura Job') {
            steps {
                sh '''
                    ENDURA_JOB_ID=$(endura job start)
                    echo "started endura job with id ${ENDURA_JOB_ID}"
                '''
            }
        }

        // Check out protected source code.
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        // Run the protected project build.
        stage('Build') {
            steps {
                sh 'make build'
            }
        }
    }

    // Stop protection after every pipeline outcome.
    post {
        always {
            sh 'endura job stop'
        }
    }
}

Declarative Pipeline normally performs an implicit checkout before the first stage. skipDefaultCheckout(true) disables it so the explicit checkout scm runs after job start.

Jenkins supplies CI and JENKINS_URL automatically; no explicit detection variables are needed.

Team Server reads user and trigger information from Jenkins build causes.

post { always { ... } } schedules cleanup after failure or abort. Runner loss, forced termination, or cancellation deadlines can prevent completion; cancellation retirement provides a fallback when the Sensor survives.

Shared Library

Centralize the lifecycle in a Jenkins Shared Library. Create vars/enduraJob.groovy:

/**
 * Runs a pipeline closure under Endura protection.
 *
 * @param body protected work invoked after job startup
 * @return result returned by the protected closure
 * @throws Exception when startup, execution, or cleanup fails
 */
def call(Closure body) {
    def jobId = null
    def primaryFailure = null

    try {
        jobId = sh(returnStdout: true, script: 'endura job start').trim()
        echo "started endura job with id ${jobId}"
        return body()
    } catch (Exception failure) {
        primaryFailure = failure
        throw failure
    } finally {
        if (jobId != null) {
            try {
                sh "endura job stop ${jobId}"
            } catch (Exception cleanupFailure) {
                if (primaryFailure == null) {
                    throw cleanupFailure
                }
                echo "Endura cleanup also failed: ${cleanupFailure.message}"
            }
        }
    }
}

The wrapper stops only a successfully started job. A cleanup failure fails otherwise successful work; if protected work already failed, the wrapper reports the cleanup error and preserves the original exception.

Then use it from pipelines. The parent pipeline must disable implicit checkout, and the wrapped body must perform checkout after job start:

pipeline {
    // Select a Sensor-enabled build agent.
    agent { label 'endura' }

    // Defer source checkout until protection starts.
    options {
        skipDefaultCheckout(true)
    }

    stages {
        // Protect checkout and build together.
        stage('Build') {
            steps {
                enduraJob {
                    checkout scm
                    sh 'make build'
                }
            }
        }
    }
}

Configure the library under Manage Jenkins > System > Global Pipeline Libraries. An implicitly loaded library makes the wrapper available without an @Library annotation.

Docker Agents

The Runtime Sensor stays on the Jenkins agent host. Mount its socket and install the CLI in the build container:

pipeline {
    // Pin the image and mount Sensor access.
    agent {
        docker {
            image 'node:24.21.0-bookworm'
            args '-v /run/endura/sensor.sock:/run/endura/sensor.sock'
        }
    }

    // Defer source checkout until protection starts.
    options {
        skipDefaultCheckout(true)
    }

    stages {
        // Install the CLI and start protection.
        stage('Start Endura Job') {
            steps {
                sh 'curl -sSf https://repo.endurasecurity.com/install/endura-sensor/testing.sh | sh'
                sh '''
                    ENDURA_JOB_ID=$(endura job start)
                    echo "started endura job with id ${ENDURA_JOB_ID}"
                '''
            }
        }

        // Check out protected source code.
        stage('Checkout') {
            steps {
                checkout scm
            }
        }

        // Test the protected project sources.
        stage('Test') {
            steps {
                sh 'npm test'
            }
        }
    }

    // Stop protection after every pipeline outcome.
    post {
        always {
            sh 'endura job stop'
        }
    }
}

Without the socket mount, the CLI cannot reach the Runtime Sensor on the host.

Multibranch and Downstream Jobs

Instrument every executable job, including branch and downstream jobs. Each has its own pipeline/policy assignment; multibranch parents are discovery containers. Assign shared policies to compatible branch pipelines, or separate policies for differing behavior. Use the shared library for consistent lifecycle handling.

Optional Build Metadata

The Sensor reads GIT_BRANCH or CHANGE_BRANCH, not BRANCH_NAME. Before checkout, Git metadata may be absent. If branch metadata is needed, optionally map multibranch variables at pipeline level:

environment {
    GIT_BRANCH = "${env.GIT_BRANCH ?: env.CHANGE_BRANCH ?: env.BRANCH_NAME ?: ''}"
}

For other jobs, supply a known branch parameter. Metadata is not required for detection or pipeline matching.

Verify

  1. Run the complete pipeline.
  2. Open the executable Jenkins job under Pipelines in Team Server.
  3. Confirm the run appears under Builds.
  4. Confirm the selected agent reports the expected Team Server connection and hook coverage.
  5. If the run is missing, check job discovery, the selected agent label, and start-stage logs.

Troubleshooting

SymptomCheck
Jobs do not appearTest the integration, confirm the service account can read every containing folder and required executable job, and verify that both Jenkins discovery jobs are scheduled.
A build does not appearConfirm the job was discovered first, the Runtime Sensor was online on the selected agent, and the start stage ran.
A Docker agent cannot reach the Runtime SensorConfirm the host socket is mounted at /run/endura/sensor.sock inside the build container.
A job remains activeConfirm endura job stop is inside post { always { ... } } and review its log for errors.

Create and Assign a Policy

Derive across representative build paths and capture the policy printed by endura job stop. Refine and test it in observe mode, then assign it to the executable Jenkins job pipeline before enforcement.

For multibranch Jenkins, assign it to each branch pipeline that should share it.

Configure notifications after violations reach Team Server.