Amazon EC2 Behind an Application Load Balancer
This guide walks through deploying JAMS Web Client on AWS using a single Amazon EC2 Windows instance behind an Application Load Balancer (ALB). The ALB terminates public HTTPS traffic using an ACM-managed certificate and forwards requests to the JAMS Gateway on the EC2. All six JAMS services run on the same instance and communicate internally through the Gateway.
This is the recommended setup for AWS-hosted JAMS deployments. The ALB is fully managed by AWS, integrates natively with ACM for automatic certificate renewal, and requires no manual TLS configuration on the public endpoint. One advantage over Azure Application Gateway is that the ALB does not validate the backend EC2 certificate, only the public-facing listener certificate needs to be publicly trusted.
All six JAMS services (Gateway, Identity, API, UI, MCP, JAX) are installed on a single EC2 Windows instance. An AWS Application Load Balancer sits in front, terminates public HTTPS traffic, and forwards to the Gateway on the EC2.
Before You Begin
Ensure you have the following:
- An EC2 Windows Server instance with the JAMS Web Client installed via the installer.
- AWS ALB created and its DNS name available.
- Security group on the EC2 instance allowing inbound HTTPS (443) from the ALB.
1. Configuring the ALB
Listener:
- Protocol: HTTPS, Port: 443
- Certificate: attach a valid CA-trusted certificate
Target group:
- Target type: Instance
- Protocol: HTTPS, Port: 443. The EC2 Gateway must be on HTTPS, not HTTP. If the JAMS Web Client was configured in EC2 to use another port, then the ALB must forward the request to that port on the EC2.
- Health check: HTTPS, path /api/system/health, interval 30s, timeout 10s, unhealthy threshold 3
Idle timeout: Increase the ALB idle timeout to at least 700 seconds. The default of 60 seconds is too short for MCP's 10-minute SSE streaming sessions. Set this in ALB | Attributes | Idle timeout. Connections will be silently dropped mid-stream without this change.
ALB does not validate the EC2's TLS certificate chain when using an HTTPS target group. It accepts self-signed certificates on the target. Only the ALB listener certificate needs to be publicly trusted by browsers.
2. Configuring the TLS certificate on the EC2
A TLS certificate must be bound to Kestrel on port 443. The JAMS installer generates a self-signed certificate automatically. This installer-generated certificate already includes DNS:localhost, the machine hostname, and 127.0.0.1 in its Subject Alternative Names. It is suitable for this setup without replacement.
The certificate must be imported into LocalMachine\Root on the EC2 so that .NET's TLS validation accepts it for internal service-to-service calls. Run the following command on the EC2 after installation:
Import-PfxCertificate `
-FilePath "C:\Program Files\JAMS\Shared\Certificates\default.pfx" `
-CertStoreLocation Cert:\LocalMachine\Root `
-Password (ConvertTo-SecureString "" -AsPlainText -Force)
This step is required because all six JAMS services make internal HTTPS calls to each other through localhost:443. Without the certificate being trusted on the machine, these calls fail with a TLS certificate validation error even though the cert is perfectly valid for internal use.
3. Updating Shared\settings.json
This single file overrides configuration for all six services. Locate it at C:\Program Files\JAMS\Shared\settings.json and add or update these sections:
{
"Kestrel": {
"Certificates": {
"Default": {
"Path": "../Shared/Certificates/default.pfx",
"Password": ""
}
}
},
"Gateway": {
"Url": "https://<your-alb-dns-name>",
"InternalUrl": "https://localhost:443",
"AllowSelfSigned": false
}
}
| Key | Description |
|---|---|
| Gateway:Url | The ALB's public DNS name exactly as clients and browsers use it. This becomes the OIDC issuer. It is stamped into every access token and must never change once users are logged in. |
| Gateway:InternalUrl | The address used for internal service-to-service calls, bypassing the ALB. Use https://localhost:443 when the installer bound the Gateway to port 443 (see port note below). If the installer selected a different port, update this value accordingly. |
| Gateway:AllowSelfSigned | Must be false in production. Enables full TLS certificate and issuer validation. See note below. |
| Kestrel:Certificates:Default:Path | Path to the PFX file generated by the installer. This default value is correct for standard installations. |
AllowSelfSigned must be explicitly set to false. The Gateway, API, UI, and Identity services ship with AllowSelfSigned: true in their base configuration, meaning TLS certificate validation and JWT issuer validation are disabled by default. Setting AllowSelfSigned: false in Shared\settings.json is what activates production-grade security for these services. Without this override, they will run with all validation disabled even in a production environment.
The JAMS installer automatically selects the HTTPS port: it tries 443 first, and falls back to 901 if port 443 is already in use on the machine. Check which port the Gateway actually bound to after installation. It is shown in Shared\JAMS Gateway\settings.json under Urls. Update Gateway:InternalUrl to match that port if it is not 443.
4. Restarting All Services
After updating Shared\settings.json, restart all six JAMS services. Kestrel loads the certificate at startup. A restart is required after any certificate or settings change.
"JAMS Gateway","JAMS Identity","JAMS API","JAMS Web UI","JAMS MCP","JAX" | ForEach-Object { Restart-Service $_ }
5. Verifying the Updates
- Go to https://<alb-dns-name>
- The JAMS Web Client login page should appear with no certificate warning.
- Log in with your credentials.
- Click Jobs from the main menu. Verify you see the expected list of Jobs. Successfully logging in and viewing the Jobs confirms the full chain is working correctly.