How To: Use credentials from CyberArk

Some of our customers use CyberArk as their enterprise password store.  Datical's "hammer" commands are able to read credentials from environment variables so we need a way to get the credentials out of CyberArk and into the environment so that Datical can use them.

In this example, we will assume that the customer is storing database credentials (username and password) in CyberArk. We know the database name, but need the userid and password to access that database.



Setting up an account in CyberArk

  1. In CyberArk UI, on the Accounts page click "Add Account"


  2. Choose "Database"
  3. We'll use Oracle for this example
  4. Next, choose the safe you want to store the creds in.  We will store them in the "test" safe


  5. Fill out the Username, Password, and Confirm fields. 
    Note that I also added the string "gambit_ora_ref" in the Address field although it's optional.  This is for visibility in the list view which we'll see in just a minute
    Also select the option to "Customize Account Name" so that you can assign a meaningful name to this account. I set it to "gambit_ora_ref"


  6. Scroll down and fill in the database name. Mine is "REF_DB" since that is what I called the Oracle database in the pipeline.  It is not used as part of this API reference though.


  7. Click "ADD" and you should get a success message:  (If you go back and edit you will see save vs add button)
  8. When the account shows up in the list view you're done setting up the account


Retrieving credentials from CyberArk via a REST call

  1. There are a few values that are going to be needed for each API call
    1. BaseURL
    2. Port number (e.g., 8080)
    3. AppID (e.g., Datical)
    4. SafeName is Test (This is what you chose in step 4 above)
    5. Folder is root 

  2. Create an http GET call using the above values and the following format template:
    {{BaseURL}}:{{Port}}/AIMWebService/api/Accounts?AppID={{AppID}}&Safe={{SafeName}}&Folder={{Folder}}&Object={{ObjectName}}
    API is documented here -> https://documenter.getpostman.com/view/998920/RzZ9Gz1U?bs=true&version=latest#97bada25-0588-4660-9fc3-bae9f1087596
  3. In the above template, {{ObjectName}} will be the value you set for the "Account Name" in step 5 of 648643282 above

  4. My resulting URL for this example will look like this:
    http://services-uswest.skytap.com:8080/AIMWebService/api/Accounts?AppID=Datical&Safe=Test&Folder=root&Object=gambit_ora_ref

  5. When I drop that in a browser address bar the server will respond with the following json object:

    JSON Response from CyberArk REST call
    {
    "Content":"password",
    "CreationMethod":"PVWA",
    "Address":"gambit_ora_ref",
    "Safe":"Test",
    "UserName":"GAMBITCARD_REF_DB",
    "Database":"REF_DB",
    "PolicyID":"Oracle",
    "DeviceType":"Database",
    "Name":"gambit_ora_ref",
    "Folder":"Root",
    "PasswordChangeInProcess":"False"
    }
  6. The password is returned in the "Content" attribute

  7. Use the instructions in Provide Runtime Credentials to set the necessary runtime database credentials.
  8. Here is an example Jenkinsfile script that I used to incorporate the credentials (lines 32-36).  (I used JsonSlurper to parse the JSON response from CyberArk)

    Jenkinsfile
    import groovy.json.JsonSlurper
    node {
    try {
    // Environment Variables
    env.appname = "GambitCard"
    env.scmCreds = "e0de9ac3-3636-48d7-b95e-35443ab32b53"
    env.scmType = "git"
    env.ddbURL = "ssh://jenkins@win-20e107kb4tn:7999/gc/gambitcard.git"
    env.srcURL = "ssh://jenkins@win-20e107kb4tn:7999/gc/gambitcardsql.git"
    // Pad env.BUILD_NUMBER so fetching LATEST will work properly on Artifactory and Xebia XLD
    // Requires https://wiki.jenkins.io/display/JENKINS/Permissive+Script+Security+Plugin
    env.BUILD_NUMBER = "${env.BUILD_NUMBER}".padLeft(4,'0')
    
    //MOVED TO JENKINS NODE SETTINGS
    //env.DATICAL_CLIENT_SECRET="123abc"
    //env.DATICAL_SERVER="hostname"
    //env.curlHome = "C:\\apps\\Git\\mingw64\\bin"
    //env.datHome = "C:\\apps\\DaticalDB\\repl"
    //env.mvnHome = "C:\\apps\\apache-maven-3.3.9\\bin"
    //env.ucdHome = "C:\\apps\\ibm-ucd-agent\\opt\\udclient"
    //env.ZipHome = "C:\\apps\\7-Zip"
    
    // Print Environment Variables
    //echo sh(returnStdout: true, script: 'env')
    
    // String Definitions
    //def appname = "${env.appname}"
    
    
    deleteDir()
    stage('Get CYBERARKCREDS') {
    URL apiURL = "http://services-uscentral.skytap.com:14200/AIMWebService/api/Accounts?AppID=Datical&Safe=Test&Folder=root&Object=gambit_ora_ref".toURL()
    Map myjson = new JsonSlurper().parse(apiURL.newReader())
    
    env.DDB_USER = myjson.UserName
    env.DDB_PASS = myjson.Content
    
    
    println("${env.DDB_USER}")
    }
    
    stage('Source Checkout') {
    if (env.scmType == 'git') {
    parallel (
    CheckoutDDB: {
    checkout([$class: "GitSCM", branches: [[name: "*/master"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: "RelativeTargetDirectory", relativeTargetDir: "ddb"], [$class: "LocalBranch", localBranch: "master"], [$class: "UserIdentity", email: "jenkins@company.com", name: "jenkins"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${env.scmCreds}", url: "${env.ddbURL}"]]])
    },
    
    CheckoutAPP: {
    checkout([$class: "GitSCM", branches: [[name: "*/${env.pipeline}"]], doGenerateSubmoduleConfigurations: false, extensions: [[$class: "RelativeTargetDirectory", relativeTargetDir: "src"], [$class: "LocalBranch", localBranch: "${env.pipeline}"], [$class: "UserIdentity", email: "jenkins@company.com", name: "jenkins"]], submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${env.scmCreds}", url: "${env.srcURL}"]]])
    }
    )
    }
    
    if (env.scmType == 'svn') {
    parallel (
    CheckoutDDB: {	
    checkout changelog: false, poll: false, scm: [$class: "SubversionSCM", additionalCredentials: [], excludedCommitMessages: "", excludedRegions: "", excludedRevprop: "", excludedUsers: "", filterChangelog: false, ignoreDirPropChanges: false, includedRegions: "", locations: [[credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "ddb", remote: "${env.ddbURL}"], [credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "ddb", remote: "${env.ddbURL}"]], workspaceUpdater: [$class: "UpdateUpdater"]]
    },
    
    CheckoutAPP: {
    checkout changelog: false, poll: false, scm: [$class: "SubversionSCM", additionalCredentials: [], excludedCommitMessages: "", excludedRegions: "", excludedRevprop: "", excludedUsers: "", filterChangelog: false, ignoreDirPropChanges: false, includedRegions: "", locations: [[credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "src", remote: "${env.srcURL}"], [credentialsId: "7545c833-66a0-4386-8a16-9d8a51c98449", depthOption: "infinity", ignoreExternalsOption: true, local: "src", remote: "${env.srcURL}"]], workspaceUpdater: [$class: "UpdateUpdater"]]
    }
    )
    }
    }
    
    stage('PackageDB') {
    // Set Upstream Branches for Git
    if (env.scmType == 'git') {
    bat 'cd src && git branch --set-upstream-to=origin/%pipeline% %pipeline%'
    bat 'cd ddb && git branch --set-upstream-to=origin/master master'
    }
    
    // Show Hammer Version Details
    //bat 'hammer.bat show version'
    
    // Set Version
    if (env.pipeline == 'pipeline1') {
    env.version = "2.0.${env.BUILD_NUMBER}"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.version = "3.0.${env.BUILD_NUMBER}"
    }
    
    if (env.pipeline == 'hotfix') {
    //ASSUME YOU ARE HOTFIXING CURRENT VERSION
    env.version = "1.0.${env.BUILD_NUMBER}_HOTFIX"
    }	
    //Check creds
    println('USER')
    println("${env.DDB_USER}")
    // Invoke Datical Database Code Packager
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //bat 'cd ddb && hammer.bat groovy deployPackager.groovy %pipeline% scm=true labels=%BUILD_TAG%'
    bat 'cd ddb && hammer.bat groovy deployPackager.groovy pipeline=%pipeline% scm=true labels=%version%'
    //}	
    
    // Create Datical Artifact
    bat 'cd ddb && 7za.exe a -tzip -x!.git -x!.svn -x!Logs -x!Reports -x!Snapshots -x!Profiles -x!.classpath -x!.gitignore -x!.metadata -x!.project -x!.reporttemplates -x!daticaldb.log -x!deployPackager.properties -x!svn-ignore.properties ..\\%appname%DB.zip'
    }
    
    stage('BuildApp') {
    bat 'sed -i s/VERSION_NO/%version%/g .\\src\\app_code\\src\\main\\webapp\\index.jsp'
    bat 'cd src\\app_code && mvn package'
    bat 'move src\\app_code\\target\\%appname%-1.0-SNAPSHOT.war .\\%appname%.war'
    }
    
    stage('Package Artifact') {
    if (env.CDTool != 'UCD') {
    // Artifactory Configuration
    def server = Artifactory.server 'art-001'
    
    def buildInfo = Artifactory.newBuildInfo()
    // Set custom build name and number.
    buildInfo.setName "${env.appname}"
    buildInfo.setNumber "${env.version}"
    
    def uploadSpec = """ {
    "files": [
    {
    "pattern": "*zip",
    "target": "${env.appname}/${env.appname}DB-${env.version}.zip",
    "props": "pipeline=${env.pipeline}"
    },
    {
    "pattern": "*war",
    "target": "${env.appname}/${env.appname}-${env.version}.war",
    "props": "pipeline=${env.pipeline}"
    }
    ]
    }"""
    
    // Upload to Artifactory.
    server.upload spec: uploadSpec, buildInfo: buildInfo
    
    // Publish build info.
    server.publishBuildInfo buildInfo
    
    if (env.CDTool == 'XLD') {
    // used to create and publish the artifacts in XLD
    xldCreatePackage artifactsPath: ".", manifestPath:"src/deployit-manifest.xml", darPath: '${appname}-${version}.dar'
    xldPublishPackage serverCredentials: 'Admin', darPath: '${appname}-${version}.dar'
    
    //xldCreatePackage artifactsPath: ".", manifestPath:"src/sql_code/deployit-manifest_ddb.xml", darPath: '${appname}_ddb-${version}.dar'
    //xldPublishPackage serverCredentials: 'Admin', darPath: '${appname}_ddb-${version}.dar'
    }
    }
    
    if (env.CDTool == 'UCD') {
    // Add UCD Component Version
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 createVersion -component %appname%-DB -name %version%'
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 createVersion -component %appname%-WAR -name %version%'
    
    // Add Files to new Component Version
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 addVersionFiles -component %appname%-DB -version %version% -base %WORKSPACE% -include **/%appname%*.zip'
    bat 'udclient.cmd -username admin -password password -weburl https://win-20e107kb4tn:8444 addVersionFiles -component %appname%-WAR -version %version% -base %WORKSPACE% -include **/%appname%*.war'	
    }
    }
    
    if (env.pipeline != 'hotfix') {
    stage('Deploy To DEV') {
    env.deployenv = "DEV"
    
    parallel(
    DeployApp: {
    if (env.pipeline == 'pipeline1') {
    env.deployenv = "DEV"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.deployenv = "DEV2"
    }
    
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]	
    },
    
    DeployDB: {
    //xldDeploy serverCredentials: 'Admin', environmentId: 'Environments/${deployenv} ENV', packageId: 'Applications/${env.appname}_ddb/${version}'
    //Refresh Pipeline for DMC Status
    //bat 'cd ddb && hammer.bat status'
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //	bat 'cd ddb && hammer.bat status %appname%'
    //}
    }
    )
    }
    
    stage('Promotion Approval') {
    echo 'wait for approval'
    }
    
    input 'Continue to Deploy TEST'
    
    stage('Deploy To TEST') {
    env.deployenv = "TEST"
    
    parallel(
    DeployApp: {
    if (env.pipeline == 'pipeline1') {
    env.deployenv = "TEST"
    }
    
    if (env.pipeline == 'pipeline2') {
    env.deployenv = "TEST2"
    }
    
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]	
    },
    
    
    DeployDB: {
    //xldDeploy serverCredentials: 'Admin', environmentId: 'Environments/${deployenv} ENV', packageId: 'Applications/${env.appname}_ddb/${version}'
    sleep 15
    }
    )
    }
    }
    
    stage('Promotion Approval') {
    echo 'wait for approval'
    }
    
    input 'Continue to Deploy PROD'
    
    stage('Deploy To PROD') {
    env.deployenv = "PROD"
    
    parallel(
    DeployApp: {
    build job: String.valueOf(appname) + '-DEP',
    parameters: [
    string(name: 'pipeline', value: String.valueOf("${env.pipeline}")),
    string(name: 'labels', value: String.valueOf("${env.pipeline}")),
    string(name: 'deployenv', value: String.valueOf("${env.deployenv}")),
    string(name: 'deployver', value: String.valueOf("${env.version}")),
    string(name: 'CDTool', value: String.valueOf("${env.CDTool}"))
    ]
    },
    
    DeployDB: {
    if (env.pipeline == 'hotfix') {
    //withCredentials([usernamePassword(credentialsId: 'DATICAL5', usernameVariable: 'DATICAL_USERNAME', passwordVariable: 'DATICAL_PASSWORD')]) {
    //bat 'cd ddb\\%appname% && hammer.bat status %appname%'
    //}
    }
    }
    )
    }
    
    } catch (e) {
    // If there was an exception thrown, the build failed
    currentBuild.result = "FAILED"
    throw e
    } finally {
    // Success or failure, always send notifications
    notifyBuild(currentBuild.result)
    archiveArtifacts allowEmptyArchive: true, artifacts: '**/ddb/**/Reports/**'
    }
    }
    
    def notifyBuild(String buildStatus = 'STARTED') {
    // build status of null means successful
    buildStatus = buildStatus ?: 'SUCCESSFUL'
    
    def subject = "${buildStatus}: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]'"
    //def summary = "${subject} (${env.BUILD_URL})"
    def summary = "${subject} (http://win-20e107kb4tn:8080/blue/organizations/jenkins/${env.JOB_NAME}/detail/${env.JOB_NAME}/${env.BUILD_NUMBER}/pipeline)"
    
    // Send notifications
    mail bcc: '', body: summary, cc: '', from: 'jenkins@company.local', replyTo: '', subject: subject, to: 'dev@company.local'
    }




Filter by label

There are no items with the selected labels at this time.




Copyright © Datical 2012-2020 - Proprietary and Confidential