-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
30 changed files
with
4,833 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
name: Test-Go | ||
|
||
on: | ||
push: | ||
branches: [ master ] | ||
pull_request: | ||
branches: [ master ] | ||
|
||
jobs: | ||
test-go: | ||
strategy: | ||
matrix: | ||
go-version: [1.16.x] | ||
os: [ubuntu-latest, macos-latest, windows-latest] | ||
runs-on: ${{ matrix.os }} | ||
defaults: | ||
run: | ||
working-directory: ./test | ||
steps: | ||
- name: Install Go | ||
uses: actions/setup-go@v2 | ||
with: | ||
go-version: ${{ matrix.go-version }} | ||
- name: Checkout code | ||
uses: actions/checkout@v2 | ||
- name: Run tests | ||
run: go test -p 1 ./... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2021 Keeper Security | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Secrets Management Go SDK | ||
|
||
![Go](https://github.com/keeper-security/secrets-manager-go/actions/workflows/test.go.yml/badge.svg) | ||
|
||
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: | ||
|
||
## 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?](https://docs.keeper.io/secrets-manager/secrets-manager/overview/terminology) | ||
|
||
### Via Keeper Commander CLI | ||
Login to Keeper with Commander CLI and perform following: | ||
1. Create Application | ||
```bash | ||
$ sm app create [NAME] | ||
``` | ||
|
||
2. Share Secrets to the Application | ||
```bash | ||
$ 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 | ||
```bash | ||
$ sm client add --app [NAME] --unlock-ip --count 1 | ||
``` | ||
|
||
### Install | ||
```bash | ||
go get github.com/keeper-security/secrets-manager-go/core | ||
``` | ||
|
||
### Quick Start | ||
|
||
```golang | ||
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 | ||
sm := ksm.NewSecretsManager() | ||
sm.Token = "MmzGdls-rDG39vgqgFD1HL70h0_L_sKQOdI0qwXU3JI" | ||
// One time tokens can be used only once - afterwards use the generated config file | ||
// sm := ksm.NewSecretsManagerFromConfig(ksm.NewFileKeyValueStorage("client-config.json")) | ||
// Retrieve all password records | ||
allRecords, _ := sm.GetSecrets([]string{}) | ||
// Get password from first record: | ||
password := allRecords[0].Password() | ||
// WARNING: Avoid logging sensitive data | ||
print("My password from Keeper: ", password) | ||
} | ||
``` | ||
|
||
## Samples | ||
### File Download | ||
```golang | ||
sm := ksm.NewSecretsManagerFromConfig(ksm.NewFileKeyValueStorage("client-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 | ||
```golang | ||
sm := ksm.NewSecretsManagerFromConfig(ksm.NewFileKeyValueStorage("client-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) | ||
record.RawJson = ksm.DictToJson(record.RecordDict) | ||
if err := sm.Save(record); err != nil { | ||
fmt.Println("Error saving record: " + err.Error()) | ||
} | ||
} | ||
``` | ||
## Configuration | ||
### Types | ||
Listed in priority order | ||
1. Environment variable | ||
1. Configuration store | ||
1. Code | ||
### Available configurations: | ||
- `clientKey` - One Time Access Token used during initialization | ||
- `hostname` - Keeper Backend host. Available values: | ||
- `keepersecurity.com` | ||
- `keepersecurity.eu` | ||
- `keepersecurity.com.au` | ||
- `govcloud.keepersecurity.us` | ||
## 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 | ||
```bash | ||
sm share add --app [NAME] --secret [UID2] | ||
sm share add --app [NAME] --secret [UID3] --editable | ||
``` | ||
### Retrieve secret(s) | ||
```golang | ||
secretsManager := ksm.NewSecretsManagerFromConfig(ksm.NewFileKeyValueStorage("client-config.json")) | ||
allSecrets, _ := secretsManager.GetSecrets([]string{}) | ||
``` | ||
### Update secret | ||
```golang | ||
secretToUpdate = allSecrets[0] | ||
secretToUpdate.SetPassword("NewPassword123$") | ||
secretsManager.Save(secretToUpdate) | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
package core | ||
|
||
import ( | ||
"os" | ||
"strings" | ||
) | ||
|
||
const defautFilePath = "cache.dat" | ||
|
||
type ICache interface { | ||
SaveCachedValue(data []byte) error | ||
GetCachedValue() ([]byte, error) | ||
Purge() error | ||
} | ||
|
||
// File based cache | ||
type fileCache struct { | ||
FilePath string | ||
} | ||
|
||
func (c *fileCache) SaveCachedValue(data []byte) error { | ||
if data == nil { | ||
data = []byte{} | ||
} | ||
return os.WriteFile(c.FilePath, data, 0600) | ||
} | ||
|
||
func (c *fileCache) GetCachedValue() ([]byte, error) { | ||
return os.ReadFile(c.FilePath) | ||
} | ||
|
||
func (c *fileCache) Purge() error { | ||
return os.Remove(c.FilePath) | ||
} | ||
|
||
func NewFileCache(filePath string) *fileCache { | ||
path := strings.TrimSpace(filePath) | ||
if path == "" { | ||
path = defautFilePath | ||
} | ||
return &fileCache{FilePath: path} | ||
} | ||
|
||
// Memory based cache | ||
type memoryCache struct { | ||
cache []byte | ||
} | ||
|
||
func (c *memoryCache) SaveCachedValue(data []byte) error { | ||
c.cache = []byte{} // always erase old value | ||
if len(data) > 0 { | ||
bytes := make([]byte, len(data)) | ||
copy(bytes, data) | ||
c.cache = bytes | ||
} | ||
return nil | ||
} | ||
|
||
func (c *memoryCache) GetCachedValue() ([]byte, error) { | ||
return c.cache, nil | ||
} | ||
|
||
func (c *memoryCache) Purge() error { | ||
c.cache = []byte{} | ||
return nil | ||
} | ||
|
||
func NewMemoryCache() *memoryCache { | ||
return &memoryCache{cache: []byte{}} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package core | ||
|
||
type ConfigKey string | ||
|
||
const ( | ||
KEY_URL ConfigKey = "url" // base URL for the Secrets Manager service | ||
KEY_SERVER_PUBLIC_KEY_ID ConfigKey = "serverPublicKeyId" | ||
KEY_CLIENT_ID ConfigKey = "clientId" | ||
KEY_CLIENT_KEY ConfigKey = "clientKey" // The key that is used to identify the client before public key | ||
KEY_APP_KEY ConfigKey = "appKey" // The application key with which all secrets are encrypted | ||
KEY_PRIVATE_KEY ConfigKey = "privateKey" // The client's private key | ||
KEY_PUBLIC_KEY ConfigKey = "publicKey" // The client's public key | ||
KEY_HOSTNAME ConfigKey = "hostname" // base hostname for the Secrets Manager service | ||
) | ||
|
||
func GetConfigKey(value string) ConfigKey { | ||
switch value { | ||
case string(KEY_URL): | ||
return KEY_URL | ||
case string(KEY_SERVER_PUBLIC_KEY_ID): | ||
return KEY_SERVER_PUBLIC_KEY_ID | ||
case string(KEY_CLIENT_ID): | ||
return KEY_CLIENT_ID | ||
case string(KEY_CLIENT_KEY): | ||
return KEY_CLIENT_KEY | ||
case string(KEY_APP_KEY): | ||
return KEY_APP_KEY | ||
case string(KEY_PRIVATE_KEY): | ||
return KEY_PRIVATE_KEY | ||
case string(KEY_PUBLIC_KEY): | ||
return KEY_PUBLIC_KEY | ||
case string(KEY_HOSTNAME): | ||
return KEY_HOSTNAME | ||
default: | ||
return "" | ||
} | ||
} |
Oops, something went wrong.