wrkflw-secrets
Comprehensive secrets management for wrkflw workflow execution. This crate provides secure handling of secrets with support for multiple providers, encryption, masking, and GitHub Actions-compatible variable substitution.
Features
- Multiple Secret Providers: Environment variables, files, HashiCorp Vault, AWS Secrets Manager, Azure Key Vault, Google Cloud Secret Manager
- Secure Storage: AES-256-GCM encryption for secrets at rest
- Variable Substitution: GitHub Actions-compatible
${{ secrets.* }}syntax - Secret Masking: Automatic masking of secrets in logs and output with pattern detection
- Caching: Optional caching with TTL for performance optimization
- Rate Limiting: Built-in protection against secret access abuse
- Input Validation: Comprehensive validation of secret names and values
- Health Checks: Provider health monitoring and diagnostics
- Configuration: Flexible YAML/JSON configuration with environment variable support
- Thread Safety: Full async/await support with concurrent access
- Performance Optimized: Compiled regex patterns and caching for high-throughput scenarios
Quick Start
use *;
async
Configuration
Environment Variables
# Set default provider
# Enable/disable secret masking
# Set operation timeout
Configuration File
Create ~/.wrkflw/secrets.yml:
default_provider: env
enable_masking: true
timeout_seconds: 30
enable_caching: true
cache_ttl_seconds: 300
providers:
env:
type: environment
prefix: "WRKFLW_SECRET_"
file:
type: file
path: "~/.wrkflw/secrets.json"
vault:
type: vault
url: "https://vault.example.com"
auth:
method: token
token: "${VAULT_TOKEN}"
mount_path: "secret"
Secret Providers
Environment Variables
The simplest provider reads secrets from environment variables:
// With prefix
set_var;
let secret = manager.get_secret_from_provider.await?;
// Without prefix
set_var;
let secret = manager.get_secret_from_provider.await?;
File-based Storage
Store secrets in JSON, YAML, or environment files:
JSON format (secrets.json):
Environment format (secrets.env):
API_KEY=secret_api_key
DB_PASSWORD="quoted password"
GITHUB_TOKEN='single quoted token'
YAML format (secrets.yml):
API_KEY: secret_api_key
DB_PASSWORD: secret_password
HashiCorp Vault
providers:
vault:
type: vault
url: "https://vault.example.com"
auth:
method: token
token: "${VAULT_TOKEN}"
mount_path: "secret"
AWS Secrets Manager
providers:
aws:
type: aws_secrets_manager
region: "us-east-1"
role_arn: "arn:aws:iam::123456789012:role/SecretRole" # optional
Azure Key Vault
providers:
azure:
type: azure_key_vault
vault_url: "https://myvault.vault.azure.net/"
auth:
method: service_principal
client_id: "${AZURE_CLIENT_ID}"
client_secret: "${AZURE_CLIENT_SECRET}"
tenant_id: "${AZURE_TENANT_ID}"
Google Cloud Secret Manager
providers:
gcp:
type: gcp_secret_manager
project_id: "my-project"
key_file: "/path/to/service-account.json" # optional
Variable Substitution
Support for GitHub Actions-compatible secret references:
let mut substitution = new;
// Default provider
let template = "TOKEN=${{ secrets.GITHUB_TOKEN }}";
let resolved = substitution.substitute.await?;
// Specific provider
let template = "API_KEY=${{ secrets.vault:API_KEY }}";
let resolved = substitution.substitute.await?;
Secret Masking
Automatically mask secrets in logs and output:
let mut masker = new;
// Add specific secrets
masker.add_secret;
// Automatic pattern detection for common secret types
let log = "Token: ghp_1234567890123456789012345678901234567890";
let masked = masker.mask;
// Output: "Token: ghp_***"
Supported patterns:
- GitHub Personal Access Tokens (
ghp_*) - GitHub App tokens (
ghs_*) - GitHub OAuth tokens (
gho_*) - AWS Access Keys (
AKIA*) - JWT tokens
- Generic API keys
Encrypted Storage
For sensitive environments, use encrypted storage:
use ;
// Create encrypted store
let = new?;
// Add secrets
store.add_secret?;
// Save to file
store.save_to_file.await?;
// Load from file
let loaded_store = load_from_file.await?;
let secret = loaded_store.get_secret?;
Error Handling
All operations return SecretResult<T> with comprehensive error types:
match manager.get_secret.await
Health Checks
Monitor provider health:
let health_results = manager.health_check.await;
for in health_results
Security Best Practices
- Use encryption for secrets at rest
- Enable masking to prevent secrets in logs
- Rotate secrets regularly
- Use least privilege access for secret providers
- Monitor access through health checks and logging
- Use provider-specific authentication (IAM roles, service principals)
- Configure rate limiting to prevent abuse
- Validate input - the system automatically validates secret names and values
Rate Limiting
Protect against abuse with built-in rate limiting:
use RateLimitConfig;
use Duration;
let mut config = default;
config.rate_limit = RateLimitConfig ;
let manager = new.await?;
// Rate limiting is automatically applied to all secret access operations
match manager.get_secret.await
Input Validation
All inputs are automatically validated:
// Secret names must:
// - Be 1-255 characters long
// - Contain only letters, numbers, underscores, hyphens, and dots
// - Not start or end with dots
// - Not contain consecutive dots
// - Not be reserved system names
// Secret values must:
// - Be under 1MB in size
// - Not contain null bytes
// - Be valid UTF-8
// Invalid examples that will be rejected:
manager.get_secret.await; // Empty name
manager.get_secret.await; // Invalid characters
manager.get_secret.await; // Starts with dot
manager.get_secret.await; // Reserved name
Performance Features
Caching
let config = SecretConfig ;
Optimized Pattern Matching
- Pre-compiled regex patterns for secret detection
- Global pattern cache using
OnceLock - Efficient string replacement algorithms
- Cached mask generation
Benchmarking
Run performance benchmarks:
Feature Flags
Enable optional providers:
[]
= { = "0.1", = ["vault-provider", "aws-provider"] }
Available features:
env-provider(default)file-provider(default)vault-provideraws-providerazure-providergcp-providerall-providers
License
MIT License - see LICENSE file for details.