No RDM. No separate Redis GUI. No _redis-cli KEYS *_ against production.
In my last article, I showed how AsGuard drops a live request and exception dashboard into any ASP.NET Core app with four lines of config. This one covers what happens after someone on your team asks: “can we also see what’s actually in Redis?”
You already have Redis wired into your app somewhere — session state, a distributed cache, a rate limiter. And you probably already have a terminal tab open with redis-cli, typing KEYS user:* and hoping nobody notices the instance hang for a second.
That command is the problem. KEYS blocks the entire Redis server for as long as it takes to walk every key. On a small dev instance you won't notice. On a production cache with a few million keys, you just caused an incident.
AsGuard ships a Redis tab inside the dashboard you already have — and if AsGuard is already in your app for request and exception logging, turning it on costs one line.
What “Wiring Redis Into AsGuard” Actually Means
AsGuard doesn’t stand up a new service, a new port, or a new login screen. It adds a Redis tab to the dashboard you’re already authenticated into. That tab gives you:
- A key browser that pages through your keyspace with
SCAN— neverKEYS - A value inspector and editor for String, Hash, List, Set, and Sorted Set types
- TTL viewing and editing
- Live server stats (memory, ops/sec, hit rate, clients) streamed over the same SSE connection the rest of the dashboard already uses
It’s opt-in. Every other AsGuard feature defaults to on. Redis management defaults to off, because it’s the one module that touches your application’s actual data instead of just observability data.
Step 1 — Turn It On
If AsGuard is already in your app, this is the entire integration:
builder.Services.AddRequestLogging(options =>
{
options.DatabaseProvider = LoggingDatabaseProvider.Sqlite;
options.ConnectionString = "Data Source=asguard.db";
options.DashboardUsername = "ops";
options.DashboardPassword = builder.Configuration["AsGuard:Password"]!;options.EnableRedisManagement = true;
});
No Redis connection string to type in. No second set of credentials. Which raises the obvious question.
Step 2 — Where Does It Get Your Redis Connection From?
AsGuard reuses the connection your app already built. It never asks you to configure Redis twice.
If you’ve registered a StackExchange.Redis IConnectionMultiplexer in DI — which almost every ASP.NET Core app wiring up Redis already does — AsGuard finds it automatically the first time you open the tab:
// Your existing Redis registration — nothing AsGuard-specific here
builder.Services.AddSingleton<IConnectionMultiplexer>(sp =>
ConnectionMultiplexer.Connect("localhost:6379"));
builder.Services.AddRequestLogging(options =>
{
options.EnableRedisManagement = true;
});
Discovery runs once, lazily, on first use, and checks several places in order:
-
**IAsGuardRedisConnectionProvider**in DI — custom connection abstractions AsGuard can't see any other way: token-refreshing wrappers (e.g. Entra ID), multi-tenant multiplexers. -
**IConnectionMultiplexer**in DI — the common case:AddSingleton<IConnectionMultiplexer>, or Aspire'sAddRedisClient. - Keyed
**IConnectionMultiplexer**— Aspire'sAddKeyedRedisClient("cache"), or multiple named instances. -
**AddStackExchangeRedisCache(...)**— apps that only wired upIDistributedCache, nothing lower-level. -
**options.RedisConnections**— no Redis client registered anywhere; AsGuard builds its own.
Every rung is additive and fault-isolated: if one source is misconfigured, it doesn’t take the others down with it. AsGuard also never disposes or reconfigures a connection it borrows from rungs 1 through 4 — closing your application’s own multiplexer to satisfy a dashboard tab would be a worse bug than the one you’re trying to fix.
Rung 1 is the escape hatch, and it’s the one you actually need if your app doesn’t hold a plain IConnectionMultiplexer in DI. If you connect to Redis through your own abstraction — a wrapper that lazily authenticates (say, against Azure Cache for Redis via Microsoft Entra ID, where there's a token to refresh instead of a static password) or picks an endpoint per tenant — implement the interface and hand AsGuard the multiplexer once it's built:
internal sealed class AsGuardRedisConnectionProvider : IAsGuardRedisConnectionProvider
{
private readonly RedisConnectionProvider _connectionProvider;
private readonly RedisOptions _options;
public AsGuardRedisConnectionProvider(RedisConnectionProvider connectionProvider, IOptions<RedisOptions> options)
{
_connectionProvider = connectionProvider;
_options = options.Value;
}
public IEnumerable<AsGuardRedisConnection> GetConnections()
{
if (!_connectionProvider.IsConfigured)
{
return [];
}
var multiplexer = _connectionProvider.GetAsync().GetAwaiter().GetResult();
var name = string.IsNullOrWhiteSpace(_options.KeyPrefix) ? "matensa" : _options.KeyPrefix;
return [new AsGuardRedisConnection(name, multiplexer)];
}
}
builder.Services.AddSingleton<IAsGuardRedisConnectionProvider, AsGuardRedisConnectionProvider>();
Two things worth calling out. First, GetConnections() is synchronous by contract, but acquiring an Entra token is inherently asynchronous — blocking on GetAwaiter().GetResult() is fine here specifically because discovery runs lazily, once, on the first dashboard request, and the result is cached for the process lifetime. It never blocks startup and never blocks a real user request. Second, returning an empty sequence when the provider isn't configured is deliberate: AsGuard reports "no connection discovered" instead of the dashboard implying a Redis nobody is actually using.
Nothing registered yet? Rung 5 covers that — a plain connection string with no DI abstraction at all:
options.RedisConnections.Add(new RedisConnectionDescriptor
{
Name = "sessions",
ConnectionString = "localhost:6379,ssl=False"
});
Why This Matters More Than It Looks: Azure Cache With Entra ID
If your Redis is Azure Cache for Redis authenticated via Microsoft Entra ID, there’s no password to put in a connection string. The multiplexer authenticates with a short-lived access token that your app’s startup code refreshes on a timer, configured directly on a ConfigurationOptions object.
A connection string can’t reconstruct that. Reusing the multiplexer your app already built and already keeps authenticated is the only thing that works — which is exactly why AsGuard checks DI before it ever looks at a connection string.
Step 3 — Browse Keys Safely
Open the Redis tab, pick a connection, and page through keys. A few things happen under the hood that you’d otherwise have to build yourself:
- Enumeration uses
SCANwith cursor-based paging — neverKEYS. AsGuard even checks the server version at connect time and refuses to enumerate on anything old enough that StackExchange.Redis would silently fall back toKEYS. - Type and TTL for each row are pipelined in a single round trip batch, so a 100-key page doesn’t cost you 200+ requests.
- Binary keys (not valid UTF-8) show up base64-encoded instead of being mangled or hidden.
Click into any key to inspect and edit it. Strings, hashes, lists, sets, and sorted sets are all supported, with a MATCH filter for large hashes and sets, and a byte cap so one giant value can't blow up the dashboard.
options.MaxRedisValueBytes = 262_144; // default: 256 KB, larger values become read-only
options.RedisScanPageSize = 100; // keys per SCAN round trip
Locking It Down for Production
Three settings decide how far the Redis tab can reach once it’s live:
options.EnableRedisManagement = true;
options.RedisManagementReadOnly = true; // browse only — no edits, deletes, or flushes
options.AllowRedisFlushDatabase = false; // FLUSHDB stays off unless you explicitly opt in
RedisManagementReadOnly is enforced server-side, in the same code path every mutating operation passes through — hiding the edit buttons in the UI is cosmetic on top of that, not the actual gate. And FLUSHDB, if you ever turn it on, requires the connection to have been built with allowAdmin=true by your own application code, plus a typed confirmation phrase on the request body naming the exact database. AsGuard never issues FLUSHALL, and there's no bulk pattern-delete — a mistyped filter against production shouldn't be a one-click mistake.
What You Get for Free
Because the Redis tab lives inside the dashboard you already authenticated into, it also inherits:
- CSRF protection on every mutating request
- Live server stats (memory, ops/sec, hit rate, connected clients, eviction rate) streamed over the dashboard’s existing SSE connection — no second polling loop, no extra background service
The stats sampler is demand-driven too. If nobody has the tab open, AsGuard isn’t quietly polling INFO against your Redis server every few seconds for no one.
Try It
If you already have AsGuard installed:
options.EnableRedisManagement = true;
If you don’t yet:
dotnet add package AsGuard
Then follow the Quick Setup in the README, add the line above, and open the Redis tab next to your request logs.
Full reference: docs/redis-management.md
GitHub: mahmood-alsarraj/asguard
If this saved you from typing _KEYS *_ in production one more time, give the repo a star.


Top comments (0)