Skip to content

Keeper-Security/secrets-manager-go

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Secrets Management Go SDK Header

Keeper Secrets Manager : Go SDK

Go

View docs

This library provides interface to Keeper Secrets Manager and can be used to access your Keeper vault, read and update existing records, rotate passwords and more. Keeper Secrets Manager is an open source project with contributions from Keeper's engineering team and partners.

Features

  • Zero-knowledge client-side encryption (AES-256-GCM, ECDH)
  • Read, create, update, and delete vault records and files
  • HTTP proxy support via ClientOptions.ProxyUrl or HTTPS_PROXY/HTTP_PROXY env vars
  • Regional token support (US:, EU:, AU:, GOV:, JP:, CA:)
  • Pluggable caching via the ICache interface
  • No external dependencies (Go standard library only)
  • Requires Go 1.16+

Obtain a One-Time Access Token

Keeper Secrets Manager authenticates your API requests using advanced encryption that uses locally stored private key, device id and client id. To register your device and generate private key you will need to generate a One-Time Access Token via Web Vault or Keeper Commander CLI.

Via Web Vault

Secrets Manager > Applications > Create Application - will let you chose application name, shared folder(s) and permissions and generate One-Time Access Token. Note: Keeper does not store One-Time Access Tokens - save or copy the token offline for later use.

One-Time Access Tokens can be generated as needed: Secrets Manager > Applications > Application Name > Devices Tab > Edit > Add Device button - will let you create new Device and generate its One-Time Access Token.

What is an application?

Via Keeper Commander CLI

Login to Keeper with Commander CLI and perform following:

  1. Create Application

    $ sm app create [NAME]
  2. Share Secrets to the Application

    $ sm share add --app [NAME] --secret [UID] --editable
    • --app - Name of the Application.
    • --secret - Record UID or Shared Folder UID
    • --editable - if omitted defaults to false
  3. Create client

    $ sm client add --app [NAME] --unlock-ip --count 1

Install

go get github.com/keeper-security/secrets-manager-go/core

Quick Start

package main

// Import Secrets Manager
import ksm "github.com/keeper-security/secrets-manager-go/core"

func main() {
	// Establish connection
	// One time secrets generated via Web Vault or Commander CLI
	clientOptions := &ksm.ClientOptions{
		Token:  "US:ONE_TIME_TOKEN_BASE64",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	// One time tokens can be used only once - afterwards use the generated config file
	// sm := ksm.NewSecretsManager(&ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")})

	// Retrieve all records
	allRecords, err := sm.GetSecrets([]string{})
	if err != nil || len(allRecords) == 0 {
		print("No records found")
		return
	}

	// Get password from first record:
	password := allRecords[0].Password()

	// WARNING: Avoid logging sensitive data
	print("My password from Keeper: ", password)
}

Samples

File Download

sm := ksm.NewSecretsManager(&ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")})

if records, err := sm.GetSecrets([]string{}); err == nil {
	for _, r := range records {
		fmt.Println("\tTitle: " + r.Title())
		for i, f := range r.Files {
			fmt.Printf("\t\tfile #%d -> name: %s", i, f.Name)
			f.SaveFile("/tmp/"+f.Name, true)
		}
	}
}

Update record

sm := ksm.NewSecretsManager(&ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")})

if records, err := sm.GetSecrets([]string{}); err == nil && len(records) > 0 {
	record := records[0]
	newPassword := fmt.Sprintf("Test Password - " + time.Now().Format(time.RFC850))
	record.SetPassword(newPassword)

	if err := sm.Save(record); err != nil {
		fmt.Println("Error saving record: " + err.Error())
	}
}

Configuration

Types

Listed in priority order

  1. Environment variable
  2. Configuration store
  3. Code

Available configurations:

  • clientKey - One Time Access Token used during initialization
  • hostname - Keeper Backend host. Available values:
    • keepersecurity.com (US)
    • keepersecurity.eu (EU)
    • keepersecurity.com.au (AU)
    • govcloud.keepersecurity.us (GOV)
    • keepersecurity.jp (JP)
    • keepersecurity.ca (CA)

Alternatively, pass a regional token (e.g. US:ONE_TIME_TOKEN) and the hostname is set automatically.

HTTP Proxy

Set ClientOptions.ProxyUrl to route SDK traffic through a proxy:

sm := ksm.NewSecretsManager(&ksm.ClientOptions{
    Config:   ksm.NewFileKeyValueStorage("ksm-config.json"),
    ProxyUrl: "http://proxy.example.com:8080",
})

If ProxyUrl is not set, the standard HTTPS_PROXY and HTTP_PROXY environment variables are honored automatically.

Adding more records or shared folders to the Application

Via Web Vault

Drag&Drop records into the shared folder or select from the record menu any of the options to CreateDuplicate/Move or create new records straight into the shared folder. As an alternative use: Secrets Manager > Application > Application Name > Folders & Records > Edit and use search field to add any folders or records then click Save.

Via Commander CLI

sm share add --app [NAME] --secret [UID2]
sm share add --app [NAME] --secret [UID3] --editable

Retrieve secret(s)

sm := ksm.NewSecretsManager(&ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")})
allSecrets, _ := sm.GetSecrets([]string{})

Update secret

secretToUpdate = allSecrets[0]
secretToUpdate.SetPassword("NewPassword123$")
secretsManager.Save(secretToUpdate)

Custom Cache

The SDK supports pluggable caching through the ICache interface. The cache is an offline resilience mechanism, not a request-rate limiter. The SDK always contacts the Keeper API on every call. After a successful response it writes the encrypted payload to SaveCachedValue. When the API is unreachable (DNS failure, connection refused, TLS error, timeout, or non-200 response), the SDK calls GetCachedValue and — if a prior payload exists — decrypts and returns those records instead of surfacing the error. A warning is logged when cached records are served.

Common uses: multi-instance applications sharing a Redis cache, applying a custom staleness window, or adding cache-event logging.

type ICache interface {
    SaveCachedValue(data []byte) error  // called after each successful API response
    GetCachedValue() ([]byte, error)    // return nil, nil on cache miss or expiry
    Purge() error                        // clear the cache on explicit invalidation
}

The data passed to SaveCachedValue is already encrypted by the SDK — implementations do not need additional encryption.

Register a custom cache after creating the client:

sm := ksm.NewSecretsManager(&ksm.ClientOptions{
    Config: ksm.NewFileKeyValueStorage("ksm-config.json"),
})
sm.SetCache(myCustomCache)

See example/custom-cache/ for a complete working demonstration: the first call populates the cache from the live API; subsequent calls with an unreachable API serve records from the cache; after Purge() the original network error surfaces.

Change Log

1.7.0

  • KSM-532 - Add proxy support
  • KSM-565 - Add parsing for KSM tokens with prefix
  • KSM-583 - Fix SetNotes
  • KSM-616 - Remove deprecated ioutil dependency
  • KSM-626 - Add GraphSync links
  • KSM-632 - Add links2Remove parameter for files removal
  • KSM-658 - Add custom cache example and document ICache interface
  • KSM-663 - Handle broken records, files, and folders
  • KSM-665 - Add HTTP Status Code to the error messages
  • KSM-701 - Write config files with secure permissions (0600)
  • KSM-736 - Fix notation lookup with record shortcuts (duplicate UID bug)
  • KSM-745 - Add transmission public key #18 for Gov Cloud Dev support
  • KSM-756 - Fix shared-folder flat records decrypting with wrong key (folder vs app key)
  • KSM-826 - Fix RecordCreate.ToDict() to always include "custom" key
  • KSM-860 - Fix RecordField JSON serialization (lowercase keys, no double-nesting)
  • KSM-911 - Skip records whose AES-GCM data decryption fails instead of returning empty stubs
  • KSM-912 - Fix proxy env var fallback (HTTPS_PROXY/HTTP_PROXY now respected)
  • KSM-913 - Return nil from NewFolderFromJson/NewKeeperFolder when folder key/name decryption fails
  • KSM-914 - Return nil from NewKeeperFileFromJson when file key decryption fails
  • KSM-916 - Return error from GetSecrets when app key decryption fails in just-bound flow
  • KSM-917 - Return nil from NewKeeperFolder when CBC-decrypted folder name fails json.Unmarshal
  • KSM-918 - Return error from SaveFile/DownloadFile/DownloadFileByTitle instead of bool
  • KSM-919 - Expose HTTP status code via KeeperHTTPError on JSON-error path (errors.As support)
  • KSM-920 - Update custom-cache example to demonstrate offline-fallback semantics
  • KSM-921 - Consult cache on network-level errors (DNS failure, connection refused, timeout)

1.6.5

  • KSM-565 - Added parsing for KSM tokens with prefix
  • KSM-616 - Removed deprecated ioutil dependency and upgarded to Go 1.16

1.6.4

  • KSM-551 - Stop generating UIDs that start with "-"
  • KSM-555 - Added new field types and updated PAM field types

1.6.3

  • KSM-497 - Expose additional methods to create record from data, options and UID

1.6.2

  • KSM-467 - Fixed ExpiresOn conversion from UnixTimeMilliseconds.

1.6.1

  • KSM-450 - Added folderUid and innerFolderUid to Record
  • KSM-451 - Fix subFolderUid crash on empty string value

1.6.0

  • KSM-414 - Added support for Folders
  • KSM-435 - Improved Passkey field type support

1.5.2

  • KSM-409 New field type: Passkey
  • KSM-404 New filed type: script and modification to some record types
  • KSM-384 Support for record Transactions

1.5.0

  • KSM-317 - Notation improvements
  • KSM-356 - Create custom fields
  • KSM-365 - Fixed KEY_CLINET_KEY is missing error
  • KSM-366 - Avoid exceptions/panics and return errors instead
  • KSM-367 - Fixed license not shown on pkg.go.dev

1.4.0

  • KSM-288 - Record removal
  • KSM-306 - Added support for Japan and Canada data centers
  • KSM-312 - Improve password generation entropy

For additional information please check our detailed Go SDK docs for Keeper Secrets Manager.

Documentation

Secrets Manager Guide

Enterprise Admin Guide

Keeper Commander Guide

Keeper Security Website

About

Keeper Secrets Manager Go SDK

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages