Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
61 commits
Select commit Hold shift + click to select a range
b2bc1d3
EDFI-2762 Add Windows installation scripts
analiliagutierrez May 19, 2026
ecb0de6
EDFI-2762 Add PostgreSQL support via -DbEngine
adiaz-msdf May 20, 2026
6dc33e5
EDFI-2762 Add Yopass three-mode integration to windows-install
analiliagutierrez May 28, 2026
7e79860
EDFI-2776 Renumber windows-install scripts to official guide order
analiliagutierrez Jun 15, 2026
c137451
EDFI-2776 Consolidate Node and Keycloak install scripts
analiliagutierrez Jun 15, 2026
39ee80f
EDFI-2776 Split Keycloak teardown into uninstall-keycloak.ps1
analiliagutierrez Jun 15, 2026
6c374e3
EDFI-2776 Switch to two standalone HTTP sites (IIS topology)
analiliagutierrez Jun 15, 2026
cdb0c5d
EDFI-2776 Align uninstall.ps1 with standalone HTTP topology
analiliagutierrez Jun 15, 2026
b648719
EDFI-2776 Decouple OIDC config from Keycloak naming
analiliagutierrez Jun 15, 2026
47ce79a
EDFI-2776 Reconcile pre-flight check with the restructured scripts
analiliagutierrez Jun 15, 2026
11ee628
EDFI-2776 Add precondition checks to the install scripts
analiliagutierrez Jun 15, 2026
346ab85
EDFI-2776 Scope the npm cache override to the App Pool
analiliagutierrez Jun 15, 2026
5596665
EDFI-2776 Add actionable error handling to the install scripts
analiliagutierrez Jun 15, 2026
dd6444f
EDFI-2776 Rewrite windows-install README for the new scheme
analiliagutierrez Jun 15, 2026
ff80d9e
EDFI-2776 Require IIS 10+ as a precondition
analiliagutierrez Jun 16, 2026
b655449
EDFI-2776 Deploy the standalone sites to dedicated directories
analiliagutierrez Jun 16, 2026
890e05e
EDFI-2776 Remove Keycloak/Java checks from the generic pre-flight
analiliagutierrez Jun 16, 2026
3b4d876
EDFI-2776 Make install-all work with any OIDC provider
analiliagutierrez Jun 16, 2026
2779170
EDFI-2776 Drop the unused OIDC management M2M params from 05-deploy-api
analiliagutierrez Jun 16, 2026
a61aa92
EDFI-2776 Fix stale synopsis comments in install scripts
analiliagutierrez Jun 16, 2026
fe90c75
EDFI-2776 Harden Keycloak startup against a blocked output pipe
analiliagutierrez Jun 24, 2026
4b91ec3
Merge branch 'main' into EDFI-2776-windows-install-restructure
stephenfuqua Jun 26, 2026
0f2bd5f
docs: Deployment guide PRD
stephenfuqua Jun 26, 2026
64f37d0
docs: Soften FT3 backend hosting requirement in Deployment Guide PRD
stephenfuqua Jun 26, 2026
dc99020
Update windows-install/docker/README.md
analiliagutierrez Jun 30, 2026
8b581f1
EDFI-2776 Replace iisnode with an httpPlatform reverse proxy
analiliagutierrez Jul 3, 2026
ebe1e2e
EDFI-2776 Generate a per-install data-at-rest encryption key
analiliagutierrez Jul 2, 2026
3040378
EDFI-2776 Run the Admin App as a least-privilege DB login
analiliagutierrez Jul 2, 2026
80283f2
EDFI-2776 Remove the unused hardcoded management secret from config
analiliagutierrez Jul 3, 2026
b120196
EDFI-2776 Keep credentials off the command line and out of the instal…
analiliagutierrez Jul 3, 2026
69eec7d
EDFI-2776 Enforce the SQL Server password policy on install
analiliagutierrez Jul 3, 2026
d15e229
EDFI-2776 Inject Admin App config via NODE_CONFIG and guard residual …
analiliagutierrez Jul 4, 2026
3f21e03
EDFI-2776 Reconcile the OIDC connection row on re-deploy
analiliagutierrez Jul 4, 2026
1ec08b7
EDFI-2776 Match the OIDC redirect URI to the actual oidc row id
analiliagutierrez Jul 4, 2026
53de480
EDFI-2776 Verify remote downloads with SHA-256 before install
analiliagutierrez Jul 5, 2026
9d32120
EDFI-2776 Harden IIS response headers and error mode on both sites
analiliagutierrez Jul 6, 2026
90482e8
EDFI-2776 Run the FE site under a dedicated App Pool
analiliagutierrez Jul 6, 2026
5c5d7f9
EDFI-2776 Tighten Keycloak redirect and post-logout URIs
analiliagutierrez Jul 6, 2026
184b83f
EDFI-2776 Add always-on HTTPS binding with certificate resolution
analiliagutierrez Jul 6, 2026
c21f701
EDFI-2776 Redirect HTTP to HTTPS on both IIS sites
analiliagutierrez Jul 6, 2026
0836f4e
EDFI-2776 Build the FE bundle against the HTTPS API URL
analiliagutierrez Jul 6, 2026
e61c715
EDFI-2776 Serve the Admin App over HTTPS end to end
analiliagutierrez Jul 6, 2026
564a410
EDFI-2776 Clean up TLS bindings on uninstall and pre-flight the HTTPS…
analiliagutierrez Jul 6, 2026
20e3b47
EDFI-2776 Fix the install-all smoke test and OIDC discovery over HTTPS
analiliagutierrez Jul 7, 2026
461e7d0
EDFI-2776 Enforce the Content-Security-Policy on both sites
analiliagutierrez Jul 7, 2026
598cbc2
EDFI-2776 Trust the self-signed certificate on the local machine by d…
analiliagutierrez Jul 7, 2026
9ba594e
EDFI-2776 Harden the Keycloak client-diff against StrictMode
analiliagutierrez Jul 8, 2026
5184bb2
EDFI-2776 Verify upstream TLS certificates by default
analiliagutierrez Jul 8, 2026
73e4d3a
EDFI-2776 Warn when Direct Access Grants targets a non-localhost IdP
analiliagutierrez Jul 8, 2026
0d33ecb
EDFI-2776 Bind the dockerized Postgres to loopback by default
analiliagutierrez Jul 8, 2026
838a1cc
EDFI-2776 Let Keycloak survive a reboot and flag its dev mode
analiliagutierrez Jul 8, 2026
0e4e231
EDFI-2776 Document the upstream TLS verification opt-out
analiliagutierrez Jul 8, 2026
cd8be62
EDFI-2776 Align the Windows install docs with the final hosting, TLS,…
analiliagutierrez Jul 9, 2026
4ce430b
EDFI-2776 Update the Docker compose docs for httpPlatform and the sup…
analiliagutierrez Jul 9, 2026
cffdb9b
EDFI-2776 Unblock only the known install scripts, not every .ps1
analiliagutierrez Jul 9, 2026
b86c954
EDFI-2776 Align the Docker Postgres re-run with the least-privilege o…
analiliagutierrez Jul 9, 2026
508650c
EDFI-2776 Grant CREATE on the app database to the least-privilege PG …
analiliagutierrez Jul 14, 2026
c82f7a3
EDFI-2776 Kill the lingering node by command line, not by a parsed lo…
analiliagutierrez Jul 14, 2026
35161fb
EDFI-2776 Warn when the requested httpPlatform handler is not the ins…
analiliagutierrez Jul 14, 2026
2ae25f7
EDFI-2776 Rebuild the frontend when its API URL changed, not just on …
analiliagutierrez Jul 14, 2026
256b193
EDFI-2776 Keep a transient OIDC-row sqlcmd failure from aborting the …
analiliagutierrez Jul 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions compose/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -367,9 +367,6 @@ authentication flow:
CLIENT_ID: 'edfiadminapp',
CLIENT_SECRET: 'big-secret-123',
MACHINE_AUDIENCE: 'edfiadminapp-api',
MANAGEMENT_DOMAIN: 'localhost',
MANAGEMENT_CLIENT_ID: 'edfiadminapp-machine',
MANAGEMENT_CLIENT_SECRET: 'edfi-machine-secret-456',
}
```

Expand Down
252 changes: 252 additions & 0 deletions docs/PRD-Deployment-Guide-v4.0.md

Large diffs are not rendered by default.

5 changes: 1 addition & 4 deletions packages/api/config/local.js-edfi
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,7 @@ module.exports = {
ISSUER: 'https://localhost/auth/realms/edfi',
CLIENT_ID: 'edfiadminapp',
CLIENT_SECRET: 'big-secret-123',
MACHINE_AUDIENCE: 'edfiadminapp-api',
MANAGEMENT_DOMAIN: 'localhost',
MANAGEMENT_CLIENT_ID: 'edfiadminapp-machine',
MANAGEMENT_CLIENT_SECRET: 'edfi-machine-secret-456'
MACHINE_AUDIENCE: 'edfiadminapp-api'
},

WHITELISTED_REDIRECTS: [FE_URL],
Expand Down
11 changes: 5 additions & 6 deletions packages/api/config/production.js-edfi
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,7 @@ module.exports = {
ISSUER: 'https://localhost/auth/realms/edfi',
CLIENT_ID: 'edfiadminapp',
CLIENT_SECRET: 'big-secret-123',
MACHINE_AUDIENCE: 'edfiadminapp-api',
MANAGEMENT_DOMAIN: 'localhost',
MANAGEMENT_CLIENT_ID: 'edfiadminapp-machine',
MANAGEMENT_CLIENT_SECRET: 'edfi-machine-secret-456'
MACHINE_AUDIENCE: 'edfiadminapp-api'
},

WHITELISTED_REDIRECTS: [FE_URL],
Expand All @@ -72,8 +69,10 @@ module.exports = {

USE_PKCE: true,

// Deliverating set in false since we are using self-signed certificates but in production should be set in true
SSL_VERIFICATION: false,
// SSL verification for the API's outbound HTTPS calls (ODS/API, AdminApi, Yopass).
// Secure by default; the installer sets this via NODE_CONFIG and can disable it
// with -DisableSslVerification for upstreams that use self-signed certificates.
SSL_VERIFICATION: true,
// Certification artifact configuration
CERT_BRUNO_SRC_REF: 'v2.1.0',
CERT_BRUNO_SRC_CHECKSUM: '71840f51f464c60d7b90c7bbf08d9be039df291d51dd69085ffc4703b98f11e6',
Expand Down
437 changes: 437 additions & 0 deletions windows-install/00-check-prereqs.ps1

Large diffs are not rendered by default.

171 changes: 171 additions & 0 deletions windows-install/01-prereqs-iis.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
#Requires -RunAsAdministrator
<#
.SYNOPSIS
Installs the IIS URL Rewrite Module and an httpPlatform handler (HttpBridge or
Microsoft HttpPlatformHandler), and unlocks the IIS config the Admin App's
web.config files need.

.DESCRIPTION
- Downloads + installs the IIS URL Rewrite Module MSI (verifying a pinned SHA-256)
- Downloads + installs the chosen httpPlatform handler MSI (verifying a pinned SHA-256)
- Unlocks system.webServer/handlers so app-level web.config can register the handler

The API is hosted by IIS via the httpPlatform handler: IIS launches node.exe as a
child process, hands it a loopback port through HTTP_PLATFORM_PORT, and reverse-
proxies requests to it.

Idempotent -- safe to re-run.

This sets up the IIS engine prerequisites only. The API and FE are deployed as
two standalone sites by 05-deploy-api.ps1 and 06-deploy-fe.ps1.

.PARAMETER HttpHandler
Which httpPlatform handler to install:
HttpBridge (default) -- LeXtudio fork (MIT), actively maintained,
drop-in compatible with the httpPlatform schema. Currently
shipped as a release candidate.
HttpPlatformHandler -- Microsoft's original v1.2 (signed, stable, frozen ~2016).
Both register the same 'httpPlatformHandler' global module, so the API web.config
is identical either way.

.EXAMPLE
.\01-prereqs-iis.ps1
.\01-prereqs-iis.ps1 -HttpHandler HttpPlatformHandler
#>

param(
[ValidateSet('HttpBridge','HttpPlatformHandler')]
[string]$HttpHandler = 'HttpBridge'
)

$ErrorActionPreference = 'Stop'

# Pinned downloads. Each MSI is verified against a SHA-256 captured from the
# published artifact before install (defends against corrupt/partial downloads and
# a tampered mirror). Mirrors the CERT_BRUNO_SRC_CHECKSUM pattern in the codebase.
$UrlRewrite = @{
Url = 'https://download.microsoft.com/download/D/D/E/DDE57C26-C62C-4C59-A1BB-31D58B36ADA2/rewrite_amd64_en-US.msi'
Sha256 = '7B327108055C4B5BA9445E3B1AFCC4DC5EDD373BAA83EBE6DCB0B1CE57EE3FC2'
File = 'rewrite_amd64_en-US.msi'
}
$Handlers = @{
HttpBridge = @{
Url = 'https://github.com/lextudio/httpbridge/releases/download/httpbridge_v10.0.0-rc.1/httpbridge_x64_en_10.0.0-dev.msi'
Sha256 = '35E06DC2EEBBDA4C6756787FA6650B56504684907242ED760B855D1D0248709F'
File = 'httpbridge_x64_en_10.0.0-dev.msi'
}
HttpPlatformHandler = @{
Url = 'https://download.microsoft.com/download/8/1/3/813AC4E6-9203-4F7A-8DD5-F3D54D10C5CD/httpPlatformHandler_amd64.msi'
Sha256 = '90F8D4905A0AB4F2C95223B3C79E2807A0B74507747D240E43C4302E8DB4B5EF'
File = 'httpPlatformHandler_amd64.msi'
}
}

function Install-VerifiedMsi {
[CmdletBinding()]
param(
[Parameter(Mandatory)][string]$Name,
[Parameter(Mandatory)][string]$Url,
[Parameter(Mandatory)][string]$Sha256,
[Parameter(Mandatory)][string]$FileName
)
$msi = Join-Path $env:TEMP $FileName

# Reuse an already-downloaded MSI only if its hash matches; otherwise
# (missing, or mismatch -> possibly corrupt/partial/tampered) (re)download.
$needsDownload = $true
if (Test-Path $msi) {
if ((Get-FileHash -Path $msi -Algorithm SHA256).Hash -ieq $Sha256) {
Write-Host "$Name MSI already downloaded and verified -- reusing $msi."
$needsDownload = $false
} else {
Write-Host "$Name MSI at $msi failed the pinned hash (corrupt/partial?); re-downloading." -ForegroundColor Yellow
Remove-Item $msi -Force
}
}
if ($needsDownload) {
Write-Host "Downloading $Name from $Url ..."
try {
Invoke-WebRequest -Uri $Url -OutFile $msi -UseBasicParsing
} catch {
throw "Failed to download $Name from $Url. Check internet connectivity and that the URL is reachable. Original: $($_.Exception.Message)"
}
$actual = (Get-FileHash -Path $msi -Algorithm SHA256).Hash
if ($actual -ine $Sha256) {
Remove-Item $msi -Force -ErrorAction SilentlyContinue
throw "$Name failed SHA-256 verification.`n Expected: $Sha256`n Actual: $actual`nThe download may be corrupt or tampered with; aborting."
}
Write-Host "$Name verified (SHA-256 match)."
}

Write-Host "Installing $Name ..."
Start-Process msiexec.exe -ArgumentList "/i `"$msi`" /qn /norestart" -Wait
}

# Precondition: the IIS web server role must already be installed
# (setup-vm-prereqs.ps1 does that). This script only adds URL Rewrite + the httpPlatform handler.
if (-not (Get-Service W3SVC -ErrorAction SilentlyContinue)) {
throw "IIS (W3SVC) is not installed. Run setup-vm-prereqs.ps1 first, or enable the IIS role via Enable-WindowsOptionalFeature."
}

# Precondition: IIS 10+ is required. 05-deploy-api.ps1 sets NPM_CONFIG_CACHE on
# the App Pool's environmentVariables, a collection added in IIS 10.0.
$iisMajor = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\InetStp" -Name MajorVersion -ErrorAction SilentlyContinue).MajorVersion
if ($iisMajor -and $iisMajor -lt 10) {
throw "IIS $iisMajor detected; this install requires IIS 10 or newer (App Pool environment variables, used to scope the npm cache, were added in IIS 10). Use Windows 10/11 or Windows Server 2016+."
}
Import-Module WebAdministration

# IIS URL Rewrite Module.
# Still required by the FE web.config SPA fallback (06-deploy-fe.ps1 rewrites to
# index.html). The API no longer uses a rewrite rule under httpPlatform.
$rewriteDll = "$env:SystemRoot\System32\inetsrv\rewrite.dll"
if (Test-Path $rewriteDll) {
Write-Host "URL Rewrite Module already installed."
} else {
Install-VerifiedMsi -Name 'IIS URL Rewrite Module' -Url $UrlRewrite.Url -Sha256 $UrlRewrite.Sha256 -FileName $UrlRewrite.File
if (-not (Test-Path $rewriteDll)) {
throw "URL Rewrite Module install failed (rewrite.dll not present)."
}
}

# Unlock system.webServer/handlers so app-level web.configs can register the
# httpPlatform handler. IIS locks this by default; without it, the API returns
# HTTP 500.19 (0x80070021).
& "$env:SystemRoot\System32\inetsrv\appcmd.exe" unlock config -section:system.webServer/handlers | Out-Null
Write-Host "Unlocked system.webServer/handlers section."

# httpPlatform handler. Both HttpBridge and Microsoft HttpPlatformHandler register
# a global module named 'httpPlatformHandler'. Skip if already present (re-run safe;
# switching handlers needs a manual uninstall first).
if (Get-WebGlobalModule -Name 'httpPlatformHandler' -ErrorAction SilentlyContinue) {
# Both handlers register the same module name, so detect which MSI is installed
# to tell whether it matches the requested -HttpHandler and warn if it does not
# (switching handlers needs a manual uninstall of the current MSI first).
$uninstallKeys = @(
'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*'
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
)
$installedName = Get-ItemProperty $uninstallKeys -ErrorAction SilentlyContinue |
Where-Object { $_.DisplayName -match 'HTTP\s*Bridge|HTTP\s*Platform\s*Handler' } |
Select-Object -First 1 -ExpandProperty DisplayName
$installedHandler =
if ($installedName -match 'Bridge') { 'HttpBridge' }
elseif ($installedName -match 'Platform\s*Handler') { 'HttpPlatformHandler' }
else { $null }
if ($installedHandler -and $installedHandler -ne $HttpHandler) {
Write-Warning "The 'httpPlatformHandler' module is already registered from '$installedName' (-HttpHandler $installedHandler), but -HttpHandler $HttpHandler was requested. Keeping the installed handler. To switch, uninstall the current handler MSI first (Programs and Features, or msiexec /x), then re-run."
} else {
Write-Host "httpPlatform handler already registered (global module 'httpPlatformHandler')."
}
} else {
$h = $Handlers[$HttpHandler]
Install-VerifiedMsi -Name $HttpHandler -Url $h.Url -Sha256 $h.Sha256 -FileName $h.File
if (-not (Get-WebGlobalModule -Name 'httpPlatformHandler' -ErrorAction SilentlyContinue)) {
throw "$HttpHandler install completed but the 'httpPlatformHandler' global module is not registered. Check the MSI installed correctly."
}
}

Write-Host ""
Write-Host "SUCCESS: URL Rewrite + $HttpHandler installed; IIS config unlocked." -ForegroundColor Green
Write-Host "The API and FE deploy as standalone sites (05-deploy-api.ps1, 06-deploy-fe.ps1)."
Loading
Loading