From 0847d2c7cf57367ff7dc95459f44c03ac0de7ea9 Mon Sep 17 00:00:00 2001 From: "soroush.asadi" Date: Sun, 7 Jun 2026 00:41:26 +0330 Subject: [PATCH] fix(deploy): don't let docker compose build require runtime JWT_KEY docker compose build interpolates the whole file, so the ${JWT_KEY:?} guard failed the build step when ENV_FILE lacked JWT_KEY. Default it empty (${JWT_KEY:-}) so build/db steps succeed, and enforce the secret at runtime instead: the server throws on boot in Production if Jwt:Key is missing/dev/<32 chars. Co-Authored-By: Claude Opus 4.8 --- docker-compose.yml | 5 ++++- server/src/Hokm.Server/Program.cs | 7 ++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 9dc4421..433fe89 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -44,7 +44,10 @@ services: ASPNETCORE_URLS: http://0.0.0.0:5005 Database__Provider: postgres ConnectionStrings__Default: "Host=db;Port=5432;Database=hokm;Username=hokm;Password=${POSTGRES_PASSWORD:-hokm_dev_pass}" - Jwt__Key: ${JWT_KEY:?set JWT_KEY in .env} + # Default empty so `docker compose build` (which interpolates the whole file) + # never blocks on a runtime-only secret. The server REFUSES to boot in + # Production with a missing/dev key (see Program.cs guard). + Jwt__Key: ${JWT_KEY:-} Jwt__Issuer: ${JWT_ISSUER:-hokm} Jwt__Audience: ${JWT_AUDIENCE:-hokm-clients} # Comma-separated origins the browser uses to reach the web app. diff --git a/server/src/Hokm.Server/Program.cs b/server/src/Hokm.Server/Program.cs index 5608039..5d97393 100644 --- a/server/src/Hokm.Server/Program.cs +++ b/server/src/Hokm.Server/Program.cs @@ -15,9 +15,14 @@ using Microsoft.IdentityModel.Tokens; var builder = WebApplication.CreateBuilder(args); // --- options --- +const string DevJwtKey = "dev-only-insecure-key-change-me-please-32+bytes!!"; var jwt = builder.Configuration.GetSection("Jwt").Get() ?? new JwtOptions(); if (string.IsNullOrWhiteSpace(jwt.Key)) - jwt.Key = "dev-only-insecure-key-change-me-please-32+bytes!!"; + jwt.Key = DevJwtKey; +// In Production a real secret is mandatory — refuse to boot with the dev key. +if (builder.Environment.IsProduction() && (jwt.Key == DevJwtKey || jwt.Key.Length < 32)) + throw new InvalidOperationException( + "Jwt:Key (env JWT_KEY) must be a 32+ char secret in Production. Set it in ENV_FILE: openssl rand -hex 32"); builder.Services.AddSingleton(jwt); builder.Services.AddSingleton(); builder.Services.AddSingleton();