Skip to content

Commit

Permalink
Merge pull request #1 from jenkinsci/bump_ksm_sdk
Browse files Browse the repository at this point in the history
Update SDK, fix cert validation, and default radio button
  • Loading branch information
jsupun authored Dec 8, 2021
2 parents f36dca9 + 2e273db commit 4b3c1a8
Show file tree
Hide file tree
Showing 6 changed files with 82 additions and 78 deletions.
133 changes: 70 additions & 63 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,96 +3,94 @@
## Introduction

This plugin allows you to retrieve secrets from your [Keeper Secrets Manager](https://www.keepersecurity.com) account and place the values
them into environmental variables in the builder and workflow pipeline.
them into environmental variables, or files, in the builder and workflow pipeline.

## Getting Started

### Getting Credentials

First, start a Jenkins instance with the keeper-secrets-manager plugin installed. You will also need to install
[Keeper Commander](https://github.com/Keeper-Security/Commander/releases).

You can optionally install the [Keeper Secrets Manager CLI](https://docs.keeper.io/secrets-manager/secrets-manager/secrets-manager-command-line-interface)
to view records and their fields.

Keeper Commander will be used to generate the one time tokens used by the plugin.
Additional documentation can be found in the [Keeper Documentation Portral](https://docs.keeper.io/secrets-manager/secrets-manager/integrations/jenkins-plugin).

My Vault> secrets-manager client add --app MyApplication
### Getting Credentials

------------------------------------------------------------------
One Time Access Token: XX:XXXXXXXXXXX
------------------------------------------------------------------
First, start a Jenkins instance with the keeper-secrets-manager plugin installed. You will either need to install
[Keeper Commander](https://github.com/Keeper-Security/Commander/releases) or use the Keeper Vault to create a
one time access token.

Documentation for Keeper Commander can be found [here](https://docs.keeper.io/secrets-manager/commander-cli/overview).
* Get a one time access token via [Keeper Commander](https://docs.keeper.io/secrets-manager/secrets-manager/about/one-time-token#using-commander-to-generate-a-token).
* Get a one time access token via [Keeper Vault](https://docs.keeper.io/secrets-manager/secrets-manager/about/one-time-token#using-the-keeper-vault-to-generate-a-token).

Within of the Jenkins, navigate to **Manage Jenkins->Manage Credentials->(scope)->Add Credentials**,
Within Jenkins, navigate to **Manage Jenkins->Manage Credentials->(scope)->Add Credentials**,
then select **Keeper Secrets Manager** in the **Kind** dropdown.

![](images/cred_add.png)

Cut-n-paste the One Time Access Token into the UI field, set the Description, and save the credential. Upon saving
the plugin will attempt to retrieve the required keys from the Keeper Secrets Manager server and populate them. When
you open the credential again, the One Time Access Token should be blank and clicking the View Keys button will
display your private and application keys, and client id.
you open the credential again, the One Time Access Token should be blank.

If there was a problem redeeming the One Time Access Token, the error message will appear in the One Time Access Token
field.

You can also validate the credential by clicking **Advanced**, then clicking the **Validate Credential** button. If
there is a problem with the credential and error message will be displayed. If no message appears, the
credential is valid.

### Freestyle Project

The Keeper Secrets Manager is available in a freestyle project as a **Build Environment**. To
enable just check the Keeper Secrets Manager box in the Build Environment checkbox group.
enable just check the Keeper Secrets Manager box in the **Build Environment** checkbox group.

![](images/builder.png)

Next click to Add Application button and select the application credential that contains
Next click the **Add Application** button and select the application credential that contains
your secrets. At this point you can begin to add secrets.

SecretS uses [Keeper Notation](#keeper-notation) to describe which
Secrets use [Keeper Notation](#keeper-notation) to describe which
field in a record should be retrieved. The secret value can be stored in an environmental
variable or saved to a file in your workspace.

Select the desired destination radio button and enter the environmental variable or
file name.

The console logger will attempt to redact any secrets that are displayed. Any secret files
The logger will attempt to redact any secrets that are displayed. Any secret files
created the by the plugin will be removed when the build finishes. It is recommended that
any Keeper Notation that uses **file** be stored as a file in the workspace instead
of an environmental variable. Files may contain encoding or special characters that
prevent correct redacting in the console.
prevent correctly redacting the secret.

### Pipeline Workflow

Below is an example of a Jenkinsfile using the Keeper Secrets Manager plugin.

pipeline {
agent any
stages {
stage('Hello') {
steps {
withKsm(application: [
[
credentialsId: 'PID-5142ceb84e9b4a2a9179cc5b6fe2798b',
secrets: [
[destination: 'env', envVar: 'MY_LOGIN', filePath: '', notation: 'keeper://1adh_WZxtbbHWqf6IALMVg/field/login'],
[destination: 'env', envVar: 'MY_SEC_PHONE_NUM', filePath: '', notation: 'keeper://Atu8tVgMxpB-iO4xT-Vu3Q/custom_field/phone[1][number]'],
[destination: 'file', envVar: '', filePath: 'img.png', notation: 'keeper://V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png']
]
]
]) {
sh'''
# Will be redected in console
echo "MY_LOGIN = ${MY_LOGIN}"
echo "MY_SEC_PHONE_NUM = ${MY_SEC_PHONE_NUM}"

./my/build/script --login "${MY_LOGIN}" --phone "${MY_SEC_PHONE_NUM}"
ls -l img.png
'''
}
}
```groovy
pipeline {
agent any
stages {
stage('Hello') {
steps {
withKsm(application: [
[
credentialsId: 'PID-5142ceb84e9b4a2a9179cc5b6fe2798b',
secrets: [
[destination: 'env', envVar: 'MY_LOGIN', filePath: '', notation: 'keeper://1adh_WZxtbbHWqf6IALMVg/field/login'],
[destination: 'env', envVar: 'MY_SEC_PHONE_NUM', filePath: '', notation: 'keeper://Atu8tVgMxpB-iO4xT-Vu3Q/custom_field/phone[1][number]'],
[destination: 'file', envVar: '', filePath: 'img.png', notation: 'keeper://V8lFbio0Bs0LuvaSD5DDHA/file/IMG_0036.png']
]
]
]) {
sh'''
# Will be redected in console
echo "MY_LOGIN = ${MY_LOGIN}"
echo "MY_SEC_PHONE_NUM = ${MY_SEC_PHONE_NUM}"
./my/build/script --login "${MY_LOGIN}" --phone "${MY_SEC_PHONE_NUM}"
ls -l img.png
'''
}
}
}
}
}
```

The Keeper Secrets Manager snippet can be created using the **Pipeline Syntax** editor inside of Jenkins. Just select
**withKsm** from the **Sample Step** dropdown. You can then add an application, which will allow you to select the
Expand All @@ -109,25 +107,32 @@ Once you exit the block the secrets will be removed.

## Keeper Notation

You can optionally install the [Keeper Secrets Manager CLI](https://docs.keeper.io/secrets-manager/secrets-manager/secrets-manager-command-line-interface)
to view records and their fields to help build notation.

Keeper Notation is way to describe a field in a record and the parts of the field's value. It looks like the following:

keeper://Ipk9NR1rCBZXyflWbPwTGA/field/login
keeper://Ipk9NR1rCBZXyflWbPwTGA/custom_field/Lock Box Location
keeper://Ipk9NR1rCBZXyflWbPwTGA/file/cat.png
keeper://Ipk9NR1rCBZXyflWbPwTGA/custom_field/Content Phone[1][number]

Notation can be broken into three pieces: the record uid, the type of field in the record, and
Notation can be broken into three pieces: the Record UID, the type of field in the record, and
the field label, type or file name and access in to the values.

You can test notation using the Keeper Secrets Manager CLI

$ ksm secret notation
```shell
$ ksm secret notation keeper://Ipk9NR1rCBZXyflWbPwTGA/field/login
```
Additional documentation on notation can be found on the [Keeper Documentation Portal](https://docs.keeper.io/secrets-manager/secrets-manager/about/keeper-notation).

### The Record UID

Each record has a unique identifier which is obtainable from multiple tools.

In the Web UI, clicking the Info icon will show the Record UID.
In the Keeper Vault, clicking the Info icon will show the Record UID. You can copy to clipboard a URL
that contains the Record UID.

![](images/web_uid.png)

Expand All @@ -140,28 +145,29 @@ In Commander, you can see the Record UID by issuing the _list_ command.
2 6vV5bvyu5eLygHa3kMEWug login Web 2
3 Eq8KFpJkRkgOnpXjNIjYcA login Prod Database

In the CLI, you can see the
Record UID by running
In the Keeper Secrets Manager CLI, you can see the Record UID by running the command below.

$ ksm secret list
UID Record Type Title
----------------------- -------------------- -----------------
A_7YpGBUgRTeDEQLhVRo0Q file Tomcat Certs
Atu8tVgMxpB-iO4xT-Vu3Q login Router Login
A_7YpGBUgRTeDEQLhVRo0Q file Company Logos
```shell
$ ksm secret list
UID Record Type Title
----------------------- -------------------- -----------------
A_7YpGBUgRTeDEQLhVRo0Q file Tomcat Certs
Atu8tVgMxpB-iO4xT-Vu3Q login Router Login
A_7YpGBUgRTeDEQLhVRo0Q file Company Logos
```

### The Field Type

There are three field types: **field**, **custom_field**, and **file**.

* **field** - Refers to the standard field you get for the record type. These are the
fields that appear at the top of the Web UI like **Login** and **Password**.
* **custom_field** - Refers to field added in the Custom Field section.
fields that appear at the top of the record, in Keeper Vault, like **Login** and **Password**. They are part of the record type.
* **custom_field** - Refers to field added in the Custom Field section. There are fields you add to the record.
* **file** - Refers to the Files and Photo section.

### Field Label or File Name

For the **field** and **custom_field** field types, this would be the label shown in the Web UI. In Keeper Commander you can get
For the **field** and **custom_field** field types, this would be the label shown in the Keeper Vault. In Keeper Commander you can get
the details of the record using the "get <RECORD UID>" command, and via the CLI with
**ksm secret get -u <RECORD UID>**.

Expand All @@ -177,6 +183,7 @@ Only the Keeper Secrets Manager CLI will give a more detail view of the values i
at a bank card record type you can see the **paymentCard** is more complex than just a literal value. It's actually
a dictionary of values.

```shell
$ ksm secret get -u jW8FGAqf02Rlm-N1dr4vkA
Record: jW8FGAqf02Rlm-N1dr4vkA
Title: Payment Card Record
Expand All @@ -193,12 +200,12 @@ a dictionary of values.
Custom Field Type Value
------------ -------- --------------
Pin Code pinCode ****
```

To get the credit card number, the notation would look like this:

keeper://jW8FGAqf02Rlm-N1dr4vkA/field/paymentCard[cardNumber]


## Issues

Report issues and enhancements in the [Keeper Secrets Manager issue tracker](https://github.com/jenkinsci/keeper-secrets-manager-plugin/issues).
Expand Down
Binary file modified images/cred_add.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<dependency>
<groupId>com.keepersecurity.secrets-manager</groupId>
<artifactId>core</artifactId>
<version>16.1.2</version>
<version>16.2.1</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
Expand Down Expand Up @@ -152,7 +152,7 @@
<id>s01.oss.sonatype.org</id>
<url>https://s01.oss.sonatype.org/content/groups/public/</url>
<releases>
<enabled>false</enabled>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,6 @@
import org.json.*;
import java.util.Base64;

import static com.keepersecurity.secretsManager.core.SecretsManager.downloadFile;

public class KsmTestNotation extends KsmNotation {

private KeeperSecrets secrets;
Expand Down Expand Up @@ -48,7 +46,7 @@ public class KsmTestNotation extends KsmNotation {
* @param jsonString The JSON string
*/

public void addTestData(String jsonString) throws UnsupportedEncodingException {
public void addTestData(String jsonString) {
JSONObject obj = new JSONObject(jsonString);
JSONArray secretArr = obj.getJSONArray("secrets");
List<KeeperRecord> records = new ArrayList<>();
Expand Down Expand Up @@ -129,6 +127,7 @@ public void addTestData(String jsonString) throws UnsupportedEncodingException {
"HI".getBytes(StandardCharsets.UTF_8),
uid,
null,
null,
data,
0L,
files
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<f:textbox/>
</f:entry>
<f:section title="${Destination}">
<f:radioBlock name="destination" value="env" checked="${instance.isDestinationType('env')}" title="${%RadioEnvVars}" inline="true">
<f:radioBlock name="destination" value="env" checked="${instance.isDestinationType('env') || instance.destination == null}" title="${%RadioEnvVars}" inline="true">
<f:nested>
<f:entry title="${%EnvVars}" field="envVar">
<f:textbox/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<f:textbox/>
</f:entry>

<f:advanced title="${%ViewKeys}">
<f:advanced>
<f:entry title="${%ClientId}" field="clientId">
<f:secretTextarea/>
</f:entry>
Expand All @@ -18,20 +18,18 @@
<f:entry title="${%AppKey}" field="appKey">
<f:secretTextarea/>
</f:entry>
<f:validateButton
title="${%ValidateCredential}" progress="${%ValidateCredentialProgress}"
method="testCredential" with="hostname,clientId,privateKey,appKey,useSkipSslVerification"/>
</f:advanced>
<f:advanced>
<f:entry title="${%Hostname}" field="hostname">
<f:textbox/>
</f:entry>
<f:entry title="${%AllowConfigInject}" field="allowConfigInject">
<f:checkbox/>
</f:entry>
<f:entry title="${%SkipSslVerification}" field="skipSslVerification">
<f:checkbox />
</f:entry>
<f:validateButton
title="${%ValidateCredential}" progress="${%ValidateCredentialProgress}"
method="testCredential" with="hostname,clientId,privateKey,appKey,useSkipSslVerification"/>
<f:entry title="${%AllowConfigInject}" field="allowConfigInject">
<f:checkbox/>
</f:entry>
<f:entry title="${%Id}" field="${instance != null ? null : 'id'}">
<f:textbox name="_.id"
value="${instance != null ? instance.id : null}"
Expand Down

0 comments on commit 4b3c1a8

Please sign in to comment.