diff --git a/menu/menu.yaml b/menu/menu.yaml index bc3cbc488b4..ee878a6d1ab 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1400,6 +1400,20 @@ Articles: - Title: Version 1 to 2 Url: servicepulse/1to2 + - Title: Security + Articles: + - Title: Overview + Url: servicepulse/security + - Title: Configuration + Articles: + - Title: Authentication + Url: servicepulse/security/configuration/authentication + - Title: Forward Headers for Reverse Proxy + Url: servicepulse/security/configuration/forward-headers + - Title: TLS + Url: servicepulse/security/configuration/tls + - Title: Hosting guide + Url: servicepulse/security/hosting-guide - Title: Configuration Articles: - Url: servicepulse/host-config @@ -1481,6 +1495,26 @@ Url: servicecontrol/upgrades/2to3 - Title: Version 1 to 2 Url: servicecontrol/upgrades/1to2 + - Title: Security + Articles: + - Title: Overview + Url: servicecontrol/security + - Title: Configuration + Articles: + - Title: Authentication + Url: servicecontrol/security/configuration/authentication + - Title: Forward Headers for Reverse Proxy + Url: servicecontrol/security/configuration/forward-headers + - Title: TLS + Url: servicecontrol/security/configuration/tls + - Title: CORS + Url: servicecontrol/security/configuration/cors + - Title: Hosting guide + Url: servicecontrol/security/hosting-guide + - Title: Examples + Articles: + - Title: Microsoft Entra ID Authentication Guide + Url: servicecontrol/security/entra-id-authentication - Title: Planning Articles: - Title: Optimizing for use in different environments diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index fedd9f4475d..e7d58b4a882 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -153,6 +153,389 @@ Run [ServiceControl audit instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | boolean | `False` | +## [Authentication](/servicecontrol/security/configuration/authentication.md) + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [authentication configuration examples](/servicecontrol/security/configuration/authentication.md#identity-provider-setup-configuration-examples) for additional information. + +### ServiceControl.Audit/Authentication.Enabled + +_Added in version 6.11.0_ + +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_ENABLED` | +| **App config key** | `ServiceControl.Audit/Authentication.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl.Audit/Authentication.Authority + +_Added in version 6.11.0_ + +The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_AUTHORITY` | +| **App config key** | `ServiceControl.Audit/Authentication.Authority` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl.Audit/Authentication.Audience + +_Added in version 6.11.0_ + +The expected audience value in the JWT token, typically the application ID or URI of the API. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_AUDIENCE` | +| **App config key** | `ServiceControl.Audit/Authentication.Audience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl.Audit/Authentication.ValidateIssuer + +_Added in version 6.11.0_ + +Controls whether the token issuer is validated against the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_VALIDATEISSUER` | +| **App config key** | `ServiceControl.Audit/Authentication.ValidateIssuer` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl.Audit/Authentication.ValidateAudience + +_Added in version 6.11.0_ + +Controls whether the token audience is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_VALIDATEAUDIENCE` | +| **App config key** | `ServiceControl.Audit/Authentication.ValidateAudience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl.Audit/Authentication.ValidateLifetime + +_Added in version 6.11.0_ + +Controls whether the token expiration is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_VALIDATELIFETIME` | +| **App config key** | `ServiceControl.Audit/Authentication.ValidateLifetime` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl.Audit/Authentication.ValidateIssuerSigningKey + +_Added in version 6.11.0_ + +Controls whether the token signing key is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_VALIDATEISSUERSIGNINGKEY` | +| **App config key** | `ServiceControl.Audit/Authentication.ValidateIssuerSigningKey` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl.Audit/Authentication.RequireHttpsMetadata + +_Added in version 6.11.0_ + +Controls whether HTTPS is required when retrieving metadata from the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_AUTHENTICATION_REQUIREHTTPSMETADATA` | +| **App config key** | `ServiceControl.Audit/Authentication.RequireHttpsMetadata` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> Setting this to `false` is not recommended for production environments. + +## [TLS](/servicecontrol/security/configuration/tls.md) + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [TLS configuration examples](/servicecontrol/security/configuration/tls.md#configuration-examples) for additional information. + +### ServiceControl.Audit/Https.Enabled + +_Added in version 6.11.0_ + +Enables Kestrel HTTPS with a certificate. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_ENABLED` | +| **App config key** | `ServiceControl.Audit/Https.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl.Audit/Https.CertificatePath + +_Added in version 6.11.0_ + +The path to the PFX or PEM certificate file. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_CERTIFICATEPATH` | +| **App config key** | `ServiceControl.Audit/Https.CertificatePath` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl.Audit/Https.CertificatePassword + +_Added in version 6.11.0_ + +The password for the certificate file, if required. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_CERTIFICATEPASSWORD` | +| **App config key** | `ServiceControl.Audit/Https.CertificatePassword` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl.Audit/Https.RedirectHttpToHttps + +_Added in version 6.11.0_ + +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `ServiceControl.Audit/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> When running ServiceControl directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). This setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +### ServiceControl.Audit/Https.Port + +_Added in version 6.11.0_ + +The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_PORT` | +| **App config key** | `ServiceControl.Audit/Https.Port` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | None | + +### ServiceControl.Audit/Https.EnableHsts + +_Added in version 6.11.0_ + +Enables HTTP Strict Transport Security (HSTS). + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_ENABLEHSTS` | +| **App config key** | `ServiceControl.Audit/Https.EnableHsts` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> Review the implications of [enabling HSTS](/servicecontrol/security/configuration/tls.md#security-considerations-hsts) before doing so. + +### ServiceControl.Audit/Https.HstsMaxAgeSeconds + +_Added in version 6.11.0_ + +The max-age value in seconds for the HSTS header. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_HSTSMAXAGESECONDS` | +| **App config key** | `ServiceControl.Audit/Https.HstsMaxAgeSeconds` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | `31536000` (1 year) | + +### ServiceControl.Audit/Https.HstsIncludeSubDomains + +_Added in version 6.11.0_ + +Includes subdomains in the HSTS policy. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_HSTSINCLUDESUBDOMAINS` | +| **App config key** | `ServiceControl.Audit/Https.HstsIncludeSubDomains` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +## [Forwarded headers](/servicecontrol/security/configuration/forward-headers.md) + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [forward headers configuration examples](/servicecontrol/security/configuration/forward-headers.md#configuration-examples) for additional information. + +### ServiceControl.Audit/ForwardedHeaders.Enabled + +_Added in version 6.11.0_ + +Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_ENABLED` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl.Audit/ForwardedHeaders.TrustAllProxies + +_Added in version 6.11.0_ + +Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_TRUSTALLPROXIES` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.TrustAllProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments behind a reverse proxy, set this to `false` and configure `KnownProxies` or `KnownNetworks` to restrict which proxies are trusted. + +### ServiceControl.Audit/ForwardedHeaders.KnownProxies + +_Added in version 6.11.0_ + +A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl.Audit/ForwardedHeaders.KnownNetworks + +_Added in version 6.11.0_ + +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/8,172.16.0.0/12` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +## [CORS](/servicecontrol/security/configuration/cors.md) + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [cors configuration examples](/servicecontrol/security/configuration/cors.md#configuration-examples) for additional information. + +### ServiceControl.Audit/Cors.AllowAnyOrigin + +_Added in version 6.11.0_ + +Allows requests from any origin. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_CORS_ALLOWANYORIGIN` | +| **App config key** | `ServiceControl.Audit/Cors.AllowAnyOrigin` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments, set this to `false` and configure `AllowedOrigins` to restrict which origins can access the API. + +### ServiceControl.Audit/Cors.AllowedOrigins + +_Added in version 6.11.0_ + +A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_CORS_ALLOWEDORIGINS` | +| **App config key** | `ServiceControl.Audit/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + ## Embedded database These settings are not valid for ServiceControl instances hosted in a container. diff --git a/servicecontrol/monitoring-instances/configuration.md b/servicecontrol/monitoring-instances/configuration.md index 9d21dba6ff2..127892a93ab 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -93,6 +93,389 @@ The maximum allowed time for the process to complete the shutdown. | Installation via PowerShell (on Windows) | TimeSpan | `00:02:00` (2 minutes) | | Installation via ServiceControl Management Utility (SCMU) (on Windows) | TimeSpan | `00:02:00` (2 minutes) | +## [Authentication](/servicecontrol/security/configuration/authentication.md) + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [authentication configuration examples](/servicecontrol/security/configuration/authentication.md#identity-provider-setup-configuration-examples) for additional information. + +### Monitoring/Authentication.Enabled + +_Added in version 6.11.0_ + +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_ENABLED` | +| **App config key** | `Monitoring/Authentication.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### Monitoring/Authentication.Authority + +_Added in version 6.11.0_ + +The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_AUTHORITY` | +| **App config key** | `Monitoring/Authentication.Authority` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### Monitoring/Authentication.Audience + +_Added in version 6.11.0_ + +The expected audience value in the JWT token, typically the application ID or URI of the API. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_AUDIENCE` | +| **App config key** | `Monitoring/Authentication.Audience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### Monitoring/Authentication.ValidateIssuer + +_Added in version 6.11.0_ + +Controls whether the token issuer is validated against the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_VALIDATEISSUER` | +| **App config key** | `Monitoring/Authentication.ValidateIssuer` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### Monitoring/Authentication.ValidateAudience + +_Added in version 6.11.0_ + +Controls whether the token audience is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_VALIDATEAUDIENCE` | +| **App config key** | `Monitoring/Authentication.ValidateAudience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### Monitoring/Authentication.ValidateLifetime + +_Added in version 6.11.0_ + +Controls whether the token expiration is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_VALIDATELIFETIME` | +| **App config key** | `Monitoring/Authentication.ValidateLifetime` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### Monitoring/Authentication.ValidateIssuerSigningKey + +_Added in version 6.11.0_ + +Controls whether the token signing key is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_VALIDATEISSUERSIGNINGKEY` | +| **App config key** | `Monitoring/Authentication.ValidateIssuerSigningKey` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### Monitoring/Authentication.RequireHttpsMetadata + +_Added in version 6.11.0_ + +Controls whether HTTPS is required when retrieving metadata from the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_AUTHENTICATION_REQUIREHTTPSMETADATA` | +| **App config key** | `Monitoring/Authentication.RequireHttpsMetadata` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> Setting this to `false` is not recommended for production environments. + +## [TLS](/servicecontrol/security/configuration/tls.md) + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [TLS configuration examples](/servicecontrol/security/configuration/tls.md#configuration-examples) for additional information. + +### Monitoring/Https.Enabled + +_Added in version 6.11.0_ + +Enables Kestrel HTTPS with a certificate. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_ENABLED` | +| **App config key** | `Monitoring/Https.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### Monitoring/Https.CertificatePath + +_Added in version 6.11.0_ + +The path to the PFX or PEM certificate file. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_CERTIFICATEPATH` | +| **App config key** | `Monitoring/Https.CertificatePath` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### Monitoring/Https.CertificatePassword + +_Added in version 6.11.0_ + +The password for the certificate file, if required. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_CERTIFICATEPASSWORD` | +| **App config key** | `Monitoring/Https.CertificatePassword` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### Monitoring/Https.RedirectHttpToHttps + +_Added in version 6.11.0_ + +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `Monitoring/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> When running ServiceControl directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). This setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +### Monitoring/Https.Port + +_Added in version 6.11.0_ + +The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_PORT` | +| **App config key** | `Monitoring/Https.Port` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | None | + +### Monitoring/Https.EnableHsts + +_Added in version 6.11.0_ + +Enables HTTP Strict Transport Security (HSTS). + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_ENABLEHSTS` | +| **App config key** | `Monitoring/Https.EnableHsts` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> Review the implications of [enabling HSTS](/servicecontrol/security/configuration/tls.md#security-considerations-hsts) before doing so. + +### Monitoring/Https.HstsMaxAgeSeconds + +_Added in version 6.11.0_ + +The max-age value in seconds for the HSTS header. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_HSTSMAXAGESECONDS` | +| **App config key** | `Monitoring/Https.HstsMaxAgeSeconds` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | `31536000` (1 year) | + +### Monitoring/Https.HstsIncludeSubDomains + +_Added in version 6.11.0_ + +Includes subdomains in the HSTS policy. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_HSTSINCLUDESUBDOMAINS` | +| **App config key** | `Monitoring/Https.HstsIncludeSubDomains` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +## [Forwarded headers](/servicecontrol/security/configuration/forward-headers.md) + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [forward headers configuration examples](/servicecontrol/security/configuration/forward-headers.md#configuration-examples) for additional information. + +### Monitoring/ForwardedHeaders.Enabled + +_Added in version 6.11.0_ + +Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_ENABLED` | +| **App config key** | `Monitoring/ForwardedHeaders.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### Monitoring/ForwardedHeaders.TrustAllProxies + +_Added in version 6.11.0_ + +Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_TRUSTALLPROXIES` | +| **App config key** | `Monitoring/ForwardedHeaders.TrustAllProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments behind a reverse proxy, set this to `false` and configure `KnownProxies` or `KnownNetworks` to restrict which proxies are trusted. + +### Monitoring/ForwardedHeaders.KnownProxies + +_Added in version 6.11.0_ + +A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `Monitoring/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### Monitoring/ForwardedHeaders.KnownNetworks + +_Added in version 6.11.0_ + +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/8,172.16.0.0/12` + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `Monitoring/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +## [CORS](/servicecontrol/security/configuration/cors.md) + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [cors configuration examples](/servicecontrol/security/configuration/cors.md#configuration-examples) for additional information. + +### Monitoring/Cors.AllowAnyOrigin + +_Added in version 6.11.0_ + +Allows requests from any origin. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_CORS_ALLOWANYORIGIN` | +| **App config key** | `Monitoring/Cors.AllowAnyOrigin` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments, set this to `false` and configure `AllowedOrigins` to restrict which origins can access the API. + +### Monitoring/Cors.AllowedOrigins + +_Added in version 6.11.0_ + +A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_CORS_ALLOWEDORIGINS` | +| **App config key** | `Monitoring/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + ## Logging ### Monitoring/LogPath diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md new file mode 100644 index 00000000000..44c65de59e9 --- /dev/null +++ b/servicecontrol/security/configuration/authentication.md @@ -0,0 +1,157 @@ +--- +title: ServiceControl Authentication Configuration +summary: How to enable and configure authentication for ServiceControl +reviewed: 2026-01-12 +component: ServiceControl +related: +- servicecontrol/security/hosting-guide +- servicepulse/security/configuration/authentication +--- + +ServiceControl instances can be configured to require [JWT](https://en.wikipedia.org/wiki/JSON_Web_Token) authentication using [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/). This enables integration with identity providers like Microsoft Entra ID (Azure AD), Okta, Auth0, and other OIDC-compliant providers. This guide explains how to configure ServiceControl to enable authentication for both ServiceControl and ServicePulse. + +> [!NOTE] +> Authentication is disabled by default. To enable it, see below. + +## Configuration + +ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjunction with [Forward Header](forward-headers.md) and [TLS](tls.md) configuration settings in a scenario based format. + +- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#authentication) +- [Audit Instance](/servicecontrol/audit-instances/configuration.md#authentication) +- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#authentication) + +## Identity Provider Setup + +When registering ServiceControl with your identity provider, you will need the following information: + +| Setting | Description | +|-------------------------------|------------------------------------------------------------------------------------------------------------------| +| Application type | Web application / API (confidential client) | +| Redirect URI | Not required for API-only registration | +| Audience | A unique identifier for the ServiceControl API (e.g., `api://servicecontrol` or a custom URI) | +| Scopes | Define at least one scope that ServicePulse can request (e.g., `api.access`) | +| Allowed token audiences | Must include the audience configured in ServiceControl | + +Additionally, a separate application registration is required for ServicePulse. See [ServicePulse Identity Provider Setup](/servicepulse/security/configuration/authentication.md#identity-provider-setup) for those requirements. + +### Identity Provider Guides + +For step-by-step instructions on configuring specific identity providers, see: + +- [Microsoft Entra ID](../entra-id-authentication.md) + +### Configuration examples + +The following examples show complete authentication configurations for common identity providers using the primary ServiceControl instance. + +#### Microsoft Entra ID + +```xml + + + + + + + + + +``` + +#### Auth0 + +```xml + + + + + + + + + +``` + +#### Keycloak + +```xml + + + + + + + + + +``` + +## Troubleshooting + +### 401 Unauthorized responses + +This error occurs when: + +1. The token is missing or malformed +2. The token has expired +3. The token audience doesn't match the configured `Authentication.Audience` +4. The token issuer doesn't match the configured `Authentication.Authority` + +**Solution:** Verify that the `Authority` and `Audience` settings match exactly what is configured in your identity provider. Check the ServiceControl logs for detailed validation error messages. + +### Token validation fails with "IDX10205: Issuer validation failed" + +This typically means: + +1. The `Authority` URL is incorrect or doesn't match the token's `iss` claim +2. For Microsoft Entra ID, ensure the authority URL includes or excludes `/v2.0` consistently with your token version + +**Solution:** Compare the `iss` claim in your JWT token (decode it at [jwt.ms](https://jwt.ms)) with your configured authority URL. + +### Token validation fails with "IDX10214: Audience validation failed" + +This occurs when: + +1. The `Audience` setting doesn't match the token's `aud` claim +2. The identity provider is issuing tokens for a different audience + +**Solution:** Verify the `aud` claim in your token matches the `Authentication.Audience` configuration exactly. + +### Unable to retrieve OpenID Connect metadata + +This error appears when ServiceControl cannot reach the identity provider's discovery endpoint: + +1. Network connectivity issues to the identity provider +2. Firewall blocking outbound HTTPS connections +3. Invalid `Authority` URL +4. TLS/SSL certificate issues + +**Solution:** Verify network connectivity to `{authority}/.well-known/openid-configuration`. For local development, you may need to set `RequireHttpsMetadata` to `false`. + +### ServicePulse cannot authenticate + +If ServicePulse shows authentication errors: + +1. Verify the ServicePulse-specific settings are configured on the **primary** ServiceControl instance +2. Ensure the `ServicePulse.ClientId` matches the SPA application registration +3. Check that `ServicePulse.ApiScopes` includes the correct scope(s) for your API + +**Solution:** See the [ServicePulse authentication troubleshooting](/servicepulse/security/configuration/authentication.md#troubleshooting) for client-side issues. + +### Clock skew causing token validation failures + +JWT tokens are time-sensitive. If server clocks are not synchronized: + +1. Tokens may be rejected as "not yet valid" or "expired" +2. This commonly occurs in virtual machines or containers + +**Solution:** Ensure all servers are using NTP to synchronize their clocks. + +## Matching Authentication Configuration Required + +When using scatter-gather with authentication enabled: + +- All instances (Primary, Audit, Monitoring) must use the **same** Authority and Audience +- Client tokens must be valid for all instances +- There is no service-to-service authentication mechanism; client tokens are forwarded directly diff --git a/servicecontrol/security/configuration/cert-management.include.md b/servicecontrol/security/configuration/cert-management.include.md new file mode 100644 index 00000000000..dc7fda75287 --- /dev/null +++ b/servicecontrol/security/configuration/cert-management.include.md @@ -0,0 +1,4 @@ +### Certificate Management + +- ServiceControl supports PFX (PKCS#12) certificate files +- Store certificate files securely with appropriate file permissions \ No newline at end of file diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md new file mode 100644 index 00000000000..43725e15219 --- /dev/null +++ b/servicecontrol/security/configuration/cors.md @@ -0,0 +1,98 @@ +--- +title: ServiceControl CORS Configuration +summary: How to configure Cross-Origin Resource Sharing for ServiceControl instances +reviewed: 2026-01-14 +component: ServiceControl +related: +- servicecontrol/security/hosting-guide +--- + +Cross-Origin Resource Sharing (CORS) controls which web applications can make requests to ServiceControl. This is important when ServicePulse is hosted on a different domain than ServiceControl. + +## Configuration + +ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjunction with [Authentication](authentication.md), [TLS](tls.md), and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. + +- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#cors) +- [Audit Instance](/servicecontrol/audit-instances/configuration.md#cors) +- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#cors) + +## When to configure CORS + +CORS configuration is required when: + +- ServicePulse is hosted on a different domain than ServiceControl +- ServiceControl is accessed through a reverse proxy with a different domain + +## Configuration examples + +To restrict access to only your ServicePulse domain, using the primary ServiceControl instance: + +```xml + + + + +``` + +To allow multiple origins: + +```xml + + + + +``` + +## Troubleshooting + +### ServicePulse cannot connect to ServiceControl + +**Symptom**: ServicePulse displays connection errors or fails to load data, and browser developer tools show CORS errors like "Access-Control-Allow-Origin" or "blocked by CORS policy". + +**Cause**: The ServicePulse origin is not in the allowed origins list, or the origin URL doesn't match exactly (including protocol and port). + +**Solutions**: + +- Check browser developer tools (F12 > Console) for the exact CORS error message +- Verify the origin in `AllowedOrigins` matches exactly, including: + - Protocol (`https://` vs `http://`) + - Domain name (no trailing slash) + - Port number if non-standard (e.g., `https://servicepulse.example.com:8080`) +- For testing, temporarily set `AllowAnyOrigin` to `true` to confirm CORS is the issue + +### CORS preflight requests failing + +**Symptom**: Simple GET requests work, but POST/PUT/DELETE requests fail with CORS errors. Browser shows OPTIONS request failures. + +**Cause**: The browser sends a preflight OPTIONS request for complex requests, which may be blocked by a firewall or reverse proxy. + +**Solutions**: + +- Ensure the reverse proxy forwards OPTIONS requests to ServiceControl +- Check that no firewall or WAF is blocking OPTIONS requests +- Verify ServiceControl is responding to OPTIONS requests (check response headers) + +### Origin mismatch with reverse proxy + +**Symptom**: CORS errors occur even though the origin appears to be configured correctly. + +**Cause**: When using a reverse proxy, the origin seen by ServiceControl may differ from what's configured. The browser sends the origin based on where ServicePulse is loaded from. + +**Solutions**: + +- Check which URL the browser is using to access ServicePulse (this is the origin) +- Ensure the configured origin matches the ServicePulse URL exactly +- If using different domains for internal and external access, add both origins to `AllowedOrigins` + +### Credentials not being sent + +**Symptom**: Authenticated requests fail even when CORS is configured. The `Authorization` header is not sent. + +**Cause**: When using authentication with CORS, credentials are only sent if the response includes appropriate CORS headers and the origin is explicitly allowed (not wildcard). + +**Solutions**: + +- Ensure `AllowAnyOrigin` is set to `false` when using authentication +- Add the specific origin to `AllowedOrigins` (wildcards don't support credentials) +- Verify the `Access-Control-Allow-Credentials` header is present in responses diff --git a/servicecontrol/security/configuration/forward-header-troubleshooting.include.md b/servicecontrol/security/configuration/forward-header-troubleshooting.include.md new file mode 100644 index 00000000000..64e838e76e9 --- /dev/null +++ b/servicecontrol/security/configuration/forward-header-troubleshooting.include.md @@ -0,0 +1,56 @@ +### HTTPS redirect loops + +**Symptom**: Browser shows "too many redirects" or redirect loop errors when accessing the application through a reverse proxy with SSL termination. + +**Cause**: The `X-Forwarded-Proto` header is not being processed, so the application thinks the request is HTTP and keeps redirecting to HTTPS. + +**Solutions**: + +- Verify forwarded headers are enabled +- Check that the proxy IP is in `KnownProxies` or `KnownNetworks`, or enable `TrustAllProxies` +- Confirm the reverse proxy is sending the `X-Forwarded-Proto` header + +### Wrong host in generated URLs + +**Symptom**: Links or redirects use the internal hostname (e.g., `localhost` or container name) instead of the public hostname. + +**Cause**: The `X-Forwarded-Host` header is not being trusted or processed. + +**Solutions**: + +- Verify the proxy IP is trusted (check `KnownProxies`/`KnownNetworks` configuration) +- Confirm the reverse proxy is sending the `X-Forwarded-Host` header +- In Kubernetes, ensure the correct pod/node network is in `KnownNetworks` + +### Client IP shows proxy IP instead of real client + +**Symptom**: Logs or audit trails show the proxy's IP address instead of the actual client IP. + +**Cause**: The `X-Forwarded-For` header is not being processed, or the wrong IP is being extracted from a proxy chain. + +**Solutions**: + +- Verify forwarded headers are enabled and the proxy is trusted +- For proxy chains, check the `ForwardLimit` behavior — with `TrustAllProxies=false`, only the last proxy IP is used +- If using multiple proxies, ensure all proxy IPs are listed in `KnownProxies` + +### Headers not processed in Kubernetes + +**Symptom**: Forward headers work locally but not in Kubernetes, even with headers enabled. + +**Cause**: In Kubernetes, the ingress controller or load balancer IP may differ from what's configured in `KnownProxies`. + +**Solutions**: + +- Use `KnownNetworks` with the pod/service CIDR range instead of specific IPs (e.g., `10.0.0.0/8`) +- Check what IP the request is actually coming from (ingress controller pod IP, node IP, or load balancer IP) +- For development/testing, temporarily enable `TrustAllProxies=true` to confirm headers are the issue + +### Verifying header processing + +To confirm whether forwarded headers are being processed correctly: + +1. Enable verbose logging to see incoming request details +2. Check that `Request.Scheme` shows `https` (not `http`) when accessing via HTTPS-terminating proxy +3. Verify the `Host` header in logs matches the expected public hostname +4. Compare client IP in logs against the expected client IP diff --git a/servicecontrol/security/configuration/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md new file mode 100644 index 00000000000..4660dc8ec2b --- /dev/null +++ b/servicecontrol/security/configuration/forward-headers.md @@ -0,0 +1,130 @@ +--- +title: ServiceControl Forward Headers for Reverse Proxy Configuration +summary: How to enable and configure forward headers for ServiceControl instances +reviewed: 2026-01-14 +component: ServiceControl +related: +- servicecontrol/security/hosting-guide +- servicepulse/security/configuration/forward-headers +--- + +When ServiceControl instances are deployed behind a reverse proxy that terminates SSL/TLS (like NGINX, Traefik, or a cloud load balancer), you need to configure forwarded headers so ServiceControl correctly understands the original client request. + +## Configuration + +ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjunction with [Authentication](authentication.md) and [TLS](tls.md) configuration settings in a scenario based format. + +- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#forwarded-headers) +- [Audit Instance](/servicecontrol/audit-instances/configuration.md#forwarded-headers) +- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#forwarded-headers) + +## What Headers are Processed + +When enabled, ServiceControl instances processes: + +- `X-Forwarded-For` - Original client IP address +- `X-Forwarded-Proto` - Original protocol (http/https) +- `X-Forwarded-Host` - Original host header + +When the proxy is trusted: + +- `Request.Scheme` will be set from `X-Forwarded-Proto` (e.g., `https`) +- `Request.Host` will be set from `X-Forwarded-Host` (e.g., `servicecontrol.example.com`) +- Client IP will be available from `X-Forwarded-For` + +When the proxy is **not** trusted (incorrect `KnownProxies`): + +- `X-Forwarded-*` headers are **ignored** (not applied to the request) +- `Request.Scheme` remains `http` +- `Request.Host` remains the internal hostname +- The request is still processed (not blocked) + +## HTTP to HTTPS Redirect + +When using a reverse proxy that terminates SSL, you can configure ServiceControl instances to redirect HTTP requests to HTTPS. This works in combination with forwarded headers: + +1. The reverse proxy forwards both HTTP and HTTPS requests to ServiceControl +2. The proxy sets `X-Forwarded-Proto` to indicate the original protocol +3. ServiceControl reads this header (via forwarded headers processing) +4. If the original request was HTTP and redirect is enabled, ServiceControl returns a redirect to HTTPS + +```mermaid +sequenceDiagram + participant Client + participant Proxy as Reverse Proxy + participant SC as ServiceControl + + Client->>Proxy: HTTP Request + Note over Proxy: Terminates request
Sets X-Forwarded-Proto: http + Proxy->>SC: Request + X-Forwarded-Proto: http + Note over SC: Reads X-Forwarded-Proto
Detects original was HTTP + SC-->>Proxy: 301 Redirect to HTTPS + Proxy-->>Client: 301 Redirect to HTTPS + Client->>Proxy: HTTPS Request + Note over Proxy: Terminates SSL
Sets X-Forwarded-Proto: https + Proxy->>SC: Request + X-Forwarded-Proto: https + SC->>Client: Response (via Proxy) +``` + +To enable HTTP to HTTPS redirect, see [TLS Configuration](tls.md) for details on how to do this. + +## Proxy Chain Behavior (ForwardLimit) + +When processing `X-Forwarded-For` headers with multiple IPs (proxy chains), the behavior depends on trust configuration: + +| Configuration | ForwardLimit | Behavior | +|---------------------------|-------------------|-----------------------------------------------| +| `TrustAllProxies = true` | `null` (no limit) | Processes all IPs, returns original client IP | +| `TrustAllProxies = false` | `1` (default) | Processes only the last proxy IP | + +For example, with `X-Forwarded-For: 203.0.113.50, 10.0.0.1, 192.168.1.1`: + +- **TrustAllProxies = true**: Returns `203.0.113.50` (original client) +- **TrustAllProxies = false**: Returns `192.168.1.1` (last proxy) + +## Configuration examples + +The following examples show common forwarded headers configurations for different deployment scenarios using the primary ServiceControl instance. + +### Single reverse proxy (known IP) + +When running behind a single reverse proxy with a known IP address: + +```xml + + + +``` + +### Multiple reverse proxies + +When running behind multiple proxies (e.g., load balancer and application gateway): + +```xml + + + +``` + +### Container/Kubernetes environment + +When running in a container environment where proxy IPs are dynamic, trust a network range: + +```xml + + + +``` + +### Development/trusted environment + +For development or fully trusted environments (not recommended for production): + +```xml + + +``` + +## Troubleshooting + +include: forward-header-troubleshooting diff --git a/servicecontrol/security/configuration/hsts-considerations.include.md b/servicecontrol/security/configuration/hsts-considerations.include.md new file mode 100644 index 00000000000..692f8a9a0c2 --- /dev/null +++ b/servicecontrol/security/configuration/hsts-considerations.include.md @@ -0,0 +1,3 @@ +### HSTS + +The [HTTP Strict-Transport-Security](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Strict-Transport-Security) response header (often abbreviated as HSTS) informs browsers that the host should only be accessed using HTTPS, and that any future attempts to access it using HTTP should automatically be upgraded to HTTPS. Additionally, on future connections to the host, the browser will not allow the user to bypass secure connection errors, such as an invalid certificate. HSTS identifies a host by its domain name only. Its important to read what each of these settings do before enabling them. \ No newline at end of file diff --git a/servicecontrol/security/configuration/index.md b/servicecontrol/security/configuration/index.md new file mode 100644 index 00000000000..4ba0fac2b2b --- /dev/null +++ b/servicecontrol/security/configuration/index.md @@ -0,0 +1,29 @@ +--- +title: ServiceControl Security Configuration +summary: How to secure ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +related: +- servicecontrol/security/hosting-guide +- servicepulse/security/hosting-guide +--- + +ServiceControl provides several configuration options to secure instances. This section covers the available security settings and how to configure them. + +## Configuration topics + +### [Authentication](authentication.md) + +Configure JWT authentication using OpenID Connect (OIDC) to secure ServiceControl and ServicePulse. Supports identity providers like Microsoft Entra ID, Okta, Auth0, Keycloak, and other OIDC-compliant providers. + +### [TLS](tls.md) + +Enable encrypted connections by configuring ServiceControl to use HTTPS directly. Includes options for certificate management, HTTP to HTTPS redirects, and HTTP Strict Transport Security (HSTS). + +### [Forward Headers](forward-headers.md) + +Configure forwarded header processing for deployments behind a reverse proxy. Ensures ServiceControl correctly interprets client requests when SSL/TLS is terminated at a load balancer or proxy. + +### [CORS](cors.md) + +Configure Cross-Origin Resource Sharing to control which web applications can access the ServiceControl API. diff --git a/servicecontrol/security/configuration/servicecontrol-instance-prefix.include.md b/servicecontrol/security/configuration/servicecontrol-instance-prefix.include.md new file mode 100644 index 00000000000..56d2ae20009 --- /dev/null +++ b/servicecontrol/security/configuration/servicecontrol-instance-prefix.include.md @@ -0,0 +1,8 @@ +> [!NOTE] +> Environment variables take precedence over App.config settings. + +| Instance | Environment Variable Prefix | App.Config Prefix | Default Port | +|---------------------------|-----------------------------|------------------------|--------------| +| ServiceControl (Primary) | `SERVICECONTROL` | `ServiceControl` | 33333 | +| ServiceControl.Audit | `SERVICECONTROL_AUDIT` | `ServiceControl.Audit` | 44444 | +| ServiceControl.Monitoring | `MONITORING` | `Monitoring` | 33633 | diff --git a/servicecontrol/security/configuration/tls-troubleshooting.include.md b/servicecontrol/security/configuration/tls-troubleshooting.include.md new file mode 100644 index 00000000000..18222003c25 --- /dev/null +++ b/servicecontrol/security/configuration/tls-troubleshooting.include.md @@ -0,0 +1,90 @@ +### Certificate not found or access denied + +**Symptom**: The application fails to start with certificate-related errors when using a PFX certificate file. + +**Cause**: The certificate file path is incorrect, the file is not readable, or the password is wrong. + +**Solutions**: + +- Verify the certificate path is correct and the file exists +- Check that the certificate file has appropriate permissions +- Confirm the certificate password is correct +- For containers, ensure the volume mount is correct (e.g., `-v certificate.pfx:/usr/share/ParticularSoftware/certificate.pfx`) + +### HTTPS redirect not working + +**Symptom**: HTTP requests are not redirected to HTTPS when using a reverse proxy. + +**Cause**: The redirect requires the `X-Forwarded-Proto` header to detect the original protocol, which may not be processed. + +**Solutions**: + +- Verify `RedirectHttpToHttps` is set to `true` +- Ensure the HTTPS port setting is configured correctly +- Configure [forward headers](forward-headers.md) so the `X-Forwarded-Proto` header is trusted +- Confirm the reverse proxy is sending the `X-Forwarded-Proto` header + +### HSTS header not appearing + +**Symptom**: The `Strict-Transport-Security` header is not present in responses. + +**Cause**: HSTS headers are only sent over HTTPS connections, or the setting is not enabled. + +**Solutions**: + +- Verify `EnableHsts` is set to `true` +- Confirm you are accessing via HTTPS (HSTS headers are not sent over HTTP) +- When using a reverse proxy, ensure the request is recognized as HTTPS via `X-Forwarded-Proto` + +### Browser shows certificate warning + +**Symptom**: Browser displays "Your connection is not private" or similar certificate warnings. + +**Cause**: The client (browser or another container) doesn't trust the CA that signed the server's certificate. + +**Solutions**: + +- Use a certificate from a trusted Certificate Authority for production +- Ensure the certificate's Common Name (CN) or Subject Alternative Name (SAN) matches the hostname +- Check that the certificate has not expired +- Ensure the certificate is in the correct Trusted Root Certificate Authorities store. e.g., + - If running in a Windows Service as `Local System`, the certificate should be in the `Local Computer` store. + - If running as yourself, the certificate should be in the `Current User` store. +- For internal/development use, add the self-signed certificate to the trusted root store +- For containers: Add the CA certificate to the CA bundle and set `SSL_CERT_FILE` + +### The remote certificate is invalid according to the validation procedure + +**Symptom**: Service starts but fails when calling other services (e.g., ServiceControl can't reach ServiceControl-Audit) or when validating tokens with Azure AD. + +**Cause**: The CA bundle doesn't contain the CA certificate that signed the remote server's certificate. + +**Solutions**: + +- Ensure the CA bundle includes your local CA certificate (e.g., mkcert's rootCA.pem) +- For Azure AD authentication, append the Mozilla CA bundle: curl https://curl.se/ca/cacert.pem >> ca-bundle.crt +- Verify `SSL_CERT_FILE` environment variable points to the correct path inside the container +- Check the CA bundle is mounted correctly + +### The certificate doesn't match the hostname + +**Symptom**: Browser or client rejects the certificate with a hostname mismatch error + +**Cause**: The certificate's Subject Alternative Names (SANs) don't include the hostname being used to connect. + +**Solutions**: + +- Regenerate the certificate with all required hostnames +- Include both the Docker service name (for container-to-container) and localhost (for host access) + +### Health checks fail with certificate errors + +**Symptom**: Container health check reports unhealthy, logs show SSL errors from the health check command. + +**Cause**: The health check binary inside the container doesn't trust the certificate. + +**Solutions**: + +- Ensure `SSL_CERT_FILE` is set so the health check process can find the CA bundle +- Check the health check URL uses the correct protocol: `https://` not `http://` +- Verify the certificate includes localhost in its SANs (health checks run inside the container) \ No newline at end of file diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md new file mode 100644 index 00000000000..ceac017321a --- /dev/null +++ b/servicecontrol/security/configuration/tls.md @@ -0,0 +1,135 @@ +--- +title: ServiceControl TLS Configuration +summary: How to enable and configure TLS for ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +related: +- servicecontrol/security/hosting-guide +- servicepulse/security/configuration/tls +--- + +ServiceControl instances can be configured to use HTTPS directly, enabling encrypted connections without relying on a reverse proxy for SSL termination. + +## Configuration + +ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings, along with [Authentication](authentication.md) and [Forward Headers](forward-headers.md), in a scenario-based format. + +- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#tls) +- [Audit Instance](/servicecontrol/audit-instances/configuration.md#tls) +- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#tls) + +## Security Considerations + +include: cert-management + +include: hsts-considerations + +### HTTP to HTTPS Redirect + +The `HTTPS_REDIRECTHTTPTOHTTPS` setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. When enabled: + +- The redirect uses HTTP 307 (Temporary Redirect) to preserve the request method +- The reverse proxy must forward both HTTP and HTTPS requests to ServiceControl +- ServiceControl will redirect HTTP requests to HTTPS based on the `X-Forwarded-Proto` header +- **Important:** You must also set `HTTPS_PORT` to specify the HTTPS port for the redirect URL + +> [!NOTE] +> When running ServiceControl directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). + +## Configuration examples + +The following examples show common TLS configurations for different deployment scenarios using the primary ServiceControl instance. + +### Direct HTTPS with certificate + +When ServiceControl handles TLS directly using a PFX certificate: + +```xml + + + +``` + +**Container**: + +> [!NOTE] +> The following is a docker compose snippets. For full examples, see the [Platform Container Examples repository](https://github.com/Particular/PlatformContainerExamples). + +```bash +servicecontrol: + image: particular/servicecontrol:latest + env_file: .env + ports: + - "33333:33333" + environment: + RAVENDB_CONNECTIONSTRING: http://servicecontrol-db:8080 + REMOTEINSTANCES: '[{"api_uri":"https://servicecontrol-audit:44444/api"}]' + SERVICECONTROL_HTTPS_ENABLED: "true" + SERVICECONTROL_HTTPS_CERTIFICATEPATH: "/usr/share/ParticularSoftware/certificate.pfx" + SERVICECONTROL_HTTPS_CERTIFICATEPASSWORD: "..." + SSL_CERT_FILE: "/etc/ssl/certs/ca-bundle.crt" + SERVICECONTROL_AUTHENTICATION_ENABLED: "true" + SERVICECONTROL_AUTHENTICATION_AUTHORITY: "https://login.microsoftonline.com/{tenantId}" + SERVICECONTROL_AUTHENTICATION_AUDIENCE: "api://{api-id}" + SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID: "{servicepulse-clientid}" + SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY: "https://login.microsoftonline.com/{tenantId}/v2.0" + SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES: '["api://{api-id}/access_as_user"]' + command: --setup-and-run + restart: unless-stopped + volumes: + - C:\path\to\servicecontrol\cert.pfx:/usr/share/ParticularSoftware/certificate.pfx + - C:\path\to\servicecontrol\ca-bundle.crt:/etc/ssl/certs/ca-bundle.crt:ro + healthcheck: + test: ["CMD", "/healthcheck/healthcheck", "https://localhost:33333/api"] + interval: 30s + timeout: 10s + start_period: 60s + retries: 3 + depends_on: + servicecontrol-db: + condition: service_healthy + rabbitmq: + condition: service_healthy +``` + +**SSL_CERT_FILE (CRT)**: This tells SSL/TLS libraries (including .NET's HttpClient, OpenSSL, and libcurl) the path to a CA (Certificate Authority) certificate bundle file. This bundle contains the public certificates of trusted CAs used to verify the authenticity of SSL/TLS certificates presented by remote servers. This certificate is used to verify HTTPS (trust others). + +**SERVICEPULSE_HTTPS_CERTIFICATEPATH (PFX)**: This is a binary archive format that bundles together the private key, public certificate, and certificate chain. This certificate is used to serve HTTPS (prove identity). + +> [!NOTE] +> When containers communicate with each other over HTTPS, they use the Docker service names (like `servicecontrol`, `servicecontrol-audit`) as hostnames, and TLS validation will fail if the certificate doesn't include these names in its Subject Alternative Names (SANs). + +### Direct HTTPS with HSTS + +When ServiceControl handles TLS directly and you want to enable HSTS: + +```xml + + + + + +``` + +### Reverse proxy with HTTP to HTTPS redirect + +When TLS is terminated at a reverse proxy and you want ServiceControl to redirect HTTP requests: + +```xml + + +``` + +### Reverse proxy with HSTS + +When TLS is terminated at a reverse proxy and you want ServiceControl to add HSTS headers: + +```xml + + + +``` + +## Troubleshooting + +include: tls-troubleshooting diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md new file mode 100644 index 00000000000..6ebb4be31aa --- /dev/null +++ b/servicecontrol/security/entra-id-authentication.md @@ -0,0 +1,110 @@ +--- +title: Microsoft Entra ID Authentication Guide +summary: Set up authentication with Microsoft Entra ID for ServiceControl and ServicePulse +reviewed: 2026-01-13 +component: ServiceControl +related: +- servicecontrol/security/configuration/authentication +- servicepulse/security/configuration/authentication +--- + +This guide explains how to configure Microsoft Entra ID (formerly Azure Active Directory) as the identity provider for ServiceControl and ServicePulse. + +## Prerequisites + +- Administrator permissions on the Microsoft Entra ID tenant +- ServiceControl 6.9.0 or later +- ServicePulse 2.5.0 or later + +## Overview + +Two app registrations are required in Microsoft Entra ID: + +1. **ServiceControl API** - Represents the ServiceControl API that ServicePulse will call +2. **ServicePulse** - Represents the ServicePulse single-page application that users sign into + +## Step 1: Register the ServiceControl API + +Follow Microsoft's guide to [register an application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) with the following settings: + +| Setting | Value | +|-------------------------|----------------------------------------------------------------| +| Name | `ServiceControl API` | +| Supported account types | Accounts in this organizational directory only (single tenant) | + +After registration, collect these values from the app registration: + +| Value | Location | Used for | +|-----------------------|---------------|-----------------------------------| +| Directory (tenant) ID | Overview page | Authority URLs | +| Application ID URI | Expose an API | `Authentication.Audience` setting | + +### Expose the API + +Follow Microsoft's guide to [expose a web API](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-configure-app-expose-web-apis) and add a scope with these settings: + +| Setting | Value | +|----------------------------|----------------------------------------------| +| Application ID URI | Accept the default (`api://{app-id}`) | +| Scope name | `api.access` | +| Who can consent | Admins and users | +| Admin consent display name | `Full access to ServiceControl API` | +| Admin consent description | `Allows ServicePulse to call ServiceControl` | + +## Step 2: Register ServicePulse + +Follow Microsoft's guide to [register an application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) with the following settings: + +| Setting | Value | +|-------------------------|----------------------------------------------------------------------------------| +| Name | `ServicePulse` | +| Supported account types | Accounts in this organizational directory only (single tenant) | +| Redirect URI - Platform | Single-page application (SPA) | +| Redirect URI - URI | The URL where ServicePulse is hosted (e.g., `https://servicepulse.example.com/`) | + +After registration, collect this value: + +| Value | Location | Used for | +|-------------------------|---------------|-----------------------------------------------| +| Application (client) ID | Overview page | `Authentication.ServicePulse.ClientId` setting | + +> [!WARNING] +> Redirect URIs must use HTTPS in production. HTTP is only acceptable for local development. If ServicePulse is accessed from multiple URLs, add each as a redirect URI under **Manage** > **Authentication**. + +### Grant API permissions + +Follow Microsoft's guide to [configure a client application to access a web API](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-configure-app-access-web-apis): + +1. In the ServicePulse app registration, go to **API permissions** +2. Add a permission for **ServiceControl API** (under My APIs) +3. Select the **api.access** delegated permission + +## Step 3: Configure ServiceControl + +Use the collected values to configure ServiceControl. For Entra ID, the authority URLs follow this pattern: + +- **ServiceControl authority**: `https://login.microsoftonline.com/{tenant-id}` +- **ServicePulse authority**: `https://login.microsoftonline.com/{tenant-id}/v2.0` + +The following table summarizes how Entra ID values map to ServiceControl settings: + +| Entra ID value | ServiceControl setting | +|--------------------------------------|------------------------------------------| +| Directory (tenant) ID | Used in `Authentication.Authority` URL | +| Application ID URI | `Authentication.Audience` | +| Application ID URI + `/api.access` | `Authentication.ServicePulse.ApiScopes` | +| ServicePulse Application (client) ID | `Authentication.ServicePulse.ClientId` | + +See [Authentication Configuration](configuration/authentication.md) for all settings and configuration examples, including App.config and environment variable formats. + +> [!NOTE] +> All ServiceControl instances (Primary, Audit, and Monitoring) must be configured with the same authority and audience values. ServicePulse settings are only required on the Primary instance. + +## Verify the configuration + +After configuring ServiceControl, restart all instances. When accessing ServicePulse: + +1. The browser should redirect to the Microsoft sign-in page +2. After signing in, ServicePulse should load and display data from ServiceControl + +If authentication fails, check the ServiceControl logs for token validation errors. diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md new file mode 100644 index 00000000000..e2b33a3825c --- /dev/null +++ b/servicecontrol/security/hosting-guide.md @@ -0,0 +1,268 @@ +--- +title: ServiceControl Hosting and Security Guide +summary: Example hosting options for ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +related: +- servicecontrol/security/configuration/authentication +- servicecontrol/security/configuration/cors +- servicecontrol/security/configuration/forward-headers +- servicecontrol/security/configuration/tls +- servicepulse/security/hosting-guide +--- + +This guide covers hosting and security options available for ServiceControl, ServiceControl.Audit, and ServiceControl.Monitoring instances. + +> [!NOTE] +> All scenarios assume HTTPS and authentication are required. + +## Hosting Model + +ServiceControl runs as a standalone Windows service with Kestrel as the built-in web server. It does not support being hosted inside IIS (in-process hosting). + +If you place IIS, nginx, or another web server in front of ServiceControl, it acts as a **reverse proxy** forwarding requests to Kestrel. + +## Deployment Scenarios + +> [!WARNING] +> When authentication is enabled, all instances (Primary, Audit, Monitoring) must use the **same** Identity Provider (IdP) Authority and Audience settings. Client tokens are forwarded to remote instances during scatter-gather operations. + +The below scenarios assume the use of `App.config` and only show the configuration for the primary ServiceControl instance. For additional details on environment variables and the other ServiceControl instances, see [Authentication](configuration/authentication.md), [TLS](configuration/tls.md), and [Forward Headers](configuration/forward-headers.md). + +### Scenario 0: Default / Backward Compatible Configuration + +The default configuration with no additional setup required. Backwards compatible with existing deployments. + +#### Security Features + +| Feature | Status | +|-------------------------|-------------------------| +| JWT Authentication | ❌ Disabled | +| Kestrel HTTPS | ❌ Disabled | +| HTTPS Redirection | ❌ Disabled | +| HSTS | ❌ Disabled | +| Restricted CORS Origins | ❌ Disabled (any origin) | +| Forwarded Headers | ✅ Enabled (trusts all) | +| Restricted Proxy Trust | ❌ Disabled | + +#### Example Configuration + +```xml + + + + + +``` + +Or explicitly: + +```xml + + + + + + + +``` + +### Scenario 1: Strict Reverse Proxy + +Strict Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). + +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant RP as Reverse Proxy
(SSL termination) + participant SC as ServiceControl
(JWT validation) + + Client->>RP: HTTPS + RP->>SC: HTTP +``` + +#### Security Features + +| Feature | Status | +|-------------------------|-------------------------------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ❌ Disabled (handled by proxy) | +| HTTPS Redirection | ✅ Enabled (optional) | +| HSTS | ❌ Disabled (handled by proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | + +> [!NOTE] +> HTTPS redirection is optional in this scenario. The reverse proxy typically handles HTTP to HTTPS redirection at its layer. However, enabling it at ServiceControl provides defense-in-depth - if an HTTP request somehow bypasses the proxy and reaches ServiceControl directly, it will be redirected to the HTTPS URL. This requires configuring `Https.Port` to specify the external [HTTPS port](configuration/tls.md) used by the proxy. + +#### Example Configuration + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Scenario 2: Direct HTTPS with Authentication + +Kestrel handles TLS directly with JWT authentication without a reverse proxy. + +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant SC as ServiceControl (Kestrel)
(TLS + JWT validation) + + Client->>SC: HTTPS +``` + +#### Security Features + +| Feature | Status | +|-------------------------|-----------------------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HSTS | ✅ Enabled | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ❌ Disabled (no proxy) | +| Restricted Proxy Trust | N/A | + +> [!NOTE] +> HTTPS redirection is not configured in this scenario because clients connect directly over HTTPS. There is no HTTP endpoint exposed that would need to redirect. HTTPS redirection is only useful when a reverse proxy handles SSL termination and ServiceControl needs to redirect HTTP requests to the proxy's HTTPS endpoint. + +#### Example Configuration + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +### Scenario 3: End-to-End Encryption with Reverse Proxy and Direct HTTPS + +For environments requiring encryption of internal traffic. End-to-end TLS encryption where the reverse proxy terminates external TLS and re-encrypts traffic to ServiceControl over HTTPS. + +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant RP as Reverse Proxy
(TLS termination) + participant SC as ServiceControl (Kestrel)
(TLS + JWT validation) + + Client->>RP: HTTPS + RP->>SC: HTTPS +``` + +#### Security Features + +| Feature | Status | +|----------------------------|--------------------------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | N/A (no HTTP endpoint) | +| HSTS | N/A (configure at proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | +| Internal Traffic Encrypted | ✅ Yes | + +> [!NOTE] +> HTTPS redirection and HSTS are not applicable in this scenario because ServiceControl only exposes an HTTPS endpoint (Kestrel HTTPS is enabled). There is no HTTP endpoint to redirect from. The reverse proxy is responsible for redirecting external HTTP requests to HTTPS and sending HSTS headers to browsers. Compare this to Scenario 1, where Kestrel HTTPS is disabled and ServiceControl exposes an HTTP endpoint - in that case, HTTPS redirection can optionally be enabled as defense-in-depth. + +#### Example Configuration + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md new file mode 100644 index 00000000000..a7cc63b1681 --- /dev/null +++ b/servicecontrol/security/index.md @@ -0,0 +1,121 @@ +--- +title: ServiceControl Security Overview +summary: Secure ServiceControl with authentication, TLS, and other security features +reviewed: 2026-01-14 +component: ServiceControl +related: +- servicepulse/security +--- + +This section covers security features for ServiceControl, including authentication, transport layer security (TLS), and reverse proxy configuration. + +## In this section + +- Security Configuration - Configuration reference for authentication, TLS, and forward headers +- [Hosting Guide](hosting-guide.md) - Deployment scenarios with complete configuration examples +- [Microsoft Entra ID](entra-id-authentication.md) - Step-by-step guide for configuring authentication with Microsoft Entra ID + +## [Authentication](configuration/authentication.md) + +ServiceControl and [ServicePulse](/servicepulse/) support standards-based authentication using [OAuth 2.0](https://oauth.net/2/) with [JSON Web Tokens (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token), and [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/). When enabled, users must sign in through the configured identity provider before accessing ServicePulse. + +> [!WARNING] +> Authentication is disabled by default to maintain backward compatibility with existing deployments. Until authentication is enabled, ServicePulse and ServiceControl are accessible without credentials. + +Any OIDC-compliant identity provider can be used, including Microsoft Entra ID, Okta, Auth0, Keycloak, AWS IAM Identity Center, and others. + +When authentication is enabled: + +1. ServicePulse retrieves authentication configuration from an anonymous endpoint +2. Users sign in through the configured identity provider +3. API requests include a JWT bearer token in the `Authorization` header +4. ServiceControl validates the token against the configured authority +5. For scatter-gather requests, the Primary instance forwards the client token to Audit and Monitoring instances + +```mermaid +sequenceDiagram + participant User + participant ServicePulse + participant Primary as ServiceControl Primary + participant Audit as Audit Instance + participant IdP as Identity Provider + + User->>ServicePulse: Open ServicePulse + Note over ServicePulse,Primary: Anonymous endpoint (no auth required) + ServicePulse->>Primary: GET /api/authentication/configuration + Primary-->>ServicePulse: Auth settings (authority, clientId, scopes) + ServicePulse->>IdP: Redirect to sign-in + User->>IdP: Enter credentials + IdP-->>ServicePulse: Access token (JWT) + Note over ServicePulse,Primary: Authenticated request + ServicePulse->>Primary: API request + Authorization: Bearer {token} + Primary->>IdP: Validate token (via OIDC metadata) + IdP-->>Primary: Token valid + Note over Primary,Audit: Scatter-gather (token forwarded) + Primary->>Audit: Forward request + Bearer {token} + Audit-->>Primary: Response data + Primary-->>ServicePulse: Aggregated API response + ServicePulse-->>User: Display data +``` + +Certain endpoints remain accessible without authentication to support API discovery, client bootstrapping, and service-to-service communication between ServiceControl instances. + +### Anonymous endpoints + +The following endpoints remain anonymous to support API Discovery, health checks, service-to-service requests, and authentication bootstrapping: + +| Endpoint | Method | Instance | Purpose | +|-------------------------------------|---------|----------------|--------------------------------------------------------------------| +| `/api` | GET | Primary, Audit | API root/discovery - returns available endpoints | +| `/api/instance-info` | GET | Primary, Audit | Returns instance configuration information | +| `/api/configuration` | GET | Primary, Audit | Returns instance configuration information (alias) | +| `/api/configuration/remotes` | GET | Primary | Returns remote instance configurations | +| `/api/authentication/configuration` | GET | Primary | Returns authentication configuration for clients like ServicePulse | +| `/` | GET | Monitoring | API root/discovery - returns instance information | +| `/` | OPTIONS | Monitoring | CORS support - returns supported operations | +| `/endpoints` | OPTIONS | Monitoring | CORS support - returns supported operations | +| `/endpoints/{endpoint}/audit-count` | GET | Audit | Service-to-service request | + +### Token Forwarding Security Considerations + +- Client tokens are forwarded to remote instances in their entirety +- Remote instances see the same token as the primary instance +- Token scope/claims are not modified during forwarding + +## [TLS](configuration/tls.md) + +When authentication is enabled, access tokens are exchanged between ServicePulse and ServiceControl. To protect these tokens, TLS must be enabled. + +> [!IMPORTANT] +> Without TLS, tokens are transmitted in clear text, exposing the system to interception and unauthorized access. Always use HTTPS in production environments. + +ServiceControl supports two approaches for HTTPS: + +- **Direct HTTPS**: Configure Kestrel to handle TLS with a certificate +- **Reverse proxy**: Terminate TLS at a reverse proxy (NGINX, IIS, Azure App Gateway, etc.) and forward requests to ServiceControl over HTTP + +## [Reverse proxy support](configuration/forward-headers.md) + +When ServiceControl runs behind a reverse proxy, forwarded headers ensure ServiceControl correctly interprets client requests. This is important for: + +- Determining the original client IP address +- Understanding whether the original request used HTTPS +- Generating correct redirect URLs + +## [Deployment scenarios](hosting-guide.md) + +The Hosting Guide provides complete configuration examples for common deployment patterns: + +- **Default configuration**: No authentication, HTTP only (backward compatible) +- **Reverse proxy with authentication**: TLS termination at proxy, JWT authentication +- **Direct HTTPS with authentication**: Kestrel handles TLS directly +- **End-to-end encryption**: TLS at both proxy and Kestrel for internal traffic encryption + +## ServiceInsight compatibility + +[ServiceInsight has been sunset](/serviceinsight/) and does not support OAuth 2.0 or OpenID Connect authentication. If authentication is enabled on a ServiceControl instance, ServiceInsight cannot connect. + +Users relying on ServiceInsight can: + +1. **[Use ServicePulse](/servicepulse/installation.md)** instead (Recommended. Functionality previously in ServiceInsight has been migrated to ServicePulse.) +2. **Leave authentication disabled** on the relevant ServiceControl instance diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 9a182f2586c..29e47df62ab 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -175,6 +175,444 @@ Run [ServiceControl error instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | bool | False | +## [Authentication](/servicecontrol/security/configuration/authentication.md) + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [authentication configuration examples](/servicecontrol/security/configuration/authentication.md#identity-provider-setup-configuration-examples) for additional information. + +### ServiceControl/Authentication.Enabled + +_Added in version 6.11.0_ + +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_ENABLED` | +| **App config key** | `ServiceControl/Authentication.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl/Authentication.Authority + +_Added in version 6.11.0_ + +The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_AUTHORITY` | +| **App config key** | `ServiceControl/Authentication.Authority` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Authentication.Audience + +_Added in version 6.11.0_ + +The expected audience value in the JWT token, typically the application ID or URI of the API. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_AUDIENCE` | +| **App config key** | `ServiceControl/Authentication.Audience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +> [!NOTE] +> ServicePulse with use this ServiceControl audience setting. + +### ServiceControl/Authentication.ValidateIssuer + +_Added in version 6.11.0_ + +Controls whether the token issuer is validated against the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_VALIDATEISSUER` | +| **App config key** | `ServiceControl/Authentication.ValidateIssuer` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl/Authentication.ValidateAudience + +_Added in version 6.11.0_ + +Controls whether the token audience is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_VALIDATEAUDIENCE` | +| **App config key** | `ServiceControl/Authentication.ValidateAudience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl/Authentication.ValidateLifetime + +_Added in version 6.11.0_ + +Controls whether the token expiration is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_VALIDATELIFETIME` | +| **App config key** | `ServiceControl/Authentication.ValidateLifetime` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl/Authentication.ValidateIssuerSigningKey + +_Added in version 6.11.0_ + +Controls whether the token signing key is validated. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_VALIDATEISSUERSIGNINGKEY` | +| **App config key** | `ServiceControl/Authentication.ValidateIssuerSigningKey` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl/Authentication.RequireHttpsMetadata + +_Added in version 6.11.0_ + +Controls whether HTTPS is required when retrieving metadata from the authority. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_REQUIREHTTPSMETADATA` | +| **App config key** | `ServiceControl/Authentication.RequireHttpsMetadata` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> Setting this to `false` is not recommended for production environments. Disabling this setting allows metadata to be retrieved over unencrypted HTTP connections, which could expose sensitive configuration information to attackers. + +### ServiceControl/Authentication.ServicePulse.ClientId + +_Added in version 6.11.0_ + +The client ID for ServicePulse to use when authenticating with the identity provider. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | +| **App config key** | `ServiceControl/Authentication.ServicePulse.ClientId` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Authentication.ServicePulse.Authority + +_Added in version 6.11.0_ + +The URL of the OpenID Connect authority for ServicePulse to use when authenticating users. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | +| **App config key** | `ServiceControl/Authentication.ServicePulse.Authority` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Authentication.ServicePulse.ApiScopes + +_Added in version 6.11.0_ + +The API scopes for ServicePulse to request when authenticating. This is a JSON array of scope strings e.g., `["api://{app-id}/api.access"]` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | +| **App config key** | `ServiceControl/Authentication.ServicePulse.ApiScopes` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string (JSON array) | None | + +## [TLS](/servicecontrol/security/configuration/tls.md) + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [TLS configuration examples](/servicecontrol/security/configuration/tls.md#configuration-examples) for additional information. + +### ServiceControl/Https.Enabled + +_Added in version 6.11.0_ + +Enables Kestrel HTTPS with a certificate. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_ENABLED` | +| **App config key** | `ServiceControl/Https.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl/Https.CertificatePath + +_Added in version 6.11.0_ + +The path to the PFX or PEM certificate file. If hosting as a container, the certificate file can also be volume-mounted to the container: + +```text +-v certificate.pfx:/usr/share/ParticularSoftware/certificate.pfx +``` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_CERTIFICATEPATH` | +| **App config key** | `ServiceControl/Https.CertificatePath` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Https.CertificatePassword + +_Added in version 6.11.0_ + +The password for the certificate file, if required. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_CERTIFICATEPASSWORD` | +| **App config key** | `ServiceControl/Https.CertificatePassword` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Https.RedirectHttpToHttps + +_Added in version 6.11.0_ + +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `ServiceControl/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> When running ServiceControl directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). This setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +### ServiceControl/Https.Port + +_Added in version 6.11.0_ + +The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_PORT` | +| **App config key** | `ServiceControl/Https.Port` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | None | + +### ServiceControl/Https.EnableHsts + +_Added in version 6.11.0_ + +Enables HTTP Strict Transport Security (HSTS). + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_ENABLEHSTS` | +| **App config key** | `ServiceControl/Https.EnableHsts` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +> [!NOTE] +> Review the implications of [enabling HSTS](/servicecontrol/security/configuration/tls.md#security-considerations-hsts) before doing so. + +### ServiceControl/Https.HstsMaxAgeSeconds + +_Added in version 6.11.0_ + +The max-age value in seconds for the HSTS header. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_HSTSMAXAGESECONDS` | +| **App config key** | `ServiceControl/Https.HstsMaxAgeSeconds` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| int | `31536000` (1 year) | + +### ServiceControl/Https.HstsIncludeSubDomains + +_Added in version 6.11.0_ + +Includes subdomains in the HSTS policy. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_HSTSINCLUDESUBDOMAINS` | +| **App config key** | `ServiceControl/Https.HstsIncludeSubDomains` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +## [Forwarded headers](/servicecontrol/security/configuration/forward-headers.md) + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [forward headers configuration examples](/servicecontrol/security/configuration/forward-headers.md#configuration-examples) for additional information. + +### ServiceControl/ForwardedHeaders.Enabled + +_Added in version 6.11.0_ + +Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_ENABLED` | +| **App config key** | `ServiceControl/ForwardedHeaders.Enabled` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +### ServiceControl/ForwardedHeaders.TrustAllProxies + +_Added in version 6.11.0_ + +Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_TRUSTALLPROXIES` | +| **App config key** | `ServiceControl/ForwardedHeaders.TrustAllProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments behind a reverse proxy, set this to `false` and configure `KnownProxies` or `KnownNetworks` to restrict which proxies are trusted. + +### ServiceControl/ForwardedHeaders.KnownProxies + +_Added in version 6.11.0_ + +A comma-separated list of trusted proxy IP addresses e.g., `10.0.0.5,10.0.0.6` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `ServiceControl/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/ForwardedHeaders.KnownNetworks + +_Added in version 6.11.0_ + +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/24,192.168.1.0/24` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `ServiceControl/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +## [CORS](/servicecontrol/security/configuration/cors.md) + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md), or [cors configuration examples](/servicecontrol/security/configuration/cors.md#configuration-examples) for additional information. + +### ServiceControl/Cors.AllowAnyOrigin + +_Added in version 6.11.0_ + +Allows requests from any origin. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_CORS_ALLOWANYORIGIN` | +| **App config key** | `ServiceControl/Cors.AllowAnyOrigin` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `true` | + +> [!WARNING] +> For production environments, set this to `false` and configure `AllowedOrigins` to restrict which origins can access the API. + +### ServiceControl/Cors.AllowedOrigins + +_Added in version 6.11.0_ + +A comma-separated list of allowed origins e.g., `https://servicepulse.yourcompany.com,https://admin.yourcompany.com` + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_CORS_ALLOWEDORIGINS` | +| **App config key** | `ServiceControl/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + ## Embedded database These settings are not valid for ServiceControl instances hosted in a container. diff --git a/servicepulse/containerization/index.md b/servicepulse/containerization/index.md index 37a251f42bf..b99066511e4 100644 --- a/servicepulse/containerization/index.md +++ b/servicepulse/containerization/index.md @@ -95,3 +95,164 @@ _Added in version 1.44.0_ | **Environment variable** | `ENABLE_REVERSE_PROXY` | | **Type** | bool | | **Default** | `true` | + +### [Forward headers](/servicepulse/security/configuration/forward-headers.md) + +These settings configure forward headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicepulse/security/hosting-guide.md), or [forward headers configuration examples](/servicepulse/security/configuration/forward-headers.md#configuration-examples) for additional information. + +#### Forward headers enabled + +_Added in version 2.5.0_ + +Enable forward headers processing. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_FORWARDEDHEADERS_ENABLED` | +| **Type** | bool | +| **Default** | `true` | + +#### Trust all proxies + +_Added in version 2.5.0_ + +Trust all proxies. Auto-disabled if known proxies/networks set. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES` | +| **Type** | bool | +| **Default** | `true` | + +> [!WARNING] +> The default configuration (`TrustAllProxies = true`) is suitable for development and trusted container environments only. For production deployments accessible from untrusted networks, its recommended to configure `KnownProxies` or `KnownNetworks` to restrict which sources can set forwarded headers. Failing to do so can allow attackers to spoof client IP addresses. + +#### Known proxies + +_Added in version 2.5.0_ + +Comma-separated IP addresses of trusted proxies (e.g., `10.0.0.1,172.16.0.1`). + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES` | +| **Type** | string | +| **Default** | (none) | + +#### Known networks + +_Added in version 2.5.0_ + +Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`). + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **Type** | string | +| **Default** | (none) | + +### [TLS](/servicepulse/security/configuration/tls.md) + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicepulse/security/hosting-guide.md), or [TLS configuration examples](/servicepulse/security/configuration/tls.md#configuration-examples) for additional information. + +#### HTTPS enabled + +_Added in version 2.5.0_ + +Enable HTTPS with Kestrel. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_ENABLED` | +| **Type** | bool | +| **Default** | `false` | + +#### Certificate path + +_Added in version 2.5.0_ + +Path to the certificate file (.pfx). + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_CERTIFICATEPATH` | +| **Type** | string | +| **Default** | (none) | + +#### Certificate password + +_Added in version 2.5.0_ + +Password for the certificate file. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD` | +| **Type** | string | +| **Default** | (none) | + +#### Redirect HTTP to HTTPS + +_Added in version 2.5.0_ + +Redirect HTTP requests to HTTPS. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS` | +| **Type** | bool | +| **Default** | `false` | + +> [!NOTE] +> When running ServicePulse directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). This setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. + +#### HTTPS port + +_Added in version 2.5.0_ + +HTTPS port for redirect (required for reverse proxy scenarios). + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_PORT` | +| **Type** | int | +| **Default** | (none) | + +#### Enable HSTS + +_Added in version 2.5.0_ + +Enable HTTP Strict Transport Security. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_ENABLEHSTS` | +| **Type** | bool | +| **Default** | `false` | + +> [!NOTE] +> Review the implications of [enabling HSTS](/servicepulse/security/configuration/tls.md#security-considerations-hsts) before doing so. + +#### HSTS max age + +_Added in version 2.5.0_ + +HSTS max-age in seconds. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS` | +| **Type** | int | +| **Default** | `31536000` (1 year) | + +#### HSTS include subdomains + +_Added in version 2.5.0_ + +Include subdomains in HSTS policy. + +| | | +|-|-| +| **Environment variable** | `SERVICEPULSE_HTTPS_HSTSINCLUDESUBDOMAINS` | +| **Type** | bool | +| **Default** | `false` | diff --git a/servicepulse/security/configuration/authentication.md b/servicepulse/security/configuration/authentication.md new file mode 100644 index 00000000000..6f2ac1a877f --- /dev/null +++ b/servicepulse/security/configuration/authentication.md @@ -0,0 +1,134 @@ +--- +title: ServicePulse Authentication Configuration +summary: How to enable and configure authentication for ServicePulse +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/hosting-guide +- servicecontrol/security/configuration/authentication +- servicecontrol/security/entra-id-authentication +--- + +ServicePulse supports authentication using [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/) and works with any OpenID Connect compliant identity provider (Microsoft Entra ID, Okta, Auth0, Keycloak, etc.). When enabled, users must sign in with their identity provider before accessing the dashboard. + +> [!IMPORTANT] +> Ensure ServiceControl has been setup with [authentication](/servicecontrol/security/configuration/authentication.md) and [TLS encryption](/servicecontrol/security/configuration/tls.md). This is a prerequisite for ServicePulse authentication. + +## Configuration + +Authentication in ServicePulse is [configured in the primary ServiceControl instance](/servicecontrol/security/configuration/authentication.md#configuration). ServicePulse fetches authentication settings on startup from the ServiceControl API and the following settings are set: + +| Setting | Description | +|--------------|-------------------------------------------------------------------------------| +| `enabled` | Enable or disable authentication | +| `authority` | The OIDC authority URL (identity provider) | +| `client_id` | The OIDC client ID registered with your identity provider | +| `api_scopes` | API scopes to request (space-separated or JSON array) | +| `audience` | The audience claim for the access token (required by some identity providers) | + +## Identity Provider Setup + +When registering ServicePulse with your identity provider, configure the following: + +| Setting | Value | +|--------------------------|---------------------------------------------------| +| Application type | Single Page Application (SPA) | +| Grant type | Authorization Code with PKCE | +| Redirect URI | `https://your-servicepulse-url/` | +| Post-logout redirect URI | `https://your-servicepulse-url/` | +| Silent renew URI | `https://your-servicepulse-url/silent-renew.html` | + +### Identity Provider Guides + +For step-by-step instructions on configuring specific identity providers, see: + +- [Microsoft Entra ID](/servicecontrol/security/entra-id-authentication.md) + +### Required Scopes + +- [ServiceControl API Access](/servicecontrol/security/configuration/authentication.md#identity-provider-setup) + +ServicePulse requests the following OIDC scopes in addition to any API scopes configured: + +- `openid` - Required for OIDC +- `profile` - User's name and profile information +- `email` - User's email address +- `offline_access` - Enables refresh tokens for silent renewal + +## Token Management + +### Storage + +User tokens are stored in the browser's `sessionStorage`. This means: + +- Tokens are cleared when the browser tab is closed +- Each browser tab maintains its own session +- Tokens are not shared across tabs + +### Silent Renewal + +ServicePulse automatically renews access tokens before they expire using a hidden iframe (`silent-renew.html`). This provides a seamless experience without requiring users to re-authenticate. + +If silent renewal fails (e.g., session expired at the identity provider), users are redirected to log in again. + +## User Interface + +When authentication is enabled and the user is signed in, the dashboard header displays: + +- User's name (from the `name` claim) +- User's email (from the `email` claim) +- A sign-out button + +## Troubleshooting + +### "Authentication required" error + +This error appears when: + +1. Authentication is enabled but no valid token exists +2. The token has expired and silent renewal failed +3. The user cancelled the login flow + +**Solution:** Click the login button or refresh the page to initiate authentication. + +### Redirect loop or login failures + +Common causes: + +1. **Incorrect redirect URI** - Ensure the redirect URI registered with your identity provider exactly matches the ServicePulse URL (including trailing slash if present) +2. **CORS issues** - Your identity provider must allow requests from the ServicePulse origin +3. **Clock skew** - Ensure server clocks are synchronized; token validation is time-sensitive + +### Silent renewal fails repeatedly + +This can occur when: + +1. The identity provider session has expired +2. Third-party cookies are blocked (required for iframe-based renewal) +3. The `silent-renew.html` page is not accessible + +**Solution:** Check the browser console for specific error messages. Some browsers block third-party cookies by default, which can prevent silent renewal from working. + +### Token not included in API requests + +Verify that: + +1. Authentication is enabled in ServiceControl +2. The user has completed the login flow +3. The token has not expired + +Check the browser's Network tab to confirm the `Authorization: Bearer` header is present on API requests. + +## Security Considerations + +### HTTPS Required + +For production deployments, [always use HTTPS](tls.md). OIDC tokens are sensitive credentials that should only be transmitted over encrypted connections. + +### Session Duration + +Token lifetime is controlled by your identity provider. Consider configuring: + +- **Access token lifetime** - Short-lived (e.g., 1 hour) for security +- **Refresh token lifetime** - Longer-lived to enable silent renewal +- **Session policies** - Maximum session duration before re-authentication is required diff --git a/servicepulse/security/configuration/forward-headers.md b/servicepulse/security/configuration/forward-headers.md new file mode 100644 index 00000000000..eedc1ddd2a8 --- /dev/null +++ b/servicepulse/security/configuration/forward-headers.md @@ -0,0 +1,205 @@ +--- +title: ServicePulse Forward Headers for Reverse Proxy Configuration +summary: How to enable and configure forward headers for ServicePulse +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/hosting-guide +- servicecontrol/security/configuration/forward-headers +--- + +> [!NOTE] +> This page is **not** relevant if the [ServicePulse static files have been extracted](/servicepulse/install-servicepulse-in-iis.md), and is being hosted in anything other than the [Container](/servicepulse/containerization/) or [Windows Service](/servicepulse/installation.md) hosting options provided. Forward header configuration is only required if using a reverse proxy. + +When ServicePulse is deployed behind a reverse proxy that terminates SSL/TLS (like nginx, Traefik, or a cloud load balancer), you need to configure forwarded headers so ServicePulse correctly understands the original client request. + +## Configuration + +There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables, while the Windows Service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings, along with [Authentication](authentication.md) and [TLS](tls.md), in a scenario-based format. + +### Container + +- [Container forward header settings](/servicepulse/containerization/#settings-forward-headers) + +### Windows Service + +| Command-Line Argument | Default | Description | +|---------------------------------------|---------|------------------------------------------------------------------| +| `--forwardedheadersenabled=` | `true` | Enable forwarded headers processing | +| `--forwardedheaderstrustallproxies=` | `true` | Trust all proxies (auto-disabled if known proxies/networks set) | +| `--forwardedheadersknownproxies=` | (none) | Comma-separated IP addresses of trusted proxies | +| `--forwardedheadersknownnetworks=` | (none) | Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`) | + +Example: + +```cmd +"C:\Program Files (x86)\Particular Software\ServicePulse\ServicePulse.Host.exe" --forwardedheadersenabled=true --forwardedheaderstrustallproxies=true +``` + +## What Headers Are Processed + +When enabled, ServicePulse processes: + +- `X-Forwarded-For` - Original client IP address +- `X-Forwarded-Proto` - Original protocol (http/https) +- `X-Forwarded-Host` - Original host header + +When the proxy is trusted: + +- `Request.Scheme` will be set from `X-Forwarded-Proto` (e.g., `https`) +- `Request.Host` will be set from `X-Forwarded-Host` (e.g., `servicepulse.example.com`) +- Client IP will be available from `X-Forwarded-For` + +When the proxy is **not** trusted (incorrect `KnownProxies`): + +- `X-Forwarded-*` headers are **ignored** (not applied to the request) +- `Request.Scheme` remains `http` +- `Request.Host` remains the internal hostname +- The request is still processed (not blocked) + +## Interaction with the Container Built-in Reverse Proxy + +ServicePulse includes a [built-in YARP reverse proxy with the Container](/servicepulse/containerization/#reverse-proxy) that forwards requests to ServiceControl Primary and Monitoring instances. The forwarded headers configuration does **not** affect this proxy. + +```mermaid +sequenceDiagram + participant Client + participant Proxy as Upstream Proxy + participant SP as ServicePulse + participant YARP + participant SC as ServiceControl + + Client->>Proxy: Request + Note over Proxy: Sets X-Forwarded-For
Sets X-Forwarded-Proto
Sets X-Forwarded-Host + Proxy->>SP: Request + X-Forwarded-* headers + Note over SP: UseForwardedHeaders
updates request context + SP->>YARP: Proxied request + YARP->>SC: Request to ServiceControl +``` + +- **UseForwardedHeaders** processes incoming headers from an upstream proxy so ServicePulse understands the original client request (scheme, host, client IP) +- **YARP** independently handles outgoing requests to ServiceControl/Monitoring backends + +These operate at different points in the request flow and do not conflict. + +## HTTP to HTTPS Redirect + +When using a reverse proxy that terminates SSL, you can configure ServicePulse to redirect HTTP requests to HTTPS. This works in combination with forwarded headers: + +1. The reverse proxy forwards both HTTP and HTTPS requests to ServicePulse +2. The proxy sets `X-Forwarded-Proto` to indicate the original protocol +3. ServicePulse reads this header (via forwarded headers processing) +4. If the original request was HTTP and redirect is enabled, ServicePulse returns a redirect to HTTPS + +```mermaid +sequenceDiagram + participant Client + participant Proxy as Reverse Proxy + participant SP as ServicePulse + + Client->>Proxy: HTTP Request + Note over Proxy: Terminates request
Sets X-Forwarded-Proto: http + Proxy->>SP: Request + X-Forwarded-Proto: http + Note over SP: Reads X-Forwarded-Proto
Detects original was HTTP + SP-->>Proxy: 301 Redirect to HTTPS + Proxy-->>Client: 301 Redirect to HTTPS + Client->>Proxy: HTTPS Request + Note over Proxy: Terminates SSL
Sets X-Forwarded-Proto: https + Proxy->>SP: Request + X-Forwarded-Proto: https + SP->>Client: Response (via Proxy) +``` + +To enable HTTP to HTTPS redirect, see [TLS Configuration](tls.md) for details on how to do this. + +## Proxy Chain Behavior (ForwardLimit) + +When processing `X-Forwarded-For` headers with multiple IPs (proxy chains), the behavior depends on trust configuration: + +| Configuration | ForwardLimit | Behavior | +|---------------------------|-------------------|-----------------------------------------------| +| `TrustAllProxies = true` | `null` (no limit) | Processes all IPs, returns original client IP | +| `TrustAllProxies = false` | `1` (default) | Processes only the last proxy IP | + +For example, with `X-Forwarded-For: 203.0.113.50, 10.0.0.1, 192.168.1.1`: + +- **TrustAllProxies = true**: Returns `203.0.113.50` (original client) +- **TrustAllProxies = false**: Returns `192.168.1.1` (last proxy) + +## Configuration examples + +The following examples show common forward header configurations for different deployment scenarios. + +### Single reverse proxy (known IP) + +When running behind a single reverse proxy with a known IP address: + +**Container:** + +```bash +docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES=10.0.0.5 \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --forwardedheadersenabled=true --forwardedheaderstrustallproxies=false --forwardedheadersknownproxies=10.0.0.5 +``` + +### Multiple reverse proxies + +When running behind multiple proxies (e.g., load balancer and application gateway): + +**Container:** + +```bash +docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES=10.0.0.5,10.0.0.6 \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --forwardedheadersenabled=true --forwardedheaderstrustallproxies=false --forwardedheadersknownproxies=10.0.0.5,10.0.0.6 +``` + +### Container/Kubernetes environment + +When running in a container environment where proxy IPs are dynamic, trust a network range: + +```bash +docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_KNOWNNETWORKS=10.0.0.0/8 \ + ... + particular/servicepulse:latest +``` + +### Development/trusted environment + +For development or fully trusted environments (not recommended for production): + +**Container:** + +```bash +docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=true \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --forwardedheadersenabled=true --forwardedheaderstrustallproxies=true +``` + +## Troubleshooting + +include: forward-header-troubleshooting diff --git a/servicepulse/security/configuration/index.md b/servicepulse/security/configuration/index.md new file mode 100644 index 00000000000..e927071ab38 --- /dev/null +++ b/servicepulse/security/configuration/index.md @@ -0,0 +1,25 @@ +--- +title: ServicePulse Security Configuration +summary: How to secure ServicePulse instances +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/hosting-guide +- servicecontrol/security/hosting-guide +--- + +ServicePulse provides several configuration options to secure instances. This section covers the available security settings and how to configure them. + +## Configuration topics + +### [Authentication](authentication.md) + +Authentication settings are fetched from the primary ServiceControl instance, streamlining the authentication setup for ServicePulse. + +### [TLS](tls.md) + +Enable encrypted connections by configuring ServicePulse to use HTTPS directly. Includes options for certificate management, HTTP to HTTPS redirects, and HTTP Strict Transport Security (HSTS). + +### [Forward Headers](forward-headers.md) + +Configure forwarded header processing for deployments behind a reverse proxy. Ensures ServicePulse correctly interprets client requests when SSL/TLS is terminated at a load balancer or proxy. diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md new file mode 100644 index 00000000000..96d732abe7a --- /dev/null +++ b/servicepulse/security/configuration/tls.md @@ -0,0 +1,133 @@ +--- +title: ServicePulse TLS Configuration +summary: How to enable and configure TLS for ServicePulse +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/hosting-guide +- servicecontrol/security/configuration/tls +--- + +> [!NOTE] +> This page is **not** relevant if the [ServicePulse static files have been extracted](/servicepulse/install-servicepulse-in-iis.md), and is being hosted in anything other than the [Container](/servicepulse/containerization/) or [Windows Service](/servicepulse/installation.md) hosting options provided. If using [authentication](/servicepulse/security/configuration/authentication.md), it is recommended to use TLS encryption. + +ServicePulse can be configured to use HTTPS directly, enabling encrypted connections without relying on a reverse proxy for SSL termination. + +## Configuration + +There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables, while the Windows Service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings, along with [Authentication](authentication.md) and [Forward Headers](forward-headers.md), in a scenario-based format. + +### Container + +- [Container TLS settings](/servicepulse/containerization/#settings-tls) + +### Window Service + +| Command-Line Argument | Default | Description | +|---------------------------------|------------|----------------------------------------------------------------| +| `--httpsenabled=` | `false` | Enable HTTPS with Kestrel | +| `--httpsredirecthttptohttps=` | `false` | Redirect HTTP requests to HTTPS | +| `--httpsport=` | (none) | HTTPS port for redirect (required for reverse proxy scenarios) | +| `--httpsenablehsts=` | `false` | Enable HTTP Strict Transport Security | +| `--httpshstsmaxageseconds=` | `31536000` | HSTS max-age in seconds (default: 1 year) | +| `--httpshstsincludesubdomains=` | `false` | Include subdomains in HSTS policy | + +> [!NOTE] +> The windows service uses Windows HttpListener which requires [SSL certificate binding at the OS level using `netsh`](https://learn.microsoft.com/en-us/dotnet/framework/wcf/feature-details/how-to-configure-a-port-with-an-ssl-certificate). The certificate is not configured in the application itself. + +Example: + +```cmd +"C:\Program Files (x86)\Particular Software\ServicePulse\ServicePulse.Host.exe" --httpsenabled=true --httpsredirecthttptohttps=false +``` + +## Security Considerations + +include: cert-management + +include: hsts-considerations + +### HTTP to HTTPS Redirect + +The `SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS` setting is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. When enabled: + +- The redirect uses HTTP 307 (Temporary Redirect) to preserve the request method +- The reverse proxy must forward both HTTP and HTTPS requests to ServicePulse +- ServicePulse will redirect HTTP requests to HTTPS based on the `X-Forwarded-Proto` header +- **Important:** You must also set `SERVICEPULSE_HTTPS_PORT` (or `--httpsport=` for .NET Framework) to specify the HTTPS port for the redirect URL + +> [!NOTE] +> When running ServicePulse directly without a reverse proxy, the application only listens on a single protocol (HTTP or HTTPS). + +## Configuration Examples + +The following examples show common TLS configurations for different deployment scenarios. + +### Direct HTTPS with certificate + +When ServicePulse handles TLS directly using a PFX certificate: + +**Container:** + +> [!NOTE] +> The following is a docker compose snippets. For full examples, see the [Platform Container Examples repository](https://github.com/Particular/PlatformContainerExamples). + +```bash +servicepulse: + image: particular/servicepulse:latest + ports: + - "9090:9090" + environment: + SERVICECONTROL_URL: https://servicecontrol:33333 + MONITORING_URL: https://servicecontrol-monitoring:33633 + SERVICEPULSE_HTTPS_ENABLED: "true" + SERVICEPULSE_HTTPS_CERTIFICATEPATH: "/usr/share/ParticularSoftware/certificate.pfx" + SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD: "..." + SSL_CERT_FILE: "/etc/ssl/certs/ca-bundle.crt" + ASPNETCORE_URLS: "https://+:9090" + restart: unless-stopped + volumes: + - C:\path\to\servicecontrol\cert.pfx:/usr/share/ParticularSoftware/certificate.pfx + - C:\path\to\servicecontrol\ca-bundle.crt:/etc/ssl/certs/ca-bundle.crt:ro + depends_on: + servicecontrol: + condition: service_healthy + servicecontrol-monitoring: + condition: service_healthy + rabbitmq: + condition: service_healthy +``` + +**SSL_CERT_FILE (CRT)**: This tells SSL/TLS libraries (including .NET's HttpClient, OpenSSL, and libcurl) the path to a CA (Certificate Authority) certificate bundle file. This bundle contains the public certificates of trusted CAs used to verify the authenticity of SSL/TLS certificates presented by remote servers. This certificate is used to verify HTTPS (trust others). + +**SERVICEPULSE_HTTPS_CERTIFICATEPATH (PFX)**: This is a binary archive format that bundles together the private key, public certificate, and certificate chain. This certificate is used to serve HTTPS (prove identity). + +> [!NOTE] +> When containers communicate with each other over HTTPS, they use the Docker service names (like `servicecontrol`, `servicecontrol-audit`) as hostnames, and TLS validation will fail if the certificate doesn't include these names in its Subject Alternative Names (SANs). + +**Windows Service:** + +The Windows service uses Windows HttpListener which requires SSL certificate binding at the OS level: + +```cmd +netsh http add sslcert ipport=0.0.0.0:443 certhash={certificate-thumbprint} appid={application-guid} +ServicePulse.Host.exe --httpsenabled=true +``` + +## Troubleshooting + +include: tls-troubleshooting + +### SSL certificate binding fails (Windows Service) + +**Symptom**: ServicePulse fails to start with HTTPS enabled, or `netsh http add sslcert` returns an error. + +**Cause**: The certificate is not properly bound to the port, the certificate is missing from the certificate store, or the thumbprint/appid is incorrect. + +**Solutions**: + +- Verify the certificate is installed in the Windows certificate store (Local Computer > Personal) +- Check the certificate thumbprint is correct (no spaces, lowercase) +- Ensure the port is not already bound to another certificate: `netsh http show sslcert` +- Remove existing binding before adding a new one: `netsh http delete sslcert ipport=0.0.0.0:443` +- Run the command prompt as Administrator diff --git a/servicepulse/security/hosting-guide.md b/servicepulse/security/hosting-guide.md new file mode 100644 index 00000000000..29f2b2db8cc --- /dev/null +++ b/servicepulse/security/hosting-guide.md @@ -0,0 +1,181 @@ +--- +title: ServicePulse Hosting and Security Guide +summary: Example hosting options for ServicePulse +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/configuration/authentication +- servicepulse/security/configuration/forward-headers +- servicepulse/security/configuration/tls +- servicecontrol/security/hosting-guide +--- + +This guide covers hosting and configuration for ServicePulse. + +> [!NOTE] +> Authentication for ServicePulse is configured in ServiceControl, not in ServicePulse itself. When authentication is enabled on ServiceControl, ServicePulse automatically retrieves the OIDC configuration from the ServiceControl API and handles the OAuth flow. See the [ServiceControl hosting guide](/servicecontrol/security/hosting-guide.md) for authentication configuration examples. All scenarios assume HTTPS and authentication are required. + +## Deployment Scenarios + +The below scenarios assume the use of the [Container](/servicepulse/containerization/). For additional details on the use of the windows service, see [Authentication](configuration/authentication.md), [TLS](configuration/tls.md), and [Forward Headers](configuration/forward-headers.md). + +### Scenario 0: Default / Backward Compatible Configuration + +The default configuration with no additional setup required. Backwards compatible with existing deployments. + +#### Security Features + +| Feature | Status | +|------------------------|----------------------------------| +| JWT Authentication | N/A (ServiceControl controlled) | +| Kestrel HTTPS | ❌ Disabled | +| HTTPS Redirection | ❌ Disabled | +| HSTS | ❌ Disabled | +| Forwarded Headers | ✅ Enabled (trusts all) | +| Restricted Proxy Trust | ❌ Disabled | + +No additional variables need to be set, however if prefered, the following can be explicity set for the same outcome: + +#### Example Configuration + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=true \ + ... + particular/servicepulse:latest +``` + +### Scenario 1: Strict Reverse Proxy with ServicePulse + +ServicePulse sits behind a reverse proxy (NGINX, IIS ARR, cloud load balancer) that handles SSL/TLS termination. + +#### Architecture + +```mermaid +sequenceDiagram + participant Browser + participant RP as Reverse Proxy
(SSL termination) + participant SP as ServicePulse
(reverse proxy) + participant SC as ServiceControl + + Browser->>RP: HTTPS + RP->>SP: HTTP + SP->>SC: HTTP +``` + +#### Security Features + +| Feature | Status | +|-------------------------|-------------------------------| +| JWT Authentication | N/A (ServiceControl controlled) | +| Kestrel HTTPS | ❌ Disabled (handled by proxy) | +| HTTPS Redirection | ✅ Enabled (optional) | +| HSTS | ❌ Disabled (handled by proxy) | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | + +> [!NOTE] +> HTTPS redirection is optional in this scenario. The reverse proxy typically handles HTTP to HTTPS redirection at its layer. However, enabling it at ServicePulse provides defense-in-depth - if an HTTP request somehow bypasses the proxy and reaches ServicePulse directly, it will be redirected to the HTTPS URL. This requires configuring `Https.Port` to specify the external [HTTPS port](configuration/tls.md) used by the proxy. + +#### Example Configuration + +```bash +docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES=10.0.0.5 \ + -e SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS=true \ + -e SERVICEPULSE_HTTPS_PORT=443 \ + ... + particular/servicepulse:latest +``` + +### Scenario 2: Direct HTTPS with ServicePulse + +Kestrel handles TLS directly without a reverse proxy. + +#### Architecture + +```mermaid +sequenceDiagram + participant Browser + participant SP as ServicePulse (Kestrel)
(TLS + SPA serving) + participant SC as ServiceControl + + Browser->>SP: HTTPS + SP->>SC: HTTP +``` + +#### Security Features + +| Feature | Status | +|-------------------------|-----------------------| +| JWT Authentication | N/A (ServiceControl controlled) | +| Kestrel HTTPS | ✅ Enabled | +| HSTS | ✅ Enabled | +| Forwarded Headers | ❌ Disabled (no proxy) | +| Restricted Proxy Trust | N/A | + +> [!NOTE] +> HTTPS redirection is not configured in this scenario because clients connect directly over HTTPS. There is no HTTP endpoint exposed that would need to redirect. HTTPS redirection is only useful when a reverse proxy handles SSL termination and ServicePulse needs to redirect HTTP requests to the proxy's HTTPS endpoint. + +#### Example Configuration + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=C:\certs\servicepulse.pfx \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD=your-password \ + -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ + -e SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS=31536000 \ + -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=false \ + -v /path/to/certs:/certs \ + ... + particular/servicepulse:latest +``` + +### Scenario 3: End-to-End Encryption with Reverse Proxy and Direct HTTPS + +For environments requiring encryption of internal traffic. End-to-end TLS encryption where the reverse proxy terminates external TLS and re-encrypts traffic to ServicePulse over HTTPS. + +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant RP as Reverse Proxy
(TLS termination) + participant SP as ServicePulse (Kestrel)
(TLS + SPA serving) + participant SC as ServiceControl (Kestrel)
(TLS + JWT validation) + + Client->>RP: HTTPS + RP->>SP: HTTPS + SP->>SC: HTTPS +``` + +#### Security Features + +| Feature | Status | +|----------------------------|--------------------------| +| JWT Authentication | N/A (ServiceControl controlled) | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | N/A (no HTTP endpoint) | +| HSTS | N/A (configure at proxy) | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | +| Internal Traffic Encrypted | ✅ Yes | + +> [!NOTE] +> HTTPS redirection and HSTS are not applicable in this scenario because ServicePulse only exposes an HTTPS endpoint (Kestrel HTTPS is enabled). There is no HTTP endpoint to redirect from. The reverse proxy is responsible for redirecting external HTTP requests to HTTPS and sending HSTS headers to browsers. Compare this to Scenario 1, where Kestrel HTTPS is disabled and ServicePulse exposes an HTTP endpoint - in that case, HTTPS redirection can optionally be enabled as defense-in-depth. + +#### Example Configuration + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=C:\certs\servicepulse.pfx \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD=your-password \ + -e SERVICEPULSE_HTTPS_ENABLEHSTS=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES=false \ + -e SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES=10.0.0.5 \ + -v /path/to/certs:/certs \ + ... + particular/servicepulse:latest +``` diff --git a/servicepulse/security/index.md b/servicepulse/security/index.md new file mode 100644 index 00000000000..3cb05999c24 --- /dev/null +++ b/servicepulse/security/index.md @@ -0,0 +1,80 @@ +--- +title: ServicePulse Security Overview +summary: Secure ServicePulse with authentication, TLS, and other security features +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicecontrol/security +--- + +This section covers security features for ServicePulse, including authentication, transport layer security (TLS), and reverse proxy configuration. + +## In this section + +- Security Configuration - Configuration reference for TLS and forward headers +- [Hosting Guide](hosting-guide.md) - Deployment scenarios with complete configuration examples + +## [Authentication](/servicepulse/security/configuration/authentication.md) + +ServicePulse supports standards-based authentication using [OAuth 2.0](https://oauth.net/2/) with [JSON Web Tokens (JWT)](https://en.wikipedia.org/wiki/JSON_Web_Token), and [OpenID Connect (OIDC)](https://openid.net/developers/how-connect-works/). + +> [!IMPORTANT] +> Authentication is [configured in ServiceControl](/servicecontrol/security/configuration/authentication.md), not in ServicePulse itself. ServicePulse retrieves authentication configuration from the ServiceControl API and handles the OAuth flow automatically. + +When authentication is enabled on ServiceControl: + +1. ServicePulse retrieves authentication configuration from an anonymous ServiceControl endpoint +2. Users sign in through the configured identity provider +3. API requests to ServiceControl include a JWT bearer token in the `Authorization` header +4. ServiceControl validates the token against the configured authority + +```mermaid +sequenceDiagram + participant User + participant ServicePulse + participant ServiceControl + participant IdP as Identity Provider + + User->>ServicePulse: Open ServicePulse + Note over ServicePulse,ServiceControl: Anonymous endpoint (no auth required) + ServicePulse->>ServiceControl: GET /api/authentication/configuration + ServiceControl-->>ServicePulse: Auth settings (authority, clientId, scopes) + ServicePulse->>IdP: Redirect to sign-in + User->>IdP: Enter credentials + IdP-->>ServicePulse: Access token (JWT) + Note over ServicePulse,ServiceControl: Authenticated request + ServicePulse->>ServiceControl: API request + Authorization: Bearer {token} + ServiceControl->>IdP: Validate token (via OIDC metadata) + IdP-->>ServiceControl: Token valid + ServiceControl-->>ServicePulse: API response + ServicePulse-->>User: Display data +``` + +## [TLS](/servicepulse/security/configuration/tls.md) + +When authentication is enabled, access tokens are exchanged between ServicePulse and ServiceControl. To protect these tokens, TLS must be enabled. + +> [!IMPORTANT] +> Without TLS, tokens are transmitted in clear text, exposing the system to interception and unauthorized access. Always use HTTPS in production environments. + +ServicePulse supports two approaches for HTTPS: + +- **Direct HTTPS**: Configure Kestrel to handle TLS with a certificate +- **Reverse proxy**: Terminate TLS at a reverse proxy (NGINX, IIS, Azure App Gateway, etc.) and forward requests to ServicePulse over HTTP + +## [Reverse proxy support](/servicepulse/security/configuration/forward-headers.md) + +When ServicePulse runs behind a reverse proxy, forwarded headers ensure ServicePulse correctly interprets client requests. This is important for: + +- Determining the original client IP address +- Understanding whether the original request used HTTPS +- Generating correct redirect URLs + +## Deployment scenarios + +The [Hosting Guide](hosting-guide.md) provides complete configuration examples for common deployment patterns: + +- **Default configuration**: No authentication, HTTP only (backward compatible) +- **Reverse proxy with authentication**: TLS termination at proxy +- **Direct HTTPS with authentication**: Kestrel handles TLS directly +- **End-to-end encryption**: TLS at both proxy and Kestrel for internal traffic encryption