/

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

Next Steps

Previous
Installation