Skip to content

Commit 34256ef

Browse files
committed
RavenDBHealthCheck: prevent health check from disposing shared client certificate.
1 parent 846fbc9 commit 34256ef

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

src/HealthChecks.RavenDB/RavenDBHealthCheck.cs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context
4949
Certificate = o.Certificate
5050
};
5151

52+
// Health check doesn't own the certificate lifetime; it may be shared (e.g. DI/KeyVault).
53+
// Disposing it can break other RavenDB stores in the process.
54+
store.Conventions.DisposeCertificate = false;
55+
5256
try
5357
{
5458
store.Initialize();

test/HealthChecks.RavenDb.Tests/Functional/RavenDbHealthCheckTests.cs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
using System.Net;
2+
using System.Security.Cryptography;
3+
using System.Security.Cryptography.X509Certificates;
4+
using HealthChecks.RavenDB;
25
using HealthChecks.UI.Client;
36

47
namespace HealthChecks.RavenDb.Tests.Functional;
@@ -151,4 +154,31 @@ public async Task be_unhealthy_if_ravendb_is_available_but_database_doesnot_exis
151154

152155
response.StatusCode.ShouldBe(HttpStatusCode.ServiceUnavailable, await response.Content.ReadAsStringAsync());
153156
}
157+
158+
[Fact]
159+
public async Task not_dispose_shared_certificate_when_store_initialization_fails()
160+
{
161+
using var rsa = RSA.Create(2048);
162+
var certificateRequest = new CertificateRequest("CN=ravendb-healthcheck-test", rsa, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
163+
using var certificate = certificateRequest.CreateSelfSigned(DateTimeOffset.UtcNow.AddDays(-1), DateTimeOffset.UtcNow.AddDays(1));
164+
165+
var options = new RavenDBOptions
166+
{
167+
Urls = ["http://localhost:0"],
168+
Certificate = certificate
169+
};
170+
171+
var healthCheck = new RavenDBHealthCheck(options);
172+
var context = new HealthCheckContext
173+
{
174+
Registration = new HealthCheckRegistration("ravendb", _ => healthCheck, HealthStatus.Unhealthy, tags: null)
175+
};
176+
177+
var result = await healthCheck.CheckHealthAsync(context);
178+
179+
result.Status.ShouldBe(HealthStatus.Unhealthy);
180+
181+
using var privateKey = certificate.GetRSAPrivateKey();
182+
privateKey.ShouldNotBeNull();
183+
}
154184
}

0 commit comments

Comments
 (0)