Accessing Secrets
Prerequisites
Before accessing secrets, make sure you've installed and initialized the Secrets Manager SDK.
Basic Usage
After initializing the SDK, you can retrieve secrets with a simple API call:
using Bytehide.ToolBox;
using Bytehide.ToolBox.Secrets;
// Initialize the SDK (if not already done)
ManagerSecrets.Initialize();
// Get a secret by key
var secret = Products.Secrets.Get("database-connection");
Console.WriteLine($"Connection string: {secret}");
// Use the secret in your application
using (var connection = new SqlConnection(secret))
{
await connection.OpenAsync();
// ... use the connection
}
Creating and Updating Secrets
You can create or update secrets directly from your application:
// Create a new secret
await Products.Secrets.SetAsync("api-key", "sk_test_abc123xyz");
// Update an existing secret
await Products.Secrets.SetAsync("database-connection", "Server=new-server;Database=myapp;User=admin;Password=secret");
Handling Multiple Environments
The environment is specified during initialization, but you can also access secrets from specific environments:
// Get a secret from the development environment
var devSecret = await Products.Secrets.GetAsync("api-key", environment: "development");
// Get the same secret from production
var prodSecret = await Products.Secrets.GetAsync("api-key", environment: "production");
Console.WriteLine($"Dev API Key: {devSecret}");
Console.WriteLine($"Prod API Key: {prodSecret}");
Secrets Not Found
When a secret doesn't exist, the SDK will throw an exception. Handle this gracefully:
try
{
var secret = Products.Secrets.Get("non-existent-key");
}
catch (SecretNotFoundException ex)
{
// Handle missing secret
Console.WriteLine($"Secret not found: {ex.Message}");
// You might want to create the secret or use a default value
await Products.Secrets.SetAsync("non-existent-key", "default-value");
}
Best Practices
Caching Secrets
For improved performance, cache secrets in memory:
// Simple in-memory cache
private static readonly Dictionary<string, string> _secretCache = new Dictionary<string, string>();
public static async Task<string> GetSecretWithCachingAsync(string key)
{
// Check cache first
if (_secretCache.TryGetValue(key, out var cachedSecret))
return cachedSecret;
// Get from ByteHide
var secret = await Products.Secrets.GetAsync(key);
// Add to cache
_secretCache[key] = secret;
return secret;
}
Refresh Secrets
Periodically refresh your secrets to ensure they're up-to-date:
public static async Task StartSecretRefreshTimer()
{
// Refresh secrets every 5 minutes
var timer = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds);
timer.Elapsed += async (sender, e) =>
{
_secretCache.Clear(); // Clear cache
// Preload critical secrets
_secretCache["api-key"] = await Products.Secrets.GetAsync("api-key");
_secretCache["database-connection"] = await Products.Secrets.GetAsync("database-connection");
};
timer.Start();
}
Common Usage Patterns
Configuration Values
Store application configuration values as secrets:
// Configuration helper
public static class AppConfig
{
public static async Task<string> GetDatabaseConnectionAsync()
=> await Products.Secrets.GetAsync("database-connection");
public static async Task<string> GetApiKeyAsync()
=> await Products.Secrets.GetAsync("api-key");
public static async Task<int> GetCacheTimeoutAsync()
{
var value = await Products.Secrets.GetAsync("cache-timeout-minutes");
return int.TryParse(value, out var result) ? result : 10; // Default to 10
}
}
ASP.NET Core Integration
Integrate with ASP.NET Core configuration:
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureAppConfiguration((hostingContext, config) =>
{
// Initialize ByteHide Secrets
ManagerSecrets.Initialize();
// Add ByteHide configuration provider
config.Add(new ByteHideConfigurationSource());
})
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
// Custom configuration provider (implementation example)
public class ByteHideConfigurationProvider : ConfigurationProvider
{
public override void Load()
{
// Load basic secrets
Data["ConnectionStrings:DefaultConnection"] = Products.Secrets.Get("database-connection");
Data["ApiKey"] = Products.Secrets.Get("api-key");
// Add more secrets as needed
}
}