Skip to content

Commit 9bdbf2d

Browse files
Copilotcsharpfritz
andcommitted
Secure cache refresh API endpoint with API key authentication
Co-authored-by: csharpfritz <[email protected]>
1 parent 71a427e commit 9bdbf2d

3 files changed

Lines changed: 25 additions & 4 deletions

File tree

.github/workflows/content-sync.yml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ jobs:
3838

3939
- name: Refresh Web App Cache
4040
if: success()
41+
env:
42+
CACHE_REFRESH_API_KEY: ${{ secrets.CACHE_REFRESH_API_KEY }}
4143
run: |
4244
echo "Refreshing web application cache..."
4345
# Wait a moment for the content to be fully uploaded
4446
sleep 5
4547
46-
# Call the cache refresh endpoint
47-
response=$(curl -s -w "%{http_code}" -X POST "https://copilotthatjawn.com/api/cache/refresh" -o /tmp/cache_response.json)
48+
# Call the cache refresh endpoint with API key authentication
49+
response=$(curl -s -w "%{http_code}" -X POST "https://copilotthatjawn.com/api/cache/refresh" \
50+
-H "X-API-Key: $CACHE_REFRESH_API_KEY" \
51+
-o /tmp/cache_response.json)
4852
4953
if [ "$response" = "200" ]; then
5054
echo "Cache refresh successful"

Web/Extensions/EndpointExtensions.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -195,12 +195,29 @@ public static class EndpointExtensions
195195

196196
public static void MapCacheRefreshEndpoint(this WebApplication app)
197197
{
198-
app.MapPost("/api/cache/refresh", async (IContentService contentService, ILogger<Program> logger, IWebHostEnvironment environment) =>
198+
app.MapPost("/api/cache/refresh", async (HttpContext context, IContentService contentService, ILogger<Program> logger, IWebHostEnvironment environment, IConfiguration configuration) =>
199199
{
200200
try
201201
{
202202
logger.LogInformation("Cache refresh requested via API endpoint");
203203

204+
// Validate API key for security
205+
var expectedApiKey = configuration["CacheRefresh:ApiKey"];
206+
if (!string.IsNullOrEmpty(expectedApiKey))
207+
{
208+
var providedApiKey = context.Request.Headers["X-API-Key"].FirstOrDefault();
209+
if (string.IsNullOrEmpty(providedApiKey) || providedApiKey != expectedApiKey)
210+
{
211+
logger.LogWarning("Cache refresh request rejected: Invalid or missing API key");
212+
return Results.Unauthorized();
213+
}
214+
}
215+
else if (!environment.IsDevelopment())
216+
{
217+
logger.LogWarning("Cache refresh API key not configured in production environment");
218+
return Results.Problem("API key not configured", statusCode: 500);
219+
}
220+
204221
// Only perform cache refresh in non-development environments
205222
// In development, the cache isn't as critical and may require Azure Table Storage
206223
if (environment.IsDevelopment())
@@ -226,6 +243,6 @@ public static void MapCacheRefreshEndpoint(this WebApplication app)
226243
})
227244
.WithName("RefreshCache")
228245
.WithSummary("Refresh the content cache")
229-
.WithDescription("Triggers a refresh of the in-memory content cache from Azure Table Storage");
246+
.WithDescription("Triggers a refresh of the in-memory content cache from Azure Table Storage. Requires X-API-Key header for authentication.");
230247
}
231248
}

packages-microsoft-prod.deb

3.61 KB
Binary file not shown.

0 commit comments

Comments
 (0)