Developer SDKs
Sample code and SDK integration instructions for Keeper Secrets Manager
Overview
The Keeper Secrets Manager SDKs are purpose-built to provide extremely simple, fast and efficient access to Secrets Management functionality from all popular languages.
Installation
Reference the maven repository for snapshots:
repositories {
mavenCentral()
maven { url "https://s01.oss.sonatype.org/content/groups/public/" }
}
Add the following dependency to your project:
com.keepersecurity.secrets-manager:core:16.6.4
The Java SDK supports JDK version 8
through 13.02+8
Reference the maven repository for snapshots:
repositories {
mavenCentral()
maven("https://s01.oss.sonatype.org/content/groups/public/")
}
Add the following dependency to your project:
com.keepersecurity.secrets-manager:core:16.0.1-SNAPSHOT
npm install @keeper-security/secrets-manager-core
The JavaScript SDK supports Node version 11
through 16.12.0
pip3 install -U keeper-secrets-manager-core
The Python SDK supports Python version 3.6
through 3.10
dotnet add package Keeper.SecretsManager
The .Net SDK supports .Net version 4.7
and 4.8
Or .Net Core version 2.1
and later
import (
ksm "github.com/keeper-security/secrets-manager-go/core"
klog "github.com/keeper-security/secrets-manager-go/core/logger"
)
The GoLang SDK supports GoLang version 1.13
and later
Authentication
The Secrets Manager SDK authenticates to the Keeper Vault using either the One Time Access Token or using the generated keys within the local configuration file. To generate one or more One Time Access Tokens from Commander CLI use the secrets-manager client add
command.
$ keeper shell
... login ...
My Vault> secrets-manager client add --app MyApplication --unlock-ip
Initialization
Secrets Manager SDKs utilize a configuration file to hold connection tokens and settings. The following code samples show how to create a configuration file with the SDKs and an One-Time Access Token:
import com.keepersecurity.secretsManager.core.*;
import static com.keepersecurity.secretsManager.core.SecretsManager.*;
public class KSMSample {
public static void main(String[] args){
// oneTimeToken is used only once to initialize the storage
// after the first run, subsequent calls will use ksm-config.json
String oneTimeToken = "[ONE TIME TOKEN]";
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
// after the first run, this line can be removed
initializeStorage(storage, oneTimeToken);
SecretsManagerOptions options = new SecretsManagerOptions(storage);
} catch (Exception e) {
System.out.println(e.getMessage());
}
// Rest of the code using `options`
}
}
const {
getSecrets,
initializeStorage,
localConfigStorage,
downloadFile,
updateSecret
} = require('@keeper-security/secrets-manager-core')
const oneTimeToken = '[One Time Access Token]'
const getKeeperRecords = async () => {
const storage = localConfigStorage("ksm-config.json")
await initializeStorage(storage, oneTimeToken)
const {records} = await getSecrets({storage: storage})
console.log(records)
const firstRecord = records[0]
const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
console.log(firstRecordPassword.value[0])
}
getKeeperRecords().finally()
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
oneTimeToken = "[One Time Access Token]"
secrets_manager = SecretsManager(
# One time tokens can be used only once - afterwards use the generated config file
token=oneTimeToken,
config=FileKeyValueStorage('ksm-config.json')
)
# Retrieve all password records (will also initialize config)
records = secrets_manager.get_secrets()
using System;
using SecretsManager;
var oneTimeToken = "[One Time Access Token]";
var storage = new LocalConfigStorage("ksm-config.json");
try {
// One time tokens can be used only once - afterwards use the generated config file
SecretsManagerClient.InitializeStorage(storage, oneTimeToken);
var options = new SecretsManagerOptions(storage);
// Retrieve all password records (will also initialize config)
var records = (await SecretsManagerClient.GetSecrets(options)).Records;
Console.WriteLine($"Received {records.Length} record(s)");
// get the password from the first record
var firstRecord = records[0];
var password = records[0].FieldValue("password").ToString();
Console.WriteLine($"Password: {password}");
} catch (Exception e) {
Console.WriteLine(e);
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
onetimeAccessCode := "[One Time Access Token]"
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Token: onetimeAccessCode,
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve all password records (will also initialize config)
allRecords, _ := sm.GetSecrets([]string{})
// Get password from first record:
firstRecord := allRecords[0]
firstRecordPassword := firstRecord.Password()
print("Password: [", firstRecordPassword, "]")
}
After a config file has been initialized, the One-Time Access Token should be removed from code
This initialization code will create a JSON configuration file on the device local storage with the following keys:
Key | Description |
| The destination host where your Enterprise tenant is located:
|
| The hashed |
| Client Device Private Key |
| Keeper Infrastructure's Public Key ID |
| Application Private Key |
| Application Owner's Public Key |
The following is an example of a generated configuration file:
{
"hostname": "keepersecurity.com",
"clientId": "ab2x3z/Acz0QFTiilm8UxIlqNLlNa25KMj=TpOqznwa4Si-h9tY7n3zvFwlXXDoVWkIs3xrMjcLGwgu3ilmq7Q==",
"privateKey": "MLSHAgABCDEFGyqGSM49AEGCCqGSM49AwEHBG0wawIWALTARgmcnWx/DH+r7cKh4kokasdasdaDbvHmLABstNbqDwaCWhRANCAARjunta9SJdZE/LVXfVb22lpIfK4YMkJEDaFMOAyoBt0BrQ8aEhvrHN5/Z1BgZ/WpDm9dMR7E5ASIQuYUiAw0t9",
"serverPublicKeyId": "10",
"appKey": "RzhSIyKxbpjNu045TUrKaNREYIns+Hk9Kn8YtT+CtK0=",
"appOwnerPublicKey": "Sq1W1OAnTwi8V/Vs/lhsin2sfSoaRfOwwDDBqoP+EO9bsBMWCzQdl9ClauDiKLXGmlmyx2xmSAdH+hlxvBRs6kU="
}
For information on other ways to create a config file, see the Config File documentation.
Retrieve All Secrets
import com.keepersecurity.secretsManager.core.*;
import static com.keepersecurity.secretsManager.core.SecretsManager.*;
import java.io.FileOutputStream;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// get all available secrets
KeeperSecrets secrets = SecretsManager.getSecrets(options);
// print out record details
System.out.println(secrets.getRecords());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
const {
getSecrets,
initializeStorage,
localConfigStorage,
downloadFile,
updateSecret
} = require('@keeper-security/secrets-manager-core')
const oneTimeToken = '[One Time Access Token]'
const getKeeperRecords = async () => {
const storage = localConfigStorage("ksm-config.json")
await initializeStorage(storage, oneTimeToken)
const {records} = await getSecrets({storage: storage})
}
getKeeperRecords().finally()
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
all_records = secrets_manager.get_secrets()
# print out all record JSON data
for record in all_records:
# record.print() # print record to STDOUT
print(record.uid + " - " + record.title)
print("\tLogin: " + record.field('login')[0])
print("\tPassword: " + record.field('password')[0])
using System;
using System.Threading.Tasks;
using SecretsManager;
private static async Task retrieveAllSecrets()
{
// get pre-initialized storage
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
// get all available secrets
var records = (await SecretsManagerClient.GetSecrets(options)).Records;
foreach (var record in records)
{
Console.WriteLine(record.RecordUid + " - " + record.Data.title);
foreach (var field in record.Data.fields)
{
Console.WriteLine("\t" + field.label + " (" + field.type + "): [" + String.Join(", ", field.value) + "]");
}
}
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve all password records (will also initialize config)
allRecords, _ := sm.GetSecrets([]string{})
for _, record := range allRecords {
println("UID", record.Uid, ", title [", record.Title(), "]")
}
}
These examples assumes a Secrets Manager config file has already been initialized.
See the Initialization section for how to initialize a config file.
Retrieve One Individual Secret
Get Secrets By Record Title
import com.keepersecurity.secretsManager.core.*;
import java.util.List;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// title of the record to fetch
String recordTitle = "My Credentials";
// search for record by title
KeeperRecord myCredentials = secrets.getRecords().getSecretByTitle(recordTitle);
// print out record details
System.out.println("Record UID: " + myCredentials.getRecordUid());
System.out.println("Title: " + myCredentials.getData().getTitle());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
const {
getSecretByTitle,
localConfigStorage,
} = require('@keeper-security/secrets-manager-core')
const getKeeperRecord = async () => {
const options = { storage: localConfigStorage("ksm-config.json")
const {myCredential} = await getSecretByTitle(options, "My Credential")
}
getKeeperRecord().finally()
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
record_title = "My Record"
record = secrets_manager.get_secret_by_title(record_title)
if record:
print(record.uid + " - " + record.title)
print("\tLogin: " + record.field('login')[0])
print("\tPassword: " + record.field('password')[0])
else:
print("No record found with title: " + record_title)
using System;
using System.Threading.Tasks;
using SecretsManager;
private static async Task getOneIndividualSecret()
{
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
var records = (await SecretsManagerClient.GetSecretsByTitle(
options, "My Credentials")
).Records;
foreach (var record in records)
{
Console.WriteLine(record.RecordUid + " - " + record.Data.title);
foreach (var field in record.Data.fields)
{
Console.WriteLine("\t" + field.label + " (" + field.type + "): [" + String.Join(", ", field.value) + "]");
}
}
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve one individual record by Title
allRecords, _ := ksm.GetSecretsByTitle("My Credentials")
for _, record := range allRecords {
println("UID", record.Uid, ", title [", record.Title(), "]")
}
}
Get Secrets By Record UID
In this example, the Record UID is XXX
import com.keepersecurity.secretsManager.core.*;
import java.util.List;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// create a filter with the UID of the record we want
List<String> uidFilter = List.of("[XXX]");
// fetch secrets with the filter
KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);
// get the desired secret from the fetch results
KeeperRecord myCredentials = secrets.getRecords().get(0);
// print out record details
System.out.println("Record UID: " + myCredentials.getRecordUid());
System.out.println("Title: " + myCredentials.getData().getTitle());
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
const {
getSecretsByTitle,
localConfigStorage,
} = require('@keeper-security/secrets-manager-core')
const oneTimeToken = '[One Time Access Token]'
const getKeeperRecord = async () => {
const options = { storage: localConfigStorage("config.json")
const {myCredential} = await getSecrets(options, ["XXX"]
}
getKeeperRecord().finally()
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
UID_FILTER = ['RECORD_UID']
record = secrets_manager.get_secrets(UID_FILTER)[0]
print(record.uid + " - " + record.title)
print("\tLogin: " + record.field('login')[0])
print("\tPassword: " + record.field('password')[0])
With a secret retrieved, individual fields can be retrieved from the secret.
# Get a standard template field
login = record.field('login', single=True)
# Get a custom field, e.g. API Key
api_key = record.custom_field('API Key', single=True)
using System;
using System.Threading.Tasks;
using SecretsManager;
private static async Task getOneIndividualSecret()
{
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
var records = (await SecretsManagerClient.GetSecrets(
options, new[] { "XXX" })
).Records;
foreach (var record in records)
{
Console.WriteLine(record.RecordUid + " - " + record.Data.title);
foreach (var field in record.Data.fields)
{
Console.WriteLine("\t" + field.label + " (" + field.type + "): [" + String.Join(", ", field.value) + "]");
}
}
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve one individual record by UID (will also initialize config)
allRecords, _ := sm.GetSecrets([]string{"[Record UID]"})
for _, record := range allRecords {
println("UID", record.Uid, ", title [", record.Title(), "]")
}
}
These examples assumes a Secrets Manager config file has already been initialized.
See the Initialization section for how to initialize a config file.
Retrieve a Password
Example to retrieve an individual record password field.
In this example, the Record UID is XXX
import com.keepersecurity.secretsManager.core.*;
import java.util.List;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// create a filter with the UID of the record we want
List<String> uidFilter = List.of("XXX");
// fetch secrets with the filter
KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);
// get the desired secret from the fetch results
KeeperRecord myCredentials = secrets.getRecords().get(0);
// get and print out password
String pwd = myCredentials.getPassword();
System.out.println("Password from Keeper: " + pwd);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
secret.data.fields.find(x => x.type === 'password')
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
# Get an individual secret by UID
UID_FILTER = 'XXX'
secret = secrets_manager.get_secrets([UID_FILTER])[0]
# Get a password from the secret
secret.field('password', single=True)
using System;
using System.Threading.Tasks;
using SecretsManager;
private static async Task retrieveAPassword()
{
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
var records = (await SecretsManagerClient.GetSecrets(
options, new[] { "XXX" })
).Records;
foreach (var record in records)
{
// retrieve "password" field
var passwordVal = record.FieldValue("password");
Console.WriteLine(record.RecordUid + " - " + record.Data.title + " - password=[" + passwordVal + "]");
}
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve all records (will also initialize config)
allRecords, _ := sm.GetSecrets([]string{})
for _, record := range allRecords {
passwordMethod1 := record.Password()
//passwordMethod2 := record.GetFieldValueByType("password") // retrieve password by accessing field
println("UID", record.Uid, ", Password [", passwordMethod1, "]")
}
}
These examples assumes a Secrets Manager config file has already been initialized.
See the Initialization section for how to initialize a config file.
Download a File Attachment
import com.keepersecurity.secretsManager.core.*;
import java.io.FileOutputStream;
import java.util.List;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// create a filter with the UID of the record we want
List<String> uidFilter = List.of("XXX");
// fetch secrets with the filter
KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);
// get the desired secret from the fetch results
KeeperRecord myCredentials = secrets.getRecords().get(0);
// get a file reference by filename from the record
KeeperFile file = myCredentials.getFileByName("acme.cer");
// download the file
byte[] fileBytes = SecretsManager.downloadFile(file);
String filename = file.getData().getName();
FileOutputStream fos = new FileOutputStream(filename);
fos.write(fileBytes);
System.out.println("Downloaded File: " + filename);
} catch (Exception e) {
System.out.println("KSM ran into an problem: " + e.getMessage());
}
}
}
const file = firstRecord.files.find(x => x.data.name === 'acme.cer')
if (file) {
const fileBytes = await downloadFile(file)
fs.writeFileSync(file.data.name, fileBytes)
}
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
# Get an individual secret by UID
UID_FILTER = 'XXX'
secret = secrets_manager.get_secrets([UID_FILTER])[0]
# Save all files to a /tmp folder (create folder if does not exist)
for file in secret.files:
print("file: %s" % file)
file.save_file("/tmp/" + file.name, True)
using System;
using System.IO;
using System.Threading.Tasks;
using SecretsManager;
private static async Task downloadAFileAttachment()
{
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
// get record by UID
var records = (await SecretsManagerClient.GetSecrets(
options, new[] { "XXX" })
).Records;
foreach (var record in records)
{
// download the file from the 1st record
var file = record.GetFileByName("acme.cer");
if (file != null)
{
var fileBytes = SecretsManagerClient.DownloadFile(file);
// write bytes to the disc
await File.WriteAllBytesAsync(file.Data.name, fileBytes);
}
}
}
package main
// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"
func main() {
options := &ksm.ClientOptions{
// One time tokens can be used only once - afterwards use the generated config file
Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(options)
// Retrieve all password records (will also initialize config)
allRecords, _ := sm.GetSecrets([]string{"[Record UID]"})
for _, record := range allRecords {
// Search file by title
file := record.FindFileByTitle("[FILE TITLE]")
// get file from the array by its index
//file := record.Files[0]
// Save file to the disc
file.SaveFile("/tmp/"+file.Name, true)
}
}
These examples assumes a Secrets Manager config file has already been initialized.
See the Initialization section for how to initialize a config file.
Upload a File Attachment
import com.keepersecurity.secretsManager.core.*;
import java.io.File;
import java.io.FileInputStream;
import java.util.Arrays;
public class KSMSample {
public static void main(String[] args){
// get pre-initialized storage
KeyValueStorage storage = new LocalConfigStorage("ksm-config.json");
try {
SecretsManagerOptions options = new SecretsManagerOptions(storage);
// create a filter with the UID of the record we want
List<String> uidFilter = List.of("XXX");
// fetch secrets with the filter
KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);
// get the desired secret to upload a file to
KeeperRecord ownerRecord = secrets.getRecords().get(0);
// get bytes from file to upload
File file = new File("./myFile.json");
FileInputStream fl = new FileInputStream(file);
byte[] fileBytes = new byte[(int)file.length()];
fl.read(fileBytes);
fl.close();
// create a Keeper File to upload
KeeperFileUpload myFile = new KeeperFileUpload(
"myFile.json",
"My File",
"application/json",
fileBytes
);
// upload the file to the selected record
SecretsManager.uploadFile(options, ownerRecord, myFile);
} catch (Exception e) {
System.out.println("KSM ran into an problem: " + e.getMessage());
}
}
}
import * as fs from "fs";
import {getSecrets, uploadFile} from "@keeper-security/secrets-manager-core";
// get record to attach file to
const {records} = await getSecrets({storage: storage}, ['XXX'])
const ownerRecord = records[0]
// get file data to upload
const fileData = fs.readFileSync('./assets/my-file.json')
// upload file to selected record
await uploadFile(options, ownerRecord, {
name: 'my-file.json',
title: 'Sample File',
type: 'application/json',
data: fileData
})
from keeper_secrets_manager_core import SecretsManager
from keeper_secrets_manager_core.storage import FileKeyValueStorage
from keeper_secrets_manager_core.core import KeeperFileUpload
secrets_manager = SecretsManager(
config=FileKeyValueStorage('ksm-config.json')
)
# Get an individual secret by UID to attach the file to
UID_FILTER = 'XXX'
owner_record= secrets_manager.get_secrets([UID_FILTER])[0]
# Prepare file data for upload
my_file = KeeperFileUpload.from_file("./myFile.json", "myfile.json", "My File")
# Upload file attached to the owner record
upload_file(owner_record, file: my_file)
using System;
using System.IO;
using System.Threading.Tasks;
using SecretsManager;
private static async Task uploadFile()
{
// initalize storage and options
var storage = new LocalConfigStorage("ksm-config.json");
var options = new SecretsManagerOptions(storage);
// get a record to attach the file to
var records = (await SecretsManagerClient