All pages
Powered by GitBook
1 of 13

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

KSM 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.

Secrets Manager SDKs

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 the use the command.

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 with the following keys:

The following is an example of a generated configuration file:

For more information on configuration files, see the .

Configuration File Protection

Keeper provides several options for the secure encryption and storage of the KSM configuration file using popular cloud services:


Script Integration

Keeper Secrets Manager CLI provides a wrapper function that executes any arbitrary system call and replaces environmental variables with values from the Keeper Vault.

Vault and Admin SDKs

For higher level functionality at the Vault and Administrative level, please see the Vault SDKs page which contains links to various development tools.

Go
  • Ruby

  • Rust

  • PowerShell

  • Application Owner's Public Key

    Oracle Key Vault

    Key

    Description

    hostname

    The destination host where your Enterprise tenant is located:

    • keepersecurity.com

    • keepersecurity.eu

    • keepersecurity.com.au

    • keepersecurity.jp

    • keepersecurity.ca

    • govcloud.keepersecurity.us

    clientID

    The hashed clientKey where clientKey is the Unique Client Device Identifier

    privateKey

    Client Device Private Key

    serverPublicKeyId

    Keeper Infrastructure's Public Key ID

    appKey

    Application Private Key

    Python
    Java / Kotlin
    JavaScript
    .Net
    Commander CLI
    secrets-manager client add
    Config File documentation
    AWS KMS
    Azure Key Vault
    Entrust HSM
    Google Cloud Key Management
    Secrets Manager CLI Exec Command
    Vault SDKs

    appOwnerPublicKey

    My Vault> secrets-manager client add --app MyApplication --unlock-ip
    ksm-config.json
    {
      "hostname": "keepersecurity.com",
      "clientId": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "privateKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "serverPublicKeyId": "10",
      "appKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx",
      "appOwnerPublicKey": "xxxxxxxxxxxxxxxxxxxxxxxxxxx"
    }

    PowerShell

    PowerShell docs for Keeper Secrets Manager

    Features

    • Retrieve secrets from the Keeper Vault to use in PowerShell

    • Integrate Keeper vault with PowerShell Secrets Manager

    • Update secret values in the Keeper Vault from PowerShell

    • Get files from the Keeper vault

    Please refer to the documented in the Integrations section:

    Vault SDKs

    Full Vault SDKs for integration and automation

    If you are looking for SDK capabilities beyond secrets management, Keeper provides other SDKs that can perform vault and administrative functionality.

    Python Commander SDK

    The Keeper Commander SDKs for Python provide programmatic access to the platform, enabling secure management of credentials, secrets, and enterprise resources at scale.

    Python Commander CLI

    The Keeper Commander CLI is an implementation using Python that interfaces with the Keeper vault and Keeper administrative functions. The source code is available below:

    https://github.com/keeper-Security/commander

    .Net Vault SDK

    We also created a .Net based Commander tool with a developer SDK for basic vault access and administrative functions:

    https://github.com/Keeper-Security/keeper-sdk-dotnet

    PowerShell CLI

    Keeper's PowerShell command-line tool ("PowerCommander") provides basic vault access and administrative functions in PowerShell scripts.

    https://github.com/Keeper-Security/keeper-sdk-dotnet/tree/release/PowerCommander For more advanced command line capabilities, please refer to the Python-based Commander CLI.

    GoLang SDK

    The Keeper GoLang SDK is used specifically in our Terraform provider.

    https://github.com/Keeper-Security/keeper-sdk-golang

    https://github.com/Keeper-Security/keeper-sdk-python
    Keeper PowerShell module
    Go to PowerShell Plugin

    Linked Credentials on PAM Records

    Description of each accessible field type on PAM Resource Records

    SDK Version Required: 17.1.1 or higher

    The document lists out the full list of Property methods and advanced use cases when interacting with the linked credentials on PAM Resource Records:

    • All Property Methods

    • Advanced Use Cases

    All Property Methods

    Advanced Use Cases

    Advanced Data Access Patterns

    Encrypted Data Handling

    Settings-Specific Access Methods

    Complex Relationship Analysis

    Advanced PAM User Management

    Comprehensive Linked Record Data Analysis

    Complete Utility Methods Example

    Full Method Reference

    Method
    Returns
    Description

    DAG Concepts for Infrastructure Management

    Understanding Directed Acyclic Graphs

    GraphSync implements a Directed Acyclic Graph structure where:

    • DIRECTED: Links have direction (A → B is different from B → A)

    • ACYCLIC: No circular references (A → B → C → A is NOT allowed)

    • GRAPH: Records (nodes) connected by links (edges)

    Benefits:

    • ✅ Track dependencies ("this server needs this database")

    • ✅ Organize related credentials

    • ✅ Understand infrastructure relationships

    • ✅ Maintain security boundaries

    Performance Optimization

    Efficient Processing Strategies

    Error Handling Best Practices

    Important Implementation Notes

    Critical Understanding

    • Links vs Files: The linksToRemove parameter in UpdateOptions removes FILES, not record links

    • Null vs Empty: Links field is null when requestLinks=false, empty list when requestLinks=true but no links exist

    • Performance Impact: Requesting links significantly increases response size and processing time

    Security Considerations

    • Key Management: Always use the source record's key for decrypting link data

    • Access Control: Link properties indicate what operations are permitted

    • Validation: Always check link properties before performing operations

    Best Practices from Test Implementation

    1. Only request links when needed - Use requestLinks=true judiciously for performance

    2. Filter records when possible - Use recordsFilter to limit data retrieval

    3. Cache results - Build lookup maps for multiple operations on the same data

    Kotlin Support

    isLaunchCredential()

    boolean

    This is a launch credential

    allowsRotation()

    boolean

    Password rotation allowed

    allowsConnections()

    boolean

    Connections allowed

    allowsPortForwards()

    boolean

    Port forwarding allowed

    allowsSessionRecording()

    boolean

    Session recording enabled

    allowsTypescriptRecording()

    boolean

    Typescript recording enabled

    allowsRemoteBrowserIsolation()

    boolean

    Remote browser isolation allowed

    rotatesOnTermination()

    boolean

    Password rotates on session termination

    getLinkDataVersion()

    Integer

    Data format version number

    hasReadableData()

    boolean

    Data is readable JSON format

    hasEncryptedData()

    boolean

    Data is encrypted

    mightBeEncrypted()

    boolean

    Data might be encrypted (heuristic check)

    getDecryptedData(byte[])

    String

    Decrypt data using record key

    getDecodedData()

    String

    Base64 decode without decryption

    getLinkData(byte[])

    Map<String, Object>

    Generic encrypted data access

    getAiSettingsData(byte[])

    Map<String, Object>

    AI settings specific access

    getJitSettingsData(byte[])

    Map<String, Object>

    JIT settings specific access

    getSettingsForPath(String, byte[])

    Map<String, Object>

    Generic settings access by path

  • Encryption: Link data may be encrypted and requires the record's key to decrypt

  • Handle errors gracefully - Link data decryption and access may fail
  • Validate assumptions - Check link properties match expected permissions

  • Test configurations - Verify PAM setups have correct admin/launch credential counts

  • getRecordUid()

    String

    Target record UID

    getPath()

    String

    Link metadata type

    getData()

    String

    Raw Base64-encoded link data

    isAdminUser()

    boolean

    User has admin privileges

    Full Method Reference
    for (KeeperRecordLink link : record.getLinks()) {
        // Basic properties
        String targetUid = link.getRecordUid();
        String linkPath = link.getPath(); // e.g., "pamUser", "ai_settings", "jit_settings"
        String rawData = link.getData(); // Base64-encoded data
    
        // User privilege methods
        boolean isAdmin = link.isAdminUser();
        boolean isLaunchCredential = link.isLaunchCredential();
    
        // Permission methods
        boolean allowsRotation = link.allowsRotation();
        boolean allowsConnections = link.allowsConnections();
        boolean allowsPortForwards = link.allowsPortForwards();
        boolean allowsSessionRecording = link.allowsSessionRecording();
        boolean allowsTypescriptRecording = link.allowsTypescriptRecording();
        boolean allowsRemoteBrowserIsolation = link.allowsRemoteBrowserIsolation();
    
        // Settings methods
        boolean rotatesOnTermination = link.rotatesOnTermination();
        Integer dataVersion = link.getLinkDataVersion();
    
        // Data analysis methods
        boolean hasReadableData = link.hasReadableData();
        boolean hasEncryptedData = link.hasEncryptedData();
        boolean mightBeEncrypted = link.mightBeEncrypted();
    
        System.out.println("Link Analysis for " + targetUid + ":");
        System.out.println("  Path: " + linkPath);
        System.out.println("  Admin: " + isAdmin);
        System.out.println("  Launch Credential: " + isLaunchCredential);
        System.out.println("  Allows Rotation: " + allowsRotation);
        System.out.println("  Allows Connections: " + allowsConnections);
        System.out.println("  Has Encrypted Data: " + hasEncryptedData);
    }
    public void handleEncryptedLinkData(KeeperRecord record) {
        for (KeeperRecordLink link : record.getLinks()) {
            if (link.getData() != null) {
                System.out.println("\nAnalyzing link data for: " + link.getRecordUid());
                System.out.println("  Path: " + (link.getPath() != null ? link.getPath() : "null"));
    
                // Check encryption status
                boolean mightBeEncrypted = link.mightBeEncrypted();
                boolean hasEncryptedData = link.hasEncryptedData();
                boolean hasReadableData = link.hasReadableData();
    
                System.out.println("  Encryption Analysis:");
                System.out.println("    mightBeEncrypted(): " + mightBeEncrypted);
                System.out.println("    hasEncryptedData(): " + hasEncryptedData);
                System.out.println("    hasReadableData(): " + hasReadableData);
    
                try {
                    if (hasEncryptedData || mightBeEncrypted) {
                        // Method 1: Use getDecryptedData for encrypted content
                        String decryptedData = link.getDecryptedData(record.getRecordKey());
                        System.out.println("    Decrypted Data: " + decryptedData);
    
                        // Method 2: Use getLinkData for structured access
                        Map<String, Object> linkData = link.getLinkData(record.getRecordKey());
                        if (linkData != null) {
                            System.out.println("    Structured Data:");
                            for (Map.Entry<String, Object> entry : linkData.entrySet()) {
                                System.out.println("      " + entry.getKey() + ": " + entry.getValue());
                            }
                        }
                    } else {
                        // Plain base64 data
                        String plainData = link.getDecodedData();
                        System.out.println("    Plain Data: " + plainData);
                    }
    
                } catch (Exception e) {
                    System.out.println("    Error processing data: " + e.getMessage());
                    System.out.println("    Raw Base64: " + link.getData());
                }
            }
        }
    }
    public void demonstrateSettingsDataMethods(SecretsManagerOptions options) throws Exception {
        QueryOptions queryOptions = new QueryOptions(
            Collections.emptyList(),
            Collections.emptyList(),
            true
        );
    
        KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
        System.out.println("Settings Data Methods Demo:");
        boolean foundSettings = false;
    
        for (KeeperRecord record : secrets.getRecords()) {
            if (record.getLinks() != null && !record.getLinks().isEmpty()) {
                System.out.println("\nRecord: " + record.getTitle() + " (" + record.getType() + ")");
    
                for (KeeperRecordLink link : record.getLinks()) {
                    String linkPath = link.getPath();
                    System.out.println("  Link to " + link.getRecordUid() + " (path: " + linkPath + ")");
    
                    // Test AI Settings method
                    if ("ai_settings".equals(linkPath)) {
                        foundSettings = true;
                        System.out.println("    Testing getAiSettingsData():");
                        try {
                            Map<String, Object> aiSettings = link.getAiSettingsData(record.getRecordKey());
                            if (aiSettings != null) {
                                System.out.println("      AI Settings found:");
                                for (Map.Entry<String, Object> entry : aiSettings.entrySet()) {
                                    System.out.println("        " + entry.getKey() + ": " + entry.getValue());
                                }
                            } else {
                                System.out.println("      AI Settings data could not be parsed");
                            }
                        } catch (Exception e) {
                            System.out.println("      Error parsing AI settings: " + e.getMessage());
                        }
                    }
    
                    // Test JIT Settings method
                    if ("jit_settings".equals(linkPath)) {
                        foundSettings = true;
                        System.out.println(" Testing getJitSettingsData():");
                        try {
                            Map<String, Object> jitSettings = link.getJitSettingsData(record.getRecordKey());
                            if (jitSettings != null) {
                                System.out.println("   JIT Settings found:");
                                for (Map.Entry<String, Object> entry : jitSettings.entrySet()) {
                                    System.out.println("        " + entry.getKey() + ": " + entry.getValue());
                                }
                            } else {
                                System.out.println("       JIT Settings data could not be parsed");
                            }
                        } catch (Exception e) {
                            System.out.println("   Error parsing JIT settings: " + e.getMessage());
                        }
                    }
    
                    // Test generic getSettingsForPath method
                    if (linkPath != null && linkPath.endsWith("_settings")) {
                        foundSettings = true;
                        System.out.println("  Testing getSettingsForPath(\"" + linkPath + "\"):");
                        try {
                            Map<String, Object> settings = link.getSettingsForPath(linkPath, record.getRecordKey());
                            if (settings != null) {
                                System.out.println("   Settings found for path '" + linkPath + "':");
                                for (Map.Entry<String, Object> entry : settings.entrySet()) {
                                    System.out.println("        " + entry.getKey() + ": " + entry.getValue());
                                }
                            } else {
                                System.out.println("       Settings data could not be parsed");
                            }
                        } catch (Exception e) {
                            System.out.println("   Error parsing settings: " + e.getMessage());
                        }
                    }
                }
            }
        }
    
        if (!foundSettings) {
            System.out.println(" No settings paths found in current records.");
            System.out.println(" Settings paths to look for: ai_settings, jit_settings, *_settings");
        }
    }
    public class ComprehensiveDagAnalyzer {
    
        public static void analyzeLinkingPatterns(SecretsManagerOptions options) throws Exception {
            QueryOptions queryOptions = new QueryOptions(
                Collections.emptyList(),
                Collections.emptyList(),
                true // requestLinks
            );
    
            KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
            // Build relationship map
            Map<String, List<String>> relationshipMap = new HashMap<>();
            Map<String, String> recordTitles = new HashMap<>();
            Map<String, String> recordTypes = new HashMap<>();
            int totalLinks = 0;
    
            for (KeeperRecord record : secrets.getRecords()) {
                recordTitles.put(record.getRecordUid(), record.getTitle());
                recordTypes.put(record.getRecordUid(), record.getType());
    
                List<KeeperRecordLink> links = record.getLinks();
                if (links != null && !links.isEmpty()) {
                    List<String> targets = new ArrayList<>();
                    for (KeeperRecordLink link : links) {
                        targets.add(link.getRecordUid());
                        totalLinks++;
                    }
                    relationshipMap.put(record.getRecordUid(), targets);
                }
            }
    
            System.out.println("DAG Analysis Report:");
            System.out.println("===================");
            System.out.println("Total records: " + secrets.getRecords().size());
            System.out.println("Records with outgoing links: " + relationshipMap.size());
            System.out.println("Total links: " + totalLinks);
    
            // Find records that are targets (have incoming links)
            Set<String> targets = new HashSet<>();
            for (List<String> linkTargets : relationshipMap.values()) {
                targets.addAll(linkTargets);
            }
            System.out.println("Records that are link targets: " + targets.size());
    
            // Show detailed relationship patterns
            if (!relationshipMap.isEmpty()) {
                System.out.println("\nDetailed Relationship Patterns:");
                for (Map.Entry<String, List<String>> entry : relationshipMap.entrySet()) {
                    String sourceTitle = recordTitles.get(entry.getKey());
                    String sourceType = recordTypes.get(entry.getKey());
                    System.out.println("  " + sourceTitle + " [" + sourceType + "] → " + entry.getValue().size() + " record(s)");
    
                    for (String targetUid : entry.getValue()) {
                        String targetTitle = recordTitles.get(targetUid);
                        String targetType = recordTypes.get(targetUid);
                        System.out.println("    → " + (targetTitle != null ? targetTitle : "Unknown record: " + targetUid) +
                            " [" + (targetType != null ? targetType : "Unknown") + "]");
                    }
                }
            } else {
                System.out.println("  No links found in current records.");
            }
        }
    }
    public static List<UserStatus> getPamMachineUsers(String pamMachineUid, InMemoryStorage storage) {
        List<UserStatus> users = new ArrayList<>();
    
        try {
            QueryOptions queryOptions = new QueryOptions(
                Collections.emptyList(),
                Collections.emptyList(),
                true // requestLinks
            );
    
            SecretsManagerOptions options = new SecretsManagerOptions(storage);
            KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
            // Find the PAM Machine record
            KeeperRecord pamMachine = null;
            for (KeeperRecord record : secrets.getRecords()) {
                if (record.getRecordUid().equals(pamMachineUid) && "pamMachine".equals(record.getType())) {
                    pamMachine = record;
                    break;
                }
            }
    
            if (pamMachine != null && pamMachine.getLinks() != null) {
                System.out.println("PAM Machine: " + pamMachine.getTitle());
                System.out.println("Number of users associated with this PAM machine: " + pamMachine.getLinks().size());
    
                for (KeeperRecordLink link : pamMachine.getLinks()) {
                    // Find the linked user record
                    for (KeeperRecord record : secrets.getRecords()) {
                        if (record.getRecordUid().equals(link.getRecordUid()) && "pamUser".equals(record.getType())) {
                            // Use SDK utility method to check admin status
                            boolean isAdmin = link.isAdminUser();
                            boolean isLaunchCredential = link.isLaunchCredential();
    
                            users.add(new UserStatus(record.getTitle(), record.getRecordUid(), isAdmin, isLaunchCredential));
                            System.out.println("  " + record.getTitle() + " - [" + (isAdmin ? "IS ADMIN" : "IS NOT ADMIN") + "] [" +
                                             (isLaunchCredential ? "IS LAUNCH CREDENTIAL" : "IS NOT LAUNCH CREDENTIAL") + "]");
                            break;
                        }
                    }
                }
    
                // Validate PAM configuration (from your test logic)
                long adminUsersCount = users.stream().filter(UserStatus::isAdmin).count();
                long launchCredentialUsersCount = users.stream().filter(UserStatus::isLaunchCredential).count();
    
                System.out.println("Summary:");
                System.out.println("  Admin users: " + adminUsersCount);
                System.out.println("  Launch credential users: " + launchCredentialUsersCount);
    
                if (adminUsersCount > 1) {
                    System.out.println("Warning: Multiple admin users found - should typically be 1");
                }
                if (launchCredentialUsersCount > 1) {
                    System.out.println("Warning: Multiple launch credentials - should typically be 1");
                }
            }
    
        } catch (Exception e) {
            System.err.println("Error retrieving PAM machine users: " + e.getMessage());
        }
    
        return users;
    }
    
    public static class UserStatus {
        private final String userName;
        private final String userUid;
        private final boolean isAdmin;
        private final boolean isLaunchCredential;
    
        public UserStatus(String userName, String userUid, boolean isAdmin, boolean isLaunchCredential) {
            this.userName = userName;
            this.userUid = userUid;
            this.isAdmin = isAdmin;
            this.isLaunchCredential = isLaunchCredential;
        }
    
        public String getUserName() { return userName; }
        public String getUserUid() { return userUid; }
        public boolean isAdmin() { return isAdmin; }
        public boolean isLaunchCredential() { return isLaunchCredential; }
    
        @Override
        public String toString() {
            return userName + " (" + userUid + ") - [" +
                   (isAdmin ? "IS ADMIN" : "IS NOT ADMIN") + "] [" +
                   (isLaunchCredential ? "IS LAUNCH CREDENTIAL" : "IS NOT LAUNCH CREDENTIAL") + "]";
        }
    }
    public static void analyzeLinkDataStructure(SecretsManagerOptions options) throws Exception {
        QueryOptions queryOptions = new QueryOptions(
            Collections.emptyList(),
            Collections.emptyList(),
            true
        );
    
        KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
        System.out.println("Link Data Structure Analysis:");
        for (KeeperRecord record : secrets.getRecords()) {
            if (record.getLinks() != null && !record.getLinks().isEmpty()) {
                System.out.println("\nRecord: " + record.getTitle() + " (" + record.getType() + ")");
                System.out.println("UID: " + record.getRecordUid());
    
                for (int i = 0; i < record.getLinks().size(); i++) {
                    KeeperRecordLink link = record.getLinks().get(i);
                    System.out.println("  Link " + (i + 1) + ":");
                    System.out.println("    Target UID: " + link.getRecordUid());
                    System.out.println("    Path: " + (link.getPath() != null ? link.getPath() : "null"));
    
                    if (link.getData() != null) {
                        try {
                            if (link.hasEncryptedData() || link.mightBeEncrypted()) {
                                String decodedData = link.getDecryptedData(record.getRecordKey());
                                System.out.println("    Decoded Data: " + decodedData);
                            } else {
                                String decodedData = link.getDecodedData();
                                System.out.println("    Decoded Data: " + decodedData);
                            }
                        } catch (Exception e) {
                            System.out.println("    Raw Base64: " + link.getData());
                            System.out.println("    Decode Error: " + e.getMessage());
                        }
                    } else {
                        System.out.println("    Data: null");
                    }
                }
            }
        }
    }
    public static void demonstrateLinkUtilityMethods(SecretsManagerOptions options) throws Exception {
        QueryOptions queryOptions = new QueryOptions(
            Collections.emptyList(),
            Collections.emptyList(),
            true
        );
    
        KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
        System.out.println("Link Utility Methods Demo:");
        for (KeeperRecord record : secrets.getRecords()) {
            if (record.getLinks() != null && !record.getLinks().isEmpty()) {
                System.out.println("\nRecord: " + record.getTitle() + " (" + record.getType() + ")");
    
                for (int i = 0; i < record.getLinks().size(); i++) {
                    KeeperRecordLink link = record.getLinks().get(i);
                    System.out.println("  Link " + (i + 1) + " to " + link.getRecordUid() + ":");
                    System.out.println("    Path: " + (link.getPath() != null ? link.getPath() : "null"));
    
                    // User-related utilities
                    if (link.isAdminUser()) {
                        System.out.println("     Admin user");
                    }
                    if (link.isLaunchCredential()) {
                        System.out.println("     Launch credential");
                    }
    
                    // Permission utilities
                    if (link.allowsRotation()) {
                        System.out.println("     Allows rotation");
                    }
                    if (link.allowsConnections()) {
                        System.out.println("     Allows connections");
                    }
                    if (link.allowsPortForwards()) {
                        System.out.println("     Allows port forwards");
                    }
                    if (link.allowsSessionRecording()) {
                        System.out.println("     Allows session recording");
                    }
                    if (link.allowsTypescriptRecording()) {
                        System.out.println("     Allows typescript recording");
                    }
                    if (link.allowsRemoteBrowserIsolation()) {
                        System.out.println("     Allows remote browser isolation");
                    }
    
                    // Settings utilities
                    if (link.rotatesOnTermination()) {
                        System.out.println("     Rotates on termination");
                    }
    
                    Integer version = link.getLinkDataVersion();
                    if (version != null) {
                        System.out.println("     Data version: " + version);
                    }
    
                    if (link.hasReadableData()) {
                        System.out.println("     Has readable JSON data");
                    } else if (link.getData() != null) {
                        System.out.println("     Has encrypted/binary data");
                    } else {
                        System.out.println("     No data");
                    }
                }
            }
        }
    }
    public class OptimizedGraphOperations {
    
        // Strategy 1: Selective retrieval
        public void processSpecificRecords(List<String> recordUids, SecretsManagerOptions options) throws Exception {
            // Only get specific records with links to reduce bandwidth
            QueryOptions filtered = new QueryOptions(
                recordUids,  // Only these records
                Collections.emptyList(),
                true
            );
    
            KeeperSecrets secrets = SecretsManager.getSecrets2(options, filtered);
            // Process only what you need
        }
    
        // Strategy 2: Caching for multiple operations
        private Map<String, KeeperRecord> recordCache = new HashMap<>();
        private Map<String, List<KeeperRecord>> typeCache = new HashMap<>();
    
        public void initializeCache(SecretsManagerOptions options) throws Exception {
            QueryOptions queryOptions = new QueryOptions(null, null, true);
            KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
            // Build efficient lookup structures
            for (KeeperRecord record : secrets.getRecords()) {
                recordCache.put(record.getRecordUid(), record);
                typeCache.computeIfAbsent(record.getType(), k -> new ArrayList<>()).add(record);
            }
        }
    
        public List<KeeperRecord> getPamMachines() {
            return typeCache.getOrDefault("pamMachine", new ArrayList<>());
        }
    
        public KeeperRecord getRecord(String uid) {
            return recordCache.get(uid);
        }
    }
    public void robustLinkProcessing(SecretsManagerOptions options) {
        try {
            QueryOptions queryOptions = new QueryOptions(null, null, true);
            KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
            for (KeeperRecord record : secrets.getRecords()) {
                try {
                    List<KeeperRecordLink> links = record.getLinks();
    
                    // Handle null links (requestLinks was false)
                    if (links == null) {
                        System.err.println("Warning: Links not available for " + record.getTitle() +
                                         " - ensure requestLinks=true in QueryOptions");
                        continue;
                    }
    
                    // Process each link safely
                    for (KeeperRecordLink link : links) {
                        try {
                            // Safely access encrypted data
                            if (link.hasEncryptedData()) {
                                Map<String, Object> data = link.getLinkData(record.getRecordKey());
                                if (data != null) {
                                    // Successfully decrypted and processed
                                    System.out.println("Processed encrypted data for " + link.getRecordUid());
                                } else {
                                    System.out.println("Could not decrypt data for link to " + link.getRecordUid());
                                }
                            }
    
                            // Access link properties safely
                            boolean isAdmin = link.isAdminUser();
                            boolean allowsRotation = link.allowsRotation();
                            // ... other properties
    
                        } catch (Exception linkError) {
                            System.err.println("Error processing link to " + link.getRecordUid() + ": " + linkError.getMessage());
                        }
                    }
    
                } catch (Exception recordError) {
                    System.err.println("Error processing record " + record.getRecordUid() + ": " + recordError.getMessage());
                }
            }
    
        } catch (Exception e) {
            System.err.println("Failed to retrieve records with links: " + e.getMessage());
            e.printStackTrace();
        }
    }
    // Kotlin implementation with enhanced syntax
    fun analyzeAdvancedGraphRelationships(options: SecretsManagerOptions) {
        val queryOptions = QueryOptions(
            recordsFilter = emptyList(),
            foldersFilter = emptyList(),
            requestLinks = true
        )
        
        val secrets = getSecrets2(options, queryOptions)
        
        secrets.records.forEach { record ->
            record.links?.forEach { link ->
                println("${record.title} → ${link.recordUid}")
                
                // Advanced property checking with Kotlin's concise syntax
                when {
                    link.isAdminUser() -> println("   Admin privileges")
                    link.isLaunchCredential() -> println("   Launch credential")
                    link.allowsRotation() -> println("   Rotation allowed")
                    link.allowsConnections() -> println("   Connections allowed")
                    link.allowsSessionRecording() -> println("   Recording enabled")
                }
                
                // Settings data access with safe calls
                when (link.path) {
                    "ai_settings" -> {
                        link.getAiSettingsData(record.recordKey)?.let { aiData ->
                            println("  AI: ${aiData["aiEnabled"]} - Model: ${aiData["aiModel"]}")
                        }
                    }
                    "jit_settings" -> {
                        link.getJitSettingsData(record.recordKey)?.let { jitData ->
                            println("  JIT: ${jitData["enabled"]} - TTL: ${jitData["ttl"]}s")
                        }
                    }
                }
                
                // Generic encrypted data access
                link.getLinkData(record.recordKey)?.let { data ->
                    data.forEach { (key, value) ->
                        println("  $key: $value")
                    }
                }
            }
        }
    }

    Ruby SDK

    Detailed Ruby SDK docs for Keeper Secrets Manager

    Download and Installation

    Installation

    The Ruby SDK supports Ruby version 3.1 and above. For more information, see:

    Install with gem:

    Or add to your Gemfile:

    Then run:

    Source Code

    Find the Ruby source code in the

    Using the SDK

    Initialize Storage

    The Keeper Secrets Manager SDK requires a One-Time Access Token to initialize storage on a client device. After initialization, the SDK stores the configuration for future use.

    Parameter
    Type
    Required
    Default
    Description

    Note: Using a One-Time Access Token requires at least one read operation to bind the token and fully populate the configuration.

    Example Usage

    Using a One-Time Access Token:

    Using File-Based Storage

    For persistent configuration across application restarts:

    Alternatively connect with the base64 configuration file generated by your vault:

    Using Environment Variables

    For read-only configuration from environment:

    Retrieve Secrets

    Get Secrets

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: Array<KeeperRecord>

    Array containing all Keeper records, or records that match the given UID filter.

    Example Usage

    Retrieve All Secrets:

    Retrieve Secrets by UID:

    Get Secrets by Title

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: Array<KeeperRecord> (for get_secrets_by_title) or KeeperRecord (for get_secret_by_title)

    Returns all records matching the title, or the first matching record.

    Example Usage

    Retrieve Values From a Secret

    Once a secret is retrieved, individual fields can be accessed using multiple approaches:

    Using Dynamic Field Access

    Using Explicit Field Methods

    Using Keeper Notation

    Retrieve a TOTP Code

    To generate a TOTP code, retrieve the TOTP URL from the record and use the KeeperSecretsManager::TOTP module.

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns the current Time-Based One-Time Password (TOTP) code for two-factor authentication.

    Example Usage

    Note: TOTP generation requires the base32 gem for decoding the secret. Install with gem install base32.

    Generate a Random Password

    Generate cryptographically secure random passwords with customizable character requirements. This utility function is useful when creating or updating secrets programmatically.

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns a cryptographically secure random password meeting the specified requirements.

    Note: This function uses Ruby's SecureRandom for cryptographic-strength randomness and applies Fisher-Yates shuffle to ensure proper character distribution.

    Example Usage

    Generate a default 64-character password:

    Generate password with specific requirements:

    Use when creating a new secret:

    Use when updating an existing secret:

    Password rotation script:

    Update a Secret

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: void

    Updates the secret in the vault with the modified values.

    Example Usage

    Download a File

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: Hash

    Returns a hash containing:

    • 'name' - File name

    • 'data' - File contents as binary string

    • 'size' - File size in bytes

    Example Usage

    Upload a File

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns the UID of the uploaded file.

    Example Usage

    Create a Secret

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns the UID of the created secret.

    Prerequisites:

    • Shared folder UID (if specifying folder_uid)

    • Shared folder must be accessible by the Secrets Manager Application

    • You and the Secrets Manager application must have edit permission

    Example Usage

    Create Custom Type Record

    Delete a Secret

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: void

    Deletes the specified secret(s) from the vault.

    Example Usage

    Folders

    The Ruby SDK provides full CRUD support for folder operations.

    Get Folders

    Response:

    Type: Array<KeeperFolder>

    Returns all folders accessible to the Secrets Manager application.

    Example Usage

    Get Folder Path

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns the full path to the folder (breadcrumb trail separated by "/").

    Example Usage

    Find Folder by Name

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: KeeperFolder or nil

    Returns the first folder matching the name, or nil if not found.

    Example Usage

    Build Folder Tree

    Create a Folder

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: String

    Returns the UID of the created folder.

    Example Usage

    Update a Folder

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: void

    Renames the specified folder.

    Example Usage

    Delete Folders

    Parameter
    Type
    Required
    Default
    Description

    Response:

    Type: void

    Deletes the specified folder from the vault.

    Example Usage

    Caching

    Improve performance by caching secrets locally:

    Using CachingStorage

    Custom Caching with custom_post_function

    For advanced caching scenarios:

    Error Handling

    The SDK provides specific exception classes for different error scenarios:

    Common Error Scenarios

    Advanced Configuration

    Custom Hostname

    SSL Certificate Verification

    Custom Logging

    All Configuration Options

    Field Type Helpers

    Optional convenience methods for creating typed fields:

    Dynamic Record Access

    The Ruby SDK uses method_missing to provide JavaScript-style dynamic field access:

    String

    Optional

    'keepersecurity.com'

    API hostname (e.g., 'keepersecurity.eu' for EU datacenter)

    verify_ssl_certs

    Boolean

    Optional

    true

    Enable/disable SSL certificate verification

    Integer

    Optional

    6

    Number of digits in the code

    period

    Integer

    Optional

    30

    Time period in seconds

    Integer

    Optional

    0

    Minimum number of uppercase letters (A-Z)

    digits

    Integer

    Optional

    0

    Minimum number of digit characters (0-9)

    special_characters

    Integer

    Optional

    0

    Minimum number of special characters (!@#$%^&*()_+-=[]{}

    'type' - MIME type of the file

    String

    Yes

    -

    Name of the file in Keeper

    file_title

    String

    Optional

    nil

    Title/description of the file in Keeper

    There must be at least one record in the shared folder
  • Record fields must be formatted correctly (see field type documentation)

  • token

    String

    Optional

    nil

    One-Time Access Token for initial binding

    config

    KeyValueStorage

    Yes

    -

    Storage implementation for configuration persistence

    uids

    Array<String>

    Optional

    []

    Record UIDs to retrieve. Empty array retrieves all secrets.

    title

    String

    Yes

    -

    Record title to search for (exact match)

    secret

    String

    Yes

    -

    Base32-encoded TOTP secret

    algorithm

    String

    Optional

    'SHA1'

    Hash algorithm (SHA1, SHA256, SHA512)

    length

    Integer

    Optional

    64

    Total password length

    lowercase

    Integer

    Optional

    0

    Minimum number of lowercase letters (a-z)

    record

    KeeperRecord

    Yes

    -

    The modified record to update in the vault

    file

    KeeperFile

    Yes

    -

    File object from a KeeperRecord to download

    owner_record_uid

    String

    Yes

    -

    UID of the record to attach the file to

    file_data

    String

    Yes

    -

    File contents as binary string or text

    record_data

    Hash

    Yes

    -

    Hash containing record structure (type, title, fields, custom, notes)

    options

    CreateOptions

    Yes

    -

    CreateOptions object containing folder_uid (required) and optional settings

    uids

    String or Array<String>

    Yes

    -

    UID or array of UIDs of secrets to delete

    folder_uid

    String

    Yes

    -

    UID of the folder

    name

    String

    Yes

    -

    Name of the folder to find

    parent_uid

    String

    Optional

    nil

    UID of parent folder to search within

    name

    String

    Yes

    -

    Name of the folder to create

    parent_uid

    String

    Yes

    -

    UID of the parent shared folder

    folder_uid

    String

    Yes

    -

    UID of the folder to update

    new_name

    String

    Yes

    -

    New name for the folder

    folder_uid

    String

    Yes

    -

    UID of the folder to delete

    force

    Boolean

    Optional

    false

    If true, deletes folder and all its contents. If false, only deletes empty folders.

    https://rubygems.org/gems/keeper_secrets_manager
    GitHub repository

    hostname

    digits

    uppercase

    file_name

    gem install keeper_secrets_manager -v 17.1.0
    gem 'keeper_secrets_manager', '~> 17.1'
    bundle install
    KeeperSecretsManager.new(token: token, config: storage, hostname: hostname, verify_ssl_certs: verify_ssl_certs)
    require 'keeper_secrets_manager'
    
    token = "US:ONE_TIME_TOKEN_HERE"
    
    # First time setup - bind the token
    storage = KeeperSecretsManager::Storage::FileStorage.new('keeper_config.json')
    secrets_manager = KeeperSecretsManager.new(token: token, config: storage)
    
    # Complete the binding (requires at least one operation)
    records = secrets_manager.get_secrets
    
    # Verify config was saved
    File.exist?('keeper_config.json')  # Should return true
    require 'keeper_secrets_manager'
    
    # After first time binding, load from file
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    require 'keeper_secrets_manager'
    
    base64_config = File.read('config.base64').strip
    storage = KeeperSecretsManager::Storage::InMemoryStorage.new(base64_config)
    secrets_manager = KeeperSecretsManager.new(config: storage)
    require 'keeper_secrets_manager'
    
    # Set environment variables:
    # export KSM_HOSTNAME=keepersecurity.com
    # export KSM_CLIENT_ID=your-client-id
    # export KSM_PRIVATE_KEY=your-private-key
    # export KSM_APP_KEY=your-app-key
    # export KSM_SERVER_PUBLIC_KEY_ID=10
    
    # Load from environment
    config = KeeperSecretsManager::Storage::EnvironmentStorage.new('KSM_')
    secrets_manager = KeeperSecretsManager.new(config: config)
    get_secrets(uids = [])
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Retrieve all secrets
    records = secrets_manager.get_secrets
    
    records.each do |record|
      puts "#{record.title} (#{record.type})"
    end
    # Get single secret by UID
    records = secrets_manager.get_secrets(['RECORD_UID'])
    record = records.first
    
    # Get multiple secrets by UIDs
    uids = ['UID1', 'UID2', 'UID3']
    records = secrets_manager.get_secrets(uids)
    # Get all secrets matching title
    get_secrets_by_title(title)
    
    # Get first secret matching title
    get_secret_by_title(title)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get secret by exact title match
    record = secrets_manager.get_secret_by_title('My Database Credentials')
    
    # Get multiple secrets with same title
    records = secrets_manager.get_secrets_by_title('My Login')
    
    # Access fields from the record
    puts "Login: #{record.login}"
    puts "Password: #{record.password}"
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Access standard fields dynamically
    login = record.login
    password = record.password
    url = record.url
    
    # Access complex fields
    host = record.host  # Returns hash with hostName and port
    # Get single field value (returns first value)
    login = record.get_field_value_single('login')
    
    # Get all values for a field (returns array)
    passwords = record.get_field_value('password')
    
    # Access custom fields by label
    api_key = record.get_field_value_single('API Key')
    environment = record.get_field_value_single('Environment')
    # Access fields using URI-style notation
    password = secrets_manager.get_notation("keeper://#{record.uid}/field/password")
    
    # Access by record title
    url = secrets_manager.get_notation("keeper://My Login/field/url")
    
    # Access complex field properties
    hostname = secrets_manager.get_notation("keeper://#{record.uid}/field/host[hostName]")
    port = secrets_manager.get_notation("keeper://#{record.uid}/field/host[port]")
    
    # Access custom fields
    env = secrets_manager.get_notation("keeper://#{record.uid}/custom_field/Environment")
    # Get TOTP URL from record
    totp_url = record.get_field_value_single('oneTimeCode')
    
    # Parse and generate code
    require 'keeper_secrets_manager/totp'
    totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)
    totp_code = KeeperSecretsManager::TOTP.generate_code(
      totp_params['secret'],
      algorithm: totp_params['algorithm'],
      digits: totp_params['digits'],
      period: totp_params['period']
    )
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get record with TOTP
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Get TOTP URL from record
    totp_url = record.get_field_value_single('oneTimeCode')
    
    # Parse TOTP parameters
    require 'keeper_secrets_manager/totp'
    totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)
    
    # Generate TOTP code
    totp_code = KeeperSecretsManager::TOTP.generate_code(
      totp_params['secret'],
      algorithm: totp_params['algorithm'],
      digits: totp_params['digits'],
      period: totp_params['period']
    )
    
    puts "Current TOTP code: #{totp_code}"
    puts "Expires in: #{30 - (Time.now.to_i % 30)} seconds"
    KeeperSecretsManager::Utils.generate_password(
      length: 64,
      lowercase: 0,
      uppercase: 0,
      digits: 0,
      special_characters: 0
    )
    require 'keeper_secrets_manager'
    
    # Generate with all defaults (64 random characters)
    password = KeeperSecretsManager::Utils.generate_password
    puts "Generated: #{password}"
    # => "Xk9$mP2..."  (64 characters)
    # Generate 32-character password with specific minimums
    password = KeeperSecretsManager::Utils.generate_password(
      length: 32,
      lowercase: 2,
      uppercase: 2,
      digits: 2,
      special_characters: 2
    )
    
    puts "Generated: #{password}"
    # => "aB12$xY34..."  (32 chars with at least 2 of each type)
    
    # Generate strong password with mixed requirements
    password = KeeperSecretsManager::Utils.generate_password(
      length: 20,
      lowercase: 3,
      uppercase: 3,
      digits: 3,
      special_characters: 3
    )
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Create a new login record with generated password
    record_data = {
      type: 'login',
      title: 'Production Database',
      fields: [
        { type: 'login', value: ['db_admin'] },
        {
          type: 'password',
          value: [KeeperSecretsManager::Utils.generate_password(
            length: 32,
            lowercase: 4,
            uppercase: 4,
            digits: 4,
            special_characters: 4
          )]
        },
        { type: 'url', value: ['https://db.example.com'] }
      ],
      notes: 'Auto-generated secure password'
    }
    
    # Create options with required folder_uid
    options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
    record_uid = secrets_manager.create_secret(record_data, options)
    
    puts "Created record with secure password: #{record_uid}"
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get existing record
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Generate and set new password
    new_password = KeeperSecretsManager::Utils.generate_password(
      length: 40,
      lowercase: 5,
      uppercase: 5,
      digits: 5,
      special_characters: 5
    )
    
    record.password = new_password
    
    # Save changes
    secrets_manager.update_secret(record)
    
    puts "Password updated with new secure value"
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Rotate passwords for multiple records
    record_uids = ['UID1', 'UID2', 'UID3']
    
    record_uids.each do |uid|
      record = secrets_manager.get_secrets([uid]).first
    
      # Generate new password
      new_password = KeeperSecretsManager::Utils.generate_password(
        length: 32,
        lowercase: 3,
        uppercase: 3,
        digits: 3,
        special_characters: 3
      )
    
      # Update record
      record.password = new_password
      record.notes = "Password rotated on #{Time.now}"
    
      secrets_manager.update_secret(record)
    
      puts "✓ Rotated password for: #{record.title}"
    end
    update_secret(record)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get existing record
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Update fields using dynamic access
    record.password = 'NewSecurePassword123!'
    
    # Update fields using explicit method
    record.set_field('login', '[email protected]')
    
    # Update notes
    record.notes = "Updated on #{Time.now}"
    
    # Save changes
    secrets_manager.update_secret(record)
    
    puts "Secret updated successfully"
    download_file(file)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get record with files
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Check if record has files
    if record.files && record.files.any?
      # Download first file
      file = record.files.first
      downloaded = secrets_manager.download_file(file)
    
      # Save to disk
      filename = downloaded['name'] || 'downloaded_file'
      File.write(filename, downloaded['data'])
    
      puts "Downloaded: #{filename}"
      puts "Size: #{downloaded['size']} bytes"
      puts "Type: #{downloaded['type']}"
    end
    upload_file(owner_record_uid, file_data, file_name, file_title = nil)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Upload a file
    file_uid = secrets_manager.upload_file(
      'RECORD_UID',                          # owner_record_uid
      File.read('/path/to/certificate.pem'), # file_data
      'certificate.pem',                      # file_name
      'Server Certificate'                    # file_title (optional)
    )
    
    puts "File uploaded with UID: #{file_uid}"
    
    # Upload text content
    file_uid = secrets_manager.upload_file(
      'RECORD_UID',
      "server=localhost\nport=5432\n",
      'config.txt',
      'Database Config'
    )
    create_secret(record_data, options = nil)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Create a login record
    record_data = {
      type: 'login',
      title: 'Production Database',
      fields: [
        { type: 'login', value: ['db_admin'] },
        { type: 'password', value: ['SecurePassword123!'] },
        { type: 'url', value: ['https://db.example.com'] },
        {
          type: 'host',
          value: [{ hostName: '192.168.1.100', port: '5432' }],
          label: 'Database Host'
        }
      ],
      custom: [
        { type: 'text', label: 'Environment', value: ['Production'] },
        { type: 'text', label: 'Database Name', value: ['main_db'] }
      ],
      notes: 'Production database credentials'
    }
    
    # Create options with required folder_uid
    options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
    
    # Create the secret
    record_uid = secrets_manager.create_secret(record_data, options)
    
    puts "Secret created with UID: #{record_uid}"
    
    # Alternative: Create options inline
    record_uid = secrets_manager.create_secret(
      record_data,
      KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
    )
    # Create a database credentials record
    record_data = {
      type: 'databaseCredentials',
      title: 'MySQL Production',
      fields: [
        { type: 'text', label: 'Database Type', value: ['MySQL'] },
        {
          type: 'host',
          value: [{ hostName: 'mysql.example.com', port: '3306' }]
        },
        { type: 'login', value: ['root'] },
        { type: 'password', value: ['SecurePassword123!'] }
      ],
      notes: 'MySQL production database'
    }
    
    # Create options with required folder_uid
    options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
    record_uid = secrets_manager.create_secret(record_data, options)
    delete_secret(uids)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Delete a single secret
    secrets_manager.delete_secret('RECORD_UID')
    
    puts "Secret deleted successfully"
    
    # Delete multiple secrets
    uids = ['UID1', 'UID2', 'UID3']
    secrets_manager.delete_secret(uids)
    
    puts "#{uids.length} secrets deleted"
    get_folders
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Get all folders
    folders = secrets_manager.get_folders
    
    folders.each do |folder|
      puts "#{folder.name} (UID: #{folder.uid})"
    end
    get_folder_path(folder_uid)
    # Get folder path (breadcrumb trail)
    path = secrets_manager.get_folder_path('FOLDER_UID')
    puts "Folder path: #{path}"  # "Parent/Child/Grandchild"
    find_folder_by_name(name, parent_uid: nil)
    # Find folder by name
    folder = secrets_manager.find_folder_by_name('Finance')
    
    # Find folder within specific parent
    folder = secrets_manager.find_folder_by_name('Reports', parent_uid: 'PARENT_UID')
    # Get folder manager for advanced operations
    fm = secrets_manager.folder_manager
    
    # Build complete folder tree structure
    tree = fm.build_folder_tree
    
    # Print folder tree to console
    fm.print_tree
    
    # Get folder relationships
    ancestors = fm.get_ancestors('FOLDER_UID')      # [parent, grandparent, ...]
    descendants = fm.get_descendants('FOLDER_UID')   # [children, grandchildren, ...]
    create_folder(name, parent_uid:)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Create folder at root level (within a shared folder)
    folder_uid = secrets_manager.create_folder('New Folder', parent_uid: 'SHARED_FOLDER_UID')
    
    puts "Folder created with UID: #{folder_uid}"
    
    # Create subfolder within existing folder
    subfolder_uid = secrets_manager.create_folder(
      'Subfolder',
      parent_uid: folder_uid
    )
    
    puts "Subfolder created: #{subfolder_uid}"
    update_folder(folder_uid, new_name)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Rename a folder
    secrets_manager.update_folder('FOLDER_UID', 'New Folder Name')
    
    puts "Folder renamed successfully"
    delete_folder(folder_uid, force: false)
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
    
    # Delete empty folder
    secrets_manager.delete_folder('FOLDER_UID')
    
    # Force delete folder (removes all contents)
    secrets_manager.delete_folder('FOLDER_UID', force: true)
    
    puts "Folder deleted"
    
    # Delete multiple folders
    folder_uids = ['UID1', 'UID2', 'UID3']
    folder_uids.each do |uid|
      secrets_manager.delete_folder(uid, force: true)
    end
    require 'keeper_secrets_manager'
    
    # Create base storage
    base_storage = KeeperSecretsManager::Storage::FileStorage.new('keeper_config.json')
    
    # Wrap with caching (600 second TTL)
    cached_storage = KeeperSecretsManager::Storage::CachingStorage.new(base_storage, 600)
    
    # Use cached storage
    secrets_manager = KeeperSecretsManager.new(config: cached_storage)
    
    # First call fetches from server
    records = secrets_manager.get_secrets
    
    # Subsequent calls within TTL use cache
    records = secrets_manager.get_secrets  # Uses cached data
    require 'keeper_secrets_manager'
    
    # Create custom cache
    cache = {}
    
    custom_post = lambda do |url, payload|
      cache_key = "#{url}:#{payload}"
    
      # Check cache
      if cache[cache_key] && cache[cache_key][:expires_at] > Time.now
        return cache[cache_key][:response]
      end
    
      # Make actual request
      uri = URI(url)
      request = Net::HTTP::Post.new(uri)
      request['Content-Type'] = 'application/json'
      request.body = payload
    
      response = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) do |http|
        http.request(request)
      end
    
      # Cache response for 10 minutes
      cache[cache_key] = {
        response: response.body,
        expires_at: Time.now + 600
      }
    
      response.body
    end
    
    secrets_manager = KeeperSecretsManager.from_file(
      'keeper_config.json',
      custom_post_function: custom_post
    )
    require 'keeper_secrets_manager'
    
    begin
      secrets_manager = KeeperSecretsManager.from_file('keeper_config.json')
      records = secrets_manager.get_secrets
    
    rescue KeeperSecretsManager::AuthenticationError => e
      puts "Authentication failed: #{e.message}"
      # Token expired or invalid
    
    rescue KeeperSecretsManager::NetworkError => e
      puts "Network error: #{e.message}"
      # Connection timeout or DNS failure
    
    rescue KeeperSecretsManager::CryptoError => e
      puts "Encryption error: #{e.message}"
      # Decryption failed or key error
    
    rescue KeeperSecretsManager::NotationError => e
      puts "Notation parsing error: #{e.message}"
      # Invalid notation URI format
    
    rescue KeeperSecretsManager::Error => e
      puts "General error: #{e.message}"
      # Other SDK errors
    
    rescue StandardError => e
      puts "Unexpected error: #{e.message}"
    end
    # Handle missing records gracefully
    begin
      record = secrets_manager.get_secret_by_title('Nonexistent Record')
    rescue KeeperSecretsManager::Error => e
      puts "Record not found: #{e.message}"
      # Provide fallback or create new record
    end
    
    # Retry logic for network errors
    max_retries = 3
    retries = 0
    
    begin
      records = secrets_manager.get_secrets
    rescue KeeperSecretsManager::NetworkError => e
      retries += 1
      if retries < max_retries
        sleep 2 ** retries  # Exponential backoff
        retry
      else
        raise
      end
    end
    require 'keeper_secrets_manager'
    
    # EU datacenter
    secrets_manager = KeeperSecretsManager.new(
      token: 'EU:ONE_TIME_TOKEN',
      hostname: 'keepersecurity.eu',
      config: storage
    )
    
    # Australian datacenter
    secrets_manager = KeeperSecretsManager.new(
      token: 'AU:ONE_TIME_TOKEN',
      hostname: 'keepersecurity.com.au',
      config: storage
    )
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.new(
      config: storage,
      verify_ssl_certs: true  # Default is true
    )
    require 'keeper_secrets_manager'
    require 'logger'
    
    # Create custom logger
    logger = Logger.new(STDOUT)
    logger.level = Logger::DEBUG
    
    secrets_manager = KeeperSecretsManager.new(
      config: storage,
      logger: logger,
      log_level: Logger::DEBUG
    )
    require 'keeper_secrets_manager'
    
    secrets_manager = KeeperSecretsManager.new(
      token: 'US:ONE_TIME_TOKEN',           # One-time access token
      config: storage,                       # Storage implementation
      hostname: 'keepersecurity.com',        # API hostname
      verify_ssl_certs: true,                # SSL verification
      logger: Logger.new(STDOUT),            # Custom logger
      log_level: Logger::WARN,               # Log level
      custom_post_function: my_post_func     # Custom HTTP handler
    )
    require 'keeper_secrets_manager'
    
    # Use field helpers for type safety
    fields = [
      KeeperSecretsManager::FieldTypes::Helpers.login('admin'),
      KeeperSecretsManager::FieldTypes::Helpers.password('SecurePass123!'),
      KeeperSecretsManager::FieldTypes::Helpers.url('https://example.com'),
      KeeperSecretsManager::FieldTypes::Helpers.host(
        hostname: '192.168.1.100',
        port: 22
      ),
      KeeperSecretsManager::FieldTypes::Helpers.name(
        first: 'John',
        middle: 'Q',
        last: 'Doe'
      ),
      KeeperSecretsManager::FieldTypes::Helpers.address(
        street1: '123 Main St',
        city: 'New York',
        state: 'NY',
        zip: '10001'
      )
    ]
    
    # Convert to hashes for record creation
    record_data = {
      type: 'login',
      title: 'Server with Helpers',
      fields: fields.map(&:to_h)
    }
    
    # Create options with required folder_uid
    options = KeeperSecretsManager::Dto::CreateOptions.new(folder_uid: 'FOLDER_UID')
    record_uid = secrets_manager.create_secret(record_data, options)
    # Get record
    record = secrets_manager.get_secrets(['RECORD_UID']).first
    
    # Dynamic getters
    login = record.login          # Returns field value
    password = record.password    # Returns field value
    url = record.url             # Returns field value
    
    # Dynamic setters
    record.password = 'NewPassword123!'
    record.url = 'https://newurl.example.com'
    
    # Check if field exists
    if record.respond_to?(:oneTimeCode)
      # Generate TOTP code from oneTimeCode field
      require 'keeper_secrets_manager/totp'
      totp_url = record.oneTimeCode
      totp_params = KeeperSecretsManager::TOTP.parse_url(totp_url)
      totp_code = KeeperSecretsManager::TOTP.generate_code(
        totp_params['secret'],
        algorithm: totp_params['algorithm'],
        digits: totp_params['digits'],
        period: totp_params['period']
      )
    end
    
    # Access all fields as hash
    fields = record.fields
    fields.each do |type, values|
      puts "#{type}: #{values.join(', ')}"
    end

    Python SDK

    Detailed Python SDK docs for Keeper Secrets Manager

    Download and Installation

    Install with PIP

    JavaScript SDK

    Detailed Javascript SDK docs for Keeper Secrets Manager

    Download and Installation

    Install with NPM

    Source Code

    Find the Python source code in the GitHub repository

    Using the SDK

    Initialize

    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

    Parameter

    Required

    Description

    Type

    token

    Yes

    One Time Access Token

    String

    config

    Yes

    Storage Configuration

    KeyValueStorage

    Retrieve Secrets

    Parameter

    Type

    Required

    Default

    Description

    uids

    String[]

    Optional

    None

    Record UIDs to fetch

    Response

    Type: Record[]

    All Keeper records, or records with the given UIDs

    Retrieve Values From a Secret

    Retrieve a Password

    This shortcut gets the password of a secret once that secret has been retrieved from Keeper Secrets Manager.

    Retrieve Standard Fields

    Parameter

    Type

    Required

    Default

    Description

    field_type

    String

    Yes

    Field type to get

    single

    boolean

    Optional

    False

    Field types are based on the Keeper . For a detailed list of available fields based on the Keeper Record Type, see the record-type-info command in Keeper Commander.

    Retrieve Custom Fields

    Parameter

    Type

    Required

    Default

    Description

    label

    String

    Yes

    Label of the custom field

    field_type

    String

    Yes

    Custom fields are any field that is not part of the record type definition, but can be added by users.

    It is possible for multiple fields of the same custom type to appear on a single record, to differentiate these fields, the field label is required.

    Response

    Type: String or String[]

    the value or values of the field. Will be a single value only if the single=True option is passed.

    Retrieve Secrets by Title

    Parameter
    Type
    Required
    Description

    record_title

    String

    Yes

    Record title to search for

    Retrieve Values using Keeper Notation

    See Keeper Notation documentation to learn about Keeper Notation format and capabilities

    Parameter

    Type

    Required

    Default

    Description

    query

    String

    Yes

    Keeper Notation query for getting a value from a specified field

    Returns

    Type: string or string[]

    The value of the queried field

    Retrieve a TOTP Code

    Parameter

    Type

    Required

    Default

    Description

    url

    String

    Yes

    TOTP Url

    Update a Secret

    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.

    Save Changes to a Secret

    record

    KeeperRecord

    Yes

    Storage and query configuration

    Set field values using the field method. For a detailed list of available fields based on the Keeper Record Type, see the record-type-info command in Keeper Commander. Some fields have multiple values, in these cases the value can be set to a list.

    Update a Standard Field Value

    Parameter

    Type

    Required

    Default

    Description

    field_type

    String

    Yes

    Field type to get

    single

    boolean

    Optional

    False

    Update a Custom Field Value

    Parameter

    Type

    Required

    Default

    Description

    label

    String

    Yes

    Label of the custom field

    field_type

    String

    Yes

    Generate a Random Password

    Parameter
    Type
    Required
    Default

    length

    int

    Optional

    64

    lowercase

    int

    Optional

    0

    uppercase

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

    Download a File

    Parameter

    Type

    Required

    Default

    Description

    file_path

    String

    Yes

    Path to save file to

    create_folders

    boolean

    No

    False

    Upload a File

    Upload File:

    Creating the Keeper File Upload Object:

    Upload File

    Parameter
    Type
    Required
    Description

    owner_record

    KeeperRecord

    Yes

    The record to attach the uploaded file to

    file

    KeeperFileUpload

    Yes

    The File to upload

    Keeper File Upload From File

    Parameter
    Type
    Required
    Default
    Description

    path

    string

    Yes

    Path to the file to upload

    file_name

    string

    No

    Returns

    Type: string

    The file UID of the attached file

    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 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

    Parameter
    Type
    Required
    Default

    folder_uid

    String

    Yes

    record

    KeeperRecord

    Yes

    Parameter
    Type
    Required
    Default

    This example creates a login type record with a login value and a generated password.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    This example creates a record with a custom record type.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    Returns

    Type: string

    The record UID of the new record

    Delete a Secret

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

    Parameter
    Type
    Required

    record_uid

    string

    Yes

    Caching

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

    Setup and Configure Cache

    In order to setup caching in the Python SDK, include a caching post function when creating a SecretsManager object.

    The Python SDK includes a default caching function in KSMCache class which stores cached queries to a local file thus serving as a disaster recovery function (as long as there's network connectivity it always prefers network over cached data and will use cache only if web vault is inaccessible). You can create your own caching function using KSMCache as a starting point - ex. one that prefers local cache over network access and provide own cache management (ex. refresh cached data once every 5 min)

    The default caching function in KSMCache class always stores last request only - ex. filtered request on UID1 but on disconnect request UID2 from same cache will return empty response (although UID2 may be shared to the same KSM app but it was not cached)

    Updating a record from cache (or creating new record) invalidates cached record data and consecutive updates of the same record will fail. Batch updates work as long as they modify different records. Always follow up cached record updates with a call to get_secrets function to refresh cache (and pull updated metadata from vault like the new record revision etc.)

    Creating your own caching function

    For start create caching function with following arguments and call post_function

    Then you can implement any custom logic of caching using KSMCache. Full basic example:

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Response

    Type: List[KeeperFolder]

    Example Usage

    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.

    Parameter
    Type
    Required
    Default
    Description

    create_options

    CreateOptions

    Yes

    The parent and sub-folder UIDs

    folder_name

    str

    Yes

    Example Usage

    Update a Folder

    Updates the folder metadata - currently folder name only.

    Parameter
    Type
    Required
    Default
    Description

    folder_uid

    str

    Yes

    The folder UID

    folder_name

    str

    Yes

    Example Usage

    Delete Folders

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

    When using force_deletion 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.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    Parameter
    Type
    Required
    Default
    Description

    folder_uids

    List[str]

    Yes

    The folder UID list

    force_deletion

    bool

    No

    Example Usage

    Proxy support

    Environment variable

    Keeper Secrets Manager SDK uses the requests library to support the HTTPS_PROXY environment variable by default

    Every request including Keeper Secrets Manager requests will go through declared proxy

    Using environment variables for proxy settings is preferred because it keeps configuration out of code, ensures consistency across tools, and simplifies deployment.

    SecretsManager parameter

    Optionally, you can pass your proxy url to SecretsManager if you want proxy to be used only in SDK:

    If your proxy has authentication, just pass your username and password in proxy url

    Source Code

    Find the JavaScript source code in the GitHub repository

    Using the SDK

    Initialize Storage

    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

    In order to retrieve secrets, you must first initialize the local storage on your machine.

    Parameter

    Type

    Required

    Default

    Description

    storage

    KeyValueStorage

    Yes

    storage location

    clientKey

    string

    Optional

    null

    Example Usage

    Retrieve Secrets

    Parameter

    Type

    Required

    Default

    Description

    storage

    KeyValueStorage

    Yes

    Storage location

    recordsFilter

    string[]

    Optional

    Empty List

    Response

    Type: KeeperSecrets

    Object containing all Keeper records, or records that match the given filter criteria

    Example Usage

    Retrieve all Secrets

    Retrieve Secrets by Title

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    recordTitle

    string

    Yes

    Record title to search for

    Example Usage

    Retrieve Values From a Secret

    Retrieve a Password

    Field types are based on the Keeper . For a detailed list of available fields based on the Keeper Record Type, see the record-type-info command in Keeper Commander.

    Retrieve other Fields with Keeper Notation

    See Keeper Notation documentation to learn about Keeper Notation format and capabilities

    Parameter

    Type

    Required

    Default

    Description

    secrets

    KeeperSecrets

    Yes

    Secrets to query

    query

    string

    Yes

    * The record UID in the notation query must be for a secret passed in the secrets parameter or nothing will be found by the query

    Returns

    Type: any

    The value of the field at the location specified by the dot notation query if any, otherwise undefined.

    Retrieve a TOTP Code

    See Keeper Notation documentation to learn about Keeper Notation format and capabilities

    Parameter

    Type

    Required

    Default

    Description

    url

    string

    Yes

    TOTP Url

    * The record UID in the notation query must be for a secret passed in the secrets parameter or nothing will be found by the query

    Returns

    Type: any

    The value of the field at the location specified by the dot notation query if any, otherwise undefined.

    Update a Secret

    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.

    Parameter

    Type

    Required

    Default

    Description

    options

    SecretManagerOptions

    Yes

    record

    KeeperRecord

    Yes

    Returns

    Type: Promise<void>

    Generate a Random Password

    Parameter
    Type
    Required
    Default

    length

    int

    Optional

    64

    lowercase

    int

    Optional

    0

    uppercase

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

    Returns

    Type: String

    Download a File

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File to download

    Response

    Type: Promise<Uint8Array

    Bytes of file for download

    Download a Thumbnail

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File with thumbnail to download

    Response

    Type: Promise<Uint8Array>

    Bytes of thumbnail for download

    Upload a File

    Upload File:

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    ownerRecord

    KeeperRecord

    Yes

    The record to attach the uploaded file to

    file

    Creating the Keeper File Upload Object:

    Parameter
    Type
    Required
    Description

    name

    string

    Yes

    What the name of the file will be in Keeper once uploaded

    title

    string

    Yes

    What the title of the file will be in Keeper once uploaded

    type

    Example Usage

    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 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

    Parameter
    Type
    Required
    Default

    options

    SecretManagerOptions

    Yes

    folderUid

    string

    Yes

    Parameter
    Type
    Required
    Default

    This example creates a login type record with a login value and a generated password.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    This example creates a record with a custom record type.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    Delete a Secret

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

    Parameter
    Type
    Required

    smOptions

    SecretManagerOptions

    Yes

    recordUids

    string[]

    Yes

    Caching

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

    Add queryFunction: cachingPostFunction to SecretManagerOptions

    Example usage:

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Response

    Type: KeeperFolder[]

    Example Usage

    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.

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    createOptions

    CreateOptions

    Yes

    The parent and sub-folder UIDs

    folderName

    Example Usage

    Update a Folder

    Updates the folder metadata - currently folder name only.

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUid

    string

    Yes

    The folder UID

    folderName

    Example Usage

    Delete Folders

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

    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.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    Parameter
    Type
    Required
    Default
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUids

    string[]

    Yes

    Example Usage

    Proxy Support

    In order to use proxy, you need to install and set a proxy agent using setCustomProxyAgent from @keeper-security/secrets-manager-core

    Example Usage

    setCustomProxyAgent works only in NodeJs environment and is not supported in browser.

    Rust SDK

    Detailed Rust SDK docs for Keeper Secrets Manager

    Download and Installation

    Adding as Package using Cargo

    Source Code

    Find the Rust source code in the

    Using the SDK

    Initialise

    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

    Retrieve Secrets

    Response

    Type: Vec<Record>

    All Keeper records, or records with the given UIDs

    default - we will get all records which the token given has access to

    Retrieve Values from secret

    Retrieve a password

    This shortcut gets the password of a secret once that secret has been retrieved from Keeper Secrets Manager.

    Retrieve Standard Fields

    Parameter
    Type
    Required
    Default
    Description

    Field types are based on the Keeper . For a detailed list of available fields based on the Keeper Record Type, see the command in Keeper Commander.

    Retrieve Custom Fields

    Parameter
    Type
    Required
    Default
    Description

    Custom fields are any field that is not part of the record type definition but can be added by users.

    Response

    Type: String or Vec<String>

    the value or values of the field. It will be a single value only if the single=true option is passed.

    Records by Title

    Response

    Type: Record<Option<Vec<Record>>>

    Parameter
    Type
    Required
    Description

    Retrieve Values using Keeper Notation

    See to learn about Keeper Notation format and capabilities

    Parameter
    Type
    Required
    Default
    Description

    Returns

    The value of the queried field

    Type: String or Vec<String>

    Retrieve a TOTP Code

    Returns

    Type: Result<TotpCode,KSMRError>

    Parameter
    Type
    Required
    Description

    Update a Secret

    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.

    Save Changes to a Secret

    Parameter
    Type
    Required
    Default
    Description

    Set field values using the set_standard_field_value_mut or the set_custom_field_value_mut method.

    Fields are found by type.

    For a list of field types, see the documentation. Some fields have multiple values in these cases, the value can be set to a list.

    Update a Standard Field Value

    Parameter
    Type
    Required
    Default
    Description

    Fields are found by type. For a list of field types, see the documentation.

    Update a Custom Field Value

    Parameter
    Type
    Required
    Default
    Description

    Generate a Random Password

    Parameter
    Type
    Required
    Default
    Description

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

    Download a File

    Parameter
    Type
    Required
    Default
    Description

    Upload File

    Upload File Parameters

    Parameter
    Type
    Required
    Default
    Description

    File Parameters

    Parameter
    Type
    Required
    Default
    Description

    Returns

    Type: String

    The file UID of the attached file

    Create a secret

    Prerequisites:

    • Shared folder UID

      • The 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

    Parameter
    Type
    Required
    Default
    Description

    Returns

    Type: String

    The record UID of the new record

    Delete A Secret

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

    Parameter
    Type
    Required
    Default
    Description

    Caching

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

    Setup and Configure Cache

    In order to setup caching in the Rust SDK, include a caching post function when creating a SecretsManager object.

    The Rust SDK includes a default caching function in the KSMRCache class, which stores cached queries to a local file, thus serving as a disaster recovery function (as long as there's network connectivity, it always prefers network over cached data and will use cache only if the web vault is inaccessible).

    The default caching function in KSMCache class always stores last request only. For example, if the first request (R1) successfully retrieves UID1 and updates the cache, but a subsequent request (R2) for UID2 fails, the cache will not include UID2. As a result, any later operations involving UID2 (e.g., lookup or disconnect) will return an empty response, since it was never added to the cache.

    Updating a record from cache (or creating new record) invalidates cached record data and consecutive updates of the same record will fail. Batch updates work as long as they modify different records. Always follow up cached record updates with a call to get_secrets function to refresh cache (and pull updated metadata from vault like the new record revision etc.)

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Returns

    Type: Vec<KeeperFolder>

    Create Folder

    Requires CreateOptions and folder name to be provided. The folder UID parameter in CreateOptions is required—the UID of a shared folder, while sub-folder UID is optional, and if missing, a 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.

    Parameter
    Type
    Required
    Default
    Description

    Update Folder

    Updates the folder metadata—currently folder name only.

    Parameter
    Type
    Required
    Default
    Description

    Delete Folders

    Removes a list of folders. Use the force_deletion flag to remove non-empty folders.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    When using force_deletion 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.

    Parameter
    Type
    Required
    Default
    Description

    Go SDK

    Detailed Go SDK docs for Keeper Secrets Manager

    Download and Installation

    Install from GitHub

    SecretsManager(token, config)
    # Using token, only to generate a config (for later usage),
    # requires at least one access operation to bind the token
    #get_secrets(uids=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    # Using token only to generate the config 
    # requires at least one access operation to bind the token
    #secrets_manager.get_secrets(uids=None)
    get_secrets(uids=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get all records
    all_secrets = secrets_manager.get_secrets()
    
    # print out all records
    for secret in all_secrets:
        print(secret.dict)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by record UID
    secret = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # print out secret
    print(secret.dict)
    secret.field('password', single=True)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by record UID
    secret = secrets_manager.get_secrets(['<RECORD UID>'])[0]
    
    # get password from record
    my_secret_password = secret.field('password', single=True)
    secret.field(field_type, single=False, value=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by record UID
    secret = secrets_manager.get_secrets(['<RECORD UID>'])[0]
    
    # get login field from the secret
    my_secret_login = secret.field("login", single=True)
    secret.custom_field(label, field_type=None, single=False, value=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by UID
    secret = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # Get a standard template field
    password = secret.field('password', single=True)
    
    # Get a custom field, e.g. API Key
    api_key = secret.custom_field('API Key', single=True)
    # get all matching records
    get_secrets_by_title(record_title)
    
    # get only the first matching record
    get_secret_by_title(record_title)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        config=FileKeyValueStorage('ksm-config.json'))
    
    # get the first secret matching the record title
    secret = secrets_manager.get_secret_by_title("My Credentials")
    
    # get all secrets matching the record title
    secrets = secrets_manager.get_secrets_by_title("My Credentials")
    get_notation(query)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific standard field with Keeper Notation
    password = secrets_manager.get_notation('EG6KdJaaLG7esRZbMnfbFA/field/password')[0]
    
    # get a specific custom field with Keeper Notation
    custom_field_value = secrets_manager.get_notation('EG6KdJaaLG7esRZbMnfbFA/custom_field/my_field')
    get_totp_code(url)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    from keeper_secrets_manager_core.utils import get_totp_code
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get TOTP url value from a record
    url = record.get_standard_field_value('oneTimeCode', True)
    
    # get code from TOTP url
    totp = get_totp_code(url)
    print(totp.code)
    save(record: KeeperRecord)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by UID
    secret_to_update = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # update a field value
    secret_to_update.field('login', 'new login')
    
    # update non-field values
    secret_to_update.title = "New Title"
    secret_to_update.dict["notes"] = "New Notes"
    secret_to_update._update()
    
    # save updated secret
    secrets_manager.save(secret_to_update)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
         config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by UID
    secret = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # rotate password on the record
    secret.field('password', 'new password')
    # start a transaction
    secrets_manager.save(secret, 'rotation')
    # rotate password on remote host
    success = rotate_remote_ssh_password('new password')
    # complete the transaction - commit or rollback
    secrets_manager.complete_transaction(secret.uid, rollback=not success)
    
    secret.field(field_type, single=False, value=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by record UID
    secret = secrets_manager.get_secrets(['<RECORD UID>'])[0]
    
    # update login
    secret.field("login", single=True, "My New Login")
    
    # save secret
    secrets_manager.save(secret)
    secret.custom_field(label, field_type=None, single=False, value=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by UID
    secret = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # Get a standard template field
    password = secret.field('password', single=True)
    
    # Set custom field 'API Key'
    my_new_api_key = "wKridl2ULt20qGuiP3IY"
    secret.custom_field('API Key', single=True, my_new_api_key)
    
    # Save changes to the secret
    secrets_manager.save(secret)
    generate_password(length, lowercase, uppercase, digits, specialCharacters)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    from keeper_secrets_manager_core.utils import generate_password
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # get a specific secret by UID
    secret = secrets_manager.get_secrets(['EG6KdJaaLG7esRZbMnfbFA'])[0]
    
    # generate a random password
    password = generate_password()
    # update a record with new password
    secret.field('password', value=password)
    
    # Save changes to the secret
    secrets_manager.save(secret)
    file.save_file(file_path, create_folders=False)
    # 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)
    upload_file(owner_record, file: my_file)
    KeeperFileUpload.from_file(path, file_name=None, file_title=None, mime_type=None)
    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 and get the file UID
    file_uid = secrets_manager.upload_file(owner_record, file = my_file)
    from keeper_secrets_manager_core.dto.dtos import RecordCreate,RecordField
    
    record = RecordCreate(record_type='login', title='test_KSM')
    record.fields = [ 
        RecordField(field_type='login',value='test_login'),
        RecordField(field_type='password',value='test_pwd') 
    ]
    
    secrets_manager.create_secret(folder_uid, record)
    secrets_manager.delete_secret(record_uid)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    # delete a specific secret by record UID
    secret = secrets_manager.delete_secret('EG6KdJaaLG7esRZbMnfbFA')
    pip3 install -U keeper-secrets-manager-core
    secrets_manager = SecretsManager(
        token='<One Time Access Token>',
        config=FileKeyValueStorage('ksm-config.json'),
        custom_post_function=KSMCache.caching_post_function
    )
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.core import KSMCache, KSMHttpResponse
    
    def caching_post_function(
            url, transmission_key, encrypted_payload_and_signature, verify_ssl_certs=True, proxy_url=None
    ):
        ksm_rs = SecretsManager.post_function(
            url, transmission_key, encrypted_payload_and_signature, verify_ssl_certs
        )
        # Your custom caching logic here ...
    
        # Make sure to always return a KSMHttpResponse object
        return ksm_rs
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.core import KSMCache, KSMHttpResponse
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    from http import HTTPStatus
    
    def caching_post_function(
            url, transmission_key, encrypted_payload_and_signature, verify_ssl_certs=True, proxy_url=None
    ):
        ksm_rs = SecretsManager.post_function(
            url, transmission_key, encrypted_payload_and_signature, verify_ssl_certs
        )
    
        if ksm_rs.status_code < 400:
            KSMCache.save_cache(transmission_key.key + ksm_rs.data)
            return ksm_rs
    
        # KSMCache can be empty    
        cached_data = KSMCache.get_cached_data()
        cached_transmission_key = cached_data[:32]
        transmission_key.key = cached_transmission_key
        data = cached_data[32 : len(cached_data)]
    
        new_rs = KSMHttpResponse(HTTPStatus.OK, data, None)
        return new_rs
    
    
    secrets_manager = SecretsManager(
        config=FileKeyValueStorage('ksm-config.json'),
        verify_ssl_certs=False,
        custom_post_function=caching_post_function
    )
    get_folders()
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    secrets_manager = SecretsManager(config=FileKeyValueStorage('ksm-config.json'))
    folders = secrets_manager.get_folders()
    create_folder(create_options: CreateOptions, folder_name: str, folders=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.core import CreateOptions
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    secrets_manager = SecretsManager(config=FileKeyValueStorage('ksm-config.json'))
    co = CreateOptions(folder_uid="[PARENT_SHARED_FOLDER_UID]", subfolder_uid="")
    new_folder_uid = secrets_manager.create_folder(co, "new_folder")
    update_folder(folder_uid: str, folder_name: str, folders=None)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    secrets_manager = SecretsManager(config=FileKeyValueStorage('ksm-config.json'))
    secrets_manager.update_folder("[FOLDER_UID]", "new_folder_name")
    delete_folder(folder_uids: List[str], force_deletion: bool = False)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    
    secrets_manager = SecretsManager(config=FileKeyValueStorage('ksm-config.json'))
    secrets_manager.delete_folder(["[FOLDER_UID1]", "[FOLDER_UID2]"], True)
    HTTPS_PROXY=https://yourproxy:8888 python main.py
    secrets_manager = SecretsManager(
        config=FileKeyValueStorage('ksm-config.json'),
        proxy_url="https://yourproxy:8888"
    )
    https://username:pass@yourproxy:8888
    secret.data.fields.find(x => x.type === 'password')
    const { getSecrets, initializeStorage, localConfigStorage } = require('@keeper-security/secrets-manager-core')
    
    const getKeeperRecords = async () => {
        const storage = localConfigStorage("ksm-config.json")
        // get records
        const {records} = await getSecrets({storage: storage})
        // get password from first record
        const firstRecord = records[0]
        const firstRecordPassword = firstRecord.data.fields.find(x => x.type === 'password')
    }
    getValue(secrets: KeeperSecrets, query: string): any
    const {
        getSecrets,
        localConfigStorage,
        getValue
    } = require('@keeper-security/secrets-manager-core')
    
    const getKeeperRecords = async () => {
        const options = { storage: localConfigStorage("ksm-config.json") }
        
        // get secrets
        const secrets = await getSecrets(options)
    
        // get login with dot notation
        const loginValue = getValue(secrets, 'RECORD_UID/field/login')
    }
    getTotpCode(url: string): string
    const { 
        getSecrets, 
        localConfigStorage, 
        getTotpCode, 
        getValue} = require('@keeper-security/secrets-manager-core')
    
    const getKeeperRecords = async () => {
        const options = { storage: localConfigStorage("ksm-config.json") }
    
        // get secrets
        const secrets = await getSecrets(options)
    
        // get login with dot notation
        const totpUri = getValue(secrets,'RECORD_UID/field/oneTimeCode')
    
        //get TOTP code
        const totp = await getTotpCode(totpUri)
    }
    updateSecret(options, record)
    const { 
        getSecrets, 
        localConfigStorage, 
        updateSecret} = require('@keeper-security/secrets-manager-core')
    
    const storage = localConfigStorage("ksm-config.json")
    
    // get records
    const {records} = await getSecrets({storage: storage})
    
    // get the first record
    const recordToUpdate = records[0]
    
    // set new record title and notes
    recordToUpdate.data.title = 'New Title'
    recordToUpdate.data.notes = "New Notes"
    
    // save record changes
    await updateSecret(options, recordToUpdate)
    const { 
        getSecrets, 
        localConfigStorage, 
        updateSecret,
        completeTransaction,
        UpdateTransactionType,
        SecretManagerOptions
    } = require('@keeper-security/secrets-manager-core')
    
    // get records
    const options = { storage: localConfigStorage("ksm-config.json") }
    const {records} = await getSecrets(options)
    
    // rotate password on the first record
    const secret = records[0]
    const password = secret.data.fields.find(x => x.type === "password")
    password.value[0] = "MyNewPassword"
    
    //start a transaction to update record in vault
    await updateSecret(options, secret, UpdateTransactionType.Rotation)
    
    // rotate password on remote host
    const success = rotateRemoteSshPassword("MyNewPassword");
    
    // complete the transaction - commit or rollback
    const rollback = !success
    await completeTransaction(options, secret.recordUid, rollback)
    generatePassword(length, lowercase, uppercase, digits, specialCharacters)
    const { 
        getSecrets, 
        localConfigStorage, 
        updateSecret, 
        generatePassword } = require('@keeper-security/secrets-manager-core')
    
    // generate a random password
    let newRandomPwd = await generatePassword()
    
    const storage = localConfigStorage("ksm-config.json")
    const {records} = await getSecrets({storage: storage})
    
    // get the first record
    const recordToUpdate = records[0]
    
    // Find the field with the type "password"
    const recordToUpdatePasswordField = recordToUpdate.data.fields.find(x => x.type === 'password')
    
    // set new value to the password field
    recordToUpdatePasswordField.value[0] = newRandomPwd
    
    await updateSecret({storage: storage}, recordToUpdate)
    createSecret(options, folderUid, record)
    deleteSecret(smOptions, recordUids);
    // setup secrets manager
    const smOptions = { storage: localConfigStorage("ksm-config.json") 
    
    // delete a specific secret by record UID
    await deleteSecret(smOptions, ["EG6KdJaaLG7esRZbMnfbFA"]);
    npm install @keeper-security/secrets-manager-core
    initializeStorage(storage: KeyValueStorage, clientKey: String? = null, hostName: String? = null)
    const { getSecrets, initializeStorage, localConfigStorage } = require('@keeper-security/secrets-manager-core')
    
    const getKeeperRecords = async () => {
    
        // oneTimeToken is used only once to initialize the storage
        // after the first run, subsequent calls will use ksm-config.txt
        const oneTimeToken = "<One Time Access Token>";
        
        const storage = localConfigStorage("ksm-config.json")
        
        await initializeStorage(storage, oneTimeToken)
        // Using token only to generate a config (for later usage)
        // requires at least one access operation to bind the token
        //await getSecrets({storage: storage})
        
        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()
    getSecrets(options: SecretsManagerOptions, recordsFilter: List<String> = emptyList()): KeeperSecrets
    const storage = inMemoryStorage() // see initialization example
    val secrets = getSecrets(storage)
    // get all matching records
    getSecretsByTitle = async (options: SecretManagerOptions, recordTitle: string): Promise<KeeperRecord[]>
    
    // get only the first matching record
    getSecretByTitle = async (options: SecretManagerOptions, recordTitle: string): Promise<KeeperRecord>
    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()
    downloadFile(file: KeeperFile): ByteArray
    downloadThumbnail(file: KeeperFile): ByteArray
    uploadFile = async (options: SecretManagerOptions, ownerRecord: KeeperRecord, file: KeeperFileUpload): Promise<string>
    type KeeperFileUpload = {
        name: string
        title: string
        type?: string
        data: Uint8Array
    }
    // 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
    })
    const options: SecretManagerOptions = {    
        storage: kvs,
        queryFunction: cachingPostFunction // Import `cachingPostFunction`
    }
    getFolders = async (options: SecretManagerOptions): Promise<KeeperFolder[]>
    const storage = localConfigStorage("ksm-config.json")
    const folders = await getFolders({storage: storage})
    createFolder = async (options: SecretManagerOptions, createOptions: CreateOptions, folderName: string): Promise<string>
    type CreateOptions = {
        folderUid: string
        subFolderUid?: string
    }
    const storage = localConfigStorage("ksm-config.json")
    const folderUid = await createFolder({storage: storage}, {folderUid: "[PARENT_SHARED_FOLDER_UID]"}, "new_folder")
    updateFolder = async (options: SecretManagerOptions, folderUid: string, folderName: string): Promise<void>
    const storage = localConfigStorage("ksm-config.json")
    await updateFolder({storage: storage}, "[FOLDER_UID]", "new_folder_name")
    deleteFolder = async (options: SecretManagerOptions, folderUids: string[], forceDeletion?: boolean): Promise<SecretsManagerDeleteResponse>
    const storage = localConfigStorage("ksm-config.json")
    await deleteFolder({storage: storage}, ["[FOLDER_UID1]", "[FOLDER_UID2]"], true)
    const {
        getSecrets,
        initializeStorage,
        localConfigStorage,
        setCustomProxyAgent
    } = require('@keeper-security/secrets-manager-core')
    const { HttpsProxyAgent } = require('https-proxy-agent')
    
    const getKeeperRecords = async () => {
        // Set you proxy URL
        setCustomProxyAgent(new HttpsProxyAgent('http://user:[email protected]:3128'))
    
        const storage = localConfigStorage("config.json")
        
        await initializeStorage(storage, 'US:EXAMPLE_ONE_TIME_TOKEN', 'keepersecurity.com')
        const {records} = await getSecrets({storage: storage})
    
        console.log(records)
    }
    cargo add keeper-secrets-manager-core

    JSON Object

    Yes

    token for connecting with Keeper Secrets Manager

    hostName

    string

    Optional

    null

    server location to get secrets. If nothing is passed, will use keepersecurity.com (US)

    Record UIDs to get

    Keeper Notation query

    int

    Optional

    0

    digits

    int

    Optional

    0

    specialCharacters

    int

    Optional

    0

    KeeperFileUpload

    Yes

    The File to upload

    string

    Optional

    The mime type of data in the file. 'application/octet-stream' will be used if nothing is given

    data

    Uint8Array

    Yes

    File data as bytes

    record

    JSON Object

    Yes

    options

    SecretManagerOptions

    Yes

    createOptions

    CreateOptions

    Yes

    string

    Yes

    The Folder name

    string

    Yes

    The new folder name

    The folder UID list

    forceDeletion

    bool

    No

    false

    Force deletion of non-empty folders

    uploadFile

    record

    i32

    Optional

    64

    Length of password

    lowercase

    i32

    Optional

    0

    Count of lowercase characters in the password

    uppercase

    i32

    Optional

    0

    Count of uppercase characters in the password

    digits

    i32

    Optional

    0

    Count of digits in the password

    special_characters

    i32

    Optional

    0

    Count of special characters in the password

    Option<&str>

    Yes

    Title of the file to be uploaded

    mime_type

    Option<&str>

    Yes

    None

    The type of data in the file. If none is provided, 'application/octet-stream' will be used

    Created records and record fields must be formatted correctly

    • See the documentation 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 upload_file

  • String

    Yes

    None

    The note to be made in the created record

    value

    String

    Yes

    Value for the field

    label

    String

    Yes

    None

    Label for the field

    required

    bool

    Yes

    false

    Defines if the field is required

    privacy_screen

    bool

    Yes

    false

    Defines if the field value should be hidden

    Vec<KeeperFolder>

    No

    None

    List of folders to use in the search for parent and sub-folder from CreateOptions

    Vec<KeeperFolder>

    No

    None

    List of folders to use in the search for parent folder

    Parameter

    Required

    Description

    Type

    token

    Yes

    One Time Access Token

    String

    config

    Yes

    Storage Configuration

    KeyValueStorage

    Parameter

    Type

    Required

    Default

    Description

    uids

    Vec<String>

    Optional

    None

    Record UIDs to fetch

    field_type

    String

    Yes

    None

    Field type to get

    single

    boolean

    Optional

    False

    Return only the first value

    field_type

    String

    Yes

    -

    Field type to get

    single

    boolean

    Optional

    False

    Return only the first value

    record_title

    &str

    Yes

    Title of the record to be fetched

    query

    String

    Yes

    -

    Keeper Notation query for getting a value from a specified field

    url

    String

    Yes

    TOTP Url

    record

    Record

    Yes

    Storage and query configuration

    transaction_type

    UpdateTransactionType

    Yes

    Configuration for transactional update

    field_type

    String

    Yes

    Field type to get

    transaction_type

    UpdateTransactionType

    Yes

    None

    Configuration for transactional update

    field_type

    String

    Yes

    Field type to get

    transaction_type

    UpdateTransactionType

    Yes

    None

    Configuration for transactional update

    password_options

    PasswordOptions

    Yes

    Configuration for the password

    charset

    String

    Optional

    Set of special characters to be included in the password

    file_name

    &str

    Yes

    Name of the file to be downloaded

    path

    &str

    Yes

    Path to download file

    owner_record

    Record

    Yes

    None

    The record in which the file has to be uploaded

    keeper_file

    KeeperFileUpload

    Yes

    The file to be uploaded

    file_path

    &str

    Yes

    Path to upload file

    file_name

    Option<&str>

    Yes

    Name of the file to be uploaded

    record_type

    DefaultRecordType

    Yes

    None

    Type of record to be created

    title

    String

    Yes

    The title of the created record

    record_uid

    String

    Yes

    None

    The uid of the record to be deleted

    create_options

    CreateOptions

    Yes

    None

    The parent and sub-folder UIDs

    folder_name

    str

    Yes

    The folder name

    folder_uid

    str

    Yes

    The folder uid

    folder_name

    str

    Yes

    The new folder name

    folder_uids

    Vec<String>

    Yes

    The folder UID list

    force_deletion

    boolean

    No

    false

    Force deletion of non-empty folders

    GitHub repository
    record-type-info
    Keeper Notation documentation
    Record Types
    Record Types

    length

    file_title

    note

    folders

    folders

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

    Source Code

    Find the Go source code in the GitHub repository

    Using the SDK

    Initialize

    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

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

    Parameter

    Type

    Required

    Default

    Description

    token

    string

    Yes

    Keeper Secrets Manager One time token

    hostName

    string

    Yes

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

    Retrieve Secrets

    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

    Retrieve Secrets with a Filter

    Retrieve Secrets by Title

    Parameter
    Type
    Required
    Description

    recordTitle

    string

    Yes

    Record title to search for

    Example Usage

    Get Values From a Secret

    Get a Password

    Field types are based on the Keeper . For a detailed list of available fields based on the Keeper Record Type, see the record-type-info command in Keeper Commander.

    Retrieve Values using Keeper Notation

    See Keeper Notation documentation to learn about Keeper Notation format and capabilities

    Parameter

    Type

    Required

    Default

    Description

    query

    String

    Yes

    Keeper Notation query for getting a value from a specified field

    Returns

    Type: []interface{}

    The value of the queried field

    Retrieve TOTP Code

    Parameter

    Type

    Required

    Default

    Description

    url

    string

    Yes

    TOTP Url

    Update a Secret

    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.

    Update Password

    Parameter

    Type

    Required

    Default

    Description

    password

    string

    Yes

    New password to set to the record

    Update Other Fields

    Parameter

    Type

    Required

    Default

    Description

    field

    string

    Yes

    name of the field to update

    value

    string

    Yes

    Update Secret in Vault

    Save the record to make the changes made appear in the

    Parameter

    Type

    Required

    Default

    Description

    record

    KeeperRecord

    Yes

    Record with updated field to save changes for

    Example Usage

    Update Password

    Update other fields

    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 documentation for a list of field types.

    Generate a Random Password

    Parameter
    Type
    Required
    Default

    length

    int

    Yes

    lowercase

    int

    Yes

    uppercase

    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

    Parameter

    Type

    Required

    Default

    Description

    title

    string

    Yes

    Name of file to download

    path

    string

    Yes

    Response

    Type: bool

    Did the file save succeed

    Example Usage

    Upload a File

    Parameter
    Type
    Required
    Description

    ownerRecord

    Record

    Yes

    The record to attach the uploaded file to

    file

    KeeperFileUpload

    Yes

    The File to upload

    Parameter
    Type
    Required
    Description

    name

    string

    Yes

    What the name of the file will be in Keeper once uploaded

    title

    string

    Yes

    What the title of the file will be in Keeper once uploaded

    type

    Example Usage

    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 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

    Parameter
    Type
    Required
    Default

    recordUid

    string

    No

    auto generated random UID

    folderUid

    string

    Yes

    Parameter
    Type
    Required
    Default

    This example creates a login type record with a login value and a generated password.

    Replace [FOLDER UID] in the example with the UID of a shared folder that your Secrets Manager has access to.

    Replace [FOLDER UID] in the example with the UID of a shared folder that your Secrets Manager has access to.

    This example creates a record with a custom record type.

    Delete a Secret

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

    Parameter
    Type
    Required

    recordUids

    []string

    Yes

    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.

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

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Response

    Type: []*KeeperFolder, error

    Example Usage

    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.

    Parameter
    Type
    Required
    Description

    createOptions

    CreateOptions

    Yes

    The parent and sub-folder UIDs

    folderName

    string

    Yes

    The Folder name

    folders

    Example Usage

    Update a Folder

    Updates the folder metadata - currently folder name only.

    Parameter
    Type
    Required
    Description

    folderUid

    string

    Yes

    The folder UID

    folderName

    string

    Yes

    The new folder name

    folders

    Example Usage

    Delete Folders

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

    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.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    Parameter
    Type
    Required
    Description

    folderUids

    []string

    Yes

    The folder UID list

    forceDeletion

    bool

    Yes

    Force deletion of non-empty folders

    Example Usage

    Return only the first value

    value

    String or String[]

    Optional

    None

    If passed, set the value of the field to the given value

    Field type to get

    single

    boolean

    Optional

    False

    Return only the first value

    value

    String or String[]

    Optional

    None

    If passed, set the value of the field to the given value

    Return only the first value

    value

    String or String[]

    Optional

    None

    If passed, set the value of the field to the given value

    Field type to get

    single

    boolean

    Optional

    False

    Return only the first value

    value

    String or String[]

    Optional

    None

    If passed, set the value of the field to the given value

    int

    Optional

    0

    digits

    int

    Optional

    0

    specialCharacters

    int

    Optional

    0

    Create folders in the file_path if not present

    None

    What the name of the file will be in Keeper once uploaded

    file_title

    string

    No

    None

    What the title of the file will be in Keeper once uploaded

    mime_type

    string

    No

    None

    The type of data in the file. If none is provided, 'application/octet-stream' will be used

    create_options

    CreateOptions

    Yes

    record

    KeeperRecord

    Yes

    The Folder name

    folders

    List[KeeperFolder]

    No

    None

    List of folders to use in the search for parent and sub-folder from CreateOptions

    The new folder name

    folders

    List[KeeperFolder]

    No

    None

    List of folders to use in the search for parent folder

    False

    Force deletion of non-empty folders

    upload_file
    createSecret2(options, createOptions, record)
    let newRec = {
        "title": "Sample KSM Record: JavaScript",
        "type": "login",
        "fields": [
            { "type": "login",    "value": [ "[email protected]" ] },
            { "type": "password", "value": [ await generatePassword() ] }
        ],
        "notes": "This is a JavaScript record creation example"
    }
    
    let recordUid = await createSecret(options, folderUid, newRec)
    let newRec = {
        "title": "Sample Custom Type KSM Record: JavaScript",
        "type": "Custom Login",
        "fields": [
            {
                "type": "host",
                "label": "My Custom Host lbl",
                "value": [ {"hostName": "127.0.0.1", "port": "8080"} ],
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "login",
                "label": "My Custom Login lbl",
                "value": [ "[email protected]" ],
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "password",
                "label": "My Custom Password lbl",
                "value": [ await generatePassword() ],
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "url",
                "label": "My Login Page",
                "value": [ "http://localhost:8080/login" ],
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "securityQuestion",
                "label": "My Question 1",
                "value": [ {
                    "question": "What is one plus one (write just a number)",
                    "answer": "2"
                } ],
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "phone",
                "value": [{
                    "region": "US",
                    "number": "510-444-3333",
                    "ext": "2345",
                    "type": "Mobile"
                }],
                "label": "My Phone Number"
            },
            {
                "type": "date",
                "value": [ 1641934793000 ],
                "label": "My Date Lbl",
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "name",
                "value": [{
                    "first": "John",
                    "middle": "Patrick",
                    "last": "Smith"
                }],
                "label": "My Custom Name lbl",
                "required": true,
                "privacyScreen": false
            },
            {
                "type": "oneTimeCode",
                "label": "My TOTP",
                "value": ["otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example"],
                "required": true,
                "privacyScreen": false
            }
        ],
        "custom": [
            {
                "type": "phone",
                "value": [{
                    "region": "US",
                    "number": "(510) 123-3456"
                }],
                "label": "My Custom Phone Lbl 1"
            },
            {
                "type": "phone",
                "value": [ {
                    "region": "US",
                    "number": "510-111-3333",
                    "ext": "45674",
                    "type": "Mobile" } ],
                "label": "My Custom Phone Lbl 2"
            }
        ],
        "notes": "\tThis custom type record was created\n\tvia KSM Katacoda JavaScript Example"
    }
    
    let recordUid = await createSecret(options, "[FOLDER UID]", newRec)
    SecretsManager::new(client_options)?
    use keeper_secrets_manager_core::{ClientOptions, SecretsManager,storage::FileKeyValueStorage}
    
    fn main()-> Result<(), KSMRError>{
        let client_options = ClientOptions::new_client_options_with_token(token, config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
        Ok(())
    }
    let records_filter = Vec::new(); // add record filters of needed based on UID
    let secrets = secrets_manager.get_secrets(records_filter)?;
    use keeper_secrets_manager_core::{core::{ClientOptions, SecretsManager}, custom_error::KSMRError, storage::FileKeyValueStorage};
    
    fn main()-> Result<(), KSMRError>{
        let token = "<Your One time token>".to_string();
        let file_name = FileKeyValueStorage::new_config_storage("test.json".to_string())?;
        let client_options = ClientOptions::new_client_options(token, file_name); 
        
        let mut secrets_manager = SecretsManager::new(client_options)?;
        let secrets = secrets_manager.get_secrets(Vec::new())?;
    
        for secret in secrets {
            secret.print();
            println!("---");
        }
        Ok(())
    }
    use keeper_secrets_manager_core::{core::{ClientOptions, SecretsManager}, custom_error::KSMRError, storage::FileKeyValueStorage};
    
    fn main()-> Result<(), KSMRError>{
        let token = "<Your One time token>".to_string();
        let file_name = FileKeyValueStorage::new_config_storage("test.json".to_string())?;
        let client_options = ClientOptions::new_client_options(token, file_name); 
        
        let mut secrets_manager = SecretsManager::new(client_options)?;
        let records_filter = vec!["record_uid1","record_uid2"]; // add record filters of needed based on UID
        let secrets = secrets_manager.get_secrets(records_filter)?;
    
        for secret in secrets {
            secret.print();
            println!("---");
        }
        Ok(())
    }
    secret.get_standard_field_value('password', true);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by record UID
        let secrets = secrets_manager.get_secrets(vec!["record_uid".to_string()])?;
        let secret = match secrets.len(){
            0 => return Err(KSMRError::CustomError("no secret with given uid is found".to_string())),
            _ => &secrets[0],
        };
        // get password from record
        let my_secret_password = secret.get_standard_field_value("password", true);
        Ok(())
    }
    secret.get_standard_field_value(“FIELD_TYPE”.to_string(), true);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::FileKeyValueStorage,
        custom_error::KSMRError,
        enums::StandardFieldTypeEnum
    };
    
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let token = "your_token_goes_here".to_string();
        let config = FileKeyValueStorage::new_config_storage("test.json".to_string())?;
        let client_options = ClientOptions::new_client_options_with_token(token, config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by record UID
        let secrets = secrets_manager.get_secrets(vec!["record_uid".to_string()])?;
        let secret = match secrets.len(){
            0 => return Err(KSMRError::CustomError("no secret with given uid is found".to_string())),
            _ => &secrets[0],
        };
        // use StandardFieldTypeEnum for getting accurate type for standard field without any typographic errors
        let login_field = StandardFieldTypeEnum::LOGIN.get_type().to_string();
        // get login field from the secret
        let my_secret_login = secret.get_standard_field_value(login_field, true)
        Ok(())
    }
    secret.get_custom_field_value(“FIELD_TYPE”, true);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by record UID
        let secrets = secrets_manager.get_secrets(vec!["record_uid".to_string()])?;
        let secret = match secrets.len(){
            0 => return Err(KSMRError::CustomError("no secret with given uid is found".to_string())),
            _ => &secrets[0],
        };
        // Get a custom field, e.g. API Key
        let api_key = secret.get_custom_field_value(“API Key”, true)
        Ok(())
    }
    secrets_manager.get_secret_by_title(record_title);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get all secrets matching the record title
        let secrets = secrets_manager.get_secret_by_title("My Credentials").unwrap().unwrap();
        Ok(())
    }
    secrets_manager.get_notation(query)
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get all secrets matching the notation
        let mut notation = "HDQTnxkTcPSOsHNAlbI4aQ/field/login".to_string();
        let mut result = secrets_manager.get_notation(notation)?;
        Ok(())
    }
    get_totp_code(&url)
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get TOTP url value from a record
        let value = record.get_standard_field_value(StandardFieldTypeEnum::ONETIMECODE.get_type(), false)
        let url: String = utils::get_otp_url_from_value_obj(value)?;
    
        // get code from TOTP url
        let totp = utils::get_totp_code(&url)?;
        println!("{}", totp.get_code());
        Ok(())
    }
    secrets_manager.save(Record, UpdateTransactionType)
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secret_to_update = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?;
    
        // update a field value
        let field_type= StandardFieldTypeEnum::LOGIN.get_type();
        secret_to_update.set_standard_field_value_mut(field_type, "[email protected]".into())?;
    
        let transaction_type: Option<UpdateTransactionType> = Some(UpdateTransactionType::None);
    
        secrets_manager.save(secret_to_update, transaction_type);
        Ok(())
    }
    secret.set_standard_field_value_mut(field_type, "new_field_value".into())
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secret_to_update = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?;
    
        // update a field value
        let field_type= StandardFieldTypeEnum::LOGIN.get_type();
        secret_to_update.set_standard_field_value_mut(field_type, "[email protected]".into())?;
    
        let transaction_type: Option<UpdateTransactionType> = Some(UpdateTransactionType::None);
    
        secrets_manager.save(secret_to_update, transaction_type);
        Ok(())
    }
    secret.set_custom_field_value_mut(field_type, "new_field_value".into());
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secret_to_update = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?;
    
        // update a field value
        secret_to_update.set_custom_field_value_mut("Email", "[email protected]".into())?;
    
        let transaction_type: Option<UpdateTransactionType> = Some(UpdateTransactionType::None);
    
        secrets_manager.save(secret_to_update, transaction_type);
        Ok(())
    }
    generate_password_with_options(password_options);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secret_to_update = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?;
    
        # generate a random password
        let charset: String = "$_!?#".to_string();
        let length = 32;
        let digits = 2;
        let lowercase = 2;
        let uppercase = 2;
        let special_characters = 2;
        let password_options = PasswordOptions::new().length(length).digits(digits).lowercase(lowercase).uppercase(uppercase).special_characters(special_characters).special_characterset(charset);
        let password = generate_password_with_options(password_options).unwrap();
    
        # update a record with new password
        let field_type= StandardFieldTypeEnum::PASSWORD.get_type();
        secret.set_standard_field_value_mut(field_type, password.into())?;
    
        # Save changes to the secret
        let transaction_type: Option<UpdateTransactionType> = Some(UpdateTransactionType::None);
        secrets_manager.save(secret, transaction_type);
        Ok(())
    }
    download_file(file_name, path);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secrets = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?[0];
        // Save all files to a tmp folder (create folder if does not exist)
        let path = format!("./temp/demo_{}.txt", secret.title);
        secret.download_file("uploaded_file.txt", &path)?;
        Ok(())
    }
    upload_file(owner_record, keeper_file);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // get a specific secret by UID
        let secrets = secrets_manager.get_secrets(["<RECORD UID>".to_string()])?[0];
        // Save all files to a tmp folder (create folder if does not exist)
        let path = format!("./temp/demo_{}.txt", secret.title);
        // Prepare file data for upload
        let keeper_file = KeeperFileUpload::get_file_for_upload(file_path, Some(file_name),file_title, mime_type)?;
    
        // Upload file attached to the owner record and get the file UID
        file_uid = secrets_manager.upload_file(owner_record, keeper_file)?;
        Ok(())
    }
    secrets_manager.create_secret(folder_uid, record);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        dto::{dtos::RecordCreate, field_structs::RecordField}
    };
    use serde_json::{self, json, Number, Value};
    
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // This is how we create a Record
        let mut created_record =  RecordCreate::new("login".to_string(), "Login Record RUST_LOG_TEST".to_string(), Some("Dummy Notes".to_string()));
        
        // This is how we create a single field 
        let password_field = RecordField::new_record_field_with_options("password".to_string(), Value::String(utils::generate_password()?), Some("Random password label".to_string()), false, true);
    
        //This is one way to create all fields directly in a vector
        let fields = vec![
            RecordField::new_record_field("login".to_string(), Value::String("[email protected]".to_string()), Some("My Custom Login lbl".to_string())),
    
            password_field,
         ];
    
        created_record.fields = Some(fields);
      
        // Make the API call
        let _ = secrets_manager.create_secret("Shared_folder_uid".to_string(), created_record)?;
        Ok(())
    }
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        dto::{dtos::RecordCreate, field_structs::RecordField}
    };
    use serde_json::{self, json, Number, Value};
    
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // This is how we create a Record
        let mut created_record =  RecordCreate::new("login".to_string(), "Login Record RUST_LOG_TEST".to_string(), Some("Dummy Notes".to_string()));
        
        // This is how we create a single field 
        let password_field = RecordField::new_record_field_with_options("password".to_string(), Value::String(utils::generate_password()?), Some("Random password label".to_string()), false, true);
    
        // This is one of the ways to create a value object from JSON String
        let security_question_value = Value::from_str("{\"question\": \"What is the question?\", \"answer\": \"This is the answer!\"}")?;
        
        //This is one way to create all fields directly in a vector
        let fields = vec![
            RecordField::new_record_field("login".to_string(), Value::String("[email protected]".to_string()), Some("My Custom Login lbl".to_string())),
    
            RecordField::new_record_field("login".to_string(), Value::String("[email protected]".to_string()), Some("My Label".to_string())),
    
            password_field,
            
            RecordField::new_record_field("securityQuestion".to_string(),security_question_value , Some("My Label".to_string())),
    
            RecordField::new_record_field("multiline".to_string(),Value::String("This\nIs a multiline\nnote".to_string()) , Some("My Multiline lbl".to_string())),
    
            RecordField::new_record_field("secret".to_string(),Value::String("SecretText".to_string()) , Some("My Hidden Field lbl".to_string())),
    
            RecordField::new_record_field("pinCode".to_string(),Value::String("1234567890".to_string()) , Some("My Pin Code Field Lbl".to_string())),
    
            RecordField::new_record_field("addressRef".to_string(),Value::String("some_UID".to_string()) , Some("My Address Reference".to_string())),
    
            RecordField::new_record_field("phone".to_string(),json!({"region": "US", "number": "510-444-3333"}) , Some("My Phone Number".to_string())),
    
            RecordField::new_record_field("date".to_string(),Value::Number(Number::from(1641934793000i64)) , Some("My date".to_string())),
    
            RecordField::new_record_field("date".to_string(),Value::String("September eleventh two thousand and eleven".to_string()) , Some("Bad day in history of humanity".to_string())),
    
            RecordField::new_record_field("name".to_string(),json!({"first": "Lincoln", "last": "Adams"}) , Some("His Name".to_string())),
            ];
    
        // Here we are adding fields object to standard fields 
        created_record.fields = Some(fields);
        
        created_record.custom = Some(
            vec![
                RecordField::new_record_field("phone".to_string(),json!({"region": "US", "number": "510-222-5555", "ext": "99887", "type": "Mobile"}) , Some("My Custom Phone Lbl".to_string())),
            ]
        );
       
        // Make the API call
        let _ = secrets_manager.create_secret("Shared_folder_uid".to_string(), created_record)?;
        Ok(())
    }
    secrets_manager.delete_secret(vec![record_uid]);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        // delete a specific secret by UID
        let secret_to_delete = secrets_manager.delete_secret(["<RECORD UID>".to_string()])?;
        Ok(())
    }
    use keeper_secrets_manager_core::{core::{ClientOptions, SecretsManager}, custom_error::KSMRError, storage::FileKeyValueStorage, cache::KSMRCache};
    fn main()-> Result<(), KSMRError>{
        let cache = KSMRCache::new_file_cache(Some("./cache.bin"))?;
    
        let token = "<Token>".to_string();
    
        let file_name = FileKeyValueStorage::new_config_storage("test.json".to_string())?;
        
        let mut client_options = ClientOptions::new_client_options_with_token(token, file_name);
        client_options.set_cache(cache.into()); 
        
        let mut secrets_manager = SecretsManager::new(client_options)?;  
        let secrets = secrets_manager.get_secrets(Vec::new())?;
        for secret in secrets {
            info!("Secret: {}", secret);
        };
    }
    get_folders()
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
        
        // get all folder
        let secrets = secrets_manager.ger_folders()?;
        Ok(())
    }
    create_folder(create_options: CreateOptions, folder_name: str, folders=None)
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        let parent_folder_uid: String = "<parent_folder_uid>".to_string();
        let sub_folder_uid: Option<String> = Option::Some((""));
        let create_options: CreateOptions = CreateOptions::new(parent_folder_uid, None);
        let new_folder_name: String = "Sample Folder 200".to_string();
        println!("Creating folder: {new_folder_name}");
        let created_folder_name = new_folder_name.clone();
        let result = secrets_manager.create_folder(create_options, new_folder_name, Vec::new())?;
        println!("Created folder {created_folder_name}");
        Ok(())
    }
    secrets_manager.update_folder(folder_uid: str, folder_name: str, folders=None)
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::InMemoryKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
    
        let update_folder = secrets_manager.update_folder("<folder_uid>".to_string(),"dummy_updated_API_RUST".to_string(),Vec::new())?;
        println!("{}",(serde_json::to_string_pretty(&update_folder)?));
        Ok(())
    }
    delete_folder(vec![“<FOLDER_UID>”.to_string()], false);
    use keeper_secrets_manager_core::{
        core::{ClientOptions, SecretsManager},
        storage::FileKeyValueStorage,
        custom_error::KSMRError
    };
    fn main()-> Result<(), KSMRError>{
        // setup secrets manager
        let config_string = "your_base64_goes_here".to_string();
        let config = InMemoryKeyValueStorage::new_config_storage(Some(config_string))?;
        let client_options = ClientOptions::new_client_options(config);
        let mut secrets_manager = SecretsManager::new(client_options)?;
        
        let folder_uids = vec!["folder1_uid".to_string(),"folder_2_uid".to_string()];
        secrets_manager.delete_folder(folder_uids, true)?;
        Ok(())
    }
    secret.GetFieldsByType("password")
    	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]
    	}
    
    sm.GetNotation(query)
    	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")
    		}
    	}
    GetTotpCode(url)
    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)
    		}
    	}
    }
    GeneratePassword(length, lowercase, uppercase, digits, specialCharaters)
    // 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)
    secretsManager.CreateSecretWithRecordData(recordUid, folderUid, record)
    secretsManager.DeleteSecrets(recordUids)
    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"})
    }
    $ go get github.com/keeper-security/secrets-manager-go/core
    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{})
    }
    secretsManager := NewSecretsManager(options)
    records, err := sm.GetSecrets([]string{})
    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{})
    }
    
    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]"})
    }
    // get all matching records
    GetSecretsByTitle(recordTitle string) (records []*Record, err error)
    
    // get only the first matching record
    GetSecretByTitle(recordTitle string) (records *Record, err error)
    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(), "]")
    	}
    }
    (r *Record) SetPassword(password string) 
    (r *Record) SetFieldValueSingle(field string, value string) 
    (c *secretsManager) Save(record *Record) (err error) 
    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)
    }
    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)
    }
    (r *Record) DownloadFileByTitle(title string, path string) bool
    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")
    UploadFile(record *Record, file *KeeperFileUpload) (uid string, err error)
    type KeeperFileUpload struct {
    	Name  string
    	Title string
    	Type  string
    	Data  []byte
    }
    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)
    }
    type ICache interface {
    	SaveCachedValue(data []byte) error
    	GetCachedValue() ([]byte, error)
    	Purge() error
    }
    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)
    GetFolders() ([]*KeeperFolder, error)
    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()
    }
    CreateFolder(createOptions CreateOptions, folderName string, folders []*KeeperFolder) (folderUid string, err error)
    type CreateOptions struct {
    	FolderUid    string
    	SubFolderUid string
    }
    type KeeperFolder struct {
    	FolderKey []byte
    	FolderUid string
    	ParentUid string
    	Name      string
    }
    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)
    }
    UpdateFolder(folderUid, folderName string, folders []*KeeperFolder) (err error)
    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)
    }
    DeleteFolder(folderUids []string, forceDeletion bool) (statuses map[string]string, err error)
    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)
    
    	stats, err := sm.DeleteFolder([]string{"[FOLDER_UID1]", "[FOLDER_UID2]"}, true)
    }
    from keeper_secrets_manager_core.dto.dtos import RecordCreate,RecordField
    
    record = RecordCreate(record_type='login', title='test_KSM')
    record.fields = [ 
        RecordField(field_type='login',value='test_login'),
        RecordField(field_type='password',value='test_pwd') 
    ]
    
    from keeper_secrets_manager_core.dto.payload import CreateOptions
    
    create_options = CreateOptions(
        folder_uid='shared_folder_uid',
        subfolder_uid='user_folder_uid'
    )
    
    secrets_manager.create_secret_with_options(create_options, record)
    # create a new login record
    new_login_record = RecordCreate('login', "Sample KSM Record: Python")
    # fill in login and password fields
    new_login_record.fields = [
        RecordField(field_type='login', value='[email protected]'),
        RecordField(field_type='password', value=generate_password())
    ]
    # fill in notes
    new_login_record.notes = 'This is a Python record creation example'
    # create the new record and get its UID
    record_uid = secrets_manager.create_secret('[FOLDER UID]', new_login_record)
    from keeper_secrets_manager_core import SecretsManager
    from keeper_secrets_manager_core.storage import FileKeyValueStorage
    from keeper_secrets_manager_core.dto.dtos import RecordCreate, RecordField
    from keeper_secrets_manager_core.utils import generate_password
    
    # setup secrets manger
    secrets_manager = SecretsManager(
        # token='US:XXXXXX',
        config=FileKeyValueStorage('ksm-config.json')
    )
    
    custom_login = RecordCreate(record_type='Custom Login', title='Sample Custom Type KSM Record: Python')
    custom_login.fields = [
        RecordField(field_type='host', 
                    value={'hostName': '127.0.0.1', 'port': '8080'}, 
                    label="My Custom Host lbl", 
                    required=True),
        RecordField(field_type='login', 
                    value='[email protected]', 
                    label='My Custom Login lbl', 
                    required=True),
        RecordField(field_type='password', 
                    value=generate_password(), 
                    label='My Custom Password lbl', 
                    required=True),
        RecordField(field_type='url', 
                    value='http://localhost:8080/login', 
                    label='My Login Page', 
                    required=True),
        RecordField(field_type='securityQuestion', 
                    value={
                        'question': 'What is one plus one (write just a number)', 
                        'answer': '2'
                    }, 
                    label='My Question 1', 
                    required=True),
        RecordField(field_type='phone', 
                    value={
                      'region': 'US', 
                      'number': '510-444-3333', 
                      'ext': '2345', 
                      'type': 'Mobile'}, 
                    label='My Phone Number'),
        RecordField(field_type='date', 
                    value=1641934793000, 
                    label='My Date Lbl', 
                    required=True),
        RecordField(field_type='name', 
                    value={
                      'first': 'John', 
                      'middle': 'Patrick', 
                      'last': 'Smith'}, 
                    label="My Custom Name lbl", 
                    required=True),
        RecordField(field_type='oneTimeCode', 
                    value='otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example', 
                    label='My TOTP', 
                    required=True)
    ]
    
    custom_login.custom = [
        RecordField(field_type='phone', 
                    value={'region': 'US', 'number': '510-222-5555', 'ext': '99887', 'type': 'Mobile'}, 
                    label='My Custom Phone Lbl 1'),
        RecordField(field_type='phone', 
                    value={'region': 'US', 'number': '510-111-3333', 'ext': '45674', 'type': 'Mobile'}, 
                    label='My Custom Phone Lbl 2'),
    ]
    
    custom_login.notes = "\tThis custom type record was created\n\tvia Python SDK copied from https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/python-sdk"
    
    record_uid = secrets_manager.create_secret('[FOLDER UID]', custom_login)

    []*KeeperFolder

    No

    Server to connect to

    verifySslCerts

    bool

    yes

    Choose whether to verify SSL certificates or not

    config

    IKeyValueStorage

    yes

    File Storage Configuration

    Value to set the field to

    int

    Yes

    digits

    int

    Yes

    specialCharacters

    int

    Yes

    Path to save the file to

    string

    Yes

    The mime type of data in the file. 'application/octet-stream' for example

    data

    []byte

    Yes

    File data as bytes

    record

    *RecordCreate

    Yes

    createOptions

    CreateOptions

    Yes

    recordData

    *RecordCreate

    Yes

    []*KeeperFolder

    No

    List of folders to use in the search for parent and sub-folder from CreateOptions

    []*KeeperFolder

    No

    List of folders to use in the search for parent folder

    UploadFile

    folders

    .NET SDK

    Detailed .Net SDK docs for Keeper Secrets Manager

    Download and Installation

    Prerequisites

    secretsManager.CreateSecretWithRecordDataAndOptions(createOptions, recordData, folders)
    // 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("[email protected]"),
        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)
    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("[email protected]"),
    	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:[email protected]?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)

    dotnet add package Keeper.SecretsManager

    Source Code

    Find the .Net source code in the GitHub repository

    Using the SDK

    Initialize Storage

    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

    In order to retrieve secrets, you must first initialize the local storage on your machine.

    Parameter

    Type

    Required

    Default

    Description

    storage

    KeyValueStorage

    Yes

    clientKey

    String

    Optional

    null

    Example Usage

    Secrets Manager Options

    Parameter

    Type

    Required

    Default

    storage

    KeyValueStorage

    Yes

    queryFunction

    String

    Optional

    null

    allowUnverifiedCertificate

    Bool

    Retrieve Secrets

    Parameter

    Type

    Required

    Default

    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    recordsFilter

    List<String>

    Optional

    Empty List

    Response

    Type: KeeperSecrets

    Object containing all Keeper records, or records that match the given filter criteria

    Example Usage

    Retrieve all Secrets

    Retrieve Secrets by Title

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    recordTitle

    string

    Yes

    Record title to search for

    Example Usage

    Retrieve Values from a Secret

    Retrieve a Password

    Field types are based on the Keeper . For a detailed list of available fields based on the Keeper Record Type, see the record-type-info command in Keeper Commander.

    Retrieve Other Fields Using Keeper Notation

    See Keeper Notation documentation to learn about Keeper Notation format and capabilities

    Parameter

    Type

    Required

    Default

    Description

    secrets

    KeeperSecrets

    Yes

    Secrets to query

    notation

    string

    Yes

    Retrieve TOTP Code

    Parameter

    Type

    Required

    Default

    Description

    url

    string

    Yes

    TOTP Url

    Update Values in a Secret

    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.

    Save Changes to a Secret

    Parameter

    Type

    Required

    Default

    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    Use UpdateSecret to save changes made to a secret record. Changes will not be reflected in the Keeper Vault until UpdateSecret is performed.

    Update a Field Value

    Parameter

    Type

    Required

    Default

    Description

    fieldType

    string

    Yes

    The field to update

    value

    object

    Yes

    Generate a Random Password

    Parameter
    Type
    Required
    Default

    length

    int

    Optional

    64

    lowercase

    int

    Optional

    0

    uppercase

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

    Download a File

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File to download

    Response

    Type: ByteArray

    ByteArray of file for download

    Download a Thumbnail

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File with thumbnail to download

    Response

    Type: ByteArray

    ByteArray of thumbnail for download

    Upload a File

    Upload File:

    Parameter
    Type
    Required
    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    ownerRecord

    KeeperRecord

    Yes

    The record to attach the uploaded file to

    file

    Creating the Keeper File Upload Object:

    Parameter
    Type
    Required
    Description

    name

    string

    Yes

    What the name of the file will be in Keeper once uploaded

    title

    string

    Yes

    What the title of the file will be in Keeper once uploaded

    type

    Example Usage

    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 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

    Parameter
    Type
    Required
    Defaut

    options

    SecretsManagerOptions

    Yes

    folderUid

    string

    Yes

    Parameter
    Type
    Required
    Defaut

    This example creates a login type record with a login value and a generated password.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    This example creates a record with a custom record type.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager has access to.

    Delete a Secret

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

    Parameter
    Type
    Required

    smOptions

    SecretsManagerOptions

    Yes

    recordsUids

    string[]

    Yes

    Caching

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

    Setup and Configure Cache

    In order to setup caching in the .Net SDK, include a caching post function as the second argument when instantiating aSecretsManagerOptions object.

    The .Net SDK includes a default caching function cachingPostFunction which stores cached queries to a file.

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Response

    Type: KeeperFolder[]

    Example Usage

    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, a 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.

    Parameter
    Type
    Required
    Default
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    createOptions

    CreateOptions

    Yes

    Example Usage

    Update a Folder

    Updates the folder metadata - currently folder name only.

    Parameter
    Type
    Required
    Default
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUid

    string

    Yes

    Example Usage

    Delete Folders

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

    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.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    Parameter
    Type
    Required
    Default
    Description

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUids

    string[]

    Yes

    Example Usage

    Proxy support

    .NET SDK supports setting proxy through environment variables and passing proxy url to SecretsManagerOptions directly

    Keeper recommends using environment variables for proxy settings. This approach keeps configuration details out of code, ensures consistency across tools and environments, and simplifies deployment and maintenance

    Example usage through environment variables

    Example usage passing url to SecretsManagerOptions

    secret.FieldValue("password")
    var storage = new LocalConfigStorage(configName);
    Console.WriteLine($"Local Config Storage opened from the file {configName}");
    if (clientKey != null)
        SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");
    }
    var options = new SecretsManagerOptions(storage);
    //get secrets
    var secrets= (await SecretsManagerClient.GetSecrets(options)).Records;
    
    // get the password from the first secret
    var firstSecret= secrets[0];
    var password = firstSecret.FieldValue("password").ToString();
    GetValue(KeeperSecrets secrets, string notation)
    var storage = new LocalConfigStorage(configName);
    Console.WriteLine($"Local Config Storage opened from the file {configName}");
    if (clientKey != null)
        SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");
    }
    var options = new SecretsManagerOptions(storage);
    //get secrets
    var secrets (await SecretsManagerClient.GetSecrets(options)).Records;
    
    // get login field value using dot notation
    var password = Notation.GetValue(secrets, "BediNKCMG21ztm5xGYgNww/field/login");
    CryptoUtils.GetTotpCode(string url)
    var storage = new LocalConfigStorage(configName);
    Console.WriteLine($"Local Config Storage opened from the file {configName}");
    if (clientKey != null)
        SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");
    }
    var options = new SecretsManagerOptions(storage);
    //get secrets
    var secrets (await SecretsManagerClient.GetSecrets(options)).Records;
    
    // get TOTP url from a record
    var url = Notation.GetValue(secrets, "BediNKCMG21ztm5xGYgNww/field/OneTimeCode");
    
    // get TOTP code
    var totp = CryptoUtils.GetTotpCode(url);
    Console.WriteLine(totp.Code);
    UpdateSecret(options: SecretsManagerOptions, record: KeeperRecord);
    var options = SecretsManagerOptions(storage, testPostFunction)
    await SecretsManagerClient.UpdateSecret(options, secret);
    var storage = new LocalConfigStorage(configName);
    var options = new SecretsManagerOptions(storage);
    
    //get secrets
    var secrets = (await SecretsManagerClient.GetSecrets(options)).Records;
    
    // get the first secret
    var secret = secrets[0];
    
    // rotate password on the record
    secret.updateFieldValue("password", "MyNewPassword");
    //start a transaction
    await SecretsManagerClient.UpdateSecret(options, secret, UpdateTransactionType.Rotation);
    // rotate password on remote host
    success = rotateRemoteSshPassword("MyNewPassword");
    // complete the transaction - commit or rollback
    await SecretsManagerClient.CompleteTransaction(options, secret.RecordUid, rollback: !success);
    UpdateFieldValue(string fieldType, object value)
    var storage = new LocalConfigStorage(configName);
    Console.WriteLine($"Local Config Storage opened from the file {configName}");
    if (clientKey != null)
        SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");
    }
    var options = new SecretsManagerOptions(storage);
    //get secrets
    var secrets= (await SecretsManagerClient.GetSecrets(options)).Records;
    
    // get the password from the first secret
    var firstSecret= secrets[0];
    
    // update the login field
    firstSecret.updateFieldValue("login", "My New Login");
    
    // update title and notes
    firstSecret.Data.title = "New Title";
    firstSecret.Data.notes = "New Notes";
    
    // save changes
    await SecretsManagerClient.UpdateSecret(options, firstSecret);
    
    CryptoUtils.GeneratePassword(int length, lowercase int, uppercase int, digits int, specialCharacters);
    // generate a random password
    var password = CryptoUtils.GeneratePassword();
    // update a record with the new password
    firstRecord.UpdateFieldValue("password", password);
    await SecretsManagerClient.UpdateSecret(options, firstRecord);
    SecretsManagerClient.CreateSecret(options, folderUid, record)
    DeleteSecret(smOptions, recordsUids);
    using SecretsManager;
    
    // setup secrets manager
    var storage = new LocalConfigStorage("ksm-config.json");
    //SecretsManagerClient.InitializeStorage(storage, "<One Time Access Token>");
    var smOptions = new SecretsManagerOptions(storage);
    
    // delete a specific secret by record UID
    await SecretsManagerClient.DeleteSecret(smOptions, new string[] {"EG6KdJaaLG7esRZbMnfbFA"});
    SecretsManagerClient.InitializeStorage(storage: KeyValueStorage, clientKey: String? = null, hostName: String? = null)
    var storage = new LocalConfigStorage("ksm-config.json");
    SecretsManagerClient. InitializeStorage(storage, "[One Time Access Token]");
    // Using token only to generate a config (for later usage)
    // requires at least one access operation to bind the token
    //var options = new SecretsManagerOptions(storage);
    //await SecretsManagerClient.GetSecrets(options);
    SecretsManagerOptions(IKeyValueStorage storage, QueryFunction queryFunction = null, bool allowUnverifiedCertificate = false, string proxyUrl = null)
    GetSecrets(options: SecretsManagerOptions, recordsFilter: List<String> = emptyList()): KeeperSecrets
    var options = new SecretsManagerOptions(storage, testPostFunction);
    var secrets = GetSecrets(options);
    // get all matching records
    async Task<IEnumerable<KeeperRecord>> GetSecretsByTitle(SecretsManagerOptions options, string recordTitle)
    
    // get only the first matching record
    async Task<KeeperRecord> GetSecretByTitle(SecretsManagerOptions options, string recordTitle)
    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) + "]");
            }
        }
    }
    DownloadFile(file: KeeperFile): ByteArray
    DownloadThumbnail(file: KeeperFile): ByteArray
    UploadFile(SecretsManagerOptions options, KeeperRecord ownerRecord, KeeperFileUpload file)
    KeeperFileUpload(string name, string title, string type, byte[] data)
    using System;
    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.GetSecrets(
                options, new[] { "XXX" })
            ).Records;
            
        var ownerRecord = records[0];
        
        // get file data to upload
        var bytes = await File.ReadAllBytesAsync("my-file.json");
        var myFile = new KeeperFileUpload(
            "my-file1.json", 
            "My File", 
            null, 
            bytes
        );
           
        // upload file to selected record                     
        await SecretsManagerClient.UploadFile(options, firstRecord, myFile);
        
    }
    var options = new SecretsManagerOptions(storage, SecretsManagerClient.CachingPostFunction);
    var secrets = await SecretsManagerClient.GetSecrets(options);
    Task<KeeperFolder[]> GetFolders(SecretsManagerOptions options)
    using SecretsManager;
    
    var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    var folders = await SecretsManagerClient.GetFolders(options);
    Task<string> CreateFolder(SecretsManagerOptions options, CreateOptions createOptions, string folderName, KeeperFolder[] folders = null)
    public class CreateOptions {
        public string FolderUid { get; }
        public string SubFolderUid { get; }
    }
    public class KeeperFolder {
            public byte[] FolderKey { get; }
            public string FolderUid { get; }
            public string ParentUid { get; }
            public string Name { get; }
    }
    using SecretsManager;
    
    var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    var co := new CreateOptions("[PARENT_SHARED_FOLDER_UID]");
    var folderUid = await SecretsManagerClient.CreateFolder(options, co, "new_folder");
    Task UpdateFolder(SecretsManagerOptions options, string folderUid, string folderName, KeeperFolder[] folders = null)
    using SecretsManager;
    
    var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    await SecretsManagerClient.UpdateFolder(options, "[FOLDER_UID]", "new_folder_name");
    Task DeleteFolder(SecretsManagerOptions options, string[] folderUids, bool forceDeletion = false)
    using SecretsManager;
    
    var options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    await SecretsManagerClient.DeleteFolder(options, new string[]{"[FOLDER_UID1]", "[FOLDER_UID2]"}, true);
    HTTPS_PROXY=http://user:[email protected]:3128 dotnet run
    var options = new SecretsManagerOptions(storage, null, false, "http://user:[email protected]:3128");

    KeeperRecordData

    Yes

    folders

    KeeperFolder[]

    No

    hostName

    String

    Optional

    null

    Optional

    false

    proxyUrl

    String

    Optional

    null

    Record search filters

    Field query in dot notation format

    Value to set the field to

    int

    Optional

    0

    digits

    int

    Optional

    0

    specialCharacters

    int

    Optional

    0

    KeeperFileUpload

    Yes

    The File to upload

    string

    Yes

    The mime type of data in the file. 'application/octet-stream' for example

    data

    byte[]

    Yes

    File data as bytes

    record

    KeeperRecordData

    Yes

    options

    SecretsManagerOptions

    Yes

    createOptions

    CreateOptions

    Yes

    The parent and sub-folder UIDs

    folderName

    string

    Yes

    The Folder name

    folders

    KeeperFolder[]

    No

    null

    List of folders to use in the search for parent and sub-folder from CreateOptions

    The folder UID

    folderName

    string

    Yes

    The new folder name

    folders

    KeeperFolder[]

    No

    null

    List of folders to use in the search for parent folder

    The folder UID list

    forceDeletion

    bool

    No

    false

    Force deletion of non-empty folders

    UploadFile

    record

    SecretsManagerClient.CreateSecret2(options, createOptions, record, folders)
    var newRecord = new KeeperRecordData{type = "login", title = "Sample KSM Record: C#"};
    
    newRecord.fields = new[]
    {
        new KeeperRecordField { type = "login", value = new[] { "My Username" } },
        new KeeperRecordField { type = "password", value = new[] { CryptoUtils.GeneratePassword() } },
    };
    newRecord.notes = "This is a C# record creation example";
    
    var recordUid = await SecretsManagerClient.CreateSecret(options, folderUid, newRecord);
    var newRecord = new KeeperRecordData();
    newRecord.type = "Custom Login";
    newRecord.title = "Sample Custom Type KSM Record: C#";
    newRecord.fields = new[]
    {
        new KeeperRecordField { 
            type = "host", 
            value = new[] 
            {
                new Dictionary<string, string>
                {
                    { "hostName", "127.0.0.1"},
                    { "port", "8080"}
                }
            },
            label = "My Custom Host lbl",
            required = true
        },
        
        new KeeperRecordField { 
            type = "login", 
            value = new[] { "[email protected]" }, 
            required = true, 
            label = "My Custom Login lbl"
        },
        
        new KeeperRecordField
        {
            type = "password", 
            value = new[] { CryptoUtils.GeneratePassword() }, 
            required = true, 
            label = "My Custom Password lbl"
        },
        
        new KeeperRecordField
        {
            type = "url",
            value = new[] { "http://localhost:8080/login" },
            label = "My Login Page",
            required = true
        },
        
        new KeeperRecordField { 
            type = "securityQuestion", 
            value = new[]
            {
                new Dictionary<string, string>
                {
                    {"question", "What is one plus one (write just a number)"}, 
                    { "answer", "2" }
                }
            }, 
            label = "My Question 1",
            required = true
        },
        
        new KeeperRecordField { 
            type = "phone", 
            value = new[]
            {
                new Dictionary<string,string>
                {
                    { "region", "US" },
                    { "number", "510-444-3333" },
                    { "ext", "2345" },
                    { "type", "Mobile" }
                }
            }, 
            label = "My Private Phone", 
            privacyScreen = true
        },
    
        new KeeperRecordField
        {
            type = "date", 
            value = new[] {(object) 1641934793000 }, 
            label = "My Date Lbl"
        },
        
        new KeeperRecordField { 
            type = "name", 
            value = new[]
            {
                new Dictionary<string, string>
                {
                    {"first", "John"},
                    {"middle", "Patrick"},
                    {"last", "Smith"}
                }
            },
            required = true
        },
        new KeeperRecordField
        {
            type = "oneTimeCode", 
            value = new[]
            {
                "otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example"
            }, 
            label = "My TOTP",
            required = true
        }
    };
    newRecord.notes = "\tThis custom type record was created\n\tvia Python SDK copied from https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/.net-sdk";
    
    var recordUid = await SecretsManagerClient.CreateSecret(options, "[FOLDER_UID]", newRecord);
    

    Java/Kotlin SDK

    Detailed Java and Kotlin SDK docs for Keeper Secrets Manager

    Download and Installation

    Install With Maven or Gradle

    Cryptographic Provider

    The Keeper Secrets Manager SDK expects the developer to use their required cryptographic provider. As documented above, Keeper will use the default cryptographic module of the Java runtime unless a specific provider is added. In the examples here in this documentation, we are using the BouncyCastle FIPS provider.

    In the source code, ensure that the provider is loaded in the security context:

    See the file CryptoUtilsTest.kt as shown in this on how to use a custom security provider.

    Source Code

    Find the Java/Kotlin source code in the

    Initialize Storage

    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

    In order to retrieve secrets, you must first initialize the local storage on your machine.

    Example Usage

    Retrieve Secrets

    Response

    Type: KeeperSecrets

    Object containing all Keeper records, or records that match the given filter criteria

    Example Usage

    Retrieve all Secrets

    Retrieve one secret by UID

    Retrieve Secrets by Title

    Parameter
    Type
    Required
    Description

    Example Usage

    Retrieve Values From a Secret

    Retrieve a Password

    This shortcut gets the password of a secret once that secret has been retrieved from Keeper Secrets Manager.

    Retrieve Fields

    To get a field value, you will need to cast the return to the of the corresponding field type. For a list of field types see the page.

    Keeper Notation

    See to learn about Keeper Notation format and capabilities

    Get TOTP Code

    Update Values in a Secret

    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.

    Update Secret

    Update Secret is used to save changes made to a secret. Once updateSecret is performed successfully, the changes are reflected in the Keeper Vault.

    Update Password

    Update other fields

    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 documentation for a list of field types.

    Fields can have multiple values, which is accessed in a List. In this example we are updating the login field, which only accepts one value, so we update the one value in the values list.

    Generate a Random Password

    Parameter
    Type
    Required
    Default

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

    Download a File

    Response

    Type: ByteArray

    ByteArray of file for download

    Download a Thumbnail

    Response

    Type: ByteArray

    ByteArray of thumbnail for download

    Upload a File

    Upload File:

    Parameter
    Type
    Required
    Description

    Creating the Keeper File Upload Object:

    Parameter
    Type
    Required
    Description

    Example Usage

    Remove Files from a Record

    SDK Version Required: 17.1.1 or higher

    This feature add the ability to remove file attachments from records using the UpdateOptions class with the linksToRemove parameter.

    Prerequisites:

    • Record UID or KeeperRecord object containing files

    • File UIDs of the files to be removed

    • Files must exist on the record to be removed

    Parameter
    Type
    Required
    Default
    Description

    Full Example Usage:

    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

    Parameter
    Type
    Required
    Default

    Delete a Secret

    The Java/Kotlin KSM SDK can delete records in the Keeper Vault.

    Parameter
    Type
    Required

    Caching

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

    Setup and Configure Cache

    In order to setup caching in the Java SDK, include a caching post function as the second argument when instantiating aSecretsManagerOptions object.

    The Java SDK includes a default caching function cachingPostFunction which stores cached queries to a file.

    Folders

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

    Read Folders

    Downloads full folder hierarchy.

    Response

    Type: List<KeeperFolder>

    Example Usage

    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.

    Parameter
    Type
    Required
    Default
    Description

    Example Usage

    Update a Folder

    Updates the folder metadata - currently folder name only.

    Parameter
    Type
    Required
    Default
    Description

    Example Usage

    Delete Folders

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

    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.

    Any folders UIDs missing from the vault or not shared to the KSM Application will not result in error.

    Parameter
    Type
    Required
    Default
    Description

    Example Usage

    PAM Records Types - Accessing Linked Credentials

    SDK Version Required: 17.1.1 or higher

    On PAM Resource Records Types (PAM Machine, PAM Directory, PAM Database), the following credentials can be linked:

    • Administrative Credentials - the credentials used to perform administrative operations on the resource

    • Launch Credentials - the credentials used to authenticate a launched session to the resource

    Prerequisites:

    • Use getSecrets2() method instead of getSecrets()

    • Set requestLinks = true in QueryOptions to enable GraphSync™

    • Links will be null if requestLinks is false, empty list if true

    Parameter
    Type
    Required
    Default
    Description

    QueryOptions Parameters

    Parameter
    Type
    Required
    Default
    Description

    Link Methods

    Method
    Returns
    Description

    Basic Usage - Retrieve Records with Links

    Check Link Properties

    Common Example - Find PAM Users

    Additional Details

    For detailed information on the retrievable fields on the PAM record types, see the page.

    For examples on handling Linked Credentials for advanced PAM use cases, see the page.

    Record Field Classes

    Description of each accessible field type Class in the Keeper Secrets Manager Java SDK

    Accessing Record Fields

    Use the getField function to access record fields.

    The 'FIELD_TYPE' needs to be a class from the list below.

    Field Type Classes Reference

    KeeperRecordField

    All Record Fields extend the KeeperRecordField class, and contain a lbl field

    Field Values

    Password

    Field Values

    Url

    Field Values

    FileRef

    Field Values

    OneTimeCode

    Field Values

    OneTimePassword

    Field Values

    Name

    Field Values

    Names

    Field Values

    BirthDate

    Field Values

    Date

    Field Values

    ExpirationDate

    Field Values

    Text

    Field Values

    SecurityQuestion

    Field Values

    SecurityQuestions

    Field Values

    Multiline

    Field Values

    Email

    Field Values

    CardRef

    Field Values

    AddressRef

    Field Values

    PinCode

    Field Values

    Phone

    Field Values

    Phones

    Field Values

    HiddenField

    Field Values

    SecureNote

    Field Values

    AccountNumber

    Field Values

    PaymentCard

    Field Values

    PaymentCards

    Field Values

    BankAccount

    Field Values

    BankAccounts

    Field Values

    KeyPair

    Field Values

    KeyPairs

    Field Values

    Host

    Field Values

    Hosts

    Field Values

    Address

    Field Values

    Addresses

    Field Values

    LicenseNumber

    Field Values

    KeeperFileData

    Field Values

    secret.data.getfield<FIELD_TYPE>()

    No

    null

    enforceGeneration

    Boolean

    No

    null

    value

    MutableList<String>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    Yes

    Yes

    Yes

    No

    null

    No

    null

    value

    MutableList<Name>

    Yes

    No

    null

    value

    MutableList<Long>

    Yes

    No

    null

    value

    MutableList<Long>

    Yes

    No

    null

    value

    MutableList<Long>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    No

    null

    value

    MutableList<SecurityQuestion>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    Yes

    No

    null

    type

    String

    No

    null

    No

    null

    value

    List<Phone>

    Yes

    Yes

    No

    null

    value

    List<String>

    Yes

    No

    null

    value

    List<String>

    Yes

    No

    null

    No

    null

    value

    MutableList<PaymentCard>)

    Yes

    No

    null

    otherType

    String

    No

    null

    No

    null

    value

    MutableList<BankAccount>)

    Yes

    No

    null

    value

    MutableList<KeyPair>

    Yes

    No

    null

    value

    MutableList<Host>

    Yes

    No

    null

    state

    String

    No

    null

    county

    String

    No

    null

    zip

    String

    No

    null

    No

    null

    value

    MutableList<Address>

    Yes

    No

    null

    value

    MutableList<String>

    Yes

    Yes

    size

    Long

    Yes

    lastModified

    Long

    Yes

    Name

    Type

    Required

    Default

    lbl

    String

    No

    null

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    value

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    value

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    value

    Name

    Type

    Required

    Default

    first

    String

    No

    null

    middle

    String

    No

    null

    last

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    question

    String

    No

    null

    answer

    String

    No

    null

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    Label

    String

    No

    null

    required

    Boolean

    No

    null

    value

    Name

    Type

    Required

    Default

    region

    String

    No

    null

    number

    String

    No

    null

    ext

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    value

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    cardNumber

    String

    No

    null

    cardExpirationDate

    String

    No

    null

    cardSecurityCode

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    accountType

    String

    No

    null

    routingNumber

    String

    No

    null

    accountNumber

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    publicKey

    String

    no

    null

    privateKey

    String

    no

    null

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    hostName

    String

    No

    null

    port

    String

    No

    null

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    street1

    String

    No

    null

    street2

    String

    No

    null

    city

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    label

    String

    No

    null

    required

    Boolean

    No

    null

    privacyScreen

    Name

    Type

    Required

    Default

    title

    String

    Yes

    name

    String

    Yes

    type

    Boolean

    Boolean

    MutableList<String>

    MutableList<String>

    MutableList<String>

    String

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    Boolean

    MutableList<String>

    String

    Boolean

    List<String>

    Boolean

    Boolean

    String

    Boolean

    String

    Boolean

    Boolean

    Boolean

    String

    Boolean

    Boolean

    String

    sealed class KeeperRecordField(val lbl: String? = null)
    data class Password(
        var label: String? = null,
        var required: Boolean? = null,
        var privacyScreen: Boolean? = null,
        var enforceGeneration: Boolean? = null,
        var complexity: PasswordComplexity? = null,
        val value: MutableList<String>
    )
    data class Url(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class FileRef(var label: String? = null, var required: Boolean? = null, val value: MutableList<String>)
    data class OneTimeCode(var label: String? = null, var required: Boolean? = null, val value: MutableList<String>)
    data class OneTimePassword(var label: String? = null, var required: Boolean? = null, val value: MutableList<String>)
    data class Name(var first: String? = null, var middle: String? = null, var last: String? = null)
    data class Names(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Name>)
    data class BirthDate(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Long>)
    data class Date(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Long>)
    data class ExpirationDate(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Long>)
    data class Text(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, var value: MutableList<String>)
    data class SecurityQuestion(var question: String? = null, var answer: String? = null)
    data class SecurityQuestions(
        var label: String? = null,
        var required: Boolean? = null,
        var privacyScreen: Boolean? = null,
        val value: MutableList<SecurityQuestion>
    )
    data class Multiline(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class Email(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class CardRef(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class AddressRef(var label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class PinCode(var label: String? = null, var required: Boolean? = null, val value: MutableList<String>)
    data class Phone(
        val region: String? = null,
        val number: String? = null,
        val ext: String? = null,
        val type: String? = null
    )
    data class Phones(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: List<Phone>)
    data class HiddenField(val label: String? = null, var required: Boolean? = null, val value: List<String>)
    data class SecureNote(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: List<String>)
    data class AccountNumber(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: List<String>)
    data class PaymentCard(
        var cardNumber: String? = null,
        var cardExpirationDate: String? = null,
        var cardSecurityCode: String? = null
    )
    data class PaymentCards(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<PaymentCard>) :
    data class BankAccount(
        var accountType: String? = null,
        var routingNumber: String? = null,
        var accountNumber: String? = null,
        var otherType: String? = null
    )
    data class BankAccounts(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<BankAccount>) :
    data class KeyPair(
        val publicKey: String? = null,
        val privateKey: String? = null,
    )
    data class KeyPairs(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<KeyPair>)
    data class Host(
        val hostName: String? = null,
        val port: String? = null,
    )
    
    data class Hosts(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Host>)
    data class Address(
        val street1: String? = null,
        val street2: String? = null,
        val city: String? = null,
        val state: String? = null,
        val country: String? = null,
        val zip: String? = null
    )
    data class Addresses(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<Address>)
    data class LicenseNumber(val label: String? = null, var required: Boolean? = null, var privacyScreen: Boolean? = null, val value: MutableList<String>)
    data class KeeperFileData(
        val title: String,
        val name: String,
        val type: String,
        val size: Long,
        val lastModified: Long
    )

    hostName

    String

    Optional

    null

    Optional

    0

    digits

    int

    Optional

    0

    specialCharacters

    int

    Optional

    0

    Yes

    The File to upload

    Optional

    The mime type of data in the file. 'application/octet-stream' will be used if nothing is given

    data

    ByteArray

    Yes

    File data as bytes

    updateOptions

    UpdateOptions

    Yes

    Options containing files to remove

    Parameter
    Type
    Required
    Default
    Description

    transactionType

    UpdateTransactionType

    No

    null

    Transaction type for batch operations

    linksToRemove

    List<String>

    Yes

    There must be at least one record in the shared folder
  • Created records and record fields must be formatted correctly

    • See the 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

  • newRecordData

    KeeperRecordData

    Yes

    secrets

    KeeperSecrets

    Optional

    Freshly fetched list of all secrets from the Keeper servers

    Parameter
    Type
    Required
    Default

    options

    SecretsManagerOptions

    Yes

    createOptions

    CreateOptions

    Yes

    This example creates a login type record with a login value and a generated password.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager Application has access to.

    This example creates a record with a custom record type.

    Replace '[FOLDER UID]' in the example with the UID of a shared folder that your Secrets Manager Application has access to.

    The parent and sub-folder UIDs

    folderName

    String

    Yes

    The Folder name

    folders

    List<KeeperFolder>

    No

    List<KeeperFolder>

    List of folders to use in the search for parent and sub-folder from CreateOptions

    The folder UID

    folderName

    String

    Yes

    The new folder name

    folders

    List<KeeperFolder>

    No

    List<KeeperFolder>

    List of folders to use in the search for parent folder

    The folder UID list

    forceDeletion

    Boolean

    No

    false

    Force deletion of non-empty folders

    but no links exist

    boolean

    Yes

    false

    Must be true for GraphSync

    Parameter

    Type

    Required

    Default

    Description

    storage

    KeyValueStorage

    Yes

    clientKey

    String

    Optional

    null

    Parameter

    Type

    Required

    Default

    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    recordsFilter

    List<String>

    Optional

    Empty List

    recordTitle

    String

    Yes

    Record title to search for

    Parameter

    Type

    Required

    Default

    Description

    secret

    KeeperRecord

    Yes

    Record to get field value from

    query

    String

    Yes

    Parameter

    Type

    Required

    Default

    Description

    url

    String

    Yes

    TOTP Url

    Parameter

    Type

    Required

    Default

    Description

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    recordToUpdate

    KeeperRecord

    Yes

    Parameter

    Type

    Required

    Default

    Description

    password

    String

    Yes

    New password to set

    length

    int

    Optional

    64

    lowercase

    int

    Optional

    0

    uppercase

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File to download

    Parameter

    Type

    Required

    Default

    Description

    file

    KeeperFile

    Yes

    File with thumbnail to download

    options

    SecretsManagerOptions

    Yes

    Storage and query configuration

    ownerRecord

    KeeperRecord

    Yes

    The record to attach the uploaded file to

    file

    name

    string

    Yes

    What the name of the file will be in Keeper once uploaded

    title

    string

    Yes

    What the title of the file will be in Keeper once uploaded

    type

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    record

    KeeperRecord

    Yes

    options

    SecretsManagerOptions

    Yes

    folderUid

    String

    Yes

    smOptions

    SecretsManagerOptions

    Yes

    recordUids

    List<Sting>

    Yes

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    createOptions

    CreateOptions

    Yes

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUid

    String

    Yes

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    folderUids

    List<String>

    Yes

    options

    SecretsManagerOptions

    Yes

    Preconfigured options

    queryOptions

    QueryOptions

    Yes

    Must set requestLinks=true

    recordsFilter

    List<String>

    No

    Empty

    Filter by record UIDs

    foldersFilter

    List<String>

    No

    Empty

    Filter by folder UIDs

    getRecordUid()

    String

    Target record UID

    isAdminUser()

    boolean

    Admin privileges

    allowsRotation()

    boolean

    Rotation allowed

    allowsConnections()

    boolean

    Connections allowed

    example
    GitHub repository
    class
    Keeper Notation documentation
    Record Field Classes
    Linked Credentials on PAM records

    Record search filters

    Dot notation query of desired field

    Record to update

    int

    KeeperFileUpload

    string

    The record to update

    requestLinks

    // Remove files that start with "teamp_"
    List<String> filesToRemove = new ArrayList<>();
    for (KeeperFile file : record.getFiles()) {
        if (file.getData().getTitle().startsWith("temp_")) {
            filesToRemove.add(file.getFileUid());
        }
    }
    
    if (!filesToRemove.isEmpty()) {
        UpdateOptions updateOptions = new UpdateOptions(null, filesToRemove);
        SecretsManager.updateSecretWithOptions(options, record, updateOptions);
    }
    // Remove files that start with "teamp_"
    val filesToRemove = record.files
        ?.filter { it.data?.title?.startsWith("temp_") == true }
        ?.map { it.fileUid }
        ?: emptyList()
    
    if (filesToRemove.isNotEmpty()) {
        updateSecretWithOptions(
            options,
            record,
            UpdateOptions(linksToRemove = filesToRemove)
        )
    }
    SecretsManager.createSecret2(options, createOptions, newRecordData, folders);
    import com.keepersecurity.secretsManager.core.*;
    
    KeeperRecordData newRecordData = new KeeperRecordData(
            "Sample KSM Record: Java",
            "login",
            Arrays.asList(
                    new Login("My Username"),
                    new Password(CryptoUtils.generatePassword())
            ),
            null,
            "This is a \nmultiline\n\n\tnote"
    );
    
    String recordUid = SecretsManager.createSecret(options, folderUid, newRecordData);
    import com.keepersecurity.secretsManager.core.*;
    
    KeeperRecordData newRecordData = new KeeperRecordData(
            "Sample Custom Type KSM Record: Java",
            "Custom Login",                              // Record Type Name
            Arrays.asList(
                    new Hosts(
                            "My Custom Host lbl",        // label
                            true,                        // required
                            false,                       // private screen
                            List.of(new Host("127.0.0.1", "8000"))),
                    // OR new Hosts(new Host("127.0.0.1", "8000"))
    
                    new Login("My Custom Login lbl",
                            true,
                            false,
                            List.of("[email protected]")),
                    // OR new Login("[email protected]")
    
                    new Password( "My Custom Password lbl",
                            true,
                            false,
                            List.of(CryptoUtils.generatePassword())),
                    // OR new Password(CryptoUtils.generatePassword())
    
                    new Url("My Login Page",
                            true,
                            false,
                            List.of("http://localhost:8080/login")),
                    // OR new Url("http://localhost:8080/login")
                    
                    new SecurityQuestions(
                            "My Question 1",
                            true,
                            false,
                            List.of(new SecurityQuestion("What is one plus one (write just a number)", "2"))),
                    // OR new SecurityQuestions(new SecurityQuestion("What is one plus one (write just a number)", "2"))
    
                    new Phones("My Phone Number",
                            true,
                            false,
                            List.of(new Phone("US", "510-444-3333", "2345", "Mobile"))),
                    // OR new Phones(new Phone("US", "510-444-3333", "2345", "Mobile"))
    
                    new Date("My Date Lbl",
                            true,
                            false,
                            List.of(1641934793000L)
                    ),
                    // OR new Date(1641934793000L),
    
                    new Names("My Custom Name lbl",
                            true,
                            false,
                            List.of(new Name("John", "Patrick", "Smith"))),
                    // OR new Names(new Name("John", "Patrick", "Smith"))
    
                    new OneTimeCode("My TOTP",
                            true,
                            false,
                            List.of("otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example"))
                    // OR new OneTimeCode("otpauth://totp/Example:[email protected]?secret=JBSWY3DPEHPK3PXP&issuer=Example")
            ),
            Arrays.asList(
                    new Phones(new Phone("US", "(510) 123-3456")),
                    new Phones(new Phone("US", "510-111-3333", "45674", "Mobile"))
            ),
            "\tThis custom type record was created\n\tvia KSM Java Document Example"
    );
    
    String recordUid = SecretsManager.createSecret(options, "[FOLDER UID]", newRecordData);
    build.gradle
    repositories {
        mavenCentral()
    }
    
    dependencies {
        implementation 'com.keepersecurity.secrets-manager:core:17.1.2+'
        implementation("org.bouncycastle:bc-fips:1.0.2.4")
    }
    pom.xml
    <dependency>
        <groupId>com.keepersecurity.secrets-manager</groupId>
        <artifactId>core</artifactId>
        <version>[17.1.2,)</version>
    </dependency>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bc-fips</artifactId>
        <version>1.0.2.4</version>
    </dependency>
    fun main() {
        Security.addProvider(BouncyCastleFipsProvider())
    ...
    initializeStorage(storage: KeyValueStorage, clientKey: String? = null, hostName: String? = null)
    import static com.keepersecurity.secretsManager.core.SecretsManager.initializeStorage;
    import com.keepersecurity.secretsManager.core.LocalConfigStorage;
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // oneTimeToken is used only once to initialize the storage
    // after the first run, subsequent calls will use "ksm-config.txt" file
    String oneTimeToken = "[One Time Access Token]";
    LocalConfigStorage storage = new LocalConfigStorage("ksm-config.txt");
    
    Security.addProvider(new BouncyCastleFipsProvider());
    
    try {
        initializeStorage(storage, oneTimeToken);
        SecretsManagerOptions options = new SecretsManagerOptions(storage);
        // Using token only to generate a config (for later usage)
        // requires at least one access operation to bind the token
        //getSecrets(options)
     } catch (Exception e) {
        System.out.println(e.getMessage());
     }
    getSecrets(options: SecretsManagerOptions, recordsFilter: List<String> = emptyList()): KeeperSecrets
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    //get secrets
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    KeeperSecrets secrets = SecretsManager.getSecrets(options);
    
    //get records from secrets
    List<KeeperRecord> records = secrets.getRecords();
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    //get secrets
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    KeeperSecrets secrets = SecretsManager.getSecrets(options);
    
    // identify one or more record UID to fetch secrets by
    List<String> uidFilter = List.of("[XXX]");
    
    // fetch secrets with the filter
    KeeperSecrets secrets = SecretsManager.getSecrets(options, uidFilter);
    
    //get records from secrets
    List<KeeperRecord> records = secrets.getRecords();
    // get all matching records
    getSecretsByTitle(recordTitle: String): List<KeeperRecord>
    
    // get only the first matching record
    getSecretByTitle(recordTitle: String): KeeperRecord
    import com.keepersecurity.secretsManager.core.*;
    import java.util.List;
    
    public class KSMSample {
        public static void main(String[] args){
            
            // Ensure security provider is loaded
            Security.addProvider(new BouncyCastleFipsProvider());
    
            // 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());
            }
        }
    }
    secret.getPassword()
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    //get secrets
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    KeeperSecrets secrets = SecretsManager.getSecrets(options);
    
    //get the first record
    List<KeeperRecord> records = secrets.getRecords().get(0);
    
    //get the password from the first record
    firstRecord.getPassword()
    secret.getData().getField(<FIELD_TYPE>)
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    //get secrets
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    KeeperSecrets secrets = SecretsManager.getSecrets(options);
    
    //get the first record
    List<KeeperRecord> records = secrets.getRecords();
    KeeperRecord firstRecord = secrets.getRecords().get(0);
    
    //get the password from the first record
    KeeperRecordField pwd = firstRecord.getData().getField(Password.class)
    Notation.getValue(secret, "<query>");
    // Query example "<RECORD UID>/field/login"
    import static com.keepersecurity.secretsManager.core.SecretsManager.*
    import static com.keepersecurity.secretsManager.core.Notation.*;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    // get secrets
    KeeperSecrets secrets = getSecrets(options);
    
    // get login with dot notation
    String login = getValue(secrets, "BediNKCMG21ztm5xGYgNww/field/login");
    TotpCode.uriToTotpCode(url)
    import static com.keepersecurity.secretsManager.core.Notation.*;
    import static com.keepersecurity.secretsManager.core.TotpCode.*;
    import java.security.Security;
    import org.bouncycastle.jcajce.provider.BouncyCastleFipsProvider;
    
    ...
    
    // get secrets
    KeeperSecrets secrets = getSecrets(options);
    
    // get TOTP url from record
    String url= getValue(secrets, "BediNKCMG21ztm5xGYgNww/field/oneTimeCode");
    
    // get TOTP code
    TotpCode totp = uriToTotpCode(url);
    updateSecret(options: SecretsManagerOptions, recordToUpdate: KeeperRecord);
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import static com.keepersecurity.secretsManager.core.SecretsManager.*;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    // get secrets
    SecretsManagerOptions options = SecretsManagerOptions(storage);
    KeeperSecrets secrets = getSecrets(options);
    
    // we'll update the first record
    KeeperRecord recordToUpdate = secrets.getRecords().get(0);
    
    // update password
    recordToUpdate.updatePassword("aP1$t367QOCvL$eM$bG#");
    
    // update title and notes
    recordToUpdate.data.title = "New Title"
    recordToUpdate.data.notes = "My Notes"
    
    // save changes
    updateSecret(options, recordToUpdate); 
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    
    import static com.keepersecurity.secretsManager.core.SecretsManager.*;
    
    ...
    
    // get secrets
    SecretsManagerOptions options = SecretsManagerOptions(storage);
    KeeperSecrets secrets = getSecrets(options);
    
    // we'll update the first record
    KeeperRecord record = secrets.getRecords().get(0);
    
    // rotate password on the record
    record.updatePassword("aP1$t367QOCvL$eM$bG#");
    
    // start a transaction
    updateSecret(options, record, transactionType = UpdateTransactionType.GENERAL);
    // rotate password on remote host
    boolean success = rotateRemoteSshPassword("aP1$t367QOCvL$eM$bG#");
    // complete the transaction - commit or rollback
    completeTransaction(options, record.recordUid, rollback = !success);
    recordToUpdate.updatePassword(password: String);
    
    SecretsManager.updateSecret(options, recordToUpdate);
    import static com.keepersecurity.secretsManager.core.SecretsManager;
    
    import com.keepersecurity.secretsManager.core.SecretsManagerOptions;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperSecrets;
    
    // get secrets
    SecretsManagerOptions options = SecretsManagerOptions(storage);
    KeeperSecrets secrets = getSecrets(options);
    
    // we'll update the first record
    KeeperRecord recordToUpdate = secrets.getRecords().get(0);
    
    // update password
    recordToUpdate.updatePassword("aP1$t367QOCvL$eM$bG#");
    
    // save changes
    SecretsManager.updateSecret(options, recordToUpdate);
    //format
    RecordField.getValue().set(index, value)
    
    //example - Login field
    recordLogin.getValue().set(0, "New Login");
    // get field to edit
    Login recordLogin = (Login) recordToUpdate.getData().getField(Login.class);
    
    // update field value
    recordLogin.getValue().set(0, "New Login");
    
    // save changes
    SecretsManager.updateSecret(options, recordToUpdate);
    generatePassword(length: int, lowercase: int, uppercase: int, digits: int, specialCharacters: int)
    import com.keepersecurity.secretsManager.core.CryptoUtils;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    // get field to edit
    Password recordPassword = (Password) recordToUpdate.getData().getField(Password.class);
    
    // generate a random password
    String password = CryptoUtils.generatePassword();
    
    // update field value
    recordPassword.getValue().set(0, password);
    
    // save changes
    SecretsManager.updateSecret(options, recordToUpdate);
    SecretsManager.downloadFile(file): ByteArray
    import static com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperFile;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    // download the first file from the first record
    KeeperRecord firstRecord = secrets.getRecords().get(0);
    KeeperFile file = firstRecord.getFileByName("acme.cer");
    byte[] fileBytes = SecretsManager.downloadFile(file);
    
    // write file to a disk
    try (FileOutputStream fos = new FileOutputStream(file.getData().getName())) {
        fos.write(fileBytes);
    } catch (IOException ioException){
        ioException.printStackTrace();
    }
    SecretsManager.downloadThumbnail(file): ByteArray
    import static com.keepersecurity.secretsManager.core.SecretsManager;
    import com.keepersecurity.secretsManager.core.KeeperRecord;
    import com.keepersecurity.secretsManager.core.KeeperFile;
    
    // Ensure security provider is loaded
    Security.addProvider(new BouncyCastleFipsProvider());
    
    // download the first file from the first record
    KeeperRecord firstRecord = secrets.getRecords().get(0);
    KeeperFile file = firstRecord.getFileByName("acme.cer");
    byte[] fileBytes = SecretsManager.downloadThumbnail(file);
    
    // write file to a disk
    try (FileOutputStream fos = new FileOutputStream(file.getData().getName())) {
        fos.write(fileBytes);
    } catch (IOException ioException){
        ioException.printStackTrace();
    }
    uploadFile(options: SecretsManagerOptions, ownerRecord: KeeperRecord, file: KeeperFileUpload): String
    KeeperFileUpload(
        val name: String,
        val title: String,
        val type: String?,
        val data: ByteArray
    )
    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){
        
            // Ensure security provider is loaded
            Security.addProvider(new BouncyCastleFipsProvider());
    
            // 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 com.keepersecurity.secretsManager.core.*;
    import java.util.*;
    
    // Get record with files
    QueryOptions queryOptions = new QueryOptions(
        Arrays.asList(recordUid),
        Collections.emptyList(),
        true  // request files
    );
    
    KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    KeeperRecord record = secrets.getRecords().get(0);
    
    // Remove specific files
    List<String> fileUidsToRemove = Arrays.asList("fileUid1", "fileUid2");
    
    UpdateOptions updateOptions = new UpdateOptions(
        null,              // transactionType
        fileUidsToRemove  // linksToRemove
    );
    
    SecretsManager.updateSecretWithOptions(options, record, updateOptions);
    SecretsManager.createSecret(options, folderUid, newRecordData, secrets);
    deleteSecret(smOptions, recordUids);
    // setup secrets manager
    val storage = LocalConfigStorage("ksm-config.json")
    //initializeStorage(storage, "<One Time Access Token>")
    val smOptions = SecretsManagerOptions(storage)
    
    // delete a specific secret by record UID
    deleteSecret(smOptions, List.of("EG6KdJaaLG7esRZbMnfbFA"));
    //create options with caching
    SecretsManagerOptions options = new SecretsManagerOptions(storage, SecretsManager::cachingPostFunction);
    
    //example get all secrets
    SecretsManager.getSecrets(options)
    getFolders(options: SecretsManagerOptions): List<KeeperFolder>
    import com.keepersecurity.secretsManager.core.*;
    SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    List<KeeperFolder> folders = SecretsManager.getFolders(options);
    createFolder(options: SecretsManagerOptions, createOptions: CreateOptions, folderName: String, folders: List<KeeperFolder> = getFolders(options)): String
    data class CreateOptions  constructor(
        val folderUid: String,
        val subFolderUid: String? = null,
    )
    data class KeeperFolder(
        val folderKey: ByteArray,
        val folderUid: String,
        val parentUid: String? = null,
        val name: String
    )
    import com.keepersecurity.secretsManager.core.*;
    SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    CreateOptions co := new CreateOptions("[PARENT_SHARED_FOLDER_UID]");
    String folderUid = SecretsManager.createFolder(options, co, "new_folder");
    updateFolder(options: SecretsManagerOptions, folderUid: String, folderName: String, folders: List<KeeperFolder> = getFolders(options))
    import com.keepersecurity.secretsManager.core.*;
    SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    SecretsManager.updateFolder(options, "[FOLDER_UID]", "new_folder_name");
    deleteFolder(options: SecretsManagerOptions, folderUids: List<String>, forceDeletion: Boolean = false): SecretsManagerDeleteResponse
    import com.keepersecurity.secretsManager.core.*;
    SecretsManagerOptions options = new SecretsManagerOptions(new LocalConfigStorage("ksm-config.json"));
    SecretsManager.deleteFolder(options, Arrays.asList("[FOLDER_UID1]", "[FOLDER_UID2]"), true);
    import com.keepersecurity.secretsManager.core.*;
    import java.util.*;
    
    // Enable GraphSync™
    QueryOptions queryOptions = new QueryOptions(
        Collections.emptyList(),  // recordsFilter
        Collections.emptyList(),  // foldersFilter
        true                      // requestLinks - REQUIRED
    );
    
    SecretsManagerOptions options = new SecretsManagerOptions(storage);
    KeeperSecrets secrets = SecretsManager.getSecrets2(options, queryOptions);
    
    // Access links
    for (KeeperRecord record : secrets.getRecords()) {
        List<KeeperRecordLink> links = record.getLinks();
        if (links != null && !links.isEmpty()) {
            for (KeeperRecordLink link : links) {
                System.out.println("Links to: " + link.getRecordUid());
            }
        }
    }
    for (KeeperRecordLink link : record.getLinks()) {
        // Check user privileges
        if (link.isAdminUser()) {
            System.out.println("Admin user");
        }
        
        // Check permissions
        if (link.allowsRotation()) {
            System.out.println("Password rotation allowed");
        }
    }
    // Find users associated with a PAM machine
    for (KeeperRecord machine : secrets.getRecords()) {
        if ("pamMachine".equals(machine.getType())) {
            System.out.println("PAM Machine: " + machine.getTitle());
            
            List<KeeperRecordLink> links = machine.getLinks();
            if (links != null) {
                for (KeeperRecordLink link : links) {
                    // Check if user is admin
                    if (link.isAdminUser()) {
                        System.out.println("  Admin user: " + link.getRecordUid());
                    }
                }
            }
        }
    }

    List of file UIDs to remove

    newRecordData

    KeeperRecordData

    Yes

    folders

    KeeperFolder[]

    Optional

    Freshly fetched list of all folders from the Keeper servers

    Record Field Classes

    Description of each accessible field type Class in the Keeper Secrets Manager Go SDK

    Accessing Record Fields

    Use the GetFieldByType function to access record fields.

    Field Type Classes Reference

    KeeperRecordField

    All Record Fields extend the KeeperRecordField class, and contain a Label and Type fields

    Field Values

    Password

    Field Values

    Url

    Field Values

    FileRef

    Field Values

    OneTimeCode

    Field Values

    Name

    Field Values

    Names

    Field Values

    BirthDate

    Field Values

    Date

    Field Values

    ExpirationDate

    Field Values

    Text

    Field Values

    SecurityQuestion

    Field Values

    SecurityQuestions

    Field Values

    Multiline

    Field Values

    Email

    Field Values

    CardRef

    Field Values

    AddressRef

    Field Values

    PinCode

    Field Values

    Phone

    Field Values

    Phones

    Field Values

    Secret

    Field Values

    SecureNote

    Field Values

    AccountNumber

    Field Values

    PaymentCard

    Field Values

    PaymentCards

    Field Values

    BankAccount

    Field Values

    BankAccounts

    Field Values

    KeyPair

    KeyPairs

    Field Values

    Host

    Field Values

    Hosts

    Field Values

    Address

    Field Values

    Addresses

    Field Values

    LicenseNumber

    Field Values

    KeeperFileData

    Field Values

    loginField, ok := secret.GetFieldByType(ksm.Login{}).(*ksm.Login)

    No

    false

    EnforceGeneration

    bool

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    Yes

    No

    false

    Value

    []string

    Yes

    No

    ""

    No

    false

    Value

    []Name

    Yes

    No

    false

    Value

    []int64

    Yes

    No

    false

    Value

    []int64

    Yes

    No

    false

    Value

    []int64

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []SecurityQuestion

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    ""

    Type

    string

    No

    ""

    No

    false

    Value

    []Phone

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    false

    Value

    []string

    Yes

    No

    ""

    No

    false

    Value

    []PaymentCard

    Yes

    No

    ""

    OtherType

    string

    No

    ""

    No

    false

    Value

    []BankAccount

    Yes

    No

    false

    Value

    []KeyPair

    Yes

    No

    false

    Value

    []Host

    Yes

    No

    ""

    State

    string

    No

    ""

    Country

    string

    No

    ""

    Zip

    string

    No

    ""

    No

    false

    Value

    []Address

    Yes

    No

    false

    Value

    []string

    Yes

    Yes

    Size

    int64

    Yes

    LastModified

    int64

    Yes

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Type

    string

    Yes

    ""

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    Value

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    First

    string

    No

    ""

    Middle

    string

    No

    ""

    Last

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Question

    string

    No

    ""

    Answer

    string

    No

    ""

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Region

    string

    No

    ""

    Number

    string

    No

    ""

    Ext

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    CardNumber

    string

    No

    ""

    CardExpirationDate

    string

    No

    ""

    CardSecurityCode

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    AccountType

    string

    No

    ""

    RoutingNumber

    string

    No

    ""

    AccountNumber

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    PublicKey

    string

    No

    ""

    PrivateKey

    string

    No

    ""

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Hostname

    string

    No

    ""

    Port

    string

    No

    ""

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Street1

    string

    No

    ""

    Street2

    string

    No

    ""

    City

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Label

    string

    No

    ""

    Required

    bool

    No

    false

    PrivacyScreen

    Name

    Type

    Required

    Default

    Title

    string

    Yes

    Name

    string

    Yes

    Type

    bool

    bool

    []string

    bool

    string

    bool

    bool

    bool

    bool

    bool

    bool

    bool

    bool

    bool

    bool

    bool

    string

    bool

    bool

    bool

    bool

    string

    bool

    string

    bool

    bool

    bool

    string

    bool

    bool

    string

    type KeeperRecordField struct {
    	Type  string `json:"type"`
    	Label string `json:"label,omitempty"`
    }
    type Password struct {
    	KeeperRecordField
    	Required          bool               `json:"required,omitempty"`
    	PrivacyScreen     bool               `json:"privacyScreen,omitempty"`
    	EnforceGeneration bool               `json:"enforceGeneration,omitempty"`
    	Complexity        PasswordComplexity `json:"complexity,omitempty"`
    	Value             []string           `json:"value,omitempty"`
    }
    type Url struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type FileRef struct {
    	KeeperRecordField
    	Required bool     `json:"required,omitempty"`
    	Value    []string `json:"value,omitempty"`
    }
    type OneTimeCode struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type Name struct {
    	First  string `json:"first,omitempty"`
    	Middle string `json:"middle,omitempty"`
    	Last   string `json:"last,omitempty"`
    }
    type Names struct {
    	KeeperRecordField
    	Required      bool   `json:"required,omitempty"`
    	PrivacyScreen bool   `json:"privacyScreen,omitempty"`
    	Value         []Name `json:"value,omitempty"`
    }
    type BirthDate struct {
    	KeeperRecordField
    	Required      bool    `json:"required,omitempty"`
    	PrivacyScreen bool    `json:"privacyScreen,omitempty"`
    	Value         []int64 `json:"value,omitempty"`
    }
    type Date struct {
    	KeeperRecordField
    	Required      bool    `json:"required,omitempty"`
    	PrivacyScreen bool    `json:"privacyScreen,omitempty"`
    	Value         []int64 `json:"value,omitempty"`
    }
    type ExpirationDate struct {
    	KeeperRecordField
    	Required      bool    `json:"required,omitempty"`
    	PrivacyScreen bool    `json:"privacyScreen,omitempty"`
    	Value         []int64 `json:"value,omitempty"`
    }
    type Text struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type SecurityQuestion struct {
    	Question string `json:"question,omitempty"`
    	Answer   string `json:"answer,omitempty"`
    }
    type SecurityQuestions struct {
    	KeeperRecordField
    	Required      bool               `json:"required,omitempty"`
    	PrivacyScreen bool               `json:"privacyScreen,omitempty"`
    	Value         []SecurityQuestion `json:"value,omitempty"`
    }
    type Multiline struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type Email struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type CardRef struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type AddressRef struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type PinCode struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type Phone struct {
    	Region string `json:"region,omitempty"`
    	Number string `json:"number,omitempty"`
    	Ext    string `json:"ext,omitempty"`
    	Type   string `json:"type,omitempty"`
    }
    type Phones struct {
    	KeeperRecordField
    	Required      bool    `json:"required,omitempty"`
    	PrivacyScreen bool    `json:"privacyScreen,omitempty"`
    	Value         []Phone `json:"value,omitempty"`
    }
    type Secret struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type SecureNote struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type AccountNumber struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type PaymentCard struct {
    	CardNumber         string `json:"cardNumber,omitempty"`
    	CardExpirationDate string `json:"cardExpirationDate,omitempty"`
    	CardSecurityCode   string `json:"cardSecurityCode,omitempty"`
    }
    type PaymentCards struct {
    	KeeperRecordField
    	Required      bool          `json:"required,omitempty"`
    	PrivacyScreen bool          `json:"privacyScreen,omitempty"`
    	Value         []PaymentCard `json:"value,omitempty"`
    }
    type BankAccount struct {
    	AccountType   string `json:"accountType,omitempty"`
    	RoutingNumber string `json:"routingNumber,omitempty"`
    	AccountNumber string `json:"accountNumber,omitempty"`
    	OtherType     string `json:"otherType,omitempty"`
    }
    type BankAccounts struct {
    	KeeperRecordField
    	Required      bool          `json:"required,omitempty"`
    	PrivacyScreen bool          `json:"privacyScreen,omitempty"`
    	Value         []BankAccount `json:"value,omitempty"`
    }
    type KeyPair struct {
    	PublicKey  string `json:"publicKey,omitempty"`
    	PrivateKey string `json:"privateKey,omitempty"`
    }
    type KeyPairs struct {
    	KeeperRecordField
    	Required      bool      `json:"required,omitempty"`
    	PrivacyScreen bool      `json:"privacyScreen,omitempty"`
    	Value         []KeyPair `json:"value,omitempty"`
    }
    type Host struct {
    	Hostname string `json:"hostName,omitempty"`
    	Port     string `json:"port,omitempty"`
    }
    type Hosts struct {
    	KeeperRecordField
    	Required      bool   `json:"required,omitempty"`
    	PrivacyScreen bool   `json:"privacyScreen,omitempty"`
    	Value         []Host `json:"value,omitempty"`
    }
    type Address struct {
    	Street1 string `json:"street1,omitempty"`
    	Street2 string `json:"street2,omitempty"`
    	City    string `json:"city,omitempty"`
    	State   string `json:"state,omitempty"`
    	Country string `json:"country,omitempty"`
    	Zip     string `json:"zip,omitempty"`
    }
    type Addresses struct {
    	KeeperRecordField
    	Required      bool      `json:"required,omitempty"`
    	PrivacyScreen bool      `json:"privacyScreen,omitempty"`
    	Value         []Address `json:"value,omitempty"`
    }
    type LicenseNumber struct {
    	KeeperRecordField
    	Required      bool     `json:"required,omitempty"`
    	PrivacyScreen bool     `json:"privacyScreen,omitempty"`
    	Value         []string `json:"value,omitempty"`
    }
    type KeeperFileData struct {
    	Title        string `json:"title,omitempty"`
    	Name         string `json:"name,omitempty"`
    	Type         string `json:"type,omitempty"`
    	Size         int64  `json:"size,omitempty"`
    	LastModified int64  `json:"lastModified,omitempty"`
    }
    Record Type
    documentation
    Record Type
    documentation
    Record Type
    Record Type
    Record Types
    documentation
    Record Type
    documentation
    Record Types
    Record Types
    documentation