# Go SDK

<figure><img src="https://762006384-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MJXOXEifAmpyvNVL1to%2Fuploads%2FrchyeRDPG2Xdsuhp7AmG%2FKSM%20%2B%20GO%20Icon.png?alt=media&#x26;token=aae27885-c9be-4aed-ac90-edf299ac69ac" alt=""><figcaption></figcaption></figure>

## Download and Installation

### Install from GitHub

Find the latest Go SDK release at: <https://github.com/Keeper-Security/secrets-manager-go>

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

For more information, see <https://pkg.go.dev/github.com/keeper-security/secrets-manager-go/core>

### Source Code

Find the Go source code in the [GitHub repository](https://github.com/keeper-security/secrets-manager-go)

## Using the SDK

### Initialize

{% hint style="info" %}
Using token only to generate a new config (for later usage) requires at least one read operation to bind the token and fully populate `config.json`
{% endhint %}

In order to retrieve secrets, you must first initialize the secrets manager client.

```go
package main

import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)

func main() {
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	// Using token only to generate a config (for later usage)
	// requires at least one access operation to bind the token
	//sm.GetSecrets([]string{})
}
```

| Parameter        | Type               | Required | Default | Description                                      |
| ---------------- | ------------------ | -------- | ------- | ------------------------------------------------ |
| `token`          | `string`           | Yes      |         | Keeper Secrets Manager One time token            |
| `hostName`       | `string`           | Yes      |         | Server to connect to                             |
| `verifySslCerts` | `bool`             | yes      |         | Choose whether to verify SSL certificates or not |
| `config`         | `IKeyValueStorage` | yes      |         | File Storage Configuration                       |

The `NewSecretsManager` function will initialize Secrets Manager from provided parameters and store settings from `ClientOptions` struct.

```go
secretsManager := NewSecretsManager(options)
```

### Retrieve Secrets

```go
records, err := sm.GetSecrets([]string{})
```

| Parameter | Type       | Required | Default     | Description        |
| --------- | ---------- | -------- | ----------- | ------------------ |
| `uids`    | `[]string` | Yes      | Empty slice | Record UIDs to get |

**Response**

Type: `[]*Record`

Records with the specified UIDs, or all records shared with the Secrets Manager client if no UIDs are provided

**Example Usage**

Retrieve all Secrets

```go
package main

import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)

func main() {
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	allRecords, err := sm.GetSecrets([]string{})
}

```

Retrieve Secrets with a Filter

```go
package main

import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)

func main() {
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	records, err := sm.GetSecrets([]string{"[Secret UID]"})
}
```

### Retrieve Secrets by Title

```go
// get all matching records
GetSecretsByTitle(recordTitle string) (records []*Record, err error)

// get only the first matching record
GetSecretByTitle(recordTitle string) (records *Record, err error)
```

<table><thead><tr><th width="178.10385756676556">Parameter</th><th width="226.46137991694417">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>recordTitle</code></td><td><code>string</code></td><td>Yes</td><td>Record title to search for</td></tr></tbody></table>

**Example Usage**

```go
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 the first matching record by title
	aRecord, _ := ksm.GetSecretByTitle("My Credentials")

	// Retrieve all matching records by title
	allRecords, _ := ksm.GetSecretsByTitle("My Credentials")
	for _, record := range allRecords {
		println("UID", record.Uid, ", title [", record.Title(), "]")
	}
}
```

### Get Values From a Secret

**Get a Password**

{% tabs %}
{% tab title="Get Password" %}

```go
secret.GetFieldsByType("password")
```

{% endtab %}

{% tab title="Example Usage" %}

```go
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	
	// Get all records
	allRecords, err := sm.GetSecrets([]string{})
	if err != nil {
		println("Error retrieving all records: ", err.Error())
		os.Exit(1)
	}

	// Get first record
	firstRecord := allRecords[0]

	// Get first field in a record of type password
	passwordField := map[string]interface{}{}
	if passwordFields := firstRecord.GetFieldsByType("password"); len(passwordFields) > 0 {
		passwordField = passwordFields[0]
	}

```

{% endtab %}
{% endtabs %}

Field types are based on the Keeper [Record Type](https://app.gitbook.com/s/-LO5CAzpxoaEquZJBpYz/record-types). For a detailed list of available fields based on the Keeper Record Type, see the [record-type-info](https://docs.keeper.io/en/keeperpam/commander-cli/command-reference/record-commands/record-type-commands#record-type-info-command) command in Keeper Commander.

#### Retrieve Values using Keeper Notation

{% tabs %}
{% tab title="Get Notation" %}

```go
sm.GetNotation(query)
```

{% endtab %}

{% tab title="Example Usage" %}

```go
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)

	// Get password from record with the given UID
	value, err := sm.GetNotation("[Record UID]/field/password")
	if err == nil && len(value) > 0 {
		if password, ok := value[0].(string); ok {
			println("Successfully retrieved field value using notation")
		}
	}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
See [Keeper Notation documentation](https://docs.keeper.io/en/keeperpam/secrets-manager/about/keeper-notation) to learn about Keeper Notation format and capabilities
{% endhint %}

<table data-header-hidden><thead><tr><th width="150">Parameter</th><th width="150">Type</th><th width="150">Required</th><th width="150">Default</th><th>Description</th></tr></thead><tbody><tr><td>Parameter</td><td>Type</td><td>Required</td><td>Default</td><td>Description</td></tr><tr><td><code>query</code></td><td><code>String</code></td><td>Yes</td><td></td><td>Keeper Notation query for getting a value from a specified field</td></tr></tbody></table>

#### Returns

Type: `[]interface{}`

The value of the queried field

#### Retrieve TOTP Code

{% tabs %}
{% tab title="Get TOTP Code" %}

```go
GetTotpCode(url)
```

{% endtab %}

{% tab title="Example Usage" %}

```go
clientOptions := &ksm.ClientOptions{
	Token:  "[One Time Access Token]",
	Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(clientOptions)

// Get all records
allRecords, err := sm.GetSecrets([]string{})
if err == nil {
	// Get TOTP url from record
	urls, err := sm.GetNotation("[Record UID]/field/OneTimeCode")
	if err == nil && len(urls) == 1 {
		// Get TOTP code from url
		url := urls[0].(string)
		totp, err := ksm.GetTotpCode(url)
		if err == nil {
			println(totp.Code, totp.TimeLeft)
		}
	}
}
```

{% endtab %}
{% endtabs %}

<table data-header-hidden><thead><tr><th width="150">Parameter</th><th width="150">Type</th><th width="150">Required</th><th width="150">Default</th><th>Description</th></tr></thead><tbody><tr><td>Parameter</td><td>Type</td><td>Required</td><td>Default</td><td>Description</td></tr><tr><td><code>url</code></td><td><code>string</code></td><td>Yes</td><td></td><td>TOTP Url</td></tr></tbody></table>

### Update a Secret

{% hint style="warning" %}
Record update commands don't update local record data on success *(esp. updated record revision)* so any consecutive updates to an already updated record will fail due to **revision** mismatch. Make sure to reload all updated records after each update batch.
{% endhint %}

**Update Password**

```go
(r *Record) SetPassword(password string) 
```

| Parameter  | Type     | Required | Default | Description                       |
| ---------- | -------- | -------- | ------- | --------------------------------- |
| `password` | `string` | Yes      |         | New password to set to the record |

**Update Other Fields**

```go
(r *Record) SetFieldValueSingle(field string, value string) 
```

| Parameter | Type     | Required | Default | Description                 |
| --------- | -------- | -------- | ------- | --------------------------- |
| `field`   | `string` | Yes      |         | name of the field to update |
| `value`   | `string` | Yes      |         | Value to set the field to   |

**Update Secret in Vault**

Save the record to make the changes made appear in the&#x20;

```go
(c *secretsManager) Save(record *Record) (err error) 
```

| Parameter | Type           | Required | Default | Description                                   |
| --------- | -------------- | -------- | ------- | --------------------------------------------- |
| `record`  | `KeeperRecord` | Yes      |         | Record with updated field to save changes for |

**Example Usage**

Update Password

```go
package main

import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)

func main() {
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	records, err := sm.GetSecrets([]string{"[Record UID]"})

	// get record to update
	record := records[0]

	// set new password
	record.SetPassword("NewPassword123$")

	// save changes
	ksm.Save(record)

	// Transactional updates
	// rotate password on the record
	record.SetPassword("NewPassword1234$")
	// start a transaction
	ksm.SaveBeginTransaction(secret, ksm.TransactionTypeRotation)
	// rotate password on remote host
	success := rotateRemoteSshPassword("NewPassword1234$")
	// complete the transaction - commit or rollback
	ksm.CompleteTransaction(secret.Uid, !success)
}
```

Update other fields

```go
package main

import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)

func main() {
	clientOptions := &ksm.ClientOptions{
		Token:  "[One Time Access Token]",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(clientOptions)
	records, err := sm.GetSecrets([]string{"[Record UID]"})

	// get record to update
	record := records[0]

	// set login field to a new value
	record.SetFieldValueSingle("login", "New Login Value")
	
	// update title and notes
	record.SetTitle("New Title")
	record.SetNotes("New Notes")

	// save changes
	sm.Save(record)
}
```

Each record field type is represented by a class.  Cast the field to the corresponding class in order to correctly access the field's value.  Check the [Record Types](https://app.gitbook.com/s/-LO5CAzpxoaEquZJBpYz/record-types) documentation for a list of field types.

#### Generate a Random Password

{% tabs %}
{% tab title="Generate Password" %}

```go
GeneratePassword(length, lowercase, uppercase, digits, specialCharaters)
```

{% endtab %}

{% tab title="Example Usage" %}

```go
// get a record
allRecords, err := sm.GetSecrets([]string{})
record := allRecords[0]
// generate a random password
password := GeneratePassword(64, 0,0,0,0)
// updaterecord with new password
record.SetPassword(password)
```

{% endtab %}
{% endtabs %}

<table><thead><tr><th width="223.7142857142857">Parameter</th><th width="150">Type</th><th width="150">Required</th><th>Default</th></tr></thead><tbody><tr><td><code>length</code></td><td><code>int</code></td><td>Yes</td><td></td></tr><tr><td><code>lowercase</code></td><td><code>int</code></td><td>Yes</td><td></td></tr><tr><td><code>uppercase</code></td><td><code>int</code></td><td>Yes</td><td></td></tr><tr><td><code>digits</code></td><td><code>int</code></td><td>Yes</td><td></td></tr><tr><td><code>specialCharacters</code></td><td><code>int</code></td><td>Yes</td><td></td></tr></tbody></table>

Each parameter indicates the minimum number of a type of character to include. For example, `uppercase` indicates the minimum uppercase letters to include.

### Download a File

```go
(r *Record) DownloadFileByTitle(title string, path string) bool
```

| Parameter | Type     | Required | Default | Description              |
| --------- | -------- | -------- | ------- | ------------------------ |
| `title`   | `string` | Yes      |         | Name of file to download |
| `path`    | `string` | Yes      |         | Path to save the file to |

**Response**

Type: `bool`

Did the file save succeed

**Example Usage**

```go
import (	
    ksm "github.com/keeper-security/secrets-manager-go/core"	
)
clientOptions := &ksm.ClientOptions{
	Token:  "[One Time Access Token]",
	Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
sm := ksm.NewSecretsManager(clientOptions)

// get record to update
record, err := sm.GetSecrets([]string{"[Record UID]"})

// download a file attached to the record
record.DownloadFileByTitle("certs.txt","secret_files/certs.txt")
```

### Upload a File

```go
UploadFile(record *Record, file *KeeperFileUpload) (uid string, err error)
```

<table><thead><tr><th width="184.14763231197773">Parameter</th><th width="206.99431983802478">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>ownerRecord</code></td><td><code>Record</code></td><td>Yes</td><td>The record to attach the uploaded file to</td></tr><tr><td><code>file</code></td><td><code>KeeperFileUpload</code></td><td>Yes</td><td>The File to upload</td></tr></tbody></table>

```go
type KeeperFileUpload struct {
	Name  string
	Title string
	Type  string
	Data  []byte
}
```

<table><thead><tr><th width="169">Parameter</th><th width="150">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>name</code></td><td><code>string</code></td><td>Yes</td><td>What the name of the file will be in Keeper once uploaded</td></tr><tr><td><code>title</code></td><td><code>string</code></td><td>Yes</td><td>What the title of the file will be in Keeper once uploaded</td></tr><tr><td><code>type</code></td><td><code>string</code></td><td>Yes</td><td>The mime type of data in the file.  'application/octet-stream' for example</td></tr><tr><td><code>data</code></td><td><code>[]byte</code></td><td>Yes</td><td>File data as bytes</td></tr></tbody></table>

**Example Usage**

```go
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)

	// Get a record to upload the file to
	allRecords, _ := sm.GetSecrets([]string{"[Record UID]"})
	ownerRecord := allRecords[0]
	
	// get file data and prepare for upload
	dat, err := ioutil.ReadFile("/myFile.json")
	var myFile := KeeperFileUpload{
		Name: "myFile.json",
		Title: "My File",
		Type: "application/json",
		Data: dat
	}
	
	// upload file to selected record
	sm.UploadFile(ownerRecord, myFile)
}
```

### Create a Secret

#### Prerequisites:

* Shared folder UID
  * Shared folder must be accessible by the Secrets Manager Application
  * You and the Secrets Manager application must have edit permission
  * There must be at least one record in the shared folder
* Created records and record fields must be formatted correctly
  * See the [documentation](https://app.gitbook.com/s/-LO5CAzpxoaEquZJBpYz/record-types) for expected field formats for each record type
* TOTP fields accept only URL generated outside of the KSM SDK
* After record creation, you can upload file attachments using [UploadFile](#upload-a-file)

{% tabs %}
{% tab title="Create a Record" %}

<pre class="language-go"><code class="lang-go"><strong>secretsManager.CreateSecretWithRecordData(recordUid, folderUid, record)
</strong></code></pre>

| Parameter    | Type            | Required | Default                   |
| ------------ | --------------- | :------: | ------------------------- |
| `recordUid`  | `string`        |    No    | auto generated random UID |
| `folderUid`  | `string`        |    Yes   |                           |
| `record`     | `*RecordCreate` |    Yes   |                           |
| {% endtab %} |                 |          |                           |

{% tab title="Create Record in Sub-folder" %}

<pre class="language-go"><code class="lang-go"><strong>secretsManager.CreateSecretWithRecordDataAndOptions(createOptions, recordData, folders)
</strong></code></pre>

| Parameter       | Type              | Required | Default |
| --------------- | ----------------- | :------: | ------- |
| `createOptions` | `CreateOptions`   |    Yes   |         |
| `recordData`    | `*RecordCreate`   |    Yes   |         |
| `folders`       | `[]*KeeperFolder` |    No    |         |
| {% endtab %}    |                   |          |         |

{% tab title="Login Record Example" %}
This example creates a login type record with a login value and a generated password.

{% hint style="info" %}
Replace `[FOLDER UID]` in the example with the UID of a shared folder that your Secrets Manager has access to.
{% endhint %}

```go
// create a new login record
newLoginRecord := NewRecordCreate("login", "Sample KSM Record: Go SDK")
// fill in login and password fields
password, _ := GeneratePassword(32,0,0,0,0)
newLoginRecord.Fields = append(newLoginRecord.Fields,
    NewLogin("username@email.com"),
    NewPassword(password))
// fill in notes
newLoginRecord.Notes = "This is a Go record creation example"
// create the new record 
recordUid, err := secretsManager.CreateSecretWithRecordData("", "[FOLDER UID]", newLoginRecord)
```

{% endtab %}

{% tab title="Custom Type Example" %}
{% hint style="info" %}
Replace `[FOLDER UID]` in the example with the UID of a shared folder that your Secrets Manager has access to.
{% endhint %}

This example creates a record with a custom record type.

```go
customLogin := ksm.NewRecordCreate("Custom Login", "Sample Custom Type KSM Record: Go SDK")
password, _ := ksm.GeneratePassword(32, 0, 0, 0, 0)
customLogin.Fields = append(customLogin.Fields,
	ksm.NewHosts(ksm.Host{Hostname: "127.0.0.1", Port: "8080"}),
	ksm.NewLogin("login@email.com"),
	ksm.NewPassword(password),
	ksm.NewUrl("http://localhost:8080/login"),
	ksm.NewSecurityQuestions(ksm.SecurityQuestion{Question: "What is one plus one (write just a number)", Answer: "2"}),
	ksm.NewPhones(ksm.Phone{Region: "US", Number: "510-444-3333", Ext: "2345", Type: "Mobile"}),
	ksm.NewDate(1641934793000),
	ksm.NewNames(ksm.Name{First: "John", Middle: "Patrick", Last: "Smith"}),
	ksm.NewOneTimeCode("otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example"),
)
customLogin.Custom = append(customLogin.Custom,
	ksm.NewPhones(ksm.Phone{Region: "US", Number: "510-222-5555", Ext: "99887", Type: "Mobile"}),
	ksm.NewPhones(ksm.Phone{Region: "US", Number: "510-111-3333", Ext: "45674", Type: "Mobile"}),
)
customLogin.Notes = "\tThis custom type record was created\n\tvia Go SDK copied from https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/golang-sdk"
recordUid, err := sm.CreateSecretWithRecordData("", "[FOLDER UID]", customLogin)
```

{% endtab %}
{% endtabs %}

### Delete a Secret

The Go KSM SDK can delete records in the Keeper Vault.

{% tabs %}
{% tab title="Delete Secret" %}

```go
secretsManager.DeleteSecrets(recordUids)
```

| Parameter    | Type       | Required |
| ------------ | ---------- | :------: |
| `recordUids` | `[]string` |    Yes   |
| {% endtab %} |            |          |

{% tab title="Example" %}

```go
import ksm "github.com/keeper-security/secrets-manager-go/core"

func main() {
	// setup secrets manager
	options := &ksm.ClientOptions{
		// Token:  "<One Time Access Token>",
		Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	secretsManager := ksm.NewSecretsManager(options)
	
	// delete a specific secret by record UID
	secrets, err = secretsManager.DeleteSecrets([]string{"EG6KdJaaLG7esRZbMnfbFA"})
}
```

{% endtab %}
{% endtabs %}

### Caching

To protect against losing access to your secrets when network access is lost, the Go SDK allows caching of secrets to the local machine in an encrypted file.

**Setup and Configure Cache**

In order to setup caching in the Go SDK, use the function `SetCache(cache ICache)` to set the cache to either one of the built-in memory or file based caches or use your own implementation.

```go
type ICache interface {
	SaveCachedValue(data []byte) error
	GetCachedValue() ([]byte, error)
	Purge() error
}
```

The Go SDK includes a memory based cache and a file based cache for convenience.

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

// Memory based cache
memCache := ksm.NewMemoryCache()
sm.SetCache(memCache)

// File based cache
fileCache := ksm.NewFileCache("ksm_cache.bin")
sm.SetCache(fileCache)
```

### Folders

Folders have full CRUD support - create, read, update and delete operations.

### Read Folders

Downloads full folder hierarchy.

```go
GetFolders() ([]*KeeperFolder, error)
```

**Response**

Type: `[]*KeeperFolder, error`

**Example Usage**

```go
package main

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

func main() {
	options := &ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(options)
	folders, err := sm.GetFolders()
}
```

### Create a Folder

Requires `CreateOptions` and folder name to be provided. The folder UID parameter in `CreateOptions` is required - UID of a shared folder, while sub-folder UID is optional and if missing new regular folder is created directly under the parent (shared folder). There's no requirement for the sub-folder to be a direct descendant of the parent shared folder - it could be many levels deep.

```go
CreateFolder(createOptions CreateOptions, folderName string, folders []*KeeperFolder) (folderUid string, err error)
```

<table><thead><tr><th width="209.85161529417937">Parameter</th><th width="206.99431983802478">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>createOptions</code></td><td><code>CreateOptions</code></td><td>Yes</td><td>The parent and sub-folder UIDs</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>Yes</td><td>The Folder name</td></tr><tr><td><code>folders</code></td><td><code>[]*KeeperFolder</code></td><td>No</td><td>List of folders to use in the search for parent and sub-folder from CreateOptions </td></tr></tbody></table>

```go
type CreateOptions struct {
	FolderUid    string
	SubFolderUid string
}
```

```go
type KeeperFolder struct {
	FolderKey []byte
	FolderUid string
	ParentUid string
	Name      string
}
```

**Example Usage**

```go
package main

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

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

	co := ksm.CreateOptions{FolderUid: "[PARENT_SHARED_FOLDER_UID]", SubFolderUid: ""}
	uid, err := sm.CreateFolder(co, "new_folder", nil)
}
```

### Update a Folder

Updates the folder metadata - currently folder name only.

```go
UpdateFolder(folderUid, folderName string, folders []*KeeperFolder) (err error)
```

<table><thead><tr><th width="209.85161529417937">Parameter</th><th width="206.99431983802478">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>folderUid</code></td><td><code>string</code></td><td>Yes</td><td>The folder UID</td></tr><tr><td><code>folderName</code></td><td><code>string</code></td><td>Yes</td><td>The new folder name</td></tr><tr><td><code>folders</code></td><td><code>[]*KeeperFolder</code></td><td>No</td><td>List of folders to use in the search for parent folder</td></tr></tbody></table>

**Example Usage**

```go
package main

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

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

	err := sm.UpdateFolder("[FOLDER_UID]", "new_folder_name", nil)
}
```

### Delete Folders

Removes a list of folders. Use `forceDeletion` flag to remove non-empty folders.

{% hint style="info" %}
When using forceDeletion avoid sending parent with its children folder UIDs. Depending on the delete order you may get an error - *ex.* if parent force-deleted child first. There's no guarantee that list will always be processed in FIFO order.
{% endhint %}

{% hint style="info" %}
Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.
{% endhint %}

<pre class="language-go"><code class="lang-go"><strong>DeleteFolder(folderUids []string, forceDeletion bool) (statuses map[string]string, err error)
</strong></code></pre>

<table><thead><tr><th width="209.85161529417937">Parameter</th><th width="206.99431983802478">Type</th><th width="150">Required</th><th>Description</th></tr></thead><tbody><tr><td><code>folderUids</code></td><td><code>[]string</code></td><td>Yes</td><td>The folder UID list</td></tr><tr><td><code>forceDeletion</code></td><td><code>bool</code></td><td>Yes</td><td>Force deletion of non-empty folders</td></tr></tbody></table>

**Example Usage**

<pre class="language-go"><code class="lang-go"><strong>package main
</strong>
import ksm "github.com/keeper-security/secrets-manager-go/core"

func main() {
	options := &#x26;ksm.ClientOptions{Config: ksm.NewFileKeyValueStorage("ksm-config.json")}
	sm := ksm.NewSecretsManager(options)

	stats, err := sm.DeleteFolder([]string{"[FOLDER_UID1]", "[FOLDER_UID2]"}, true)
}
</code></pre>
