XJP Secret Store SDK for Rust
A comprehensive Rust SDK for interacting with the XJP Secret Store service, providing secure storage and retrieval of secrets, configuration values, and sensitive data.
Features
- 🔐 Multiple Authentication Methods: Bearer token, API key, XJP key, and dynamic token providers
- ⚡ High Performance: Built-in caching with ETag/304 support for optimal performance
- 🔄 Automatic Retries: Exponential backoff with jitter for transient failures
- 🛡️ Secure by Default: Enforces HTTPS, proper secret handling with zeroization
- 📦 Batch Operations: Efficient bulk operations with transactional support
- 🌍 Environment Export: Export secrets in multiple formats (JSON, dotenv, shell, docker-compose)
- 📊 Comprehensive Monitoring: Cache statistics and optional OpenTelemetry support
- ⏱️ Version Management: Track and rollback secret versions
- 🔍 Audit Trail: Query audit logs for compliance and debugging
Installation
Add this to your Cargo.toml:
[]
= "0.1"
Feature Flags
rustls-tls(default): Use rustls for TLSnative-tls: Use native system TLS implementationblocking: Enable blocking/synchronous APImetrics: Enable OpenTelemetry metricswasm: WebAssembly support for browser/edge environmentsdanger-insecure-http: Allow insecure HTTP connections (development only)
Quick Start
use ;
async
Authentication
The SDK supports multiple authentication methods in priority order:
Bearer Token (Highest Priority)
let client = new
.auth
.build?;
API Key
let client = new
.auth
.build?;
Dynamic Token Provider
use ;
let client = new
.auth
.build?;
Core Operations
Get Secret
use GetOpts;
// Simple get
let secret = client.get_secret.await?;
// Get with cache disabled
let opts = GetOpts ;
let secret = client.get_secret.await?;
// Conditional get with ETag
let opts = GetOpts ;
match client.get_secret.await
Put Secret
use PutOpts;
// Simple put
client.put_secret.await?;
// Put with options
let opts = PutOpts ;
client.put_secret.await?;
List Secrets
use ListOpts;
// List all secrets
let list = client.list_secrets.await?;
// List with prefix and limit
let opts = ListOpts ;
let list = client.list_secrets.await?;
Batch Operations
Batch Get
use ;
// Get specific keys
let keys = Keys;
let result = client.batch_get.await?;
// Get all keys
let result = client.batch_get.await?;
// Export as dotenv format
let result = client.batch_get.await?;
match result
Batch Operations
use BatchOp;
let operations = vec!;
// Execute with transaction
let result = client.batch_operate.await?;
println!;
Environment Export
use ExportFormat;
// Export as JSON
let export = client.export_env.await?;
if let Json = export
// Export as shell script
let export = client.export_env.await?;
if let Text = export
Version Management
The SDK provides comprehensive version management capabilities for secrets:
List Secret Versions
// List all versions of a secret
let versions = client.list_versions.await?;
println!;
for version in &versions.versions
Get Specific Version
// Get a specific version of a secret
let secret_v2 = client.get_version.await?;
println!;
println!;
Rollback to Previous Version
// Rollback a secret to a specific version
let rollback_result = client.rollback.await?;
println!;
// The rolled back version becomes the new current version
let current = client.get_secret.await?;
println!;
Version History Example
// Create multiple versions
client.put_secret.await?;
sleep.await;
let opts = PutOpts ;
client.put_secret.await?;
// Check version history
let versions = client.list_versions.await?;
assert_eq!;
// Rollback if needed
if need_rollback
Namespace Management
// List all namespaces
let namespaces = client.list_namespaces.await?;
// Get namespace details
let info = client.get_namespace.await?;
println!;
// Initialize namespace with template
use NamespaceTemplate;
let template = NamespaceTemplate ;
client.init_namespace.await?;
Audit Logs
The SDK provides comprehensive audit log querying capabilities for compliance and debugging:
Basic Audit Query
use AuditQuery;
// Query all audit logs
let query = default;
let audit_logs = client.audit.await?;
println!;
for entry in &audit_logs.entries
Filtered Queries
// Query failed operations
let query = AuditQuery ;
let failed_ops = client.audit.await?;
// Query by namespace and time range
let query = AuditQuery ;
let prod_logs = client.audit.await?;
// Query specific actions by actor
let query = AuditQuery ;
let ci_writes = client.audit.await?;
Pagination
// Paginate through audit logs
let mut all_entries = Vecnew;
let mut offset = 0;
let limit = 100;
loop
println!;
Audit Entry Fields
Each audit entry contains:
id: Unique identifiertimestamp: When the action occurredactor: Who performed the action (optional)action: What action was performed (get, put, delete, etc.)namespace: Affected namespace (optional)key_name: Affected key (optional)success: Whether the action succeededip_address: Client IP address (optional)user_agent: Client user agent (optional)error: Error message if failed (optional)
Caching
The SDK includes an intelligent caching layer:
// Configure caching
let client = new
.auth
.enable_cache
.cache_max_entries
.cache_ttl_secs // 5 minutes
.build?;
// Get cache statistics
let stats = client.cache_stats;
println!;
println!;
// Clear cache
client.clear_cache;
// Invalidate specific entry
client.invalidate_cache.await;
Error Handling
The SDK provides detailed error information:
match client.get_secret.await
Configuration
Timeouts and Retries
let client = new
.auth
.timeout_ms // 30 seconds
.retries // up to 3 retries
.build?;
Custom User Agent
let client = new
.auth
.user_agent_extra
.build?;
Allow Insecure HTTP (Development Only)
let client = new
.auth
.allow_insecure_http
.build?;
Observability with OpenTelemetry
The SDK supports OpenTelemetry metrics when the metrics feature is enabled:
Enable Metrics
// Add to Cargo.toml
secret-store-sdk =
Configure Telemetry
use ;
// Configure telemetry
let telemetry_config = TelemetryConfig ;
// Create client with telemetry
let client = new
.auth
.with_telemetry
.build?;
// Or simply enable with defaults
let client = new
.auth
.enable_telemetry
.build?;
Available Metrics
The SDK exposes the following metrics:
- xjp_secret_store.requests_total: Total number of requests (labels: method, path, status)
- xjp_secret_store.request_duration_seconds: Request duration histogram
- xjp_secret_store.errors_total: Total number of errors (labels: type, status)
- xjp_secret_store.cache_hits_total: Cache hit counter (label: namespace)
- xjp_secret_store.cache_misses_total: Cache miss counter (label: namespace)
- xjp_secret_store.active_connections: Current active connections (UpDownCounter)
- xjp_secret_store.retry_attempts_total: Retry attempts counter (labels: attempt, reason)
Integration Example
// Initialize OpenTelemetry with Prometheus exporter
let exporter = exporter
.init;
// Set global meter provider
set_meter_provider;
// Create SDK client with telemetry
let client = new
.auth
.enable_telemetry
.build?;
// Use the client - metrics are automatically collected
let secret = client.get_secret.await?;
// Export metrics (e.g., for Prometheus scraping)
let metrics = exporter.registry.gather;
See the metrics example for a complete working implementation.
Best Practices
- Enable Caching: For read-heavy workloads, keep caching enabled to reduce API calls
- Use Batch Operations: For multiple operations, use batch APIs to reduce round trips
- Handle 304 Not Modified: Leverage ETags for conditional requests
- Set Appropriate TTLs: Use TTLs for temporary secrets
- Use Idempotency Keys: For critical write operations, use idempotency keys
- Monitor Cache Stats: Regularly check cache hit rates to optimize performance
- Secure Token Storage: Never hardcode tokens; use environment variables or secure vaults
Migration Guide
From Node.js SDK
// Node.js
const client = ;
const secret = await client.;
// Rust
let client = new
.auth
.build?;
let secret = client.get_secret.await?;
Field Mappings
- List responses:
ver(API) →version(SDK) - All timestamps are parsed to
time::OffsetDateTime - Metadata is
serde_json::Valuefor flexibility
Contributing
- Clone the repository
- Run tests:
cargo test - Run benchmarks:
cargo bench - Format code:
cargo fmt - Check lints:
cargo clippy
License
MIT OR Apache-2.0