Keeper Secrets Manager Rust SDK
The Rust SDK for Keeper Secrets Manager provides type-safe, zero-knowledge access to secrets stored in Keeper's vault with comprehensive error handling.
Features
- Type-Safe API: Leverages Rust's type system for compile-time safety
- Never Panics: All operations return
Result<T, KSMRError>- no unwraps in library code - Multiple Storage Options: File-based, in-memory, and caching support
- Comprehensive Crypto: AES-256-GCM, ECDH (P-256), ECDSA using industry-standard crates
- Notation Support: Access specific fields using
keeper://URI notation - Password Rotation: Transaction-based rotation with commit/rollback
- GraphSync Support: Linked record retrieval for managing relationships
- Disaster Recovery Caching: Automatic fallback to cached data on network failures
- Rust 1.87+: Modern Rust with async runtime (reqwest)
Installation
Add this to your Cargo.toml:
[]
= "17.2.0"
Quick Start
Initialize with One-Time Token
use ;
Initialize with Existing Configuration
use ;
Secret Retrieval
Get All Secrets
// Get all secrets
let secrets = secrets_manager.get_secrets?;
// Get specific secrets by UID
let uids = vec!;
let secrets = secrets_manager.get_secrets?;
Search by Title
// Get all secrets matching title (case-sensitive)
let matching = secrets_manager.get_secrets_by_title?;
println!;
// Get first secret with title
if let Some = secrets_manager.get_secret_by_title?
Get Secrets with GraphSync Links
use QueryOptions;
// Request linked records
let query = with_links;
let secrets = secrets_manager.get_secrets_with_options?;
// Access linked records
for secret in secrets
Accessing Field Values
Standard Fields
use StandardFieldTypeEnum;
// Get single value (first occurrence)
let login = secret.get_standard_field_value?;
let password = secret.get_standard_field_value?;
let url = secret.get_standard_field_value?;
// Get all values (returns array)
let emails = secret.get_standard_field_value?;
// Using enum for type safety
let login = secret.get_standard_field_value?;
Custom Fields
// Get custom field by label
let environment = secret.get_custom_field_value?;
let api_key = secret.get_custom_field_value?;
Using Keeper Notation
// Access fields without retrieving full records
let password = secrets_manager.get_notation?;
// Access by title
let api_key = secrets_manager.get_notation?;
// Access complex field properties
let hostname = secrets_manager.get_notation?;
// Array indexing
let first_email = secrets_manager.get_notation?;
Creating Secrets
use ;
Updating Secrets
Basic Update
use StandardFieldTypeEnum;
// Get secret to update
let mut secrets = secrets_manager.get_secrets?;
let mut record = secrets.into_iter.next
.ok_or_else?;
// Modify password field
record.set_standard_field_value_mut?;
// Save changes
secrets_manager.update_secret?;
println!;
Password Rotation with Transactions
use ;
// Get secret to rotate
let mut secrets = secrets_manager.get_secrets?;
let mut record = secrets.into_iter.next
.ok_or_else?;
let record_uid = record.uid.clone;
// Update password
record.set_standard_field_value_mut?;
// Start rotation transaction
secrets_manager.update_secret_with_transaction?;
// Test the new password in your application...
println!;
// Commit the transaction if successful
secrets_manager.complete_transaction?;
// Or rollback if testing failed:
// secrets_manager.complete_transaction(record_uid, true)?;
println!;
Update with Link Removal
use ;
// Get secret
let mut secrets = secrets_manager.get_secrets?;
let mut record = secrets.into_iter.next
.ok_or_else?;
// Modify fields as needed...
// Remove file attachments
let options = new;
secrets_manager.update_secret_with_options?;
println!;
File Operations
Download Files
// Download file from a secret
for mut secret in secrets
Download File by Title
// Download file by name without knowing UID
let secrets = secrets_manager.get_secrets?;
if let Some = secrets_manager.download_file_by_title? else
Download Thumbnails
for secret in secrets
Upload Files
use ;
// Get secret to attach file to
let mut secrets = secrets_manager.get_secrets?;
let secret = secrets.into_iter.next
.ok_or_else?;
// Prepare file for upload
let file_upload = get_file_for_upload?;
// Upload to secret
let upload_status = secrets_manager.upload_file?;
println!;
Password Generation
Basic Password Generation
use generate_password;
let password = generate_password?;
println!; // 32 chars, mixed
Custom Password Options
use ;
let options = new
.length
.lowercase // At least 5 lowercase
.uppercase // At least 5 uppercase
.digits // At least 3 digits
.special_characters // At least 2 special chars
.special_characterset;
let password = generate_password_with_options?;
println!;
Exact Character Counts
Use negative values to specify exact counts instead of minimums:
let options = new
.lowercase // Exactly 8 lowercase
.uppercase // Exactly 8 uppercase
.digits // Exactly 4 digits
.special_characters; // Exactly 4 special chars
// Total length = 8+8+4+4 = 24 (length parameter ignored)
let password = generate_password_with_options?;
println!;
TOTP Code Generation
use get_totp_code;
use StandardFieldTypeEnum;
// Get secret with TOTP
let mut secrets = secrets_manager.get_secrets?;
let secret = secrets.into_iter.next.unwrap;
// Get TOTP URL from field
let totp_value = secret.get_standard_field_value?;
// Extract URL and generate code
if let Object = totp_value
Folder Operations
List Folders
let folders = secrets_manager.get_folders?;
for folder in folders
Create Folder
use CreateOptions;
let parent_folder_uid = "PARENT_FOLDER_UID".to_string;
let create_options = new;
let folder_uid = secrets_manager.create_folder?;
println!;
Update Folder
let folder_uid = "FOLDER_UID".to_string;
secrets_manager.update_folder?;
println!;
Delete Folder
// Delete empty folder
secrets_manager.delete_folder?;
// Force delete non-empty folder
secrets_manager.delete_folder?;
Advanced Features
Disaster Recovery Caching
Automatically cache responses and fall back to cached data on network failures:
use caching;
let storage = new?;
let config = File;
let token = "YOUR_TOKEN".to_string;
let mut options = new_client_options_with_token;
// Build the client once outside any async context (safe for spawn_blocking)
let client = builder.build?;
options.set_custom_post_function;
let mut secrets_manager = new?;
// First call: saves to cache (default: KSM_CACHE_DIR/ksm_cache.bin)
let secrets = secrets_manager.get_secrets?;
// Subsequent calls: uses cache if network unavailable
println!;
Cache location can be customized via KSM_CACHE_DIR environment variable.
In-Memory Caching
use KSMRCache;
let storage = new?;
let config = File;
let cache = new_file_cache?;
let token = "YOUR_TOKEN".to_string;
let mut options = new_client_options_with_token;
options.set_cache;
let mut secrets_manager = new?;
// Secrets cached for performance
let secrets = secrets_manager.get_secrets?;
Error Handling
The SDK uses a comprehensive KSMRError enum for all errors. All public methods return Result:
use KSMRError;
match secrets_manager.get_secrets
Common error types:
RecordNotFoundError- Record UID not found in vaultFieldNotFoundError- Requested field doesn't existAuthenticationError- Invalid token or credentialsInvalidTokenError- Malformed tokenCryptoError- Encryption/decryption failureHTTPError- Network or API errorStorageError- Config file I/O errorNotationError- Invalidkeeper://URI syntax
Storage Options
File Storage (Persistent)
use FileKeyValueStorage;
use KvStoreType;
// Default location: keeper_config.json
let storage = new?;
// Custom location
let storage = new?;
let config = File;
File permissions:
- Automatically created with
0600(owner read/write only) on Unix - Secure ACLs on Windows (user + Administrator only)
In-Memory Storage (Ephemeral)
use InMemoryKeyValueStorage;
use KvStoreType;
// From base64 config string
let base64_config = "eyJ...".to_string;
let storage = new?;
// Empty config (useful for one-time token initialization)
let storage = new?;
let config = InMemory;
Use cases:
- Serverless/Lambda functions
- Docker containers
- CI/CD pipelines
- Applications without filesystem access
Examples
See examples/manual_tests/ for comprehensive runnable examples:
| Example | Description |
|---|---|
01_initialize_and_get_secrets.rs |
Basic initialization and secret retrieval |
02_update_secret.rs |
Update secret fields |
03_password_rotation.rs |
Transaction-based password rotation |
04_search_by_title.rs |
Title-based secret search |
05_update_with_options.rs |
Advanced updates with link removal |
06_caching_function.rs |
Disaster recovery caching |
07_test_rotation_base64.rs |
Rotation with base64 config |
08_test_link_removal.rs |
File link removal |
09_check_fileref.rs |
File reference validation |
10_test_link_removal_debug.rs |
Debug link removal |
11_upload_and_remove_file.rs |
File upload and removal |
Run examples:
See examples/manual_tests/README.md for detailed setup instructions.
Configuration
Environment Variables
KSM_CONFIG- Base64-encoded JSON configuration (overrides file storage)KSM_CACHE_DIR- Cache directory for disaster recovery caching (default: current directory)KSM_SKIP_VERIFY- Skip SSL certificate verification (true/false)KSM_PROXY_URL- Proxy URL used by the barecaching_post_function(not used bymake_caching_post_function— configure proxy on thereqwest::Clientbuilder instead)HTTP_PROXY- HTTP proxy URL (automatically used ifproxy_urlnot set)HTTPS_PROXY- HTTPS proxy URL (automatically used ifproxy_urlnot set)NO_PROXY- Comma-separated list of hosts to exclude from proxying
Client Options
use ClientOptions;
use KSMCache;
use Level;
// Full control over initialization
let options = new;
// Or use convenience constructors
let options = new_client_options_with_token;
let options = new_client_options;
Proxy Configuration
The Rust SDK supports HTTP/HTTPS proxy configuration for all network operations.
Explicit Configuration
use ClientOptions;
use KvStoreType;
use FileKeyValueStorage;
// Create storage
let storage = new?;
let config = File;
// Configure with proxy
let options = new;
let mut secrets_manager = new?;
Proxy with Authentication
Include credentials in the proxy URL:
let proxy_url = "http://username:password@proxy.example.com:8080";
let options = new;
Environment Variable Fallback
If proxy_url is not explicitly set (None), the SDK automatically respects standard HTTP proxy environment variables:
Priority: Explicit proxy_url parameter > Environment variables (HTTPS_PROXY/HTTP_PROXY)
Proxy with caching
With make_caching_post_function, configure the proxy on the reqwest::Client you pass in:
let client = builder
.proxy
.build?;
client_options.set_custom_post_function;
The bare caching_post_function (non-async contexts only) reads KSM_PROXY_URL at call time instead:
client_options.set_custom_post_function;
Dependencies
aes-gcm- AES-256-GCM encryptionp256- ECDH and ECDSA on NIST P-256 curvereqwest- HTTP client (blocking mode)serde/serde_json- Serializationbase64- Encodingchrono- Date/time handlinglog- Logging facade
Development dependencies:
mockall- Mocking framework for testsserial_test- Sequential test executiontempfile- Temporary file handling in tests
Testing
# Run all tests
# Run specific test file
# Run with output
# Run single test
# Generate documentation
Documentation
- Official Docs: https://docs.keeper.io/secrets-manager/secrets-manager/developer-sdk-library/rust-sdk
- Repository: https://github.com/Keeper-Security/secrets-manager/tree/master/sdk/rust
- crates.io: https://crates.io/crates/keeper-secrets-manager-core
- API Docs: https://docs.rs/keeper-secrets-manager-core
License
MIT
Support
For questions or issues:
- Email: sm@keepersecurity.com
- GitHub Issues: https://github.com/Keeper-Security/secrets-manager/issues