HTTPS & Certificates

Add TLS with a development self‑signed certificate or an existing PFX.

Prerequisites: see Certificates section for creating a self‑signed cert.

Full source

File: pwsh/tutorial/examples/7.3-Https.ps1

<#
    Sample Kestrun Server - HTTPS
    Demonstrates adding an HTTPS listener with a development self-signed certificate.
    For production use a proper certificate and secure secret storage.
    FileName: 7.3-Https.ps1
#>

[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '')]
param(
    [int]$Port = 5000,
    [IPAddress]$IPAddress = [IPAddress]::Loopback
)

# (Optional) Configure console logging
New-KrLogger |
    Add-KrSinkConsole |
    Register-KrLogger -Name 'console' -SetAsDefault | Out-Null

# Ensure a development certificate exists (self-signed) - dev ONLY
$certPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath 'devcert.pfx'
$pw = ConvertTo-SecureString -String 'P@ssw0rd!' -AsPlainText -Force
if (-not (Test-Path $certPath)) {
    Write-Host 'Creating development self-signed certificate devcert.pfx'
    New-KrSelfSignedCertificate -DnsName 'localhost' -Exportable -ValidDays 30 |
        Export-KrCertificate -FilePath $certPath -Format Pfx -IncludePrivateKey -Password $pw | Out-Null
}

$port2 = $Port + 443
# Create a new Kestrun server
New-KrServer -Name 'Endpoints Https'

# HTTP listener (optional)
Add-KrEndpoint -Port $Port -IPAddress $IPAddress

# HTTPS listener
Add-KrEndpoint -Port $port2 -IPAddress $IPAddress -CertPath $certPath -CertPassword $pw

# Enable configuration
Enable-KrConfiguration

# Secure route
Add-KrMapRoute -Verbs Get -Pattern '/secure' -Endpoints "$($IPAddress.ToString()):$port2" -ScriptBlock {
    Write-KrLog -Level Information -Message 'Secure endpoint invoked'
    Write-KrTextResponse -InputObject 'Secure hello' -StatusCode 200
}

# Unsecure route (available on HTTP listener)
Add-KrMapRoute -Verbs Get -Pattern '/unsecure' -Endpoints "$($IPAddress.ToString()):$Port" -ScriptBlock {
    Write-KrLog -Level Information -Message 'Unsecure endpoint invoked'
    Write-KrTextResponse -InputObject 'Unsecure hello' -StatusCode 200
}

Write-KrLog -Level Information -Message 'HTTP listener active on {Port}' -Values $Port
Write-KrLog -Level Information -Message 'HTTPS listener active on {Port2}' -Values $port2

# Start the server
Start-KrServer -CloseLogsOnExit

Step-by-step

  1. Ensure / create PFX (dev only) with New-KrSelfSignedCertificate.
  2. Add HTTP listener (optional) and HTTPS listener with -CertPath/-CertPassword.
  3. Enable configuration.
  4. Map /secure route with -Endpoints parameter to bind to HTTPS listener only.
  5. Map /unsecure route with -Endpoints parameter to bind to HTTP listener only.
  6. Start server.
  7. (Optional) Tune via Set-KrServerHttpsOptions for protocols or client certificate mode.

Endpoint-specific routing

The -Endpoints parameter in Add-KrMapRoute allows you to bind routes to specific listeners:

# Secure route - only available on HTTPS listener
Add-KrMapRoute -Verbs Get -Pattern '/secure' -Endpoints "127.0.0.1:5443" -ScriptBlock {
    Write-KrTextResponse -InputObject 'Secure hello' -StatusCode 200
}

# Unsecure route - only available on HTTP listener
Add-KrMapRoute -Verbs Get -Pattern '/unsecure' -Endpoints "127.0.0.1:5000" -ScriptBlock {
    Write-KrTextResponse -InputObject 'Unsecure hello' -StatusCode 200
}

Key points:

  • Format: "IPAddress:Port" (e.g., "127.0.0.1:5443")
  • Without -Endpoints, routes are available on all listeners
  • Use this to enforce HTTPS-only routes or separate HTTP/HTTPS functionality

Try it

curl -k https://127.0.0.1:5443/secure

Invoke-WebRequest -Uri https://127.0.0.1:5443/secure -SkipCertificateCheck | Select-Object -ExpandProperty Content

-k skips trust validation for an untrusted self‑signed cert.

Troubleshooting

Symptom Cause Fix
curl cert warning Self-signed cert Use -k or trust cert locally
HTTPS listener fails Wrong password Re-enter secure string / recreate PFX
Route works on HTTP not HTTPS Only added HTTP listener Add second listener before enabling config
Route not accessible on expected endpoint Wrong -Endpoints parameter Check IP:Port format matches listener
Route accessible on wrong protocol Missing -Endpoints parameter Add -Endpoints to bind to specific listener

See also: Certificates · Logging


References

Previous / Next