From 410b0b5d293070de53afa76c4e4b87d62fd22251 Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Thu, 11 Dec 2025 11:39:14 +1000 Subject: [PATCH 01/27] Add ServiceControl security page --- menu/menu.yaml | 4 ++++ servicecontrol/security/index.md | 6 ++++++ 2 files changed, 10 insertions(+) create mode 100644 servicecontrol/security/index.md diff --git a/menu/menu.yaml b/menu/menu.yaml index bc3cbc488b4..71a4f41c0c5 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1481,6 +1481,10 @@ Url: servicecontrol/upgrades/2to3 - Title: Version 1 to 2 Url: servicecontrol/upgrades/1to2 + - Title: Security + Articles: + - Title: ServiceControl security + Url: servicecontrol - Title: Planning Articles: - Title: Optimizing for use in different environments diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md new file mode 100644 index 00000000000..91b5e49daac --- /dev/null +++ b/servicecontrol/security/index.md @@ -0,0 +1,6 @@ +--- +title: ServiceControl security +summary: Learn how to secure ServiceControl with OAuth 2.0 and OpenID Connect +reviewed: 2025-12-11 +component: ServiceControl +--- From db9d0e0e1a0276543ec093a5a39ead99dceda75a Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Thu, 11 Dec 2025 14:28:23 +1000 Subject: [PATCH 02/27] Add authentication and configuration documentation --- menu/menu.yaml | 4 +- servicecontrol/security/configuration.md | 102 +++++++++++++++++++++++ servicecontrol/security/index.md | 25 +++++- 3 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 servicecontrol/security/configuration.md diff --git a/menu/menu.yaml b/menu/menu.yaml index 71a4f41c0c5..7f4abef86c3 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1484,7 +1484,9 @@ - Title: Security Articles: - Title: ServiceControl security - Url: servicecontrol + Url: servicecontrol/security + - Title: Configuration + Url: servicecontrol/security/configuration - Title: Planning Articles: - Title: Optimizing for use in different environments diff --git a/servicecontrol/security/configuration.md b/servicecontrol/security/configuration.md new file mode 100644 index 00000000000..1dcf5e1a3b3 --- /dev/null +++ b/servicecontrol/security/configuration.md @@ -0,0 +1,102 @@ +--- +title: Configuring authentication +summary: How to enable and configure authentication for ServiceControl and ServicePulse +reviewed: 2025-12-11 +component: ServiceControl +--- + +This guide explains how to configure ServiceControl to enable authentication. + +## Enabling authentication + +Authentication is disabled by default. To enable it, add the following settings to the ServiceControl configuration file: + +```xml + + + +``` + +## ServiceControl settings + +These settings control how ServiceControl validates incoming JWT access tokens. + +| Setting | Description | +|---------|-------------| +| `ServiceControl/Authentication.Enabled` | Set to `true` to enable authentication. Default: `false` | +| `ServiceControl/Authentication.Authority` | The OpenID Connect authority URL used to validate tokens. This is typically the issuer URL of the identity provider. | +| `ServiceControl/Authentication.Audience` | The expected audience claim in the access token. This is typically the Application ID URI of the ServiceControl API registration. | + +### Token validation settings + +These optional settings control specific aspects of token validation. The defaults are secure and should not be changed unless there is a specific requirement. + +| Setting | Default | Description | +|---------|---------|-------------| +| `ServiceControl/Authentication.ValidateIssuer` | `true` | Validates that the token was issued by the configured authority. | +| `ServiceControl/Authentication.ValidateAudience` | `true` | Validates that the token contains the expected audience claim. | +| `ServiceControl/Authentication.ValidateLifetime` | `true` | Validates that the token has not expired. | +| `ServiceControl/Authentication.ValidateIssuerSigningKey` | `true` | Validates the token signature using keys from the identity provider. | +| `ServiceControl/Authentication.RequireHttpsMetadata` | `true` | Requires HTTPS when retrieving OpenID Connect metadata. Set to `false` only for local development. | + +## ServicePulse settings + +These settings are served to ServicePulse through a bootstrap endpoint, allowing ServicePulse to authenticate users without its own configuration file. + +| Setting | Description | +|---------|-------------| +| `ServiceControl/Authentication.ServicePulse.ClientId` | The OAuth 2.0 client ID for the ServicePulse application registration. | +| `ServiceControl/Authentication.ServicePulse.Authority` | The OpenID Connect authority URL for ServicePulse authentication. For Microsoft Entra ID, this typically includes `/v2.0` at the end. | +| `ServiceControl/Authentication.ServicePulse.Audience` | The audience for ServicePulse token requests. This is typically the same as the ServiceControl audience. | +| `ServiceControl/Authentication.ServicePulse.ApiScopes` | A JSON array of scopes to request when acquiring tokens. For example: `["api://app-id/api.access"]` | + +## Configuration file example + +The following example shows a complete authentication configuration for Microsoft Entra ID: + +```xml + + + + + + + + + + + + +``` + +## Environment variables + +All settings can also be configured using environment variables, which is useful for containerized deployments and local development. Convert setting names to environment variables by replacing `/` and `.` with `_`. + +| App.config key | Environment variable | +|----------------|---------------------| +| `ServiceControl/Authentication.Enabled` | `SERVICECONTROL_AUTHENTICATION_ENABLED` | +| `ServiceControl/Authentication.Authority` | `SERVICECONTROL_AUTHENTICATION_AUTHORITY` | +| `ServiceControl/Authentication.Audience` | `SERVICECONTROL_AUTHENTICATION_AUDIENCE` | +| `ServiceControl/Authentication.ServicePulse.ClientId` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | +| `ServiceControl/Authentication.ServicePulse.Authority` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | +| `ServiceControl/Authentication.ServicePulse.Audience` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE` | +| `ServiceControl/Authentication.ServicePulse.ApiScopes` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | + +Environment variables take precedence over App.config settings. + +### Environment variable example + +```powershell +# Enable authentication +$env:SERVICECONTROL_AUTHENTICATION_ENABLED = "true" +$env:SERVICECONTROL_AUTHENTICATION_AUTHORITY = "https://login.microsoftonline.com/your-tenant-id" +$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "api://your-app-id" + +# ServicePulse settings +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID = "your-servicepulse-client-id" +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY = "https://login.microsoftonline.com/your-tenant-id/v2.0" +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE = "api://your-app-id" +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["api://your-app-id/api.access"]' +``` + diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 91b5e49daac..ba999af529a 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -1,6 +1,29 @@ --- title: ServiceControl security -summary: Learn how to secure ServiceControl with OAuth 2.0 and OpenID Connect +summary: Secure ServiceControl and ServicePulse with OAuth 2.0 and OpenID Connect reviewed: 2025-12-11 component: ServiceControl --- + +ServiceControl and [ServicePulse](/servicepulse/) support standards-based authentication using OAuth 2.0 and OpenID Connect (OIDC). 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 the ServiceControl are accessible without credentials. Enable authentication in production environments to restrict access. + +## Supported identity providers + +Any OpenID Connect (OIDC) compliant identity provider can be used, including: + +- Active Directory Federation Services (ADFS) +- Auth0 +- AWS IAM Identity Center +- Duende IdentityServer +- Google Workspace +- Keycloak +- Microsoft Entra ID +- Okta +- Ping Identity + +## Configuration + +Each ServiceControl instance must be configured separately to enable authentication. Configuration is applied by editing the instance's App.config file or by setting environment variables. ServicePulse retrieves these settings automatically from the connected ServiceControl instances, so no separate configuration is required. Read the [configuring authentication](configuration.md) guide for more details. From f2636d281d8b05e55f1ee9f75a09fbd2b002b199 Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Thu, 11 Dec 2025 14:52:17 +1000 Subject: [PATCH 03/27] Add Entra ID authentication guide --- menu/menu.yaml | 2 + servicecontrol/security/configuration.md | 55 +++++++++ .../security/entra-id-authentication.md | 108 ++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 servicecontrol/security/entra-id-authentication.md diff --git a/menu/menu.yaml b/menu/menu.yaml index 7f4abef86c3..a233ffc898f 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1487,6 +1487,8 @@ Url: servicecontrol/security - Title: Configuration Url: servicecontrol/security/configuration + - Title: Microsoft Entra ID authentication + Url: servicecontrol/security/entra-id-authentication - Title: Planning Articles: - Title: Optimizing for use in different environments diff --git a/servicecontrol/security/configuration.md b/servicecontrol/security/configuration.md index 1dcf5e1a3b3..3560b03b874 100644 --- a/servicecontrol/security/configuration.md +++ b/servicecontrol/security/configuration.md @@ -100,3 +100,58 @@ $env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE = "api://your-app-id" $env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["api://your-app-id/api.access"]' ``` + +## 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. + +### Microsoft Entra ID + +```xml + + + + + + + + + + +``` + +### Auth0 + +```xml + + + + + + + + + + +``` + +### Keycloak + +```xml + + + + + + + + + + +``` diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md new file mode 100644 index 00000000000..af2a086e52c --- /dev/null +++ b/servicecontrol/security/entra-id-authentication.md @@ -0,0 +1,108 @@ +--- +title: Microsoft Entra ID authentication +summary: Set up authentication with Microsoft Entra ID for ServiceControl and ServicePulse +reviewed: 2025-12-11 +component: ServiceControl +--- + +This guide explains how to configure Microsoft Entra ID (formerly Azure Active Directory) and ServiceControl to enable authentication for ServicePulse. + +## Configure Microsoft Entra ID + +Register ServiceControl and ServicePulse as applications in Microsoft Entra ID to allow users to authenticate. + +### Create the ServiceControl app registration + +1. Navigate to the [Azure Portal](https://portal.azure.com/). +2. Open **Microsoft Entra ID** and select **Manage** > **App registrations**. +3. Click **+ New registration**. +4. Configure the registration: + - **Name**: `ServiceControl API` + - **Supported account types**: Accounts in this organizational directory only + - Click **Register**. +5. On the **Overview** page, click **Endpoints** and copy the **OpenID Connect metadata document** URL (remove `/.well-known/openid-configuration` from the end). This is the authority URL used for `ServiceControl/Authentication.Authority`. +6. Select **Manage** > **Expose an API**. +7. Next to **Application ID URI**, click **Add** and save the default value. +8. Under **Scopes defined by this API**, click **Add a scope** and configure: + - **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` + - **State**: Enabled + - Click **Add scope**. +9. Copy the **Application ID URI**. This is used for `ServiceControl/Authentication.Audience` and as part of `ServiceControl/Authentication.ServicePulse.ApiScopes`. + +### Create the ServicePulse app registration + +1. In **App registrations**, click **+ New registration**. +2. Configure the registration: + - **Name**: `ServicePulse` + - **Supported account types**: Accounts in this organizational directory only + - **Redirect URI**: + - **Platform**: Single-page application (SPA) + - **URI**: `http://localhost:5291/` + - Click **Register**. +3. Copy the **Application (client) ID**. This is used for `ServiceControl/Authentication.ServicePulse.ClientId`. +4. Select **Manage** > **API permissions**. +5. Click **+ Add a permission**. +6. Select the **APIs my organization uses** tab. +7. Search for and select **ServiceControl API**. +8. Under **Delegated permissions**, enable **api.access**. +9. Click **Add permissions**. + +## Configure ServiceControl + +Add the Entra ID application details to the ServiceControl configuration to enable authentication. + +### Using App.config + +Add the following settings to the ServiceControl configuration file: + +```xml + + + + + + + + +``` + +Replace the placeholder values with the values copied from the Entra ID app registrations: + +| Placeholder | Value | +|-------------|-------| +| `{tenant-id}` | The directory (tenant) ID from the app registration overview | +| `{app-id}` | The Application ID URI from the ServiceControl API registration | +| `{client-id}` | The Application (client) ID from the ServicePulse registration | + +### Using environment variables + +Environment variables can be used instead of App.config, which is useful for containerized deployments and local development. Convert setting names by replacing `/` and `.` with `_`. + +| App.config key | Environment variable | +|----------------|---------------------| +| `ServiceControl/Authentication.Enabled` | `SERVICECONTROL_AUTHENTICATION_ENABLED` | +| `ServiceControl/Authentication.Authority` | `SERVICECONTROL_AUTHENTICATION_AUTHORITY` | +| `ServiceControl/Authentication.Audience` | `SERVICECONTROL_AUTHENTICATION_AUDIENCE` | +| `ServiceControl/Authentication.ServicePulse.ClientId` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | +| `ServiceControl/Authentication.ServicePulse.Authority` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | +| `ServiceControl/Authentication.ServicePulse.ApiScopes` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | + +Environment variables take precedence over App.config settings. + +```powershell +# Enable authentication +$env:SERVICECONTROL_AUTHENTICATION_ENABLED = "true" +$env:SERVICECONTROL_AUTHENTICATION_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}" +$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "api://{app-id}" + +# ServicePulse settings +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID = "{client-id}" +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}/v2.0" +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["api://{app-id}/api.access"]' +``` + +Once configured, ServiceControl enforces authentication and ServicePulse requires users to sign in through Microsoft Entra ID. + From 503880014a15b2f138f63d19d16c60e7c7f9e9c7 Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Thu, 11 Dec 2025 14:57:34 +1000 Subject: [PATCH 04/27] Added Hosting and Security Guide --- menu/menu.yaml | 2 + servicecontrol/security/hosting-guide.md | 373 +++++++++++++++++++++++ 2 files changed, 375 insertions(+) create mode 100644 servicecontrol/security/hosting-guide.md diff --git a/menu/menu.yaml b/menu/menu.yaml index a233ffc898f..86233d1db3c 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1485,6 +1485,8 @@ Articles: - Title: ServiceControl security Url: servicecontrol/security + - Title: Hosting guide + Url: servicecontrol/security/hosting-guide - Title: Configuration Url: servicecontrol/security/configuration - Title: Microsoft Entra ID authentication diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md new file mode 100644 index 00000000000..f1407f36625 --- /dev/null +++ b/servicecontrol/security/hosting-guide.md @@ -0,0 +1,373 @@ +--- +title: Hosting and Security Guide +summary: Hosting and security options for ServiceControl instances +reviewed: 2025-12-11 +component: ServiceControl +--- + +This guide covers all hosting and security options available for ServiceControl, ServiceControl.Audit, and ServiceControl.Monitoring instances. + +## Configuration Settings by Instance + +Each ServiceControl instance uses a different configuration prefix: + +| Instance | Configuration Prefix | Default Port | +|----------|---------------------|--------------| +| ServiceControl (Primary) | `ServiceControl/` | 33333 | +| ServiceControl.Audit | `ServiceControl.Audit/` | 44444 | +| ServiceControl.Monitoring | `Monitoring/` | 33633 | + +Settings can be configured via: + +- App.config / Web.config files +- Windows Registry (legacy) + +--- + +## 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 + +### Scenario 1: Default 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 | + +```xml + + + + + +``` + +Or explicitly: + +```xml + + + + + + + +``` + +--- + +### Scenario 2: Reverse Proxy with SSL Termination + +ServiceControl behind a reverse proxy (nginx, IIS, cloud load balancer) that handles SSL/TLS termination. + +**Security Features:** + +| Feature | Status | +|---------|--------| +| JWT Authentication | ❌ Disabled | +| Kestrel HTTPS | ❌ Disabled (handled by proxy) | +| HTTPS Redirection | ❌ Disabled (handled by proxy) | +| HSTS | ❌ Disabled (handled by proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | + +```xml + + + + + + + + + + + + +``` + +--- + +### Scenario 3: Direct HTTPS (No Reverse Proxy) + +Kestrel handles TLS directly without a reverse proxy. + +**Security Features:** + +| Feature | Status | +|---------|--------| +| JWT Authentication | ❌ Disabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | ✅ Enabled | +| HSTS | ✅ Enabled | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ❌ Disabled (no proxy) | +| Restricted Proxy Trust | N/A | + +```xml + + + + + + + + + + + + + + + + + + + +``` + +--- + +### Scenario 4: Reverse Proxy with Authentication + +Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). + +**Security Features:** + +| Feature | Status | +|---------|--------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ❌ Disabled (handled by proxy) | +| HTTPS Redirection | ❌ Disabled (handled by proxy) | +| HSTS | ❌ Disabled (handled by proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +> **Note:** The token validation settings (`ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, `ValidateIssuerSigningKey`, `RequireHttpsMetadata`) all default to `true`. + +--- + +### Scenario 5: Direct HTTPS with Authentication + +Kestrel handles TLS directly with JWT authentication. No reverse proxy. + +**Security Features:** + +| Feature | Status | +|---------|--------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | ✅ Enabled | +| HSTS | ✅ Enabled | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ❌ Disabled (no proxy) | +| Restricted Proxy Trust | N/A | + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +--- + +### Scenario 6: End-to-End Encryption with Reverse Proxy and Authentication + +End-to-end TLS encryption where the reverse proxy terminates external TLS and re-encrypts traffic to ServiceControl over HTTPS. Includes JWT authentication. + +**Security Features:** + +| Feature | Status | +|---------|--------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | ❌ Disabled (handled by proxy) | +| HSTS | ❌ Disabled (handled by proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +--- + +## Configuration Reference + +### Authentication Settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `Authentication.Enabled` | bool | `false` | Enable JWT Bearer authentication | +| `Authentication.Authority` | string | - | OpenID Connect authority URL (required when enabled) | +| `Authentication.Audience` | string | - | Expected audience for tokens (required when enabled) | +| `Authentication.ValidateIssuer` | bool | `true` | Validate token issuer | +| `Authentication.ValidateAudience` | bool | `true` | Validate token audience | +| `Authentication.ValidateLifetime` | bool | `true` | Validate token expiration | +| `Authentication.ValidateIssuerSigningKey` | bool | `true` | Validate token signing key | +| `Authentication.RequireHttpsMetadata` | bool | `true` | Require HTTPS for metadata endpoint | +| `Authentication.ServicePulse.ClientId` | string | - | OAuth client ID for ServicePulse | +| `Authentication.ServicePulse.Authority` | string | - | Authority URL for ServicePulse (defaults to main Authority) | +| `Authentication.ServicePulse.ApiScopes` | string | - | API scopes for ServicePulse to request | + +### HTTPS Settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `Https.Enabled` | bool | `false` | Enable Kestrel HTTPS with certificate | +| `Https.CertificatePath` | string | - | Path to PFX/PEM certificate file | +| `Https.CertificatePassword` | string | - | Certificate password (if required) | +| `Https.RedirectHttpToHttps` | bool | `false` | Redirect HTTP requests to HTTPS | +| `Https.EnableHsts` | bool | `false` | Enable HTTP Strict Transport Security | +| `Https.HstsMaxAgeSeconds` | int | `31536000` | HSTS max-age in seconds (1 year) | +| `Https.HstsIncludeSubDomains` | bool | `false` | Include subdomains in HSTS | + +### Forwarded Headers Settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `ForwardedHeaders.Enabled` | bool | `true` | Enable forwarded headers processing | +| `ForwardedHeaders.TrustAllProxies` | bool | `true` | Trust X-Forwarded-* from any source | +| `ForwardedHeaders.KnownProxies` | string | - | Comma-separated list of trusted proxy IPs | +| `ForwardedHeaders.KnownNetworks` | string | - | Comma-separated list of trusted CIDR networks | + +> **Note:** If `KnownProxies` or `KnownNetworks` are configured, `TrustAllProxies` is automatically set to `false`. + +### CORS Settings + +| Setting | Type | Default | Description | +|---------|------|---------|-------------| +| `Cors.AllowAnyOrigin` | bool | `true` | Allow requests from any origin | +| `Cors.AllowedOrigins` | string | - | Comma-separated list of allowed origins | + +> **Note:** If `AllowedOrigins` is configured, `AllowAnyOrigin` is automatically set to `false`. + +--- + +## Scenario Comparison Matrix + +| Feature | Default | Reverse Proxy (SSL Termination) | Direct HTTPS | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption + Auth | +|---------|:-------:|:-------------------------------:|:------------:|:--------------------:|:-------------------:|:----------------------------:| +| **JWT Authentication** | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | +| **Direct (Kestrel) HTTPS** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | +| **HTTPS Redirection** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | +| **HSTS** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | +| **Restricted CORS** | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | +| **Forwarded Headers** | ✅ | ✅ | ❌ | ✅ | ❌ (Not needed. No Reverse Proxy) | ✅ | +| **Restricted Proxy Trust** | ❌ | ✅ | N/A | ✅ | N/A | ✅ | +| | | | | | | | +| **Reverse Proxy** | Optional | Yes | No | Yes | No | Yes | +| **Internal Traffic Encrypted** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | + +**Legend:** + +- ✅ = Enabled +- ❌ = Disabled +- N/A = Not Applicable \ No newline at end of file From ed928bb071b9b850629fd0cf196ba401dfc0fc6f Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Fri, 12 Dec 2025 08:27:40 +1000 Subject: [PATCH 05/27] Add authentication configuration for ServiceControl instances --- .../audit-instances/configuration.md | 135 ++++++++++++ .../monitoring-instances/configuration.md | 135 ++++++++++++ .../servicecontrol-instances/configuration.md | 202 ++++++++++++++++++ 3 files changed, 472 insertions(+) diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index fedd9f4475d..ab7c98bce17 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -153,6 +153,141 @@ Run [ServiceControl audit instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | boolean | `False` | +## Authentication + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). + +### ServiceControl.Audit/Authentication.Enabled + +_Added in version 6.9.0_ + +Enables or disables authentication. + +| 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.9.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.9.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.9.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.9.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.9.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.9.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.9.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. + ## 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..9f74fb76618 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -93,6 +93,141 @@ 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 + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). + +### Monitoring/Authentication.Enabled + +_Added in version 6.9.0_ + +Enables or disables authentication. + +| 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.9.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.9.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.9.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.9.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.9.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.9.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.9.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. + ## Logging ### Monitoring/LogPath diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 9a182f2586c..5ed76af1b91 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -175,6 +175,208 @@ Run [ServiceControl error instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | bool | False | +## Authentication + +These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). + +### ServiceControl/Authentication.Enabled + +_Added in version 6.9.0_ + +Enables or disables authentication. + +| 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.9.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.9.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 | + +### ServiceControl/Authentication.ValidateIssuer + +_Added in version 6.9.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.9.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.9.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.9.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.9.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.9.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.9.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.Audience + +_Added in version 6.9.0_ + +The audience value for ServicePulse to include when requesting tokens. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE` | +| **App config key** | `ServiceControl/Authentication.ServicePulse.Audience` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +### ServiceControl/Authentication.ServicePulse.ApiScopes + +_Added in version 6.9.0_ + +The API scopes for ServicePulse to request when authenticating. This is a JSON array of scope strings. + +| 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 | + +Example: `["api://12345678-90ab-cdef-1234-567890abcdef/api.access"]` +> **Note:** Replace the above Application ID URI with your actual Application (client) ID. + ## Embedded database These settings are not valid for ServiceControl instances hosted in a container. From 872a50a101c86f26f47104eb9f10fdadbad8adc5 Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Fri, 12 Dec 2025 09:43:54 +1000 Subject: [PATCH 06/27] Update HTTPS and forwarded headers documentation for ServiceControl instances --- .../audit-instances/configuration.md | 232 ++++++++++++++++++ .../monitoring-instances/configuration.md | 232 ++++++++++++++++++ .../servicecontrol-instances/configuration.md | 232 ++++++++++++++++++ 3 files changed, 696 insertions(+) diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index ab7c98bce17..1a514487305 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -288,6 +288,238 @@ Controls whether HTTPS is required when retrieving metadata from the authority. > [!WARNING] > Setting this to `false` is not recommended for production environments. +## HTTPS + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl.Audit/Https.Enabled + +_Added in version 6.9.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.9.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.9.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.9.0_ + +Redirects HTTP requests to HTTPS. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `ServiceControl.Audit/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl.Audit/Https.EnableHsts + +_Added in version 6.9.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` | + +### ServiceControl.Audit/Https.HstsMaxAgeSeconds + +_Added in version 6.9.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.9.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 + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl.Audit/ForwardedHeaders.Enabled + +_Added in version 6.9.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.9.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.9.0_ + +A comma-separated list of trusted proxy IP addresses. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `127.0.0.1` + +### ServiceControl.Audit/ForwardedHeaders.KnownNetworks + +_Added in version 6.9.0_ + +A comma-separated list of trusted CIDR network ranges. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `ServiceControl.Audit/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `10.0.0.0/8,172.16.0.0/12` + +## CORS + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl.Audit/Cors.AllowAnyOrigin + +_Added in version 6.9.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.9.0_ + +A comma-separated list of allowed origins. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_AUDIT_CORS_ALLOWEDORIGINS` | +| **App config key** | `ServiceControl.Audit/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `https://servicepulse.example.com,https://admin.example.com` + ## 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 9f74fb76618..58e2a8283ba 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -228,6 +228,238 @@ Controls whether HTTPS is required when retrieving metadata from the authority. > [!WARNING] > Setting this to `false` is not recommended for production environments. +## HTTPS + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### Monitoring/Https.Enabled + +_Added in version 6.9.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.9.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.9.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.9.0_ + +Redirects HTTP requests to HTTPS. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `Monitoring/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### Monitoring/Https.EnableHsts + +_Added in version 6.9.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` | + +### Monitoring/Https.HstsMaxAgeSeconds + +_Added in version 6.9.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.9.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 + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### Monitoring/ForwardedHeaders.Enabled + +_Added in version 6.9.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.9.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.9.0_ + +A comma-separated list of trusted proxy IP addresses. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `Monitoring/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `127.0.0.1` + +### Monitoring/ForwardedHeaders.KnownNetworks + +_Added in version 6.9.0_ + +A comma-separated list of trusted CIDR network ranges. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `Monitoring/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `10.0.0.0/8,172.16.0.0/12` + +## CORS + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### Monitoring/Cors.AllowAnyOrigin + +_Added in version 6.9.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.9.0_ + +A comma-separated list of allowed origins. + +| Context | Name | +| --- | --- | +| **Environment variable** | `MONITORING_CORS_ALLOWEDORIGINS` | +| **App config key** | `Monitoring/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `https://servicepulse.example.com,https://admin.example.com` + ## Logging ### Monitoring/LogPath diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 5ed76af1b91..6b96482bb34 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -377,6 +377,238 @@ The API scopes for ServicePulse to request when authenticating. This is a JSON a Example: `["api://12345678-90ab-cdef-1234-567890abcdef/api.access"]` > **Note:** Replace the above Application ID URI with your actual Application (client) ID. +## HTTPS + +These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl/Https.Enabled + +_Added in version 6.9.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.9.0_ + +The path to the PFX or PEM certificate file. + +| 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.9.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.9.0_ + +Redirects HTTP requests to HTTPS. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_HTTPS_REDIRECTHTTPTOHTTPS` | +| **App config key** | `ServiceControl/Https.RedirectHttpToHttps` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| bool | `false` | + +### ServiceControl/Https.EnableHsts + +_Added in version 6.9.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` | + +### ServiceControl/Https.HstsMaxAgeSeconds + +_Added in version 6.9.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.9.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 + +These settings configure forwarded headers for reverse proxy scenarios. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl/ForwardedHeaders.Enabled + +_Added in version 6.9.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.9.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.9.0_ + +A comma-separated list of trusted proxy IP addresses. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_KNOWNPROXIES` | +| **App config key** | `ServiceControl/ForwardedHeaders.KnownProxies` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `10.0.0.5,10.0.0.6` + +### ServiceControl/ForwardedHeaders.KnownNetworks + +_Added in version 6.9.0_ + +A comma-separated list of trusted CIDR network ranges. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_FORWARDEDHEADERS_KNOWNNETWORKS` | +| **App config key** | `ServiceControl/ForwardedHeaders.KnownNetworks` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `10.0.0.0/24,192.168.1.0/24` + +## CORS + +These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. + +### ServiceControl/Cors.AllowAnyOrigin + +_Added in version 6.9.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.9.0_ + +A comma-separated list of allowed origins. + +| Context | Name | +| --- | --- | +| **Environment variable** | `SERVICECONTROL_CORS_ALLOWEDORIGINS` | +| **App config key** | `ServiceControl/Cors.AllowedOrigins` | +| **SCMU field** | N/A | + +| Type | Default value | +| --- | --- | +| string | None | + +Example: `https://servicepulse.yourcompany.com,https://admin.yourcompany.com` + ## Embedded database These settings are not valid for ServiceControl instances hosted in a container. From fa1a9835ca11a83342af6c37e2cfeabeead03cae Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Fri, 12 Dec 2025 10:29:49 +1000 Subject: [PATCH 07/27] Add TLS requirements --- servicecontrol/security/index.md | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index ba999af529a..f75d3979cfe 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -24,6 +24,20 @@ Any OpenID Connect (OIDC) compliant identity provider can be used, including: - Okta - Ping Identity -## Configuration +## Enabling authentication Each ServiceControl instance must be configured separately to enable authentication. Configuration is applied by editing the instance's App.config file or by setting environment variables. ServicePulse retrieves these settings automatically from the connected ServiceControl instances, so no separate configuration is required. Read the [configuring authentication](configuration.md) guide for more details. + +## Transport Layer Security (TLS) + +When authentication is enabled, ServiceControl and ServicePulse rely on OAuth 2.0 and OpenID Connect flows that involve exchanging access tokens. To protect these tokens and other sensitive data, **TLS must be enabled on every ServiceControl instance and on any reverse proxy in front of it**. + +> [!IMPORTANT] +> Without TLS, tokens and other sensitive information are transmitted in clear text. This exposes the system to interception, session hijacking, and unauthorized access. Always secure ServiceControl with HTTPS in production environments. + +ServiceControl supports TLS termination at either: + +- **Kestrel**: Configure HTTPS directly on the ServiceControl instance +- **A reverse proxy**: Such as NGINX, Apache, IIS, or Azure App Gateway + +See the [hosting and security guide](hosting-guide.md) for detailed configuration options including HTTPS certificates, HSTS, and reverse proxy settings. From 242078f1d9af0538f90f1fa9c507263a9be42d1d Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Fri, 12 Dec 2025 10:39:56 +1000 Subject: [PATCH 08/27] Add ServiceInsight compatibility notes --- servicecontrol/security/index.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index f75d3979cfe..87955ef8771 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -41,3 +41,14 @@ ServiceControl supports TLS termination at either: - **A reverse proxy**: Such as NGINX, Apache, IIS, or Azure App Gateway See the [hosting and security guide](hosting-guide.md) for detailed configuration options including HTTPS certificates, HSTS, and reverse proxy settings. + +## ServiceInsight compatibility + +ServiceInsight does not support OAuth 2.0 or OpenID Connect authentication. If authentication is enabled on a ServiceControl instance, **ServiceInsight will not be able to connect**. + +Users relying on ServiceInsight have two options: + +1. **Do not enable authentication** on the relevant ServiceControl instance, or +2. **Use ServicePulse instead of ServiceInsight**. + +The second option is recommended, as the functionality previously available in ServiceInsight has been migrated to ServicePulse. \ No newline at end of file From 3485520633081e95cf81cf7363f75b857463045e Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Fri, 12 Dec 2025 16:08:15 +1000 Subject: [PATCH 09/27] Enhance Entra ID authentication guide with detailed app registration steps and configuration examples --- .../security/entra-id-authentication.md | 113 ++++++++++++------ 1 file changed, 75 insertions(+), 38 deletions(-) diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md index af2a086e52c..d92dd0543c4 100644 --- a/servicecontrol/security/entra-id-authentication.md +++ b/servicecontrol/security/entra-id-authentication.md @@ -7,52 +7,83 @@ component: ServiceControl This guide explains how to configure Microsoft Entra ID (formerly Azure Active Directory) and ServiceControl to enable authentication for ServicePulse. +## Prerequisites + +- Administrator permissions on the Microsoft Entra ID tenant +- ServiceControl 6.9.0 or later +- ServicePulse 2.5.0 or later + ## Configure Microsoft Entra ID Register ServiceControl and ServicePulse as applications in Microsoft Entra ID to allow users to authenticate. ### Create the ServiceControl app registration +This app registration represents the ServiceControl API and defines the permissions that ServicePulse will request when users sign in. + 1. Navigate to the [Azure Portal](https://portal.azure.com/). 2. Open **Microsoft Entra ID** and select **Manage** > **App registrations**. 3. Click **+ New registration**. 4. Configure the registration: - **Name**: `ServiceControl API` - - **Supported account types**: Accounts in this organizational directory only + - **Supported account types**: Accounts in this organizational directory only (single tenant) - Click **Register**. -5. On the **Overview** page, click **Endpoints** and copy the **OpenID Connect metadata document** URL (remove `/.well-known/openid-configuration` from the end). This is the authority URL used for `ServiceControl/Authentication.Authority`. + +> [!NOTE] +> Select **Accounts in any organizational directory** (multi-tenant) if users from multiple Entra ID tenants need access to ServicePulse. + +5. On the **Overview** page, copy the **Directory (tenant) ID**. This is used to construct the authority URLs. 6. Select **Manage** > **Expose an API**. -7. Next to **Application ID URI**, click **Add** and save the default value. -8. Under **Scopes defined by this API**, click **Add a scope** and configure: +7. Next to **Application ID URI**, click **Add** and save the default value (e.g., `api://{application-id}`). +8. Copy the **Application ID URI**. This is used for `ServiceControl/Authentication.Audience`. +9. Under **Scopes defined by this API**, click **Add a scope** and configure: - **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` - **State**: Enabled - Click **Add scope**. -9. Copy the **Application ID URI**. This is used for `ServiceControl/Authentication.Audience` and as part of `ServiceControl/Authentication.ServicePulse.ApiScopes`. ### Create the ServicePulse app registration +This app registration represents ServicePulse as a client application that users will sign into. + 1. In **App registrations**, click **+ New registration**. 2. Configure the registration: - **Name**: `ServicePulse` - - **Supported account types**: Accounts in this organizational directory only + - **Supported account types**: Accounts in this organizational directory only (single tenant) - **Redirect URI**: - **Platform**: Single-page application (SPA) - - **URI**: `http://localhost:5291/` + - **URI**: The URL where ServicePulse is hosted (e.g., `https://servicepulse.example.com/`) - Click **Register**. + +> [!WARNING] +> Redirect URIs must use HTTPS in production environments. HTTP is only acceptable for local development (e.g., `http://localhost:9090/`). + 3. Copy the **Application (client) ID**. This is used for `ServiceControl/Authentication.ServicePulse.ClientId`. 4. Select **Manage** > **API permissions**. 5. Click **+ Add a permission**. 6. Select the **APIs my organization uses** tab. -7. Search for and select **ServiceControl API**. -8. Under **Delegated permissions**, enable **api.access**. +7. Select **ServiceControl API**. +8. Under **Delegated permissions**, check **api.access**. 9. Click **Add permissions**. +> [!NOTE] +> If ServicePulse is accessed from multiple URLs (e.g., localhost during development and a production URL), add each URL as a redirect URI in the ServicePulse app registration under **Manage** > **Authentication**. + ## Configure ServiceControl -Add the Entra ID application details to the ServiceControl configuration to enable authentication. +Add the Entra ID application details to the ServiceControl Error instance configuration to enable authentication. The same settings apply to Audit and Monitoring instances, using their respective prefixes. + +### Collected values + +During the Entra ID configuration, the following values should have been collected: + +| Value | Source | Used for | +|-------|--------|----------| +| Directory (tenant) ID | ServiceControl API app registration > Overview | Authority URLs | +| Application ID URI | ServiceControl API app registration > Expose an API | `Authentication.Audience` and `Authentication.ServicePulse.ApiScopes` | +| Application (client) ID | ServicePulse app registration > Overview | `Authentication.ServicePulse.ClientId` | ### Using App.config @@ -60,49 +91,55 @@ Add the following settings to the ServiceControl configuration file: ```xml - - - + - + ``` -Replace the placeholder values with the values copied from the Entra ID app registrations: +Replace the placeholder values: -| Placeholder | Value | -|-------------|-------| -| `{tenant-id}` | The directory (tenant) ID from the app registration overview | -| `{app-id}` | The Application ID URI from the ServiceControl API registration | -| `{client-id}` | The Application (client) ID from the ServicePulse registration | +| Placeholder | Example value | +|-------------|---------------| +| `{tenant-id}` | `a1b2c3d4-e5f6-7890-abcd-ef1234567890` | +| `{application-id-uri}` | `api://a1b2c3d4-e5f6-7890-abcd-ef1234567890` | +| `{client-id}` | `f9e8d7c6-b5a4-3210-fedc-ba0987654321` | ### Using environment variables -Environment variables can be used instead of App.config, which is useful for containerized deployments and local development. Convert setting names by replacing `/` and `.` with `_`. - -| App.config key | Environment variable | -|----------------|---------------------| -| `ServiceControl/Authentication.Enabled` | `SERVICECONTROL_AUTHENTICATION_ENABLED` | -| `ServiceControl/Authentication.Authority` | `SERVICECONTROL_AUTHENTICATION_AUTHORITY` | -| `ServiceControl/Authentication.Audience` | `SERVICECONTROL_AUTHENTICATION_AUDIENCE` | -| `ServiceControl/Authentication.ServicePulse.ClientId` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | -| `ServiceControl/Authentication.ServicePulse.Authority` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | -| `ServiceControl/Authentication.ServicePulse.ApiScopes` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | - -Environment variables take precedence over App.config settings. +Environment variables can be used instead of App.config, which is useful for containerized deployments. Environment variables take precedence over App.config settings. ```powershell -# Enable authentication $env:SERVICECONTROL_AUTHENTICATION_ENABLED = "true" $env:SERVICECONTROL_AUTHENTICATION_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}" -$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "api://{app-id}" - -# ServicePulse settings +$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "{application-id-uri}" $env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID = "{client-id}" $env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}/v2.0" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["api://{app-id}/api.access"]' +$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["{application-id-uri}/api.access"]' +``` + +### Audit and Monitoring instances + +To enable authentication on Audit and Monitoring instances, configure the same settings using their respective prefixes. Only the base authentication settings are required; the ServicePulse settings are only needed on the Error instance. + +**Audit instance:** + +```xml + + + ``` -Once configured, ServiceControl enforces authentication and ServicePulse requires users to sign in through Microsoft Entra ID. +**Monitoring instance:** + +```xml + + + +``` + +## Verify the configuration + +Once configured, restart the ServiceControl instances. When accessing ServicePulse, users will be redirected to Microsoft Entra ID to sign in. From 604ff09003a71e4a59586a0e14f7284e6645b8f8 Mon Sep 17 00:00:00 2001 From: jasontaylordev Date: Thu, 8 Jan 2026 16:36:43 +1000 Subject: [PATCH 10/27] Doc update --- servicecontrol/security/hosting-guide.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md index f1407f36625..12222f7ad4c 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -17,10 +17,7 @@ Each ServiceControl instance uses a different configuration prefix: | ServiceControl.Audit | `ServiceControl.Audit/` | 44444 | | ServiceControl.Monitoring | `Monitoring/` | 33633 | -Settings can be configured via: - -- App.config / Web.config files -- Windows Registry (legacy) +Settings can be configured via App.config files or using environment variables. --- @@ -190,7 +187,8 @@ Reverse proxy with SSL termination and JWT authentication via an identity provid ``` -> **Note:** The token validation settings (`ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, `ValidateIssuerSigningKey`, `RequireHttpsMetadata`) all default to `true`. +> [!NOTE] +> The token validation settings (`ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, `ValidateIssuerSigningKey`, `RequireHttpsMetadata`) all default to `true`. --- From 72cbb1141b63fd6c62742045036ce6e021b5de09 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Mon, 12 Jan 2026 15:56:49 +0800 Subject: [PATCH 11/27] Restructure and add additional ServiceControl security details --- menu/menu.yaml | 19 +- servicecontrol/security/configuration.md | 157 ---------- .../security/configuration/authentication.md | 105 +++++++ .../security/configuration/forward-headers.md | 72 +++++ .../security/configuration/https.md | 59 ++++ .../security/configuration/index.md | 8 + .../servicecontrol-instance-prefix.include.md | 8 + servicecontrol/security/hosting-guide.md | 290 +++++++----------- servicecontrol/security/index.md | 33 +- 9 files changed, 397 insertions(+), 354 deletions(-) delete mode 100644 servicecontrol/security/configuration.md create mode 100644 servicecontrol/security/configuration/authentication.md create mode 100644 servicecontrol/security/configuration/forward-headers.md create mode 100644 servicecontrol/security/configuration/https.md create mode 100644 servicecontrol/security/configuration/index.md create mode 100644 servicecontrol/security/configuration/servicecontrol-instance-prefix.include.md diff --git a/menu/menu.yaml b/menu/menu.yaml index 86233d1db3c..2ddd0a52c43 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1483,14 +1483,23 @@ Url: servicecontrol/upgrades/1to2 - Title: Security Articles: - - Title: ServiceControl security + - Title: Overview Url: servicecontrol/security - - Title: Hosting guide - Url: servicecontrol/security/hosting-guide - Title: Configuration Url: servicecontrol/security/configuration - - Title: Microsoft Entra ID authentication - Url: servicecontrol/security/entra-id-authentication + Articles: + - Title: Authentication + Url: servicecontrol/security/configuration/authentication + - Title: Forward Headers + Url: servicecontrol/security/configuration/forward-headers + - Title: HTTPS + Url: servicecontrol/security/configuration/https + - Title: Hosting guide + Url: servicecontrol/security/hosting-guide + - Title: Examples + Articles: + - Title: Microsoft Entra ID authentication + Url: servicecontrol/security/entra-id-authentication - Title: Planning Articles: - Title: Optimizing for use in different environments diff --git a/servicecontrol/security/configuration.md b/servicecontrol/security/configuration.md deleted file mode 100644 index 3560b03b874..00000000000 --- a/servicecontrol/security/configuration.md +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: Configuring authentication -summary: How to enable and configure authentication for ServiceControl and ServicePulse -reviewed: 2025-12-11 -component: ServiceControl ---- - -This guide explains how to configure ServiceControl to enable authentication. - -## Enabling authentication - -Authentication is disabled by default. To enable it, add the following settings to the ServiceControl configuration file: - -```xml - - - -``` - -## ServiceControl settings - -These settings control how ServiceControl validates incoming JWT access tokens. - -| Setting | Description | -|---------|-------------| -| `ServiceControl/Authentication.Enabled` | Set to `true` to enable authentication. Default: `false` | -| `ServiceControl/Authentication.Authority` | The OpenID Connect authority URL used to validate tokens. This is typically the issuer URL of the identity provider. | -| `ServiceControl/Authentication.Audience` | The expected audience claim in the access token. This is typically the Application ID URI of the ServiceControl API registration. | - -### Token validation settings - -These optional settings control specific aspects of token validation. The defaults are secure and should not be changed unless there is a specific requirement. - -| Setting | Default | Description | -|---------|---------|-------------| -| `ServiceControl/Authentication.ValidateIssuer` | `true` | Validates that the token was issued by the configured authority. | -| `ServiceControl/Authentication.ValidateAudience` | `true` | Validates that the token contains the expected audience claim. | -| `ServiceControl/Authentication.ValidateLifetime` | `true` | Validates that the token has not expired. | -| `ServiceControl/Authentication.ValidateIssuerSigningKey` | `true` | Validates the token signature using keys from the identity provider. | -| `ServiceControl/Authentication.RequireHttpsMetadata` | `true` | Requires HTTPS when retrieving OpenID Connect metadata. Set to `false` only for local development. | - -## ServicePulse settings - -These settings are served to ServicePulse through a bootstrap endpoint, allowing ServicePulse to authenticate users without its own configuration file. - -| Setting | Description | -|---------|-------------| -| `ServiceControl/Authentication.ServicePulse.ClientId` | The OAuth 2.0 client ID for the ServicePulse application registration. | -| `ServiceControl/Authentication.ServicePulse.Authority` | The OpenID Connect authority URL for ServicePulse authentication. For Microsoft Entra ID, this typically includes `/v2.0` at the end. | -| `ServiceControl/Authentication.ServicePulse.Audience` | The audience for ServicePulse token requests. This is typically the same as the ServiceControl audience. | -| `ServiceControl/Authentication.ServicePulse.ApiScopes` | A JSON array of scopes to request when acquiring tokens. For example: `["api://app-id/api.access"]` | - -## Configuration file example - -The following example shows a complete authentication configuration for Microsoft Entra ID: - -```xml - - - - - - - - - - - - -``` - -## Environment variables - -All settings can also be configured using environment variables, which is useful for containerized deployments and local development. Convert setting names to environment variables by replacing `/` and `.` with `_`. - -| App.config key | Environment variable | -|----------------|---------------------| -| `ServiceControl/Authentication.Enabled` | `SERVICECONTROL_AUTHENTICATION_ENABLED` | -| `ServiceControl/Authentication.Authority` | `SERVICECONTROL_AUTHENTICATION_AUTHORITY` | -| `ServiceControl/Authentication.Audience` | `SERVICECONTROL_AUTHENTICATION_AUDIENCE` | -| `ServiceControl/Authentication.ServicePulse.ClientId` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | -| `ServiceControl/Authentication.ServicePulse.Authority` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | -| `ServiceControl/Authentication.ServicePulse.Audience` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE` | -| `ServiceControl/Authentication.ServicePulse.ApiScopes` | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | - -Environment variables take precedence over App.config settings. - -### Environment variable example - -```powershell -# Enable authentication -$env:SERVICECONTROL_AUTHENTICATION_ENABLED = "true" -$env:SERVICECONTROL_AUTHENTICATION_AUTHORITY = "https://login.microsoftonline.com/your-tenant-id" -$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "api://your-app-id" - -# ServicePulse settings -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID = "your-servicepulse-client-id" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY = "https://login.microsoftonline.com/your-tenant-id/v2.0" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE = "api://your-app-id" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["api://your-app-id/api.access"]' -``` - - -## 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. - -### Microsoft Entra ID - -```xml - - - - - - - - - - -``` - -### Auth0 - -```xml - - - - - - - - - - -``` - -### Keycloak - -```xml - - - - - - - - - - -``` diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md new file mode 100644 index 00000000000..e4dc6cdab60 --- /dev/null +++ b/servicecontrol/security/configuration/authentication.md @@ -0,0 +1,105 @@ +--- +title: Authentication Configuration +summary: How to enable and configure authentication for ServiceControl and ServicePulse +reviewed: 2026-01-12 +component: ServiceControl +--- + +ServiceControl instances can be configured to require JWT authentication using OpenID Connect (OIDC). 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 conjustion with [Forward Header](forward-headers.md) and [HTTPS](https.md) configuration settings in a scenario based format. + +include: servicecontrol-instance-prefix + +### Core Settings + +| Environment Variable | App.config | Default | Description | +|-------------------------------------|-------------------------------------|---------|-------------------------------------------------------------------------------------------| +| `{PREFIX}_AUTHENTICATION_ENABLED` | `{PREFIX}/Authentication.Enabled` | `false` | Enable JWT authentication | +| `{PREFIX}_AUTHENTICATION_AUTHORITY` | `{PREFIX}/Authentication.Authority` | (none) | OpenID Connect authority URL (e.g., `https://login.microsoftonline.com/{tenant-id}/v2.0`) | +| `{PREFIX}_AUTHENTICATION_AUDIENCE` | `{PREFIX}/Authentication.Audience` | (none) | The audience identifier (typically your API identifier or client ID, e.g., `api://servicecontrol`) | + +### Token Validation Settings + +These settings control specific aspects of token validation. The defaults below provide a secure validation process and should not be changed unless there is a specific requirement. + +| Environment Variable | App.config | Default | Description | +|----------------------------------------------------|----------------------------------------------------|---------|----------------------------------------------------------------------------------------------------| +| `{PREFIX}_AUTHENTICATION_VALIDATEISSUER` | `{PREFIX}/Authentication.ValidateIssuer` | `true` | Validates that the token was issued by the configured authority. | +| `{PREFIX}_AUTHENTICATION_VALIDATEAUDIENCE` | `{PREFIX}/Authentication.ValidateAudience` | `true` | Validates that the token contains the expected audience claim. | +| `{PREFIX}_AUTHENTICATION_VALIDATELIFETIME` | `{PREFIX}/Authentication.ValidateLifetime` | `true` | Validates that the token has not expired. | +| `{PREFIX}_AUTHENTICATION_VALIDATEISSUERSIGNINGKEY` | `{PREFIX}/Authentication.ValidateIssuerSigningKey` | `true` | Validates the token signature using keys from the identity provider. | +| `{PREFIX}_AUTHENTICATION_REQUIREHTTPSMETADATA` | `{PREFIX}/Authentication.RequireHttpsMetadata` | `true` | Requires HTTPS when retrieving OpenID Connect metadata. Set to `false` only for local development. | + +### ServicePulse settings + +These settings are served to ServicePulse through a bootstrap endpoint hosting in ServiceControl, allowing ServicePulse to authenticate users without its own configuration file. + +> [!NOTE] +> These settings are only valid on the primary ServiceControl instance. + +| Environment Variable | App.config | Description | +|--------------------------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| +| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | `ServiceControl/Authentication.ServicePulse.ClientId` | The OAuth 2.0 client ID for the ServicePulse application registration. | +| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | `ServiceControl/Authentication.ServicePulse.Authority` | The OpenID Connect authority URL for ServicePulse authentication. For Microsoft Entra ID, this typically includes `/v2.0` at the end. | +| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | `ServiceControl/Authentication.ServicePulse.ApiScopes` | A JSON array of scopes to request when acquiring tokens. For example: `["api://app-id/api.access"]` | + +> [!NOTE] +> The ServicePulse audience Open ID Connect configuration is automatically filled in using the [ServiceControl audience setting](#configuration-core-settings). + +## 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. + +### Microsoft Entra ID + +```xml + + + + + + + + + +``` + +### Auth0 + +```xml + + + + + + + + + +``` + +### Keycloak + +```xml + + + + + + + + + +``` diff --git a/servicecontrol/security/configuration/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md new file mode 100644 index 00000000000..49748877129 --- /dev/null +++ b/servicecontrol/security/configuration/forward-headers.md @@ -0,0 +1,72 @@ +--- +title: Forward Headers Configuration +summary: How to enable and configure forward headers for ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +--- + +When ServiceControl instances are deployed behind a reverse proxy (like NGINX, Traefik, or a cloud load balancer) that terminates SSL/TLS, 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 conjustion with [Authentication](authentication.md) and [HTTPS](https.md) configuration settings in a scenario based format. + +include: servicecontrol-instance-prefix + +### Settings + +| Environment Variable | App.config | Default | Description | +|---------------------------------------------|---------------------------------------------|---------|------------------------------------------------------------------------------| +| `{PREFIX}_FORWARDEDHEADERS_ENABLED` | `{PREFIX}/ForwardedHeaders.Enabled` | `true` | Enable forwarded headers processing | +| `{PREFIX}_FORWARDEDHEADERS_TRUSTALLPROXIES` | `{PREFIX}/ForwardedHeaders.TrustAllProxies` | `true` | Trust all proxies (auto-disabled if known proxies/networks set) | +| `{PREFIX}_FORWARDEDHEADERS_KNOWNPROXIES` | `{PREFIX}/ForwardedHeaders.KnownProxies` | (none) | Comma-separated IP addresses of trusted proxies (e.g., `127.0.0.1,10.0.0.5`) | +| `{PREFIX}_FORWARDEDHEADERS_KNOWNNETWORKS` | `{PREFIX}/ForwardedHeaders.KnownNetworks` | (none) | Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`) | + +> [!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. + +## 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 + +To enable HTTP to HTTPS redirect, see [HTTPS Configuration](https.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) diff --git a/servicecontrol/security/configuration/https.md b/servicecontrol/security/configuration/https.md new file mode 100644 index 00000000000..3792f8bff2c --- /dev/null +++ b/servicecontrol/security/configuration/https.md @@ -0,0 +1,59 @@ +--- +title: HTTPS +summary: How to enable and configure HTTPS for ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +--- + +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 in conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. + +include: servicecontrol-instance-prefix + +### Settings + +| Environment Variable | App.config | Default | Description | +|----------------------------------------|----------------------------------------------|------------|----------------------------------------------------------------| +| `{PREFIX}_HTTPS_ENABLED` | `{PREFIX}/Https.Enabled` | `false` | Enable HTTPS with Kestrel | +| `{PREFIX}_HTTPS_CERTIFICATEPATH` | `{PREFIX}/Https.CertificatePath` | (none) | Path to the certificate file (.pfx) | +| `{PREFIX}_HTTPS_CERTIFICATEPASSWORD` | `{PREFIX}/Https.CertificatePassword` | (none) | Password for the certificate file | +| `{PREFIX}_HTTPS_REDIRECTHTTPTOHTTPS` | `ServiceControl/Https.RedirectHttpToHttps` | `false` | Redirect HTTP requests to HTTPS | +| `{PREFIX}_HTTPS_PORT` | `ServiceControl/Https.Port` | (none) | HTTPS port for redirect (required for reverse proxy scenarios) | +| `{PREFIX}_HTTPS_ENABLEHSTS` | `{PREFIX}/Https.EnableHsts` | `false` | Enable HTTP Strict Transport Security | +| `{PREFIX}_HTTPS_HSTSMAXAGESECONDS` | `ServiceControl/Https.HstsMaxAgeSeconds` | `31536000` | HSTS max-age in seconds (default: 1 year) | +| `{PREFIX}_HTTPS_HSTSINCLUDESUBDOMAINS` | `ServiceControl/Https.HstsIncludeSubDomains` | `false` | Include subdomains in HSTS policy | + +## Security Considerations + +### Certificate File Security + +- Store certificate files securely with appropriate file permissions +- Rotate certificates before expiration +- Use certificates from a trusted Certificate Authority for production +- Never commit certificate files to source control +- Restrict read access to the certificate file to only the ServiceControl service account +- Use environment variables rather than App.config (environment variables are not persisted to disk) + +### HSTS Considerations + +- HSTS should not be tested on localhost because browsers cache the policy, which could break other local development +- HSTS is disabled in Development environment (ASP.NET Core excludes localhost by default) +- HSTS can be configured at either the reverse proxy level or in ServiceControl (but not both) +- HSTS is cached by browsers, so test carefully before enabling in production +- Start with a short max-age during initial deployment +- Consider the impact on subdomains before enabling `includeSubDomains` + +### 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). diff --git a/servicecontrol/security/configuration/index.md b/servicecontrol/security/configuration/index.md new file mode 100644 index 00000000000..1ff2583d2e4 --- /dev/null +++ b/servicecontrol/security/configuration/index.md @@ -0,0 +1,8 @@ +--- +title: Security Configuration +summary: How to secure ServiceControl instances +reviewed: 2026-01-12 +component: ServiceControl +--- + +TBA 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/hosting-guide.md b/servicecontrol/security/hosting-guide.md index 12222f7ad4c..58c35f9a420 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -1,25 +1,14 @@ --- title: Hosting and Security Guide summary: Hosting and security options for ServiceControl instances -reviewed: 2025-12-11 +reviewed: 2026-01-12 component: ServiceControl --- -This guide covers all hosting and security options available for ServiceControl, ServiceControl.Audit, and ServiceControl.Monitoring instances. +This guide covers hosting and security options available for ServiceControl, ServiceControl.Audit, and ServiceControl.Monitoring instances. -## Configuration Settings by Instance - -Each ServiceControl instance uses a different configuration prefix: - -| Instance | Configuration Prefix | Default Port | -|----------|---------------------|--------------| -| ServiceControl (Primary) | `ServiceControl/` | 33333 | -| ServiceControl.Audit | `ServiceControl.Audit/` | 44444 | -| ServiceControl.Monitoring | `Monitoring/` | 33633 | - -Settings can be configured via App.config files or using environment variables. - ---- +> [!NOTE] +> All scenarios assume HTTPS and authentication are required. ## Hosting Model @@ -27,25 +16,28 @@ ServiceControl runs as a standalone Windows service with Kestrel as the built-in 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 -### Scenario 1: Default Configuration +> [!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, see [Authentication](configuration/authentication.md), [HTTPS](configuration/https.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:** +#### Security Features -| Feature | Status | -|---------|--------| -| JWT Authentication | ❌ Disabled | -| Kestrel HTTPS | ❌ Disabled | -| HTTPS Redirection | ❌ Disabled | -| HSTS | ❌ Disabled | +| 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 | +| Forwarded Headers | ✅ Enabled (trusts all) | +| Restricted Proxy Trust | ❌ Disabled | ```xml @@ -67,96 +59,33 @@ Or explicitly: ``` ---- - -### Scenario 2: Reverse Proxy with SSL Termination - -ServiceControl behind a reverse proxy (nginx, IIS, cloud load balancer) that handles SSL/TLS termination. - -**Security Features:** - -| Feature | Status | -|---------|--------| -| JWT Authentication | ❌ Disabled | -| Kestrel HTTPS | ❌ Disabled (handled by proxy) | -| HTTPS Redirection | ❌ Disabled (handled by proxy) | -| HSTS | ❌ Disabled (handled by proxy) | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ✅ Enabled | -| Restricted Proxy Trust | ✅ Enabled | - -```xml - - - - - - - - - - - - -``` - ---- - -### Scenario 3: Direct HTTPS (No Reverse Proxy) +### Scenario 1: Reverse Proxy with Authentication -Kestrel handles TLS directly without a reverse proxy. - -**Security Features:** - -| Feature | Status | -|---------|--------| -| JWT Authentication | ❌ Disabled | -| Kestrel HTTPS | ✅ Enabled | -| HTTPS Redirection | ✅ Enabled | -| HSTS | ✅ Enabled | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ❌ Disabled (no proxy) | -| Restricted Proxy Trust | N/A | - -```xml - - - - - - - - - - - - +Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). - - +#### Architecture - - - +```text +Client → HTTPS → Reverse Proxy → HTTP → ServiceControl + (SSL termination) (JWT validation) ``` ---- - -### Scenario 4: Reverse Proxy with Authentication +#### Security Features -Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). +| 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 | -**Security Features:** +> [!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/https.md) used by the proxy. -| Feature | Status | -|---------|--------| -| JWT Authentication | ✅ Enabled | -| Kestrel HTTPS | ❌ Disabled (handled by proxy) | -| HTTPS Redirection | ❌ Disabled (handled by proxy) | -| HSTS | ❌ Disabled (handled by proxy) | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ✅ Enabled | -| Restricted Proxy Trust | ✅ Enabled | +#### Example Configuration ```xml @@ -175,38 +104,39 @@ Reverse proxy with SSL termination and JWT authentication via an identity provid - + - + + + - + + + + + ``` -> [!NOTE] -> The token validation settings (`ValidateIssuer`, `ValidateAudience`, `ValidateLifetime`, `ValidateIssuerSigningKey`, `RequireHttpsMetadata`) all default to `true`. - ---- - -### Scenario 5: Direct HTTPS with Authentication +### Scenario 2: Direct HTTPS with Authentication Kestrel handles TLS directly with JWT authentication. No reverse proxy. **Security Features:** -| Feature | Status | -|---------|--------| -| JWT Authentication | ✅ Enabled | -| Kestrel HTTPS | ✅ Enabled | -| HTTPS Redirection | ✅ Enabled | -| HSTS | ✅ Enabled | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ❌ Disabled (no proxy) | -| Restricted Proxy Trust | N/A | +| Feature | Status | +|-------------------------|-----------------------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | ✅ Enabled | +| HSTS | ✅ Enabled | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ❌ Disabled (no proxy) | +| Restricted Proxy Trust | N/A | ```xml @@ -249,15 +179,15 @@ End-to-end TLS encryption where the reverse proxy terminates external TLS and re **Security Features:** -| Feature | Status | -|---------|--------| -| JWT Authentication | ✅ Enabled | -| Kestrel HTTPS | ✅ Enabled | -| HTTPS Redirection | ❌ Disabled (handled by proxy) | -| HSTS | ❌ Disabled (handled by proxy) | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ✅ Enabled | -| Restricted Proxy Trust | ✅ Enabled | +| Feature | Status | +|-------------------------|-------------------------------| +| JWT Authentication | ✅ Enabled | +| Kestrel HTTPS | ✅ Enabled | +| HTTPS Redirection | ❌ Disabled (handled by proxy) | +| HSTS | ❌ Disabled (handled by proxy) | +| Restricted CORS Origins | ✅ Enabled | +| Forwarded Headers | ✅ Enabled | +| Restricted Proxy Trust | ✅ Enabled | ```xml @@ -301,49 +231,49 @@ End-to-end TLS encryption where the reverse proxy terminates external TLS and re ### Authentication Settings -| Setting | Type | Default | Description | -|---------|------|---------|-------------| -| `Authentication.Enabled` | bool | `false` | Enable JWT Bearer authentication | -| `Authentication.Authority` | string | - | OpenID Connect authority URL (required when enabled) | -| `Authentication.Audience` | string | - | Expected audience for tokens (required when enabled) | -| `Authentication.ValidateIssuer` | bool | `true` | Validate token issuer | -| `Authentication.ValidateAudience` | bool | `true` | Validate token audience | -| `Authentication.ValidateLifetime` | bool | `true` | Validate token expiration | -| `Authentication.ValidateIssuerSigningKey` | bool | `true` | Validate token signing key | -| `Authentication.RequireHttpsMetadata` | bool | `true` | Require HTTPS for metadata endpoint | -| `Authentication.ServicePulse.ClientId` | string | - | OAuth client ID for ServicePulse | -| `Authentication.ServicePulse.Authority` | string | - | Authority URL for ServicePulse (defaults to main Authority) | -| `Authentication.ServicePulse.ApiScopes` | string | - | API scopes for ServicePulse to request | +| Setting | Type | Default | Description | +|-------------------------------------------|--------|---------|-------------------------------------------------------------| +| `Authentication.Enabled` | bool | `false` | Enable JWT Bearer authentication | +| `Authentication.Authority` | string | - | OpenID Connect authority URL (required when enabled) | +| `Authentication.Audience` | string | - | Expected audience for tokens (required when enabled) | +| `Authentication.ValidateIssuer` | bool | `true` | Validate token issuer | +| `Authentication.ValidateAudience` | bool | `true` | Validate token audience | +| `Authentication.ValidateLifetime` | bool | `true` | Validate token expiration | +| `Authentication.ValidateIssuerSigningKey` | bool | `true` | Validate token signing key | +| `Authentication.RequireHttpsMetadata` | bool | `true` | Require HTTPS for metadata endpoint | +| `Authentication.ServicePulse.ClientId` | string | - | OAuth client ID for ServicePulse | +| `Authentication.ServicePulse.Authority` | string | - | Authority URL for ServicePulse (defaults to main Authority) | +| `Authentication.ServicePulse.ApiScopes` | string | - | API scopes for ServicePulse to request | ### HTTPS Settings -| Setting | Type | Default | Description | -|---------|------|---------|-------------| -| `Https.Enabled` | bool | `false` | Enable Kestrel HTTPS with certificate | -| `Https.CertificatePath` | string | - | Path to PFX/PEM certificate file | -| `Https.CertificatePassword` | string | - | Certificate password (if required) | -| `Https.RedirectHttpToHttps` | bool | `false` | Redirect HTTP requests to HTTPS | -| `Https.EnableHsts` | bool | `false` | Enable HTTP Strict Transport Security | -| `Https.HstsMaxAgeSeconds` | int | `31536000` | HSTS max-age in seconds (1 year) | -| `Https.HstsIncludeSubDomains` | bool | `false` | Include subdomains in HSTS | +| Setting | Type | Default | Description | +|-------------------------------|--------|------------|---------------------------------------| +| `Https.Enabled` | bool | `false` | Enable Kestrel HTTPS with certificate | +| `Https.CertificatePath` | string | - | Path to PFX/PEM certificate file | +| `Https.CertificatePassword` | string | - | Certificate password (if required) | +| `Https.RedirectHttpToHttps` | bool | `false` | Redirect HTTP requests to HTTPS | +| `Https.EnableHsts` | bool | `false` | Enable HTTP Strict Transport Security | +| `Https.HstsMaxAgeSeconds` | int | `31536000` | HSTS max-age in seconds (1 year) | +| `Https.HstsIncludeSubDomains` | bool | `false` | Include subdomains in HSTS | ### Forwarded Headers Settings -| Setting | Type | Default | Description | -|---------|------|---------|-------------| -| `ForwardedHeaders.Enabled` | bool | `true` | Enable forwarded headers processing | -| `ForwardedHeaders.TrustAllProxies` | bool | `true` | Trust X-Forwarded-* from any source | -| `ForwardedHeaders.KnownProxies` | string | - | Comma-separated list of trusted proxy IPs | -| `ForwardedHeaders.KnownNetworks` | string | - | Comma-separated list of trusted CIDR networks | +| Setting | Type | Default | Description | +|------------------------------------|--------|---------|-----------------------------------------------| +| `ForwardedHeaders.Enabled` | bool | `true` | Enable forwarded headers processing | +| `ForwardedHeaders.TrustAllProxies` | bool | `true` | Trust X-Forwarded-* from any source | +| `ForwardedHeaders.KnownProxies` | string | - | Comma-separated list of trusted proxy IPs | +| `ForwardedHeaders.KnownNetworks` | string | - | Comma-separated list of trusted CIDR networks | > **Note:** If `KnownProxies` or `KnownNetworks` are configured, `TrustAllProxies` is automatically set to `false`. ### CORS Settings -| Setting | Type | Default | Description | -|---------|------|---------|-------------| -| `Cors.AllowAnyOrigin` | bool | `true` | Allow requests from any origin | -| `Cors.AllowedOrigins` | string | - | Comma-separated list of allowed origins | +| Setting | Type | Default | Description | +|-----------------------|--------|---------|-----------------------------------------| +| `Cors.AllowAnyOrigin` | bool | `true` | Allow requests from any origin | +| `Cors.AllowedOrigins` | string | - | Comma-separated list of allowed origins | > **Note:** If `AllowedOrigins` is configured, `AllowAnyOrigin` is automatically set to `false`. @@ -351,18 +281,18 @@ End-to-end TLS encryption where the reverse proxy terminates external TLS and re ## Scenario Comparison Matrix -| Feature | Default | Reverse Proxy (SSL Termination) | Direct HTTPS | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption + Auth | -|---------|:-------:|:-------------------------------:|:------------:|:--------------------:|:-------------------:|:----------------------------:| -| **JWT Authentication** | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | -| **Direct (Kestrel) HTTPS** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | -| **HTTPS Redirection** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | -| **HSTS** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | -| **Restricted CORS** | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | -| **Forwarded Headers** | ✅ | ✅ | ❌ | ✅ | ❌ (Not needed. No Reverse Proxy) | ✅ | -| **Restricted Proxy Trust** | ❌ | ✅ | N/A | ✅ | N/A | ✅ | -| | | | | | | | -| **Reverse Proxy** | Optional | Yes | No | Yes | No | Yes | -| **Internal Traffic Encrypted** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | +| Feature | Default | Reverse Proxy (SSL Termination) | Direct HTTPS | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption + Auth | +|--------------------------------|:--------:|:-------------------------------:|:------------:|:--------------------:|:--------------------------------:|:----------------------------:| +| **JWT Authentication** | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | +| **Direct (Kestrel) HTTPS** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | +| **HTTPS Redirection** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | +| **HSTS** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | +| **Restricted CORS** | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | +| **Forwarded Headers** | ✅ | ✅ | ❌ | ✅ | ❌ (Not needed. No Reverse Proxy) | ✅ | +| **Restricted Proxy Trust** | ❌ | ✅ | N/A | ✅ | N/A | ✅ | +| | | | | | | | +| **Reverse Proxy** | Optional | Yes | No | Yes | No | Yes | +| **Internal Traffic Encrypted** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | **Legend:** diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 87955ef8771..900e1db1811 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -1,14 +1,14 @@ --- -title: ServiceControl security +title: ServiceControl security overview summary: Secure ServiceControl and ServicePulse with OAuth 2.0 and OpenID Connect reviewed: 2025-12-11 component: ServiceControl --- -ServiceControl and [ServicePulse](/servicepulse/) support standards-based authentication using OAuth 2.0 and OpenID Connect (OIDC). When enabled, users must sign in through the configured identity provider before accessing ServicePulse. +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 the ServiceControl are accessible without credentials. Enable authentication in production environments to restrict access. +> Authentication is disabled by default to maintain backward compatibility with existing deployments. Until authentication is enabled, ServicePulse and ServiceControl are accessible without credentials. Enable authentication to restrict access. ## Supported identity providers @@ -26,7 +26,18 @@ Any OpenID Connect (OIDC) compliant identity provider can be used, including: ## Enabling authentication -Each ServiceControl instance must be configured separately to enable authentication. Configuration is applied by editing the instance's App.config file or by setting environment variables. ServicePulse retrieves these settings automatically from the connected ServiceControl instances, so no separate configuration is required. Read the [configuring authentication](configuration.md) guide for more details. +Each ServiceControl instance must be configured separately to enable authentication. Configuration is applied by editing the instance's App.config file or by setting environment variables. ServicePulse retrieves these settings automatically from the connected ServiceControl instances, so no separate configuration is required. Read the [configuring authentication](configuration/authentication.md) guide for more details. + +### How it Works + +When authentication is enabled: + +1. ServicePulse retrieves authentication configuration from the ServiceControl `/api/authentication/configuration` endpoint +2. API requests must include a valid JWT bearer token in the `Authorization` header +3. ServiceControl validates the token against the configured authority +4. The token must have the correct audience and not be expired + +TODO: Add sequence diagram ## Transport Layer Security (TLS) @@ -35,20 +46,18 @@ When authentication is enabled, ServiceControl and ServicePulse rely on OAuth 2. > [!IMPORTANT] > Without TLS, tokens and other sensitive information are transmitted in clear text. This exposes the system to interception, session hijacking, and unauthorized access. Always secure ServiceControl with HTTPS in production environments. -ServiceControl supports TLS termination at either: +ServiceControl supports TLS at either: - **Kestrel**: Configure HTTPS directly on the ServiceControl instance -- **A reverse proxy**: Such as NGINX, Apache, IIS, or Azure App Gateway +- **A reverse proxy**: Terminate SSL at a reverse proxy such as NGINX, Apache, IIS, F5, or Azure App Gateway -See the [hosting and security guide](hosting-guide.md) for detailed configuration options including HTTPS certificates, HSTS, and reverse proxy settings. +See [HTTPS Configuration](configuration/https.md) for detailed configuration options including HTTPS certificates, HSTS, and reverse proxy settings, and the [hosting guide](hosting-guide.md) for example usage of the configuration. ## ServiceInsight compatibility -ServiceInsight does not support OAuth 2.0 or OpenID Connect authentication. If authentication is enabled on a ServiceControl instance, **ServiceInsight will not be able to connect**. +[ServiceInsight has been sunset](/serviceinsight/) and will not be updated to support OAuth 2.0 or OpenID Connect authentication. If authentication is enabled on a ServiceControl instance, **ServiceInsight will not be able to connect**. Users relying on ServiceInsight have two options: -1. **Do not enable authentication** on the relevant ServiceControl instance, or -2. **Use ServicePulse instead of ServiceInsight**. - -The second option is recommended, as the functionality previously available in ServiceInsight has been migrated to ServicePulse. \ No newline at end of file +1. **[Use ServicePulse](http://localhost:55666/servicepulse/installation) instead of ServiceInsight** (Recommended. Functionality previously available in ServiceInsight has been migrated to ServicePulse). +2. **Do not enable authentication** on the relevant ServiceControl instance From 4a2d8aad6ec2da9bec4905e4e268745c6705092a Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Tue, 13 Jan 2026 11:55:51 +0800 Subject: [PATCH 12/27] Update hosting guide for authentication --- .../security/configuration/https.md | 3 +- servicecontrol/security/hosting-guide.md | 171 +++++++----------- 2 files changed, 67 insertions(+), 107 deletions(-) diff --git a/servicecontrol/security/configuration/https.md b/servicecontrol/security/configuration/https.md index 3792f8bff2c..26e975ed430 100644 --- a/servicecontrol/security/configuration/https.md +++ b/servicecontrol/security/configuration/https.md @@ -28,8 +28,9 @@ include: servicecontrol-instance-prefix ## Security Considerations -### Certificate File Security +### Certificate Management +- ServiceControl supports PFX (PKCS#12) certificate files - Store certificate files securely with appropriate file permissions - Rotate certificates before expiration - Use certificates from a trusted Certificate Authority for production diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md index 58c35f9a420..25dd6a4d90e 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -21,7 +21,7 @@ If you place IIS, nginx, or another web server in front of ServiceControl, it ac > [!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, see [Authentication](configuration/authentication.md), [HTTPS](configuration/https.md), and [Forward Headers](configuration/forward-headers.md). +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), [HTTPS](configuration/https.md), and [Forward Headers](configuration/forward-headers.md). ### Scenario 0: Default / Backward Compatible Configuration @@ -29,8 +29,8 @@ The default configuration with no additional setup required. Backwards compatibl #### Security Features -| Feature | Status | -|-------------------------|--------------------------| +| Feature | Status | +|-------------------------|-------------------------| | JWT Authentication | ❌ Disabled | | Kestrel HTTPS | ❌ Disabled | | HTTPS Redirection | ❌ Disabled | @@ -59,9 +59,9 @@ Or explicitly: ``` -### Scenario 1: Reverse Proxy with Authentication +### Scenario 1: Strict Reverse Proxy with Authentication -Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). +Strict Reverse proxy with SSL termination and JWT authentication via an identity provider (Azure AD, Okta, Auth0, Keycloak, etc.). #### Architecture @@ -72,8 +72,8 @@ Client → HTTPS → Reverse Proxy → HTTP → ServiceControl #### Security Features -| Feature | Status | -|-------------------------|--------------------------------| +| Feature | Status | +|-------------------------|-------------------------------| | JWT Authentication | ✅ Enabled | | Kestrel HTTPS | ❌ Disabled (handled by proxy) | | HTTPS Redirection | ✅ Enabled (optional) | @@ -124,20 +124,30 @@ Client → HTTPS → Reverse Proxy → HTTP → ServiceControl ### Scenario 2: Direct HTTPS with Authentication -Kestrel handles TLS directly with JWT authentication. No reverse proxy. +Kestrel handles TLS directly with JWT authentication without a reverse proxy. -**Security Features:** +**Architecture:** + +```text +Client → HTTPS → ServiceControl (Kestrel) + (TLS + JWT validation) +``` + +#### Security Features | Feature | Status | |-------------------------|-----------------------| | JWT Authentication | ✅ Enabled | | Kestrel HTTPS | ✅ Enabled | -| HTTPS Redirection | ✅ 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 @@ -146,24 +156,25 @@ Kestrel handles TLS directly with JWT authentication. No reverse proxy. - + + - + - + - + @@ -171,49 +182,57 @@ Kestrel handles TLS directly with JWT authentication. No reverse proxy. ``` ---- +### Scenario 3: End-to-End Encryption with Reverse Proxy and Direct HTTPS -### Scenario 6: End-to-End Encryption with Reverse Proxy and Authentication +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. -End-to-end TLS encryption where the reverse proxy terminates external TLS and re-encrypts traffic to ServiceControl over HTTPS. Includes JWT authentication. +**Architecture:** -**Security Features:** +```text +Client → HTTPS → Reverse Proxy → HTTPS → ServiceControl (Kestrel) + (TLS termination) (TLS + JWT validation) +``` -| Feature | Status | -|-------------------------|-------------------------------| -| JWT Authentication | ✅ Enabled | -| Kestrel HTTPS | ✅ Enabled | -| HTTPS Redirection | ❌ Disabled (handled by proxy) | -| HSTS | ❌ Disabled (handled by proxy) | -| Restricted CORS Origins | ✅ Enabled | -| Forwarded Headers | ✅ Enabled | -| Restricted Proxy Trust | ✅ Enabled | +#### 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 - + - - - - + + - + - + @@ -225,77 +244,17 @@ End-to-end TLS encryption where the reverse proxy terminates external TLS and re ``` ---- - -## Configuration Reference - -### Authentication Settings - -| Setting | Type | Default | Description | -|-------------------------------------------|--------|---------|-------------------------------------------------------------| -| `Authentication.Enabled` | bool | `false` | Enable JWT Bearer authentication | -| `Authentication.Authority` | string | - | OpenID Connect authority URL (required when enabled) | -| `Authentication.Audience` | string | - | Expected audience for tokens (required when enabled) | -| `Authentication.ValidateIssuer` | bool | `true` | Validate token issuer | -| `Authentication.ValidateAudience` | bool | `true` | Validate token audience | -| `Authentication.ValidateLifetime` | bool | `true` | Validate token expiration | -| `Authentication.ValidateIssuerSigningKey` | bool | `true` | Validate token signing key | -| `Authentication.RequireHttpsMetadata` | bool | `true` | Require HTTPS for metadata endpoint | -| `Authentication.ServicePulse.ClientId` | string | - | OAuth client ID for ServicePulse | -| `Authentication.ServicePulse.Authority` | string | - | Authority URL for ServicePulse (defaults to main Authority) | -| `Authentication.ServicePulse.ApiScopes` | string | - | API scopes for ServicePulse to request | - -### HTTPS Settings - -| Setting | Type | Default | Description | -|-------------------------------|--------|------------|---------------------------------------| -| `Https.Enabled` | bool | `false` | Enable Kestrel HTTPS with certificate | -| `Https.CertificatePath` | string | - | Path to PFX/PEM certificate file | -| `Https.CertificatePassword` | string | - | Certificate password (if required) | -| `Https.RedirectHttpToHttps` | bool | `false` | Redirect HTTP requests to HTTPS | -| `Https.EnableHsts` | bool | `false` | Enable HTTP Strict Transport Security | -| `Https.HstsMaxAgeSeconds` | int | `31536000` | HSTS max-age in seconds (1 year) | -| `Https.HstsIncludeSubDomains` | bool | `false` | Include subdomains in HSTS | - -### Forwarded Headers Settings - -| Setting | Type | Default | Description | -|------------------------------------|--------|---------|-----------------------------------------------| -| `ForwardedHeaders.Enabled` | bool | `true` | Enable forwarded headers processing | -| `ForwardedHeaders.TrustAllProxies` | bool | `true` | Trust X-Forwarded-* from any source | -| `ForwardedHeaders.KnownProxies` | string | - | Comma-separated list of trusted proxy IPs | -| `ForwardedHeaders.KnownNetworks` | string | - | Comma-separated list of trusted CIDR networks | - -> **Note:** If `KnownProxies` or `KnownNetworks` are configured, `TrustAllProxies` is automatically set to `false`. - -### CORS Settings - -| Setting | Type | Default | Description | -|-----------------------|--------|---------|-----------------------------------------| -| `Cors.AllowAnyOrigin` | bool | `true` | Allow requests from any origin | -| `Cors.AllowedOrigins` | string | - | Comma-separated list of allowed origins | - -> **Note:** If `AllowedOrigins` is configured, `AllowAnyOrigin` is automatically set to `false`. - ---- - ## Scenario Comparison Matrix -| Feature | Default | Reverse Proxy (SSL Termination) | Direct HTTPS | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption + Auth | -|--------------------------------|:--------:|:-------------------------------:|:------------:|:--------------------:|:--------------------------------:|:----------------------------:| -| **JWT Authentication** | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | -| **Direct (Kestrel) HTTPS** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | -| **HTTPS Redirection** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | -| **HSTS** | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ (Handled by Reverse Proxy) | -| **Restricted CORS** | ❌ | ✅ | ✅ | ✅ | ✅ | ✅ | -| **Forwarded Headers** | ✅ | ✅ | ❌ | ✅ | ❌ (Not needed. No Reverse Proxy) | ✅ | -| **Restricted Proxy Trust** | ❌ | ✅ | N/A | ✅ | N/A | ✅ | -| | | | | | | | -| **Reverse Proxy** | Optional | Yes | No | Yes | No | Yes | -| **Internal Traffic Encrypted** | ❌ | ❌ | ✅ | ❌ | ✅ | ✅ | - -**Legend:** - -- ✅ = Enabled -- ❌ = Disabled -- N/A = Not Applicable \ No newline at end of file +| Feature | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption | +|--------------------------------|:--------------------:|:-------------------:|:---------------------:| +| **JWT Authentication** | ✅ | ✅ | ✅ | +| **Kestrel HTTPS** | ❌ | ✅ | ✅ | +| **HTTPS Redirection** | ✅ (optional) | ✅ | ❌ (at proxy) | +| **HSTS** | ❌ (at proxy) | ✅ | ❌ (at proxy) | +| **Restricted CORS** | ✅ | ✅ | ✅ | +| **Forwarded Headers** | ✅ | ❌ | ✅ | +| **Restricted Proxy Trust** | ✅ | N/A | ✅ | +| **Internal Traffic Encrypted** | ❌ | ✅ | ✅ | +| **Requires Reverse Proxy** | Yes | No | Yes | +| **Certificate Management** | At proxy only | At ServiceControl | Both | \ No newline at end of file From d3ca23f5e7cdbeb8d0964acf7c45562247621ce0 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Tue, 13 Jan 2026 13:25:05 +0800 Subject: [PATCH 13/27] Update ServiceControl security configuration and documentation - Renamed "HTTPS" to "TLS" in menu.yaml and added "CORS" section. - Enhanced configuration documentation for HTTP to HTTPS redirection in audit and monitoring instances. - Added new settings for HTTPS port in ServiceControl configuration. - Introduced CORS configuration documentation for ServiceControl instances. - Updated authentication documentation to clarify the use of Microsoft Entra ID and other OIDC providers. - Added TLS configuration documentation detailing direct HTTPS and reverse proxy setups. - Improved overall security overview and deployment scenarios in the ServiceControl documentation. --- menu/menu.yaml | 6 +- .../audit-instances/configuration.md | 18 +- .../monitoring-instances/configuration.md | 18 +- .../security/configuration/authentication.md | 43 ++++- servicecontrol/security/configuration/cors.md | 51 ++++++ .../security/configuration/forward-headers.md | 47 ++++- .../security/configuration/index.md | 31 +++- .../configuration/{https.md => tls.md} | 49 ++++- .../security/entra-id-authentication.md | 171 +++++++----------- servicecontrol/security/hosting-guide.md | 10 +- servicecontrol/security/index.md | 116 ++++++++---- .../servicecontrol-instances/configuration.md | 34 ++-- 12 files changed, 422 insertions(+), 172 deletions(-) create mode 100644 servicecontrol/security/configuration/cors.md rename servicecontrol/security/configuration/{https.md => tls.md} (71%) diff --git a/menu/menu.yaml b/menu/menu.yaml index 2ddd0a52c43..17c545b7ee1 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1492,8 +1492,10 @@ Url: servicecontrol/security/configuration/authentication - Title: Forward Headers Url: servicecontrol/security/configuration/forward-headers - - Title: HTTPS - Url: servicecontrol/security/configuration/https + - Title: TLS + Url: servicecontrol/security/configuration/tls + - Title: CORS + Url: servicecontrol/security/configuration/cors - Title: Hosting guide Url: servicecontrol/security/hosting-guide - Title: Examples diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index 1a514487305..6ea9b377a53 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -344,7 +344,7 @@ The password for the certificate file, if required. _Added in version 6.9.0_ -Redirects HTTP requests to HTTPS. +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. | Context | Name | | --- | --- | @@ -356,6 +356,22 @@ Redirects HTTP requests to HTTPS. | --- | --- | | bool | `false` | +### ServiceControl.Audit/Https.Port + +_Added in version 6.9.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.9.0_ diff --git a/servicecontrol/monitoring-instances/configuration.md b/servicecontrol/monitoring-instances/configuration.md index 58e2a8283ba..beab3f0b85f 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -284,7 +284,7 @@ The password for the certificate file, if required. _Added in version 6.9.0_ -Redirects HTTP requests to HTTPS. +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. | Context | Name | | --- | --- | @@ -296,6 +296,22 @@ Redirects HTTP requests to HTTPS. | --- | --- | | bool | `false` | +### Monitoring/Https.Port + +_Added in version 6.9.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.9.0_ diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md index e4dc6cdab60..cc7e5dcc2d4 100644 --- a/servicecontrol/security/configuration/authentication.md +++ b/servicecontrol/security/configuration/authentication.md @@ -5,14 +5,14 @@ reviewed: 2026-01-12 component: ServiceControl --- -ServiceControl instances can be configured to require JWT authentication using OpenID Connect (OIDC). 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. +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 conjustion with [Forward Header](forward-headers.md) and [HTTPS](https.md) configuration settings in a scenario based format. +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. include: servicecontrol-instance-prefix @@ -103,3 +103,42 @@ The following examples show complete authentication configurations for common id ``` + +## Limitations + +### Anonymous endpoints + +The following endpoints are accessible without authentication, even when authentication is enabled: + +| Endpoint | Purpose | +|-------------------------------------|--------------------------------------------------------------------| +| `/api/authentication/configuration` | Returns authentication configuration for clients like ServicePulse | + +This endpoint must remain accessible so clients can obtain the authentication configuration needed to acquire tokens before authenticating. + +### Scatter-gather endpoints + +The Primary ServiceControl instance communicates with other ServiceControl instances to aggregate data. The following endpoints support this scatter-gather communication and are accessible without authentication: + +| Endpoint | Purpose | +|------------------------------|-----------------------------------------------------------| +| `/api` | API root/discovery - returns available endpoints | +| `/api/instance-info` | Returns instance configuration information | +| `/api/configuration` | Returns instance configuration information (alias) | +| `/api/configuration/remotes` | Returns remote instance configurations for scatter-gather | + +These endpoints allow the Primary instance to discover remote instances. + +### Same 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 + +### 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 diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md new file mode 100644 index 00000000000..9d12f87d8aa --- /dev/null +++ b/servicecontrol/security/configuration/cors.md @@ -0,0 +1,51 @@ +--- +title: CORS Configuration +summary: How to configure Cross-Origin Resource Sharing for ServiceControl instances +reviewed: 2026-01-13 +component: ServiceControl +--- + +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. + +include: servicecontrol-instance-prefix + +### Settings + +| Environment Variable | App.config | Default | Description | +|-----------------------------------|-----------------------------------|---------|--------------------------------------------------| +| `{PREFIX}_CORS_ALLOWANYORIGIN` | `{PREFIX}/Cors.AllowAnyOrigin` | `true` | Allow requests from any origin | +| `{PREFIX}_CORS_ALLOWEDORIGINS` | `{PREFIX}/Cors.AllowedOrigins` | (none) | Comma-separated list of allowed origins | + +> [!WARNING] +> The default configuration (`AllowAnyOrigin = true`) allows any website to make requests to ServiceControl. For production deployments, set `AllowAnyOrigin` to `false` and configure `AllowedOrigins` to restrict access to trusted domains only. + +## 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 example + +To restrict access to only your ServicePulse domain: + +```xml + + + + +``` + +To allow multiple origins: + +```xml + + + + +``` diff --git a/servicecontrol/security/configuration/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md index 49748877129..f3ae7fb3107 100644 --- a/servicecontrol/security/configuration/forward-headers.md +++ b/servicecontrol/security/configuration/forward-headers.md @@ -9,7 +9,7 @@ When ServiceControl instances are deployed behind a reverse proxy (like NGINX, T ## 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 conjustion with [Authentication](authentication.md) and [HTTPS](https.md) configuration settings in a scenario based format. +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. include: servicecontrol-instance-prefix @@ -55,7 +55,7 @@ When using a reverse proxy that terminates SSL, you can configure ServiceControl 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 -To enable HTTP to HTTPS redirect, see [HTTPS Configuration](https.md) for details on how to do this. +To enable HTTP to HTTPS redirect, see [TLS Configuration](tls.md) for details on how to do this. ## Proxy Chain Behavior (ForwardLimit) @@ -70,3 +70,46 @@ 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. + +### 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 + + +``` diff --git a/servicecontrol/security/configuration/index.md b/servicecontrol/security/configuration/index.md index 1ff2583d2e4..e915c3bb173 100644 --- a/servicecontrol/security/configuration/index.md +++ b/servicecontrol/security/configuration/index.md @@ -5,4 +5,33 @@ reviewed: 2026-01-12 component: ServiceControl --- -TBA +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. + +## Configuration methods + +ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix: + +include: servicecontrol-instance-prefix + +## Related topics + +- [Hosting Guide](../hosting-guide.md) - Complete examples combining authentication, HTTPS, and forward headers configuration +- [Microsoft Entra ID](../entra-id-authentication.md) - Step-by-step guide for configuring authentication with Microsoft Entra ID diff --git a/servicecontrol/security/configuration/https.md b/servicecontrol/security/configuration/tls.md similarity index 71% rename from servicecontrol/security/configuration/https.md rename to servicecontrol/security/configuration/tls.md index 26e975ed430..4848148ba37 100644 --- a/servicecontrol/security/configuration/https.md +++ b/servicecontrol/security/configuration/tls.md @@ -1,6 +1,6 @@ --- -title: HTTPS -summary: How to enable and configure HTTPS for ServiceControl instances +title: TLS Configuration +summary: How to enable and configure TLS for ServiceControl instances reviewed: 2026-01-12 component: ServiceControl --- @@ -58,3 +58,48 @@ The `HTTPS_REDIRECTHTTPTOHTTPS` setting is intended for use with a reverse proxy > [!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. + +### Direct HTTPS with certificate + +When ServiceControl handles TLS directly using a PFX certificate: + +```xml + + + +``` + +### 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 + + + +``` diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md index d92dd0543c4..32d651ba6f2 100644 --- a/servicecontrol/security/entra-id-authentication.md +++ b/servicecontrol/security/entra-id-authentication.md @@ -1,11 +1,11 @@ --- title: Microsoft Entra ID authentication summary: Set up authentication with Microsoft Entra ID for ServiceControl and ServicePulse -reviewed: 2025-12-11 +reviewed: 2026-01-13 component: ServiceControl --- -This guide explains how to configure Microsoft Entra ID (formerly Azure Active Directory) and ServiceControl to enable authentication for ServicePulse. +This guide explains how to configure Microsoft Entra ID (formerly Azure Active Directory) as the identity provider for ServiceControl and ServicePulse. ## Prerequisites @@ -13,133 +13,100 @@ This guide explains how to configure Microsoft Entra ID (formerly Azure Active D - ServiceControl 6.9.0 or later - ServicePulse 2.5.0 or later -## Configure Microsoft Entra ID +## Overview -Register ServiceControl and ServicePulse as applications in Microsoft Entra ID to allow users to authenticate. +Two app registrations are required in Microsoft Entra ID: -### Create the ServiceControl app registration +1. **ServiceControl API** - Represents the ServiceControl API that ServicePulse will call +2. **ServicePulse** - Represents the ServicePulse single-page application that users sign into -This app registration represents the ServiceControl API and defines the permissions that ServicePulse will request when users sign in. +## Step 1: Register the ServiceControl API -1. Navigate to the [Azure Portal](https://portal.azure.com/). -2. Open **Microsoft Entra ID** and select **Manage** > **App registrations**. -3. Click **+ New registration**. -4. Configure the registration: - - **Name**: `ServiceControl API` - - **Supported account types**: Accounts in this organizational directory only (single tenant) - - Click **Register**. +Follow Microsoft's guide to [register an application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) with the following settings: -> [!NOTE] -> Select **Accounts in any organizational directory** (multi-tenant) if users from multiple Entra ID tenants need access to ServicePulse. - -5. On the **Overview** page, copy the **Directory (tenant) ID**. This is used to construct the authority URLs. -6. Select **Manage** > **Expose an API**. -7. Next to **Application ID URI**, click **Add** and save the default value (e.g., `api://{application-id}`). -8. Copy the **Application ID URI**. This is used for `ServiceControl/Authentication.Audience`. -9. Under **Scopes defined by this API**, click **Add a scope** and configure: - - **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` - - **State**: Enabled - - Click **Add scope**. - -### Create the ServicePulse app registration - -This app registration represents ServicePulse as a client application that users will sign into. - -1. In **App registrations**, click **+ New registration**. -2. Configure the registration: - - **Name**: `ServicePulse` - - **Supported account types**: Accounts in this organizational directory only (single tenant) - - **Redirect URI**: - - **Platform**: Single-page application (SPA) - - **URI**: The URL where ServicePulse is hosted (e.g., `https://servicepulse.example.com/`) - - Click **Register**. +| Setting | Value | +|-------------------------|----------------------------------------------------------------| +| Name | `ServiceControl API` | +| Supported account types | Accounts in this organizational directory only (single tenant) | -> [!WARNING] -> Redirect URIs must use HTTPS in production environments. HTTP is only acceptable for local development (e.g., `http://localhost:9090/`). +After registration, collect these values from the app registration: -3. Copy the **Application (client) ID**. This is used for `ServiceControl/Authentication.ServicePulse.ClientId`. -4. Select **Manage** > **API permissions**. -5. Click **+ Add a permission**. -6. Select the **APIs my organization uses** tab. -7. Select **ServiceControl API**. -8. Under **Delegated permissions**, check **api.access**. -9. Click **Add permissions**. +| Value | Location | Used for | +|-----------------------|---------------|-----------------------------------| +| Directory (tenant) ID | Overview page | Authority URLs | +| Application ID URI | Expose an API | `Authentication.Audience` setting | -> [!NOTE] -> If ServicePulse is accessed from multiple URLs (e.g., localhost during development and a production URL), add each URL as a redirect URI in the ServicePulse app registration under **Manage** > **Authentication**. +### Expose the API -## Configure ServiceControl +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: -Add the Entra ID application details to the ServiceControl Error instance configuration to enable authentication. The same settings apply to Audit and Monitoring instances, using their respective prefixes. +| 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` | -### Collected values +## Step 2: Register ServicePulse -During the Entra ID configuration, the following values should have been collected: +Follow Microsoft's guide to [register an application](https://learn.microsoft.com/en-us/entra/identity-platform/quickstart-register-app) with the following settings: -| Value | Source | Used for | -|-------|--------|----------| -| Directory (tenant) ID | ServiceControl API app registration > Overview | Authority URLs | -| Application ID URI | ServiceControl API app registration > Expose an API | `Authentication.Audience` and `Authentication.ServicePulse.ApiScopes` | -| Application (client) ID | ServicePulse app registration > Overview | `Authentication.ServicePulse.ClientId` | +| 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/`) | -### Using App.config +After registration, collect this value: -Add the following settings to the ServiceControl configuration file: +| Value | Location | Used for | +|-------------------------|---------------|-----------------------------------------------| +| Application (client) ID | Overview page | `Authentication.ServicePulse.ClientId` setting | -```xml - - - - - - -``` - -Replace the placeholder values: +> [!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**. -| Placeholder | Example value | -|-------------|---------------| -| `{tenant-id}` | `a1b2c3d4-e5f6-7890-abcd-ef1234567890` | -| `{application-id-uri}` | `api://a1b2c3d4-e5f6-7890-abcd-ef1234567890` | -| `{client-id}` | `f9e8d7c6-b5a4-3210-fedc-ba0987654321` | +### Grant API permissions -### Using environment variables +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): -Environment variables can be used instead of App.config, which is useful for containerized deployments. Environment variables take precedence over App.config settings. +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 -```powershell -$env:SERVICECONTROL_AUTHENTICATION_ENABLED = "true" -$env:SERVICECONTROL_AUTHENTICATION_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}" -$env:SERVICECONTROL_AUTHENTICATION_AUDIENCE = "{application-id-uri}" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID = "{client-id}" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY = "https://login.microsoftonline.com/{tenant-id}/v2.0" -$env:SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES = '["{application-id-uri}/api.access"]' -``` +## Step 3: Configure ServiceControl -### Audit and Monitoring instances +Use the collected values to configure ServiceControl. For Entra ID, the authority URLs follow this pattern: -To enable authentication on Audit and Monitoring instances, configure the same settings using their respective prefixes. Only the base authentication settings are required; the ServicePulse settings are only needed on the Error instance. +- **ServiceControl authority**: `https://login.microsoftonline.com/{tenant-id}` +- **ServicePulse authority**: `https://login.microsoftonline.com/{tenant-id}/v2.0` -**Audit instance:** +The following table summarizes how Entra ID values map to ServiceControl settings: -```xml - - - -``` +| 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` | -**Monitoring instance:** +See [Authentication Configuration](configuration/authentication.md) for all settings and configuration examples, including App.config and environment variable formats. -```xml - - - -``` +> [!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 -Once configured, restart the ServiceControl instances. When accessing ServicePulse, users will be redirected to Microsoft Entra ID to sign in. +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. + +## Related topics +- [Authentication Configuration](configuration/authentication.md) - All authentication settings +- [Hosting Guide](hosting-guide.md) - Deployment scenarios with HTTPS and authentication diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md index 25dd6a4d90e..9c950efcb39 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -21,7 +21,7 @@ If you place IIS, nginx, or another web server in front of ServiceControl, it ac > [!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), [HTTPS](configuration/https.md), and [Forward Headers](configuration/forward-headers.md). +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 @@ -83,7 +83,7 @@ Client → HTTPS → Reverse Proxy → HTTP → ServiceControl | 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/https.md) used by the proxy. +> 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 @@ -144,7 +144,8 @@ Client → HTTPS → ServiceControl (Kestrel) | 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. +> [!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 @@ -206,7 +207,8 @@ Client → HTTPS → Reverse Proxy → HTTPS → ServiceControl (Kestrel) | 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. +> [!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 diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 900e1db1811..8025204cd0d 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -1,63 +1,103 @@ --- -title: ServiceControl security overview -summary: Secure ServiceControl and ServicePulse with OAuth 2.0 and OpenID Connect -reviewed: 2025-12-11 +title: ServiceControl Security Overview +summary: Secure ServiceControl and ServicePulse with authentication, HTTPS, and other security features +reviewed: 2026-01-13 component: ServiceControl --- -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. +This section covers security features for ServiceControl and ServicePulse, including authentication, transport layer security (TLS), and reverse proxy configuration. -> [!WARNING] -> Authentication is disabled by default to maintain backward compatibility with existing deployments. Until authentication is enabled, ServicePulse and ServiceControl are accessible without credentials. Enable authentication to restrict access. - -## Supported identity providers +## In this section -Any OpenID Connect (OIDC) compliant identity provider can be used, including: +- [Security Configuration](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 -- Active Directory Federation Services (ADFS) -- Auth0 -- AWS IAM Identity Center -- Duende IdentityServer -- Google Workspace -- Keycloak -- Microsoft Entra ID -- Okta -- Ping Identity +## Authentication -## Enabling authentication +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. -Each ServiceControl instance must be configured separately to enable authentication. Configuration is applied by editing the instance's App.config file or by setting environment variables. ServicePulse retrieves these settings automatically from the connected ServiceControl instances, so no separate configuration is required. Read the [configuring authentication](configuration/authentication.md) guide for more details. +> [!WARNING] +> Authentication is disabled by default to maintain backward compatibility with existing deployments. Until authentication is enabled, ServicePulse and ServiceControl are accessible without credentials. -### How it Works +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 the ServiceControl `/api/authentication/configuration` endpoint -2. API requests must include a valid JWT bearer token in the `Authorization` header -3. ServiceControl validates the token against the configured authority -4. The token must have the correct audience and not be expired +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 scatter-gather communication between ServiceControl instances. See [Authentication Configuration](configuration/authentication.md#limitations) for the full list of anonymous endpoints and security considerations. + +See [Authentication Configuration](configuration/authentication.md) for settings, or [Microsoft Entra ID](entra-id-authentication.md) for a complete setup guide. + +## TLS + +When authentication is enabled, access tokens are exchanged between ServicePulse and ServiceControl. To protect these tokens, TLS must be enabled. -TODO: Add sequence diagram +> [!IMPORTANT] +> Without TLS, tokens are transmitted in clear text, exposing the system to interception and unauthorized access. Always use HTTPS in production environments. -## Transport Layer Security (TLS) +ServiceControl supports two approaches for HTTPS: -When authentication is enabled, ServiceControl and ServicePulse rely on OAuth 2.0 and OpenID Connect flows that involve exchanging access tokens. To protect these tokens and other sensitive data, **TLS must be enabled on every ServiceControl instance and on any reverse proxy in front of it**. +- **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 -> [!IMPORTANT] -> Without TLS, tokens and other sensitive information are transmitted in clear text. This exposes the system to interception, session hijacking, and unauthorized access. Always secure ServiceControl with HTTPS in production environments. +See [TLS Configuration](configuration/tls.md) for settings and certificate management. + +## Reverse proxy support + +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 + +See [Forward Headers Configuration](configuration/forward-headers.md) for settings. -ServiceControl supports TLS at either: +## Deployment scenarios -- **Kestrel**: Configure HTTPS directly on the ServiceControl instance -- **A reverse proxy**: Terminate SSL at a reverse proxy such as NGINX, Apache, IIS, F5, or Azure App Gateway +The [Hosting Guide](hosting-guide.md) provides complete configuration examples for common deployment patterns: -See [HTTPS Configuration](configuration/https.md) for detailed configuration options including HTTPS certificates, HSTS, and reverse proxy settings, and the [hosting guide](hosting-guide.md) for example usage of the configuration. +- **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 will not be updated to support OAuth 2.0 or OpenID Connect authentication. If authentication is enabled on a ServiceControl instance, **ServiceInsight will not be able to connect**. +[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 have two options: +Users relying on ServiceInsight can: -1. **[Use ServicePulse](http://localhost:55666/servicepulse/installation) instead of ServiceInsight** (Recommended. Functionality previously available in ServiceInsight has been migrated to ServicePulse). -2. **Do not enable authentication** on the relevant ServiceControl instance +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 6b96482bb34..090d01b3493 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -342,22 +342,6 @@ The URL of the OpenID Connect authority for ServicePulse to use when authenticat | --- | --- | | string | None | -### ServiceControl/Authentication.ServicePulse.Audience - -_Added in version 6.9.0_ - -The audience value for ServicePulse to include when requesting tokens. - -| Context | Name | -| --- | --- | -| **Environment variable** | `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUDIENCE` | -| **App config key** | `ServiceControl/Authentication.ServicePulse.Audience` | -| **SCMU field** | N/A | - -| Type | Default value | -| --- | --- | -| string | None | - ### ServiceControl/Authentication.ServicePulse.ApiScopes _Added in version 6.9.0_ @@ -433,7 +417,7 @@ The password for the certificate file, if required. _Added in version 6.9.0_ -Redirects HTTP requests to HTTPS. +Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. | Context | Name | | --- | --- | @@ -445,6 +429,22 @@ Redirects HTTP requests to HTTPS. | --- | --- | | bool | `false` | +### ServiceControl/Https.Port + +_Added in version 6.9.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.9.0_ From efde27b102710b1274ac1c87f28088b0c8f0e7e1 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 09:34:45 +0800 Subject: [PATCH 14/27] Add ServicePulse security pages (WIP). Update ServiceControl security page metadata --- menu/menu.yaml | 15 +++++++++++++++ .../security/configuration/authentication.md | 7 +++++-- servicecontrol/security/configuration/cors.md | 6 ++++-- .../security/configuration/forward-headers.md | 7 +++++-- servicecontrol/security/configuration/index.md | 10 ++++------ servicecontrol/security/configuration/tls.md | 5 ++++- .../security/entra-id-authentication.md | 8 +++----- servicecontrol/security/hosting-guide.md | 10 ++++++++-- servicecontrol/security/index.md | 8 +++++--- .../security/configuration/authentication.md | 11 +++++++++++ .../security/configuration/forward-headers.md | 11 +++++++++++ servicepulse/security/configuration/index.md | 11 +++++++++++ servicepulse/security/configuration/tls.md | 11 +++++++++++ servicepulse/security/hosting-guide.md | 13 +++++++++++++ servicepulse/security/index.md | 10 ++++++++++ 15 files changed, 120 insertions(+), 23 deletions(-) create mode 100644 servicepulse/security/configuration/authentication.md create mode 100644 servicepulse/security/configuration/forward-headers.md create mode 100644 servicepulse/security/configuration/index.md create mode 100644 servicepulse/security/configuration/tls.md create mode 100644 servicepulse/security/hosting-guide.md create mode 100644 servicepulse/security/index.md diff --git a/menu/menu.yaml b/menu/menu.yaml index 17c545b7ee1..5eda40a2a7d 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1400,6 +1400,21 @@ Articles: - Title: Version 1 to 2 Url: servicepulse/1to2 + - Title: Security + Articles: + - Title: Overview + Url: servicepulse/security + - Title: Configuration + Url: servicepulse/security/configuration + Articles: + - Title: Authentication + Url: servicepulse/security/configuration/authentication + - Title: Forward Headers + 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 diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md index cc7e5dcc2d4..6811022a790 100644 --- a/servicecontrol/security/configuration/authentication.md +++ b/servicecontrol/security/configuration/authentication.md @@ -1,8 +1,11 @@ --- -title: Authentication Configuration -summary: How to enable and configure authentication for ServiceControl and ServicePulse +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. diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md index 9d12f87d8aa..c127af20fdb 100644 --- a/servicecontrol/security/configuration/cors.md +++ b/servicecontrol/security/configuration/cors.md @@ -1,8 +1,10 @@ --- -title: CORS Configuration +title: ServiceControl CORS Configuration summary: How to configure Cross-Origin Resource Sharing for ServiceControl instances -reviewed: 2026-01-13 +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. diff --git a/servicecontrol/security/configuration/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md index f3ae7fb3107..654c2c840a5 100644 --- a/servicecontrol/security/configuration/forward-headers.md +++ b/servicecontrol/security/configuration/forward-headers.md @@ -1,8 +1,11 @@ --- -title: Forward Headers Configuration +title: ServiceControl Forward Headers Configuration summary: How to enable and configure forward headers for ServiceControl instances -reviewed: 2026-01-12 +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 (like NGINX, Traefik, or a cloud load balancer) that terminates SSL/TLS, you need to configure forwarded headers so ServiceControl correctly understands the original client request. diff --git a/servicecontrol/security/configuration/index.md b/servicecontrol/security/configuration/index.md index e915c3bb173..6ab62c0a30d 100644 --- a/servicecontrol/security/configuration/index.md +++ b/servicecontrol/security/configuration/index.md @@ -1,8 +1,11 @@ --- -title: Security Configuration +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. @@ -30,8 +33,3 @@ Configure Cross-Origin Resource Sharing to control which web applications can ac ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix: include: servicecontrol-instance-prefix - -## Related topics - -- [Hosting Guide](../hosting-guide.md) - Complete examples combining authentication, HTTPS, and forward headers configuration -- [Microsoft Entra ID](../entra-id-authentication.md) - Step-by-step guide for configuring authentication with Microsoft Entra ID diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index 4848148ba37..ffcc19b669a 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -1,8 +1,11 @@ --- -title: TLS Configuration +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. diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md index 32d651ba6f2..4a49cf7c163 100644 --- a/servicecontrol/security/entra-id-authentication.md +++ b/servicecontrol/security/entra-id-authentication.md @@ -3,6 +3,9 @@ title: Microsoft Entra ID authentication 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. @@ -105,8 +108,3 @@ After configuring ServiceControl, restart all instances. When accessing ServiceP 2. After signing in, ServicePulse should load and display data from ServiceControl If authentication fails, check the ServiceControl logs for token validation errors. - -## Related topics - -- [Authentication Configuration](configuration/authentication.md) - All authentication settings -- [Hosting Guide](hosting-guide.md) - Deployment scenarios with HTTPS and authentication diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md index 9c950efcb39..7957a99e6ae 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -1,8 +1,14 @@ --- -title: Hosting and Security Guide -summary: Hosting and security options for ServiceControl instances +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. diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 8025204cd0d..965f6eedb0d 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -1,11 +1,13 @@ --- title: ServiceControl Security Overview -summary: Secure ServiceControl and ServicePulse with authentication, HTTPS, and other security features -reviewed: 2026-01-13 +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 and ServicePulse, including authentication, transport layer security (TLS), and reverse proxy configuration. +This section covers security features for ServiceControl, including authentication, transport layer security (TLS), and reverse proxy configuration. ## In this section diff --git a/servicepulse/security/configuration/authentication.md b/servicepulse/security/configuration/authentication.md new file mode 100644 index 00000000000..5f465975871 --- /dev/null +++ b/servicepulse/security/configuration/authentication.md @@ -0,0 +1,11 @@ +--- +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 +--- + +TBA diff --git a/servicepulse/security/configuration/forward-headers.md b/servicepulse/security/configuration/forward-headers.md new file mode 100644 index 00000000000..9b37f5f7964 --- /dev/null +++ b/servicepulse/security/configuration/forward-headers.md @@ -0,0 +1,11 @@ +--- +title: ServicePulse Forward Headers 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 +--- + +TBA diff --git a/servicepulse/security/configuration/index.md b/servicepulse/security/configuration/index.md new file mode 100644 index 00000000000..8e9ba1050b9 --- /dev/null +++ b/servicepulse/security/configuration/index.md @@ -0,0 +1,11 @@ +--- +title: ServicePulse Security Configuration +summary: ServicePulse security configuration options +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicepulse/security/hosting-guide +- servicecontrol/security/hosting-guide +--- + +TBA diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md new file mode 100644 index 00000000000..da1d14b845d --- /dev/null +++ b/servicepulse/security/configuration/tls.md @@ -0,0 +1,11 @@ +--- +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 +--- + +TBA diff --git a/servicepulse/security/hosting-guide.md b/servicepulse/security/hosting-guide.md new file mode 100644 index 00000000000..88e6423c5f6 --- /dev/null +++ b/servicepulse/security/hosting-guide.md @@ -0,0 +1,13 @@ +--- +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 +--- + +TBA diff --git a/servicepulse/security/index.md b/servicepulse/security/index.md new file mode 100644 index 00000000000..a4e783f7079 --- /dev/null +++ b/servicepulse/security/index.md @@ -0,0 +1,10 @@ +--- +title: ServicePulse Security Overview +summary: Secure ServicePulse with authentication, TLS, and other security features +reviewed: 2026-01-14 +component: ServicePulse +related: +- servicecontrol/security +--- + +TBA From 2a79da304c8d536941820ae7d4f91b9db658469a Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 15:25:01 +0800 Subject: [PATCH 15/27] Add ServicePulse security doco. Update ServiceControl security diagrams. --- menu/menu.yaml | 6 +- .../security/configuration/authentication.md | 95 ++++++++- .../configuration/cert-management.include.md | 4 + .../security/configuration/forward-headers.md | 20 +- .../hsts-considerations.include.md | 8 + servicecontrol/security/configuration/tls.md | 21 +- .../security/entra-id-authentication.md | 2 +- servicecontrol/security/hosting-guide.md | 54 ++--- .../security/configuration/authentication.md | 125 +++++++++++- .../security/configuration/forward-headers.md | 185 +++++++++++++++++- servicepulse/security/configuration/index.md | 25 ++- servicepulse/security/configuration/tls.md | 131 ++++++++++++- servicepulse/security/hosting-guide.md | 170 +++++++++++++++- servicepulse/security/index.md | 78 +++++++- 14 files changed, 856 insertions(+), 68 deletions(-) create mode 100644 servicecontrol/security/configuration/cert-management.include.md create mode 100644 servicecontrol/security/configuration/hsts-considerations.include.md diff --git a/menu/menu.yaml b/menu/menu.yaml index 5eda40a2a7d..7a01b8eebbe 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1409,7 +1409,7 @@ Articles: - Title: Authentication Url: servicepulse/security/configuration/authentication - - Title: Forward Headers + - Title: Forward Headers for Reverse Proxy Url: servicepulse/security/configuration/forward-headers - Title: TLS Url: servicepulse/security/configuration/tls @@ -1505,7 +1505,7 @@ Articles: - Title: Authentication Url: servicecontrol/security/configuration/authentication - - Title: Forward Headers + - Title: Forward Headers for Reverse Proxy Url: servicecontrol/security/configuration/forward-headers - Title: TLS Url: servicecontrol/security/configuration/tls @@ -1515,7 +1515,7 @@ Url: servicecontrol/security/hosting-guide - Title: Examples Articles: - - Title: Microsoft Entra ID authentication + - Title: Microsoft Entra ID Authentication Guide Url: servicecontrol/security/entra-id-authentication - Title: Planning Articles: diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md index 6811022a790..df0e51c00dc 100644 --- a/servicecontrol/security/configuration/authentication.md +++ b/servicecontrol/security/configuration/authentication.md @@ -21,11 +21,11 @@ include: servicecontrol-instance-prefix ### Core Settings -| Environment Variable | App.config | Default | Description | -|-------------------------------------|-------------------------------------|---------|-------------------------------------------------------------------------------------------| -| `{PREFIX}_AUTHENTICATION_ENABLED` | `{PREFIX}/Authentication.Enabled` | `false` | Enable JWT authentication | -| `{PREFIX}_AUTHENTICATION_AUTHORITY` | `{PREFIX}/Authentication.Authority` | (none) | OpenID Connect authority URL (e.g., `https://login.microsoftonline.com/{tenant-id}/v2.0`) | -| `{PREFIX}_AUTHENTICATION_AUDIENCE` | `{PREFIX}/Authentication.Audience` | (none) | The audience identifier (typically your API identifier or client ID, e.g., `api://servicecontrol`) | +| Environment Variable | App.config | Default | Description | +|-------------------------------------|-------------------------------------|---------|----------------------------------------------------------------------------------------------------| +| `{PREFIX}_AUTHENTICATION_ENABLED` | `{PREFIX}/Authentication.Enabled` | `false` | Enable JWT authentication | +| `{PREFIX}_AUTHENTICATION_AUTHORITY` | `{PREFIX}/Authentication.Authority` | (none) | OpenID Connect authority URL (e.g., `https://login.microsoftonline.com/{tenant-id}/v2.0`) | +| `{PREFIX}_AUTHENTICATION_AUDIENCE` | `{PREFIX}/Authentication.Audience` | (none) | The audience identifier (typically your API identifier or client ID, e.g., `api://servicecontrol`) | ### Token Validation Settings @@ -55,17 +55,31 @@ These settings are served to ServicePulse through a bootstrap endpoint hosting i > [!NOTE] > The ServicePulse audience Open ID Connect configuration is automatically filled in using the [ServiceControl audience setting](#configuration-core-settings). -## Identity provider guides +## 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 +### Configuration examples The following examples show complete authentication configurations for common identity providers. -### Microsoft Entra ID +#### Microsoft Entra ID ```xml @@ -79,7 +93,7 @@ The following examples show complete authentication configurations for common id ``` -### Auth0 +#### Auth0 ```xml @@ -93,7 +107,7 @@ The following examples show complete authentication configurations for common id ``` -### Keycloak +#### Keycloak ```xml @@ -107,6 +121,67 @@ The following examples show complete authentication configurations for common id ``` +## 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. + ## Limitations ### Anonymous endpoints 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/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md index 654c2c840a5..4bf047a6ca3 100644 --- a/servicecontrol/security/configuration/forward-headers.md +++ b/servicecontrol/security/configuration/forward-headers.md @@ -1,5 +1,5 @@ --- -title: ServiceControl Forward Headers Configuration +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 @@ -58,6 +58,24 @@ When using a reverse proxy that terminates SSL, you can configure ServiceControl 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) diff --git a/servicecontrol/security/configuration/hsts-considerations.include.md b/servicecontrol/security/configuration/hsts-considerations.include.md new file mode 100644 index 00000000000..8f089b3d11b --- /dev/null +++ b/servicecontrol/security/configuration/hsts-considerations.include.md @@ -0,0 +1,8 @@ +### HSTS Considerations + +- HSTS should not be tested on localhost because browsers cache the policy, which could break other local development +- HSTS is disabled in Development environment (ASP.NET Core excludes localhost by default) +- HSTS can be configured at either the reverse proxy level or in ServiceControl (but not both) +- HSTS is cached by browsers, so test carefully before enabling in production +- Start with a short max-age during initial deployment +- Consider the impact on subdomains before enabling `includeSubDomains` \ No newline at end of file diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index ffcc19b669a..5aae0e9670b 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -31,24 +31,9 @@ include: servicecontrol-instance-prefix ## Security Considerations -### Certificate Management - -- ServiceControl supports PFX (PKCS#12) certificate files -- Store certificate files securely with appropriate file permissions -- Rotate certificates before expiration -- Use certificates from a trusted Certificate Authority for production -- Never commit certificate files to source control -- Restrict read access to the certificate file to only the ServiceControl service account -- Use environment variables rather than App.config (environment variables are not persisted to disk) - -### HSTS Considerations - -- HSTS should not be tested on localhost because browsers cache the policy, which could break other local development -- HSTS is disabled in Development environment (ASP.NET Core excludes localhost by default) -- HSTS can be configured at either the reverse proxy level or in ServiceControl (but not both) -- HSTS is cached by browsers, so test carefully before enabling in production -- Start with a short max-age during initial deployment -- Consider the impact on subdomains before enabling `includeSubDomains` +include: cert-management + +include: hsts-considerations ### HTTP to HTTPS Redirect diff --git a/servicecontrol/security/entra-id-authentication.md b/servicecontrol/security/entra-id-authentication.md index 4a49cf7c163..6ebb4be31aa 100644 --- a/servicecontrol/security/entra-id-authentication.md +++ b/servicecontrol/security/entra-id-authentication.md @@ -1,5 +1,5 @@ --- -title: Microsoft Entra ID authentication +title: Microsoft Entra ID Authentication Guide summary: Set up authentication with Microsoft Entra ID for ServiceControl and ServicePulse reviewed: 2026-01-13 component: ServiceControl diff --git a/servicecontrol/security/hosting-guide.md b/servicecontrol/security/hosting-guide.md index 7957a99e6ae..e2b33a3825c 100644 --- a/servicecontrol/security/hosting-guide.md +++ b/servicecontrol/security/hosting-guide.md @@ -45,6 +45,8 @@ The default configuration with no additional setup required. Backwards compatibl | Forwarded Headers | ✅ Enabled (trusts all) | | Restricted Proxy Trust | ❌ Disabled | +#### Example Configuration + ```xml @@ -65,15 +67,20 @@ Or explicitly:
``` -### Scenario 1: Strict Reverse Proxy with Authentication +### 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 -```text -Client → HTTPS → Reverse Proxy → HTTP → ServiceControl - (SSL termination) (JWT validation) +```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 @@ -132,11 +139,14 @@ Client → HTTPS → Reverse Proxy → HTTP → ServiceControl Kestrel handles TLS directly with JWT authentication without a reverse proxy. -**Architecture:** +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant SC as ServiceControl (Kestrel)
(TLS + JWT validation) -```text -Client → HTTPS → ServiceControl (Kestrel) - (TLS + JWT validation) + Client->>SC: HTTPS ``` #### Security Features @@ -193,11 +203,16 @@ Client → HTTPS → ServiceControl (Kestrel) 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:** +#### Architecture + +```mermaid +sequenceDiagram + participant Client + participant RP as Reverse Proxy
(TLS termination) + participant SC as ServiceControl (Kestrel)
(TLS + JWT validation) -```text -Client → HTTPS → Reverse Proxy → HTTPS → ServiceControl (Kestrel) - (TLS termination) (TLS + JWT validation) + Client->>RP: HTTPS + RP->>SC: HTTPS ``` #### Security Features @@ -251,18 +266,3 @@ Client → HTTPS → Reverse Proxy → HTTPS → ServiceControl (Kestrel) ``` - -## Scenario Comparison Matrix - -| Feature | Reverse Proxy + Auth | Direct HTTPS + Auth | End-to-End Encryption | -|--------------------------------|:--------------------:|:-------------------:|:---------------------:| -| **JWT Authentication** | ✅ | ✅ | ✅ | -| **Kestrel HTTPS** | ❌ | ✅ | ✅ | -| **HTTPS Redirection** | ✅ (optional) | ✅ | ❌ (at proxy) | -| **HSTS** | ❌ (at proxy) | ✅ | ❌ (at proxy) | -| **Restricted CORS** | ✅ | ✅ | ✅ | -| **Forwarded Headers** | ✅ | ❌ | ✅ | -| **Restricted Proxy Trust** | ✅ | N/A | ✅ | -| **Internal Traffic Encrypted** | ❌ | ✅ | ✅ | -| **Requires Reverse Proxy** | Yes | No | Yes | -| **Certificate Management** | At proxy only | At ServiceControl | Both | \ No newline at end of file diff --git a/servicepulse/security/configuration/authentication.md b/servicepulse/security/configuration/authentication.md index 5f465975871..10050b95fa7 100644 --- a/servicepulse/security/configuration/authentication.md +++ b/servicepulse/security/configuration/authentication.md @@ -6,6 +6,129 @@ component: ServicePulse related: - servicepulse/security/hosting-guide - servicecontrol/security/configuration/authentication +- servicecontrol/security/entra-id-authentication --- -TBA +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-settings). 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 index 9b37f5f7964..129c73346dc 100644 --- a/servicepulse/security/configuration/forward-headers.md +++ b/servicepulse/security/configuration/forward-headers.md @@ -1,5 +1,5 @@ --- -title: ServicePulse Forward Headers Configuration +title: ServicePulse Forward Headers for Reverse Proxy Configuration summary: How to enable and configure forward headers for ServicePulse reviewed: 2026-01-14 component: ServicePulse @@ -8,4 +8,185 @@ related: - servicecontrol/security/configuration/forward-headers --- -TBA +> [!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 (like nginx, Traefik, or a cloud load balancer) that terminates SSL/TLS, 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 and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [TLS](tls.md) configuration settings in a scenario based format. + +| Container Environment Variable | Windows Service Command-Line Argument | Default | Description | +|-------------------------------------------------|---------------------------------------|---------|------------------------------------------------------------------| +| `SERVICEPULSE_FORWARDEDHEADERS_ENABLED` | `--forwardedheadersenabled=` | `true` | Enable forwarded headers processing | +| `SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES` | `--forwardedheaderstrustallproxies=` | `true` | Trust all proxies (auto-disabled if known proxies/networks set) | +| `SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES` | `--forwardedheadersknownproxies=` | (none) | Comma-separated IP addresses of trusted proxies | +| `SERVICEPULSE_FORWARDEDHEADERS_KNOWNNETWORKS` | `--forwardedheadersknownnetworks=` | (none) | Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`) | + +> [!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. + +## 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 forwarded headers 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 +``` diff --git a/servicepulse/security/configuration/index.md b/servicepulse/security/configuration/index.md index 8e9ba1050b9..1d954212a97 100644 --- a/servicepulse/security/configuration/index.md +++ b/servicepulse/security/configuration/index.md @@ -1,6 +1,6 @@ --- title: ServicePulse Security Configuration -summary: ServicePulse security configuration options +summary: How to secure ServicePulse instances reviewed: 2026-01-14 component: ServicePulse related: @@ -8,4 +8,25 @@ related: - servicecontrol/security/hosting-guide --- -TBA +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. + +## Configuration methods + +ServicePulse can be configured differently depending on the hosting option: + +- **Container**: Environment variables (e.g., `SERVICEPULSE_HTTPS_ENABLED`) +- **Windows Service**: Command-line arguments (e.g., `--httpsenabled=`) diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md index da1d14b845d..3096ba7d2ec 100644 --- a/servicepulse/security/configuration/tls.md +++ b/servicepulse/security/configuration/tls.md @@ -8,4 +8,133 @@ related: - servicecontrol/security/configuration/tls --- -TBA +> [!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 and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. + +| Container Environment Variable | Windows Service Command-Line Argument | Default | Description | +|--------------------------------------------|---------------------------------------|------------|----------------------------------------------------------------| +| `SERVICEPULSE_HTTPS_ENABLED` | `--httpsenabled=` | `false` | Enable HTTPS with Kestrel | +| `SERVICEPULSE_HTTPS_CERTIFICATEPATH` | N/A (See note below) | (none) | Path to the certificate file (.pfx) | +| `SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD` | N/A (See note below) | (none) | Password for the certificate file | +| `SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS` | `--httpsredirecthttptohttps=` | `false` | Redirect HTTP requests to HTTPS | +| `SERVICEPULSE_HTTPS_PORT` | `--httpsport=` | (none) | HTTPS port for redirect (required for reverse proxy scenarios) | +| `SERVICEPULSE_HTTPS_ENABLEHSTS` | `--httpsenablehsts=` | `false` | Enable HTTP Strict Transport Security | +| `SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS` | `--httpshstsmaxageseconds=` | `31536000` | HSTS max-age in seconds (default: 1 year) | +| `SERVICEPULSE_HTTPS_HSTSINCLUDESUBDOMAINS` | `--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. + +## 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:** + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=/certs/servicepulse.pfx \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD={certificate-password} \ + -v /path/to/certs:/certs \ + ... + particular/servicepulse:latest +``` + +**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 +``` + +### Direct HTTPS with HSTS + +When ServicePulse handles TLS directly and you want to enable HSTS: + +**Container:** + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=/certs/servicepulse.pfx \ + -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD={certificate-password} \ + -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ + -e SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS=31536000 \ + -v /path/to/certs:/certs \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --httpsenabled=true --httpsenablehsts=true --httpshstsmaxageseconds=31536000 +``` + +### Reverse proxy with HTTP to HTTPS redirect + +When TLS is terminated at a reverse proxy and you want ServicePulse to redirect HTTP requests: + +**Container:** + +```bash +docker run -e SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS=true \ + -e SERVICEPULSE_HTTPS_PORT=443 \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --httpsredirecthttptohttps=true --httpsport=443 +``` + +### Reverse proxy with HSTS + +When TLS is terminated at a reverse proxy and you want ServicePulse to add HSTS headers: + +**Container:** + +```bash +docker run -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ + -e SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS=31536000 \ + -e SERVICEPULSE_HTTPS_HSTSINCLUDESUBDOMAINS=true \ + ... + particular/servicepulse:latest +``` + +**Windows Service:** + +```cmd +ServicePulse.Host.exe --httpsenablehsts=true --httpshstsmaxageseconds=31536000 --httpshstsincludesubdomains=true +``` diff --git a/servicepulse/security/hosting-guide.md b/servicepulse/security/hosting-guide.md index 88e6423c5f6..29f2b2db8cc 100644 --- a/servicepulse/security/hosting-guide.md +++ b/servicepulse/security/hosting-guide.md @@ -10,4 +10,172 @@ related: - servicecontrol/security/hosting-guide --- -TBA +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 index a4e783f7079..11472963c39 100644 --- a/servicepulse/security/index.md +++ b/servicepulse/security/index.md @@ -7,4 +7,80 @@ related: - servicecontrol/security --- -TBA +This section covers security features for ServicePulse, including authentication, transport layer security (TLS), and reverse proxy configuration. + +## In this section + +- [Security Configuration](configuration/) - Configuration reference for TLS and forward headers +- [Hosting Guide](hosting-guide.md) - Deployment scenarios with complete configuration examples + +## Authentication + +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 +``` + +See [ServiceControl Security Overview](/servicecontrol/security/) for complete authentication documentation, or [Microsoft Entra ID](/servicecontrol/security/entra-id-authentication.md) for a step-by-step setup guide. + +## TLS + +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 + +See [TLS Configuration](configuration/tls.md) for settings and certificate management. + +## Reverse proxy support + +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 + +See [Forward Headers Configuration](configuration/forward-headers.md) for settings. + +## 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 From 63277b2ee9dd05874dc0816fa76b597704676c81 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 16:50:22 +0800 Subject: [PATCH 16/27] Remove duplicate config tables and link to instance specific config pages --- menu/menu.yaml | 2 - .../security/configuration/authentication.md | 75 ++----------------- servicecontrol/security/configuration/cors.md | 16 +--- .../security/configuration/forward-headers.md | 20 ++--- .../hsts-considerations.include.md | 9 +-- .../security/configuration/index.md | 6 -- servicecontrol/security/configuration/tls.md | 19 +---- servicecontrol/security/index.md | 45 ++++++++--- .../security/configuration/forward-headers.md | 2 +- servicepulse/security/configuration/index.md | 7 -- servicepulse/security/index.md | 2 - 11 files changed, 55 insertions(+), 148 deletions(-) diff --git a/menu/menu.yaml b/menu/menu.yaml index 7a01b8eebbe..ee878a6d1ab 100644 --- a/menu/menu.yaml +++ b/menu/menu.yaml @@ -1405,7 +1405,6 @@ - Title: Overview Url: servicepulse/security - Title: Configuration - Url: servicepulse/security/configuration Articles: - Title: Authentication Url: servicepulse/security/configuration/authentication @@ -1501,7 +1500,6 @@ - Title: Overview Url: servicecontrol/security - Title: Configuration - Url: servicecontrol/security/configuration Articles: - Title: Authentication Url: servicecontrol/security/configuration/authentication diff --git a/servicecontrol/security/configuration/authentication.md b/servicecontrol/security/configuration/authentication.md index df0e51c00dc..44c65de59e9 100644 --- a/servicecontrol/security/configuration/authentication.md +++ b/servicecontrol/security/configuration/authentication.md @@ -17,43 +17,9 @@ ServiceControl instances can be configured to require [JWT](https://en.wikipedia 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. -include: servicecontrol-instance-prefix - -### Core Settings - -| Environment Variable | App.config | Default | Description | -|-------------------------------------|-------------------------------------|---------|----------------------------------------------------------------------------------------------------| -| `{PREFIX}_AUTHENTICATION_ENABLED` | `{PREFIX}/Authentication.Enabled` | `false` | Enable JWT authentication | -| `{PREFIX}_AUTHENTICATION_AUTHORITY` | `{PREFIX}/Authentication.Authority` | (none) | OpenID Connect authority URL (e.g., `https://login.microsoftonline.com/{tenant-id}/v2.0`) | -| `{PREFIX}_AUTHENTICATION_AUDIENCE` | `{PREFIX}/Authentication.Audience` | (none) | The audience identifier (typically your API identifier or client ID, e.g., `api://servicecontrol`) | - -### Token Validation Settings - -These settings control specific aspects of token validation. The defaults below provide a secure validation process and should not be changed unless there is a specific requirement. - -| Environment Variable | App.config | Default | Description | -|----------------------------------------------------|----------------------------------------------------|---------|----------------------------------------------------------------------------------------------------| -| `{PREFIX}_AUTHENTICATION_VALIDATEISSUER` | `{PREFIX}/Authentication.ValidateIssuer` | `true` | Validates that the token was issued by the configured authority. | -| `{PREFIX}_AUTHENTICATION_VALIDATEAUDIENCE` | `{PREFIX}/Authentication.ValidateAudience` | `true` | Validates that the token contains the expected audience claim. | -| `{PREFIX}_AUTHENTICATION_VALIDATELIFETIME` | `{PREFIX}/Authentication.ValidateLifetime` | `true` | Validates that the token has not expired. | -| `{PREFIX}_AUTHENTICATION_VALIDATEISSUERSIGNINGKEY` | `{PREFIX}/Authentication.ValidateIssuerSigningKey` | `true` | Validates the token signature using keys from the identity provider. | -| `{PREFIX}_AUTHENTICATION_REQUIREHTTPSMETADATA` | `{PREFIX}/Authentication.RequireHttpsMetadata` | `true` | Requires HTTPS when retrieving OpenID Connect metadata. Set to `false` only for local development. | - -### ServicePulse settings - -These settings are served to ServicePulse through a bootstrap endpoint hosting in ServiceControl, allowing ServicePulse to authenticate users without its own configuration file. - -> [!NOTE] -> These settings are only valid on the primary ServiceControl instance. - -| Environment Variable | App.config | Description | -|--------------------------------------------------------|--------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------| -| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_CLIENTID` | `ServiceControl/Authentication.ServicePulse.ClientId` | The OAuth 2.0 client ID for the ServicePulse application registration. | -| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_AUTHORITY` | `ServiceControl/Authentication.ServicePulse.Authority` | The OpenID Connect authority URL for ServicePulse authentication. For Microsoft Entra ID, this typically includes `/v2.0` at the end. | -| `SERVICECONTROL_AUTHENTICATION_SERVICEPULSE_APISCOPES` | `ServiceControl/Authentication.ServicePulse.ApiScopes` | A JSON array of scopes to request when acquiring tokens. For example: `["api://app-id/api.access"]` | - -> [!NOTE] -> The ServicePulse audience Open ID Connect configuration is automatically filled in using the [ServiceControl audience setting](#configuration-core-settings). +- [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 @@ -77,7 +43,7 @@ For step-by-step instructions on configuring specific identity providers, see: ### Configuration examples -The following examples show complete authentication configurations for common identity providers. +The following examples show complete authentication configurations for common identity providers using the primary ServiceControl instance. #### Microsoft Entra ID @@ -182,41 +148,10 @@ JWT tokens are time-sensitive. If server clocks are not synchronized: **Solution:** Ensure all servers are using NTP to synchronize their clocks. -## Limitations - -### Anonymous endpoints - -The following endpoints are accessible without authentication, even when authentication is enabled: - -| Endpoint | Purpose | -|-------------------------------------|--------------------------------------------------------------------| -| `/api/authentication/configuration` | Returns authentication configuration for clients like ServicePulse | - -This endpoint must remain accessible so clients can obtain the authentication configuration needed to acquire tokens before authenticating. - -### Scatter-gather endpoints - -The Primary ServiceControl instance communicates with other ServiceControl instances to aggregate data. The following endpoints support this scatter-gather communication and are accessible without authentication: - -| Endpoint | Purpose | -|------------------------------|-----------------------------------------------------------| -| `/api` | API root/discovery - returns available endpoints | -| `/api/instance-info` | Returns instance configuration information | -| `/api/configuration` | Returns instance configuration information (alias) | -| `/api/configuration/remotes` | Returns remote instance configurations for scatter-gather | - -These endpoints allow the Primary instance to discover remote instances. - -### Same Authentication Configuration Required +## 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 - -### 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 diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md index c127af20fdb..ca2031dfd08 100644 --- a/servicecontrol/security/configuration/cors.md +++ b/servicecontrol/security/configuration/cors.md @@ -13,17 +13,9 @@ Cross-Origin Resource Sharing (CORS) controls which web applications can make re 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. -include: servicecontrol-instance-prefix - -### Settings - -| Environment Variable | App.config | Default | Description | -|-----------------------------------|-----------------------------------|---------|--------------------------------------------------| -| `{PREFIX}_CORS_ALLOWANYORIGIN` | `{PREFIX}/Cors.AllowAnyOrigin` | `true` | Allow requests from any origin | -| `{PREFIX}_CORS_ALLOWEDORIGINS` | `{PREFIX}/Cors.AllowedOrigins` | (none) | Comma-separated list of allowed origins | - -> [!WARNING] -> The default configuration (`AllowAnyOrigin = true`) allows any website to make requests to ServiceControl. For production deployments, set `AllowAnyOrigin` to `false` and configure `AllowedOrigins` to restrict access to trusted domains only. +- [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 @@ -34,7 +26,7 @@ CORS configuration is required when: ## Configuration example -To restrict access to only your ServicePulse domain: +To restrict access to only your ServicePulse domain, using the primary ServiceControl instance: ```xml diff --git a/servicecontrol/security/configuration/forward-headers.md b/servicecontrol/security/configuration/forward-headers.md index 4bf047a6ca3..af98d8d5224 100644 --- a/servicecontrol/security/configuration/forward-headers.md +++ b/servicecontrol/security/configuration/forward-headers.md @@ -8,25 +8,15 @@ related: - servicepulse/security/configuration/forward-headers --- -When ServiceControl instances are deployed behind a reverse proxy (like NGINX, Traefik, or a cloud load balancer) that terminates SSL/TLS, you need to configure forwarded headers so ServiceControl correctly understands the original client request. +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. -include: servicecontrol-instance-prefix - -### Settings - -| Environment Variable | App.config | Default | Description | -|---------------------------------------------|---------------------------------------------|---------|------------------------------------------------------------------------------| -| `{PREFIX}_FORWARDEDHEADERS_ENABLED` | `{PREFIX}/ForwardedHeaders.Enabled` | `true` | Enable forwarded headers processing | -| `{PREFIX}_FORWARDEDHEADERS_TRUSTALLPROXIES` | `{PREFIX}/ForwardedHeaders.TrustAllProxies` | `true` | Trust all proxies (auto-disabled if known proxies/networks set) | -| `{PREFIX}_FORWARDEDHEADERS_KNOWNPROXIES` | `{PREFIX}/ForwardedHeaders.KnownProxies` | (none) | Comma-separated IP addresses of trusted proxies (e.g., `127.0.0.1,10.0.0.5`) | -| `{PREFIX}_FORWARDEDHEADERS_KNOWNNETWORKS` | `{PREFIX}/ForwardedHeaders.KnownNetworks` | (none) | Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`) | - -> [!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. +- [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 @@ -94,7 +84,7 @@ For example, with `X-Forwarded-For: 203.0.113.50, 10.0.0.1, 192.168.1.1`: ## Configuration examples -The following examples show common forwarded headers configurations for different deployment scenarios. +The following examples show common forwarded headers configurations for different deployment scenarios using the primary ServiceControl instance. ### Single reverse proxy (known IP) diff --git a/servicecontrol/security/configuration/hsts-considerations.include.md b/servicecontrol/security/configuration/hsts-considerations.include.md index 8f089b3d11b..692f8a9a0c2 100644 --- a/servicecontrol/security/configuration/hsts-considerations.include.md +++ b/servicecontrol/security/configuration/hsts-considerations.include.md @@ -1,8 +1,3 @@ -### HSTS Considerations +### HSTS -- HSTS should not be tested on localhost because browsers cache the policy, which could break other local development -- HSTS is disabled in Development environment (ASP.NET Core excludes localhost by default) -- HSTS can be configured at either the reverse proxy level or in ServiceControl (but not both) -- HSTS is cached by browsers, so test carefully before enabling in production -- Start with a short max-age during initial deployment -- Consider the impact on subdomains before enabling `includeSubDomains` \ No newline at end of file +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 index 6ab62c0a30d..4ba0fac2b2b 100644 --- a/servicecontrol/security/configuration/index.md +++ b/servicecontrol/security/configuration/index.md @@ -27,9 +27,3 @@ Configure forwarded header processing for deployments behind a reverse proxy. En ### [CORS](cors.md) Configure Cross-Origin Resource Sharing to control which web applications can access the ServiceControl API. - -## Configuration methods - -ServiceControl instances can be configured via environment variables or App.config. Each instance type uses a different prefix: - -include: servicecontrol-instance-prefix diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index 5aae0e9670b..bd85ae9e479 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -14,20 +14,9 @@ ServiceControl instances can be configured to use HTTPS directly, enabling encry 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 conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. -include: servicecontrol-instance-prefix - -### Settings - -| Environment Variable | App.config | Default | Description | -|----------------------------------------|----------------------------------------------|------------|----------------------------------------------------------------| -| `{PREFIX}_HTTPS_ENABLED` | `{PREFIX}/Https.Enabled` | `false` | Enable HTTPS with Kestrel | -| `{PREFIX}_HTTPS_CERTIFICATEPATH` | `{PREFIX}/Https.CertificatePath` | (none) | Path to the certificate file (.pfx) | -| `{PREFIX}_HTTPS_CERTIFICATEPASSWORD` | `{PREFIX}/Https.CertificatePassword` | (none) | Password for the certificate file | -| `{PREFIX}_HTTPS_REDIRECTHTTPTOHTTPS` | `ServiceControl/Https.RedirectHttpToHttps` | `false` | Redirect HTTP requests to HTTPS | -| `{PREFIX}_HTTPS_PORT` | `ServiceControl/Https.Port` | (none) | HTTPS port for redirect (required for reverse proxy scenarios) | -| `{PREFIX}_HTTPS_ENABLEHSTS` | `{PREFIX}/Https.EnableHsts` | `false` | Enable HTTP Strict Transport Security | -| `{PREFIX}_HTTPS_HSTSMAXAGESECONDS` | `ServiceControl/Https.HstsMaxAgeSeconds` | `31536000` | HSTS max-age in seconds (default: 1 year) | -| `{PREFIX}_HTTPS_HSTSINCLUDESUBDOMAINS` | `ServiceControl/Https.HstsIncludeSubDomains` | `false` | Include subdomains in HSTS policy | +- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#https) +- [Audit Instance](/servicecontrol/audit-instances/configuration.md#https) +- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#https) ## Security Considerations @@ -49,7 +38,7 @@ The `HTTPS_REDIRECTHTTPTOHTTPS` setting is intended for use with a reverse proxy ## Configuration examples -The following examples show common TLS configurations for different deployment scenarios. +The following examples show common TLS configurations for different deployment scenarios using the primary ServiceControl instance. ### Direct HTTPS with certificate diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 965f6eedb0d..8e8f2bbd0b5 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -11,11 +11,11 @@ This section covers security features for ServiceControl, including authenticati ## In this section -- [Security Configuration](configuration/) - Configuration reference for authentication, TLS, and forward headers +- 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 +## [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. @@ -60,9 +60,36 @@ sequenceDiagram Certain endpoints remain accessible without authentication to support API discovery, client bootstrapping, and scatter-gather communication between ServiceControl instances. See [Authentication Configuration](configuration/authentication.md#limitations) for the full list of anonymous endpoints and security considerations. -See [Authentication Configuration](configuration/authentication.md) for settings, or [Microsoft Entra ID](entra-id-authentication.md) for a complete setup guide. +### Anonymous endpoints -## TLS +The following endpoints are accessible without authentication, even when authentication is enabled: + +| Endpoint | Purpose | +|-------------------------------------|--------------------------------------------------------------------| +| `/api/authentication/configuration` | Returns authentication configuration for clients like ServicePulse | + +This endpoint must remain accessible so clients can obtain the authentication configuration needed to acquire tokens before authenticating. + +### Scatter-gather endpoints + +The Primary ServiceControl instance communicates with other ServiceControl instances to aggregate data. The following endpoints support this scatter-gather communication and are accessible without authentication: + +| Endpoint | Purpose | +|------------------------------|-----------------------------------------------------------| +| `/api` | API root/discovery - returns available endpoints | +| `/api/instance-info` | Returns instance configuration information | +| `/api/configuration` | Returns instance configuration information (alias) | +| `/api/configuration/remotes` | Returns remote instance configurations for scatter-gather | + +These endpoints allow the Primary instance to discover remote instances. + +### 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. @@ -74,9 +101,7 @@ 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 -See [TLS Configuration](configuration/tls.md) for settings and certificate management. - -## Reverse proxy support +## [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: @@ -84,11 +109,9 @@ When ServiceControl runs behind a reverse proxy, forwarded headers ensure Servic - Understanding whether the original request used HTTPS - Generating correct redirect URLs -See [Forward Headers Configuration](configuration/forward-headers.md) for settings. - -## Deployment scenarios +## [Deployment scenarios](hosting-guide.md) -The [Hosting Guide](hosting-guide.md) provides complete configuration examples for common deployment patterns: +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 diff --git a/servicepulse/security/configuration/forward-headers.md b/servicepulse/security/configuration/forward-headers.md index 129c73346dc..0e429683a22 100644 --- a/servicepulse/security/configuration/forward-headers.md +++ b/servicepulse/security/configuration/forward-headers.md @@ -11,7 +11,7 @@ related: > [!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 (like nginx, Traefik, or a cloud load balancer) that terminates SSL/TLS, you need to configure forwarded headers so ServicePulse correctly understands the original client request. +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 diff --git a/servicepulse/security/configuration/index.md b/servicepulse/security/configuration/index.md index 1d954212a97..e927071ab38 100644 --- a/servicepulse/security/configuration/index.md +++ b/servicepulse/security/configuration/index.md @@ -23,10 +23,3 @@ Enable encrypted connections by configuring ServicePulse to use HTTPS directly. ### [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. - -## Configuration methods - -ServicePulse can be configured differently depending on the hosting option: - -- **Container**: Environment variables (e.g., `SERVICEPULSE_HTTPS_ENABLED`) -- **Windows Service**: Command-line arguments (e.g., `--httpsenabled=`) diff --git a/servicepulse/security/index.md b/servicepulse/security/index.md index 11472963c39..a024f95e0c2 100644 --- a/servicepulse/security/index.md +++ b/servicepulse/security/index.md @@ -50,8 +50,6 @@ sequenceDiagram ServicePulse-->>User: Display data ``` -See [ServiceControl Security Overview](/servicecontrol/security/) for complete authentication documentation, or [Microsoft Entra ID](/servicecontrol/security/entra-id-authentication.md) for a step-by-step setup guide. - ## TLS When authentication is enabled, access tokens are exchanged between ServicePulse and ServiceControl. To protect these tokens, TLS must be enabled. From b16054d487fe292334cefadb66e5799aefe69d2a Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 22:06:20 +0800 Subject: [PATCH 17/27] Add ServicePulse config. Add more linking. Add troubleshooting section to configs. --- .../audit-instances/configuration.md | 78 ++++----- .../monitoring-instances/configuration.md | 80 ++++----- servicecontrol/security/configuration/cors.md | 53 ++++++ .../forward-header-troubleshooting.include.md | 56 ++++++ .../security/configuration/forward-headers.md | 4 + .../tls-troubleshooting.include.md | 50 ++++++ servicecontrol/security/configuration/tls.md | 4 + servicecontrol/security/index.md | 2 +- .../servicecontrol-instances/configuration.md | 92 +++++----- servicepulse/containerization/index.md | 161 ++++++++++++++++++ .../security/configuration/forward-headers.md | 33 ++-- servicepulse/security/configuration/tls.md | 48 ++++-- servicepulse/security/index.md | 12 +- 13 files changed, 519 insertions(+), 154 deletions(-) create mode 100644 servicecontrol/security/configuration/forward-header-troubleshooting.include.md create mode 100644 servicecontrol/security/configuration/tls-troubleshooting.include.md diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index 6ea9b377a53..ecab687718c 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -153,13 +153,13 @@ Run [ServiceControl audit instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | boolean | `False` | -## Authentication +## [Authentication](/servicecontrol/security/configuration/authentication.md) -These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). +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.9.0_ +_Added in version 6.10.0_ Enables or disables authentication. @@ -175,7 +175,7 @@ Enables or disables authentication. ### ServiceControl.Audit/Authentication.Authority -_Added in version 6.9.0_ +_Added in version 6.10.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -191,7 +191,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### ServiceControl.Audit/Authentication.Audience -_Added in version 6.9.0_ +_Added in version 6.10.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -207,7 +207,7 @@ The expected audience value in the JWT token, typically the application ID or UR ### ServiceControl.Audit/Authentication.ValidateIssuer -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token issuer is validated against the authority. @@ -223,7 +223,7 @@ Controls whether the token issuer is validated against the authority. ### ServiceControl.Audit/Authentication.ValidateAudience -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token audience is validated. @@ -239,7 +239,7 @@ Controls whether the token audience is validated. ### ServiceControl.Audit/Authentication.ValidateLifetime -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token expiration is validated. @@ -255,7 +255,7 @@ Controls whether the token expiration is validated. ### ServiceControl.Audit/Authentication.ValidateIssuerSigningKey -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token signing key is validated. @@ -271,7 +271,7 @@ Controls whether the token signing key is validated. ### ServiceControl.Audit/Authentication.RequireHttpsMetadata -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -288,13 +288,13 @@ Controls whether HTTPS is required when retrieving metadata from the authority. > [!WARNING] > Setting this to `false` is not recommended for production environments. -## HTTPS +## [TLS](/servicecontrol/security/configuration/tls.md) -These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables Kestrel HTTPS with a certificate. @@ -310,7 +310,7 @@ Enables Kestrel HTTPS with a certificate. ### ServiceControl.Audit/Https.CertificatePath -_Added in version 6.9.0_ +_Added in version 6.10.0_ The path to the PFX or PEM certificate file. @@ -326,7 +326,7 @@ The path to the PFX or PEM certificate file. ### ServiceControl.Audit/Https.CertificatePassword -_Added in version 6.9.0_ +_Added in version 6.10.0_ The password for the certificate file, if required. @@ -342,7 +342,7 @@ The password for the certificate file, if required. ### ServiceControl.Audit/Https.RedirectHttpToHttps -_Added in version 6.9.0_ +_Added in version 6.10.0_ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. @@ -356,9 +356,12 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -374,7 +377,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### ServiceControl.Audit/Https.EnableHsts -_Added in version 6.9.0_ +_Added in version 6.10.0_ Enables HTTP Strict Transport Security (HSTS). @@ -388,9 +391,12 @@ Enables HTTP Strict Transport Security (HSTS). | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The max-age value in seconds for the HSTS header. @@ -406,7 +412,7 @@ The max-age value in seconds for the HSTS header. ### ServiceControl.Audit/Https.HstsIncludeSubDomains -_Added in version 6.9.0_ +_Added in version 6.10.0_ Includes subdomains in the HSTS policy. @@ -420,13 +426,13 @@ Includes subdomains in the HSTS policy. | --- | --- | | bool | `false` | -## Forwarded headers +## [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) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -442,7 +448,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### ServiceControl.Audit/ForwardedHeaders.TrustAllProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -461,9 +467,9 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### ServiceControl.Audit/ForwardedHeaders.KnownProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted proxy IP addresses. +A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` | Context | Name | | --- | --- | @@ -475,13 +481,11 @@ A comma-separated list of trusted proxy IP addresses. | --- | --- | | string | None | -Example: `127.0.0.1` - ### ServiceControl.Audit/ForwardedHeaders.KnownNetworks -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted CIDR network ranges. +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/8,172.16.0.0/12` | Context | Name | | --- | --- | @@ -493,15 +497,13 @@ A comma-separated list of trusted CIDR network ranges. | --- | --- | | string | None | -Example: `10.0.0.0/8,172.16.0.0/12` - -## CORS +## [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) for additional information. +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.9.0_ +_Added in version 6.10.0_ Allows requests from any origin. @@ -520,9 +522,9 @@ Allows requests from any origin. ### ServiceControl.Audit/Cors.AllowedOrigins -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of allowed origins. +A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` | Context | Name | | --- | --- | @@ -534,8 +536,6 @@ A comma-separated list of allowed origins. | --- | --- | | string | None | -Example: `https://servicepulse.example.com,https://admin.example.com` - ## 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 beab3f0b85f..40805722163 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -93,13 +93,13 @@ 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 +## [Authentication](/servicecontrol/security/configuration/authentication.md) -These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). +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.9.0_ +_Added in version 6.10.0_ Enables or disables authentication. @@ -115,7 +115,7 @@ Enables or disables authentication. ### Monitoring/Authentication.Authority -_Added in version 6.9.0_ +_Added in version 6.10.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -131,7 +131,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### Monitoring/Authentication.Audience -_Added in version 6.9.0_ +_Added in version 6.10.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -147,7 +147,7 @@ The expected audience value in the JWT token, typically the application ID or UR ### Monitoring/Authentication.ValidateIssuer -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token issuer is validated against the authority. @@ -163,7 +163,7 @@ Controls whether the token issuer is validated against the authority. ### Monitoring/Authentication.ValidateAudience -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token audience is validated. @@ -179,7 +179,7 @@ Controls whether the token audience is validated. ### Monitoring/Authentication.ValidateLifetime -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token expiration is validated. @@ -195,7 +195,7 @@ Controls whether the token expiration is validated. ### Monitoring/Authentication.ValidateIssuerSigningKey -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token signing key is validated. @@ -211,7 +211,7 @@ Controls whether the token signing key is validated. ### Monitoring/Authentication.RequireHttpsMetadata -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -228,13 +228,13 @@ Controls whether HTTPS is required when retrieving metadata from the authority. > [!WARNING] > Setting this to `false` is not recommended for production environments. -## HTTPS +## [TLS](/servicecontrol/security/configuration/tls.md) -These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables Kestrel HTTPS with a certificate. @@ -250,7 +250,7 @@ Enables Kestrel HTTPS with a certificate. ### Monitoring/Https.CertificatePath -_Added in version 6.9.0_ +_Added in version 6.10.0_ The path to the PFX or PEM certificate file. @@ -266,7 +266,7 @@ The path to the PFX or PEM certificate file. ### Monitoring/Https.CertificatePassword -_Added in version 6.9.0_ +_Added in version 6.10.0_ The password for the certificate file, if required. @@ -282,7 +282,7 @@ The password for the certificate file, if required. ### Monitoring/Https.RedirectHttpToHttps -_Added in version 6.9.0_ +_Added in version 6.10.0_ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. @@ -296,9 +296,12 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -314,7 +317,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### Monitoring/Https.EnableHsts -_Added in version 6.9.0_ +_Added in version 6.10.0_ Enables HTTP Strict Transport Security (HSTS). @@ -328,9 +331,12 @@ Enables HTTP Strict Transport Security (HSTS). | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The max-age value in seconds for the HSTS header. @@ -346,7 +352,7 @@ The max-age value in seconds for the HSTS header. ### Monitoring/Https.HstsIncludeSubDomains -_Added in version 6.9.0_ +_Added in version 6.10.0_ Includes subdomains in the HSTS policy. @@ -360,13 +366,13 @@ Includes subdomains in the HSTS policy. | --- | --- | | bool | `false` | -## Forwarded headers +## [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) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -382,7 +388,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### Monitoring/ForwardedHeaders.TrustAllProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -401,9 +407,9 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### Monitoring/ForwardedHeaders.KnownProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted proxy IP addresses. +A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` | Context | Name | | --- | --- | @@ -415,13 +421,11 @@ A comma-separated list of trusted proxy IP addresses. | --- | --- | | string | None | -Example: `127.0.0.1` - ### Monitoring/ForwardedHeaders.KnownNetworks -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted CIDR network ranges. +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/8,172.16.0.0/12` | Context | Name | | --- | --- | @@ -431,17 +435,15 @@ A comma-separated list of trusted CIDR network ranges. | Type | Default value | | --- | --- | -| string | None | +| string | None | -Example: `10.0.0.0/8,172.16.0.0/12` +## [CORS](/servicecontrol/security/configuration/cors.md) -## CORS - -These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. +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.9.0_ +_Added in version 6.10.0_ Allows requests from any origin. @@ -460,9 +462,9 @@ Allows requests from any origin. ### Monitoring/Cors.AllowedOrigins -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of allowed origins. +A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` | Context | Name | | --- | --- | @@ -474,8 +476,6 @@ A comma-separated list of allowed origins. | --- | --- | | string | None | -Example: `https://servicepulse.example.com,https://admin.example.com` - ## Logging ### Monitoring/LogPath diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md index ca2031dfd08..8e7deb27831 100644 --- a/servicecontrol/security/configuration/cors.md +++ b/servicecontrol/security/configuration/cors.md @@ -43,3 +43,56 @@ To allow multiple origins: ``` + +## 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 index af98d8d5224..4660dc8ec2b 100644 --- a/servicecontrol/security/configuration/forward-headers.md +++ b/servicecontrol/security/configuration/forward-headers.md @@ -124,3 +124,7 @@ For development or fully trusted environments (not recommended for production): ``` + +## Troubleshooting + +include: forward-header-troubleshooting diff --git a/servicecontrol/security/configuration/tls-troubleshooting.include.md b/servicecontrol/security/configuration/tls-troubleshooting.include.md new file mode 100644 index 00000000000..b4420ccc9ad --- /dev/null +++ b/servicecontrol/security/configuration/tls-troubleshooting.include.md @@ -0,0 +1,50 @@ +### 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 /path/to/certs:/certs`) + +### 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 certificate is self-signed, expired, or doesn't match the hostname. + +**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 +- For internal/development use, add the self-signed certificate to the trusted root store diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index bd85ae9e479..c0cec357c8b 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -80,3 +80,7 @@ When TLS is terminated at a reverse proxy and you want ServiceControl to add HST ``` + +## Troubleshooting + +include: tls-troubleshooting diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index 8e8f2bbd0b5..b6027da3785 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -58,7 +58,7 @@ sequenceDiagram ServicePulse-->>User: Display data ``` -Certain endpoints remain accessible without authentication to support API discovery, client bootstrapping, and scatter-gather communication between ServiceControl instances. See [Authentication Configuration](configuration/authentication.md#limitations) for the full list of anonymous endpoints and security considerations. +Certain endpoints remain accessible without authentication to support API discovery, client bootstrapping, and scatter-gather communication between ServiceControl instances. ### Anonymous endpoints diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 090d01b3493..5e2af287197 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -175,13 +175,13 @@ Run [ServiceControl error instance in maintenance mode](/servicecontrol/ravendb/ | --- | --- | | bool | False | -## Authentication +## [Authentication](/servicecontrol/security/configuration/authentication.md) -These settings configure [authentication using OAuth 2.0 and OpenID Connect](/servicecontrol/security/). +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.9.0_ +_Added in version 6.10.0_ Enables or disables authentication. @@ -197,7 +197,7 @@ Enables or disables authentication. ### ServiceControl/Authentication.Authority -_Added in version 6.9.0_ +_Added in version 6.10.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -213,7 +213,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### ServiceControl/Authentication.Audience -_Added in version 6.9.0_ +_Added in version 6.10.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -227,9 +227,12 @@ The expected audience value in the JWT token, typically the application ID or UR | --- | --- | | string | None | +> [!NOTE] +> ServicePulse with use this ServiceControl audience setting. + ### ServiceControl/Authentication.ValidateIssuer -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token issuer is validated against the authority. @@ -245,7 +248,7 @@ Controls whether the token issuer is validated against the authority. ### ServiceControl/Authentication.ValidateAudience -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token audience is validated. @@ -261,7 +264,7 @@ Controls whether the token audience is validated. ### ServiceControl/Authentication.ValidateLifetime -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token expiration is validated. @@ -277,7 +280,7 @@ Controls whether the token expiration is validated. ### ServiceControl/Authentication.ValidateIssuerSigningKey -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether the token signing key is validated. @@ -293,7 +296,7 @@ Controls whether the token signing key is validated. ### ServiceControl/Authentication.RequireHttpsMetadata -_Added in version 6.9.0_ +_Added in version 6.10.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -312,7 +315,7 @@ Controls whether HTTPS is required when retrieving metadata from the authority. ### ServiceControl/Authentication.ServicePulse.ClientId -_Added in version 6.9.0_ +_Added in version 6.10.0_ The client ID for ServicePulse to use when authenticating with the identity provider. @@ -328,7 +331,7 @@ The client ID for ServicePulse to use when authenticating with the identity prov ### ServiceControl/Authentication.ServicePulse.Authority -_Added in version 6.9.0_ +_Added in version 6.10.0_ The URL of the OpenID Connect authority for ServicePulse to use when authenticating users. @@ -344,9 +347,9 @@ The URL of the OpenID Connect authority for ServicePulse to use when authenticat ### ServiceControl/Authentication.ServicePulse.ApiScopes -_Added in version 6.9.0_ +_Added in version 6.10.0_ -The API scopes for ServicePulse to request when authenticating. This is a JSON array of scope strings. +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 | | --- | --- | @@ -358,16 +361,13 @@ The API scopes for ServicePulse to request when authenticating. This is a JSON a | --- | --- | | string (JSON array) | None | -Example: `["api://12345678-90ab-cdef-1234-567890abcdef/api.access"]` -> **Note:** Replace the above Application ID URI with your actual Application (client) ID. - -## HTTPS +## [TLS](/servicecontrol/security/configuration/tls.md) -These settings configure HTTPS. Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables Kestrel HTTPS with a certificate. @@ -383,7 +383,7 @@ Enables Kestrel HTTPS with a certificate. ### ServiceControl/Https.CertificatePath -_Added in version 6.9.0_ +_Added in version 6.10.0_ The path to the PFX or PEM certificate file. @@ -399,7 +399,7 @@ The path to the PFX or PEM certificate file. ### ServiceControl/Https.CertificatePassword -_Added in version 6.9.0_ +_Added in version 6.10.0_ The password for the certificate file, if required. @@ -415,7 +415,7 @@ The password for the certificate file, if required. ### ServiceControl/Https.RedirectHttpToHttps -_Added in version 6.9.0_ +_Added in version 6.10.0_ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy that handles both HTTP and HTTPS traffic. @@ -429,9 +429,12 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -447,7 +450,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### ServiceControl/Https.EnableHsts -_Added in version 6.9.0_ +_Added in version 6.10.0_ Enables HTTP Strict Transport Security (HSTS). @@ -461,9 +464,12 @@ Enables HTTP Strict Transport Security (HSTS). | --- | --- | | 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.9.0_ +_Added in version 6.10.0_ The max-age value in seconds for the HSTS header. @@ -479,7 +485,7 @@ The max-age value in seconds for the HSTS header. ### ServiceControl/Https.HstsIncludeSubDomains -_Added in version 6.9.0_ +_Added in version 6.10.0_ Includes subdomains in the HSTS policy. @@ -493,13 +499,13 @@ Includes subdomains in the HSTS policy. | --- | --- | | bool | `false` | -## Forwarded headers +## [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) for additional information. +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.9.0_ +_Added in version 6.10.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -515,7 +521,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### ServiceControl/ForwardedHeaders.TrustAllProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -534,9 +540,9 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### ServiceControl/ForwardedHeaders.KnownProxies -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted proxy IP addresses. +A comma-separated list of trusted proxy IP addresses e.g., `10.0.0.5,10.0.0.6` | Context | Name | | --- | --- | @@ -548,13 +554,11 @@ A comma-separated list of trusted proxy IP addresses. | --- | --- | | string | None | -Example: `10.0.0.5,10.0.0.6` - ### ServiceControl/ForwardedHeaders.KnownNetworks -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of trusted CIDR network ranges. +A comma-separated list of trusted CIDR network ranges e.g., `10.0.0.0/24,192.168.1.0/24` | Context | Name | | --- | --- | @@ -566,15 +570,13 @@ A comma-separated list of trusted CIDR network ranges. | --- | --- | | string | None | -Example: `10.0.0.0/24,192.168.1.0/24` +## [CORS](/servicecontrol/security/configuration/cors.md) -## CORS - -These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hosting and security guide](/servicecontrol/security/hosting-guide.md) for additional information. +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.9.0_ +_Added in version 6.10.0_ Allows requests from any origin. @@ -593,9 +595,9 @@ Allows requests from any origin. ### ServiceControl/Cors.AllowedOrigins -_Added in version 6.9.0_ +_Added in version 6.10.0_ -A comma-separated list of allowed origins. +A comma-separated list of allowed origins e.g., `https://servicepulse.yourcompany.com,https://admin.yourcompany.com` | Context | Name | | --- | --- | @@ -607,8 +609,6 @@ A comma-separated list of allowed origins. | --- | --- | | string | None | -Example: `https://servicepulse.yourcompany.com,https://admin.yourcompany.com` - ## 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/forward-headers.md b/servicepulse/security/configuration/forward-headers.md index 0e429683a22..7a71e75bed6 100644 --- a/servicepulse/security/configuration/forward-headers.md +++ b/servicepulse/security/configuration/forward-headers.md @@ -17,15 +17,24 @@ When ServicePulse is deployed behind a reverse proxy that terminates SSL/TLS (li There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [TLS](tls.md) configuration settings in a scenario based format. -| Container Environment Variable | Windows Service Command-Line Argument | Default | Description | -|-------------------------------------------------|---------------------------------------|---------|------------------------------------------------------------------| -| `SERVICEPULSE_FORWARDEDHEADERS_ENABLED` | `--forwardedheadersenabled=` | `true` | Enable forwarded headers processing | -| `SERVICEPULSE_FORWARDEDHEADERS_TRUSTALLPROXIES` | `--forwardedheaderstrustallproxies=` | `true` | Trust all proxies (auto-disabled if known proxies/networks set) | -| `SERVICEPULSE_FORWARDEDHEADERS_KNOWNPROXIES` | `--forwardedheadersknownproxies=` | (none) | Comma-separated IP addresses of trusted proxies | -| `SERVICEPULSE_FORWARDEDHEADERS_KNOWNNETWORKS` | `--forwardedheadersknownnetworks=` | (none) | Comma-separated CIDR networks (e.g., `10.0.0.0/8,172.16.0.0/12`) | +### Container -> [!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. +- [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 @@ -116,9 +125,9 @@ 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 +## Configuration examples -The following examples show common forwarded headers configurations for different deployment scenarios. +The following examples show common forward header configurations for different deployment scenarios. ### Single reverse proxy (known IP) @@ -190,3 +199,7 @@ docker run -e SERVICEPULSE_FORWARDEDHEADERS_ENABLED=true \ ```cmd ServicePulse.Host.exe --forwardedheadersenabled=true --forwardedheaderstrustallproxies=true ``` + +## Troubleshooting + +include: forward-header-troubleshooting diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md index 3096ba7d2ec..500cabc1d0f 100644 --- a/servicepulse/security/configuration/tls.md +++ b/servicepulse/security/configuration/tls.md @@ -17,20 +17,30 @@ ServicePulse can be configured to use HTTPS directly, enabling encrypted connect There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. -| Container Environment Variable | Windows Service Command-Line Argument | Default | Description | -|--------------------------------------------|---------------------------------------|------------|----------------------------------------------------------------| -| `SERVICEPULSE_HTTPS_ENABLED` | `--httpsenabled=` | `false` | Enable HTTPS with Kestrel | -| `SERVICEPULSE_HTTPS_CERTIFICATEPATH` | N/A (See note below) | (none) | Path to the certificate file (.pfx) | -| `SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD` | N/A (See note below) | (none) | Password for the certificate file | -| `SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS` | `--httpsredirecthttptohttps=` | `false` | Redirect HTTP requests to HTTPS | -| `SERVICEPULSE_HTTPS_PORT` | `--httpsport=` | (none) | HTTPS port for redirect (required for reverse proxy scenarios) | -| `SERVICEPULSE_HTTPS_ENABLEHSTS` | `--httpsenablehsts=` | `false` | Enable HTTP Strict Transport Security | -| `SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS` | `--httpshstsmaxageseconds=` | `31536000` | HSTS max-age in seconds (default: 1 year) | -| `SERVICEPULSE_HTTPS_HSTSINCLUDESUBDOMAINS` | `--httpshstsincludesubdomains=` | `false` | Include subdomains in HSTS policy | +### 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 @@ -138,3 +148,21 @@ docker run -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ ```cmd ServicePulse.Host.exe --httpsenablehsts=true --httpshstsmaxageseconds=31536000 --httpshstsincludesubdomains=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/index.md b/servicepulse/security/index.md index a024f95e0c2..3cb05999c24 100644 --- a/servicepulse/security/index.md +++ b/servicepulse/security/index.md @@ -11,10 +11,10 @@ This section covers security features for ServicePulse, including authentication ## In this section -- [Security Configuration](configuration/) - Configuration reference for TLS and forward headers +- Security Configuration - Configuration reference for TLS and forward headers - [Hosting Guide](hosting-guide.md) - Deployment scenarios with complete configuration examples -## Authentication +## [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/). @@ -50,7 +50,7 @@ sequenceDiagram ServicePulse-->>User: Display data ``` -## TLS +## [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. @@ -62,9 +62,7 @@ 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 -See [TLS Configuration](configuration/tls.md) for settings and certificate management. - -## Reverse proxy support +## [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: @@ -72,8 +70,6 @@ When ServicePulse runs behind a reverse proxy, forwarded headers ensure ServiceP - Understanding whether the original request used HTTPS - Generating correct redirect URLs -See [Forward Headers Configuration](configuration/forward-headers.md) for settings. - ## Deployment scenarios The [Hosting Guide](hosting-guide.md) provides complete configuration examples for common deployment patterns: From d3cdd7503f63b62e9d2819bc1eb7362bbbf3d23c Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 22:14:22 +0800 Subject: [PATCH 18/27] Fix build issues --- servicecontrol/security/configuration/cors.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/servicecontrol/security/configuration/cors.md b/servicecontrol/security/configuration/cors.md index 8e7deb27831..43725e15219 100644 --- a/servicecontrol/security/configuration/cors.md +++ b/servicecontrol/security/configuration/cors.md @@ -24,7 +24,7 @@ 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 example +## Configuration examples To restrict access to only your ServicePulse domain, using the primary ServiceControl instance: From 7901a19f93a4b3e373bd744ec5c38deee9b7c687 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 14 Jan 2026 22:15:23 +0800 Subject: [PATCH 19/27] Fix build issues --- servicecontrol/security/configuration/tls.md | 6 +++--- servicepulse/security/configuration/authentication.md | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index c0cec357c8b..91a77320930 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -14,9 +14,9 @@ ServiceControl instances can be configured to use HTTPS directly, enabling encry 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 conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. -- [Primary Instance](/servicecontrol/servicecontrol-instances/configuration.md#https) -- [Audit Instance](/servicecontrol/audit-instances/configuration.md#https) -- [Monitoring Instance](/servicecontrol/monitoring-instances/configuration.md#https) +- [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 diff --git a/servicepulse/security/configuration/authentication.md b/servicepulse/security/configuration/authentication.md index 10050b95fa7..6f2ac1a877f 100644 --- a/servicepulse/security/configuration/authentication.md +++ b/servicepulse/security/configuration/authentication.md @@ -16,7 +16,7 @@ ServicePulse supports authentication using [OpenID Connect (OIDC)](https://openi ## Configuration -Authentication in ServicePulse is [configured in the primary ServiceControl instance](/servicecontrol/security/configuration/authentication.md#configuration-servicepulse-settings). ServicePulse fetches authentication settings on startup from the ServiceControl API and the following settings are set: +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 | |--------------|-------------------------------------------------------------------------------| From d14aa3b952ee0a6facb6c5e0269142acb0f51766 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Mon, 19 Jan 2026 20:21:03 +0800 Subject: [PATCH 20/27] Update auth config --- servicecontrol/audit-instances/configuration.md | 2 +- servicecontrol/monitoring-instances/configuration.md | 2 +- servicecontrol/servicecontrol-instances/configuration.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index ecab687718c..1bcb26189ed 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -161,7 +161,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se _Added in version 6.10.0_ -Enables or disables authentication. +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. | Context | Name | | --- | --- | diff --git a/servicecontrol/monitoring-instances/configuration.md b/servicecontrol/monitoring-instances/configuration.md index 40805722163..cefdb98a5c4 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -101,7 +101,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se _Added in version 6.10.0_ -Enables or disables authentication. +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. | Context | Name | | --- | --- | diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 5e2af287197..9e1d0c06625 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -183,7 +183,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se _Added in version 6.10.0_ -Enables or disables authentication. +Enables or disables authentication. This is a **Global switch** and all other authentication settings are ignored unless this is `true`. | Context | Name | | --- | --- | From 59c2c3156466dc76b9ec376f9dfd70bb54780dfa Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Fri, 23 Jan 2026 13:04:35 +0800 Subject: [PATCH 21/27] Update from feedback --- .../security/configuration/tls-troubleshooting.include.md | 2 +- servicecontrol/security/configuration/tls.md | 2 +- servicecontrol/servicecontrol-instances/configuration.md | 6 +++++- servicepulse/security/configuration/forward-headers.md | 2 +- servicepulse/security/configuration/tls.md | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/servicecontrol/security/configuration/tls-troubleshooting.include.md b/servicecontrol/security/configuration/tls-troubleshooting.include.md index b4420ccc9ad..fa8228d9082 100644 --- a/servicecontrol/security/configuration/tls-troubleshooting.include.md +++ b/servicecontrol/security/configuration/tls-troubleshooting.include.md @@ -9,7 +9,7 @@ - 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 /path/to/certs:/certs`) +- For containers, ensure the volume mount is correct (e.g., `-v certificate.pfx:/usr/share/ParticularSoftware/certificate.pfx`) ### HTTPS redirect not working diff --git a/servicecontrol/security/configuration/tls.md b/servicecontrol/security/configuration/tls.md index 91a77320930..7e18a3806d9 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -12,7 +12,7 @@ ServiceControl instances can be configured to use HTTPS directly, enabling encry ## 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 conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. +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) diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 9e1d0c06625..98c85e22f18 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -385,7 +385,11 @@ Enables Kestrel HTTPS with a certificate. _Added in version 6.10.0_ -The path to the PFX or PEM certificate file. +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 | | --- | --- | diff --git a/servicepulse/security/configuration/forward-headers.md b/servicepulse/security/configuration/forward-headers.md index 7a71e75bed6..eedc1ddd2a8 100644 --- a/servicepulse/security/configuration/forward-headers.md +++ b/servicepulse/security/configuration/forward-headers.md @@ -15,7 +15,7 @@ When ServicePulse is deployed behind a reverse proxy that terminates SSL/TLS (li ## Configuration -There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [TLS](tls.md) configuration settings in a scenario based format. +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 diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md index 500cabc1d0f..bb26336d212 100644 --- a/servicepulse/security/configuration/tls.md +++ b/servicepulse/security/configuration/tls.md @@ -15,7 +15,7 @@ ServicePulse can be configured to use HTTPS directly, enabling encrypted connect ## Configuration -There are two hosting options for ServiceControl, [Container](/servicepulse/containerization/) and [Windows Service](/servicepulse/installation.md). The container is configured via environment variables and the windows service is configured using command-line arguments. See the [Hosting Guide](../hosting-guide.md) for example usage of these configuration settings in conjustion with [Authentication](authentication.md) and [Forward Headers](forward-headers.md) configuration settings in a scenario based format. +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 From 88c4112c5899f07b214539404612a7f87b42a52c Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Sat, 24 Jan 2026 11:06:00 +0800 Subject: [PATCH 22/27] Updat anonymous endpoints --- servicecontrol/security/index.md | 35 +++++++++++++------------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index b6027da3785..c7e7b1d8b08 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -58,30 +58,23 @@ sequenceDiagram ServicePulse-->>User: Display data ``` -Certain endpoints remain accessible without authentication to support API discovery, client bootstrapping, and scatter-gather communication between ServiceControl instances. +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 are accessible without authentication, even when authentication is enabled: - -| Endpoint | Purpose | -|-------------------------------------|--------------------------------------------------------------------| -| `/api/authentication/configuration` | Returns authentication configuration for clients like ServicePulse | - -This endpoint must remain accessible so clients can obtain the authentication configuration needed to acquire tokens before authenticating. - -### Scatter-gather endpoints - -The Primary ServiceControl instance communicates with other ServiceControl instances to aggregate data. The following endpoints support this scatter-gather communication and are accessible without authentication: - -| Endpoint | Purpose | -|------------------------------|-----------------------------------------------------------| -| `/api` | API root/discovery - returns available endpoints | -| `/api/instance-info` | Returns instance configuration information | -| `/api/configuration` | Returns instance configuration information (alias) | -| `/api/configuration/remotes` | Returns remote instance configurations for scatter-gather | - -These endpoints allow the Primary instance to discover remote instances. +The following endpoints remain anonymous to support API Discovery, health checks, 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 | +| `/api/connection` | GET | Primary, Audit, Monitoring | API Discovery for the Platform Connector Plugin | +| `/` | GET | Monitoring | API root/discovery - returns instance information | +| `/` | OPTIONS | Monitoring | CORS support - returns supported operations | +| `/endpoints` | OPTIONS | Monitoring | CORS support - returns supported operations | ### Token Forwarding Security Considerations From 9062439ebb86c43f0e23a7a09e546fc087fdd81c Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Tue, 27 Jan 2026 11:52:26 +0800 Subject: [PATCH 23/27] Update anonymous endpoints. --- servicecontrol/security/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index c7e7b1d8b08..f76aa6bb0a0 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -71,7 +71,6 @@ The following endpoints remain anonymous to support API Discovery, health checks | `/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 | -| `/api/connection` | GET | Primary, Audit, Monitoring | API Discovery for the Platform Connector Plugin | | `/` | GET | Monitoring | API root/discovery - returns instance information | | `/` | OPTIONS | Monitoring | CORS support - returns supported operations | | `/endpoints` | OPTIONS | Monitoring | CORS support - returns supported operations | From bde610422ee9b9c72925ce432194334f54388dd3 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Thu, 29 Jan 2026 15:55:58 +0800 Subject: [PATCH 24/27] Add troublshooting for the certificate being in the wrong authorities store. --- .../security/configuration/tls-troubleshooting.include.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/servicecontrol/security/configuration/tls-troubleshooting.include.md b/servicecontrol/security/configuration/tls-troubleshooting.include.md index fa8228d9082..35f0e69f31e 100644 --- a/servicecontrol/security/configuration/tls-troubleshooting.include.md +++ b/servicecontrol/security/configuration/tls-troubleshooting.include.md @@ -47,4 +47,7 @@ - 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 From 4b4c663a6f4f36455a6b20266195d5783dfcd282 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 4 Feb 2026 10:42:52 +0800 Subject: [PATCH 25/27] Update version number for security updates --- .../audit-instances/configuration.md | 44 ++++++++-------- .../monitoring-instances/configuration.md | 44 ++++++++-------- .../servicecontrol-instances/configuration.md | 50 +++++++++---------- 3 files changed, 69 insertions(+), 69 deletions(-) diff --git a/servicecontrol/audit-instances/configuration.md b/servicecontrol/audit-instances/configuration.md index 1bcb26189ed..e7d58b4a882 100644 --- a/servicecontrol/audit-instances/configuration.md +++ b/servicecontrol/audit-instances/configuration.md @@ -159,7 +159,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se ### ServiceControl.Audit/Authentication.Enabled -_Added in version 6.10.0_ +_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`. @@ -175,7 +175,7 @@ Enables or disables authentication. This is a **Global switch** and all other au ### ServiceControl.Audit/Authentication.Authority -_Added in version 6.10.0_ +_Added in version 6.11.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -191,7 +191,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### ServiceControl.Audit/Authentication.Audience -_Added in version 6.10.0_ +_Added in version 6.11.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -207,7 +207,7 @@ The expected audience value in the JWT token, typically the application ID or UR ### ServiceControl.Audit/Authentication.ValidateIssuer -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token issuer is validated against the authority. @@ -223,7 +223,7 @@ Controls whether the token issuer is validated against the authority. ### ServiceControl.Audit/Authentication.ValidateAudience -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token audience is validated. @@ -239,7 +239,7 @@ Controls whether the token audience is validated. ### ServiceControl.Audit/Authentication.ValidateLifetime -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token expiration is validated. @@ -255,7 +255,7 @@ Controls whether the token expiration is validated. ### ServiceControl.Audit/Authentication.ValidateIssuerSigningKey -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token signing key is validated. @@ -271,7 +271,7 @@ Controls whether the token signing key is validated. ### ServiceControl.Audit/Authentication.RequireHttpsMetadata -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -294,7 +294,7 @@ These settings configure HTTPS. Refer to the [hosting and security guide](/servi ### ServiceControl.Audit/Https.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables Kestrel HTTPS with a certificate. @@ -310,7 +310,7 @@ Enables Kestrel HTTPS with a certificate. ### ServiceControl.Audit/Https.CertificatePath -_Added in version 6.10.0_ +_Added in version 6.11.0_ The path to the PFX or PEM certificate file. @@ -326,7 +326,7 @@ The path to the PFX or PEM certificate file. ### ServiceControl.Audit/Https.CertificatePassword -_Added in version 6.10.0_ +_Added in version 6.11.0_ The password for the certificate file, if required. @@ -342,7 +342,7 @@ The password for the certificate file, if required. ### ServiceControl.Audit/Https.RedirectHttpToHttps -_Added in version 6.10.0_ +_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. @@ -361,7 +361,7 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy ### ServiceControl.Audit/Https.Port -_Added in version 6.10.0_ +_Added in version 6.11.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -377,7 +377,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### ServiceControl.Audit/Https.EnableHsts -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables HTTP Strict Transport Security (HSTS). @@ -396,7 +396,7 @@ Enables HTTP Strict Transport Security (HSTS). ### ServiceControl.Audit/Https.HstsMaxAgeSeconds -_Added in version 6.10.0_ +_Added in version 6.11.0_ The max-age value in seconds for the HSTS header. @@ -412,7 +412,7 @@ The max-age value in seconds for the HSTS header. ### ServiceControl.Audit/Https.HstsIncludeSubDomains -_Added in version 6.10.0_ +_Added in version 6.11.0_ Includes subdomains in the HSTS policy. @@ -432,7 +432,7 @@ These settings configure forwarded headers for reverse proxy scenarios. Refer to ### ServiceControl.Audit/ForwardedHeaders.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -448,7 +448,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### ServiceControl.Audit/ForwardedHeaders.TrustAllProxies -_Added in version 6.10.0_ +_Added in version 6.11.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -467,7 +467,7 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### ServiceControl.Audit/ForwardedHeaders.KnownProxies -_Added in version 6.10.0_ +_Added in version 6.11.0_ A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` @@ -483,7 +483,7 @@ A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` ### ServiceControl.Audit/ForwardedHeaders.KnownNetworks -_Added in version 6.10.0_ +_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` @@ -503,7 +503,7 @@ These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hos ### ServiceControl.Audit/Cors.AllowAnyOrigin -_Added in version 6.10.0_ +_Added in version 6.11.0_ Allows requests from any origin. @@ -522,7 +522,7 @@ Allows requests from any origin. ### ServiceControl.Audit/Cors.AllowedOrigins -_Added in version 6.10.0_ +_Added in version 6.11.0_ A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` diff --git a/servicecontrol/monitoring-instances/configuration.md b/servicecontrol/monitoring-instances/configuration.md index cefdb98a5c4..127892a93ab 100644 --- a/servicecontrol/monitoring-instances/configuration.md +++ b/servicecontrol/monitoring-instances/configuration.md @@ -99,7 +99,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se ### Monitoring/Authentication.Enabled -_Added in version 6.10.0_ +_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`. @@ -115,7 +115,7 @@ Enables or disables authentication. This is a **Global switch** and all other au ### Monitoring/Authentication.Authority -_Added in version 6.10.0_ +_Added in version 6.11.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -131,7 +131,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### Monitoring/Authentication.Audience -_Added in version 6.10.0_ +_Added in version 6.11.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -147,7 +147,7 @@ The expected audience value in the JWT token, typically the application ID or UR ### Monitoring/Authentication.ValidateIssuer -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token issuer is validated against the authority. @@ -163,7 +163,7 @@ Controls whether the token issuer is validated against the authority. ### Monitoring/Authentication.ValidateAudience -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token audience is validated. @@ -179,7 +179,7 @@ Controls whether the token audience is validated. ### Monitoring/Authentication.ValidateLifetime -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token expiration is validated. @@ -195,7 +195,7 @@ Controls whether the token expiration is validated. ### Monitoring/Authentication.ValidateIssuerSigningKey -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token signing key is validated. @@ -211,7 +211,7 @@ Controls whether the token signing key is validated. ### Monitoring/Authentication.RequireHttpsMetadata -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -234,7 +234,7 @@ These settings configure HTTPS. Refer to the [hosting and security guide](/servi ### Monitoring/Https.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables Kestrel HTTPS with a certificate. @@ -250,7 +250,7 @@ Enables Kestrel HTTPS with a certificate. ### Monitoring/Https.CertificatePath -_Added in version 6.10.0_ +_Added in version 6.11.0_ The path to the PFX or PEM certificate file. @@ -266,7 +266,7 @@ The path to the PFX or PEM certificate file. ### Monitoring/Https.CertificatePassword -_Added in version 6.10.0_ +_Added in version 6.11.0_ The password for the certificate file, if required. @@ -282,7 +282,7 @@ The password for the certificate file, if required. ### Monitoring/Https.RedirectHttpToHttps -_Added in version 6.10.0_ +_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. @@ -301,7 +301,7 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy ### Monitoring/Https.Port -_Added in version 6.10.0_ +_Added in version 6.11.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -317,7 +317,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### Monitoring/Https.EnableHsts -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables HTTP Strict Transport Security (HSTS). @@ -336,7 +336,7 @@ Enables HTTP Strict Transport Security (HSTS). ### Monitoring/Https.HstsMaxAgeSeconds -_Added in version 6.10.0_ +_Added in version 6.11.0_ The max-age value in seconds for the HSTS header. @@ -352,7 +352,7 @@ The max-age value in seconds for the HSTS header. ### Monitoring/Https.HstsIncludeSubDomains -_Added in version 6.10.0_ +_Added in version 6.11.0_ Includes subdomains in the HSTS policy. @@ -372,7 +372,7 @@ These settings configure forwarded headers for reverse proxy scenarios. Refer to ### Monitoring/ForwardedHeaders.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -388,7 +388,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### Monitoring/ForwardedHeaders.TrustAllProxies -_Added in version 6.10.0_ +_Added in version 6.11.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -407,7 +407,7 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### Monitoring/ForwardedHeaders.KnownProxies -_Added in version 6.10.0_ +_Added in version 6.11.0_ A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` @@ -423,7 +423,7 @@ A comma-separated list of trusted proxy IP addresses e.g., `127.0.0.1` ### Monitoring/ForwardedHeaders.KnownNetworks -_Added in version 6.10.0_ +_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` @@ -443,7 +443,7 @@ These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hos ### Monitoring/Cors.AllowAnyOrigin -_Added in version 6.10.0_ +_Added in version 6.11.0_ Allows requests from any origin. @@ -462,7 +462,7 @@ Allows requests from any origin. ### Monitoring/Cors.AllowedOrigins -_Added in version 6.10.0_ +_Added in version 6.11.0_ A comma-separated list of allowed origins e.g., `https://servicepulse.example.com,https://admin.example.com` diff --git a/servicecontrol/servicecontrol-instances/configuration.md b/servicecontrol/servicecontrol-instances/configuration.md index 98c85e22f18..29e47df62ab 100644 --- a/servicecontrol/servicecontrol-instances/configuration.md +++ b/servicecontrol/servicecontrol-instances/configuration.md @@ -181,7 +181,7 @@ These settings configure [authentication using OAuth 2.0 and OpenID Connect](/se ### ServiceControl/Authentication.Enabled -_Added in version 6.10.0_ +_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`. @@ -197,7 +197,7 @@ Enables or disables authentication. This is a **Global switch** and all other au ### ServiceControl/Authentication.Authority -_Added in version 6.10.0_ +_Added in version 6.11.0_ The URL of the OpenID Connect authority (identity provider) used to authenticate tokens. @@ -213,7 +213,7 @@ The URL of the OpenID Connect authority (identity provider) used to authenticate ### ServiceControl/Authentication.Audience -_Added in version 6.10.0_ +_Added in version 6.11.0_ The expected audience value in the JWT token, typically the application ID or URI of the API. @@ -232,7 +232,7 @@ The expected audience value in the JWT token, typically the application ID or UR ### ServiceControl/Authentication.ValidateIssuer -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token issuer is validated against the authority. @@ -248,7 +248,7 @@ Controls whether the token issuer is validated against the authority. ### ServiceControl/Authentication.ValidateAudience -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token audience is validated. @@ -264,7 +264,7 @@ Controls whether the token audience is validated. ### ServiceControl/Authentication.ValidateLifetime -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token expiration is validated. @@ -280,7 +280,7 @@ Controls whether the token expiration is validated. ### ServiceControl/Authentication.ValidateIssuerSigningKey -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether the token signing key is validated. @@ -296,7 +296,7 @@ Controls whether the token signing key is validated. ### ServiceControl/Authentication.RequireHttpsMetadata -_Added in version 6.10.0_ +_Added in version 6.11.0_ Controls whether HTTPS is required when retrieving metadata from the authority. @@ -315,7 +315,7 @@ Controls whether HTTPS is required when retrieving metadata from the authority. ### ServiceControl/Authentication.ServicePulse.ClientId -_Added in version 6.10.0_ +_Added in version 6.11.0_ The client ID for ServicePulse to use when authenticating with the identity provider. @@ -331,7 +331,7 @@ The client ID for ServicePulse to use when authenticating with the identity prov ### ServiceControl/Authentication.ServicePulse.Authority -_Added in version 6.10.0_ +_Added in version 6.11.0_ The URL of the OpenID Connect authority for ServicePulse to use when authenticating users. @@ -347,7 +347,7 @@ The URL of the OpenID Connect authority for ServicePulse to use when authenticat ### ServiceControl/Authentication.ServicePulse.ApiScopes -_Added in version 6.10.0_ +_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"]` @@ -367,7 +367,7 @@ These settings configure HTTPS. Refer to the [hosting and security guide](/servi ### ServiceControl/Https.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables Kestrel HTTPS with a certificate. @@ -383,7 +383,7 @@ Enables Kestrel HTTPS with a certificate. ### ServiceControl/Https.CertificatePath -_Added in version 6.10.0_ +_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: @@ -403,7 +403,7 @@ The path to the PFX or PEM certificate file. If hosting as a container, the cert ### ServiceControl/Https.CertificatePassword -_Added in version 6.10.0_ +_Added in version 6.11.0_ The password for the certificate file, if required. @@ -419,7 +419,7 @@ The password for the certificate file, if required. ### ServiceControl/Https.RedirectHttpToHttps -_Added in version 6.10.0_ +_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. @@ -438,7 +438,7 @@ Redirects HTTP requests to HTTPS. This is intended for use with a reverse proxy ### ServiceControl/Https.Port -_Added in version 6.10.0_ +_Added in version 6.11.0_ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is enabled in reverse proxy scenarios. @@ -454,7 +454,7 @@ The HTTPS port to use in redirect URLs. Required when `RedirectHttpToHttps` is e ### ServiceControl/Https.EnableHsts -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables HTTP Strict Transport Security (HSTS). @@ -473,7 +473,7 @@ Enables HTTP Strict Transport Security (HSTS). ### ServiceControl/Https.HstsMaxAgeSeconds -_Added in version 6.10.0_ +_Added in version 6.11.0_ The max-age value in seconds for the HSTS header. @@ -489,7 +489,7 @@ The max-age value in seconds for the HSTS header. ### ServiceControl/Https.HstsIncludeSubDomains -_Added in version 6.10.0_ +_Added in version 6.11.0_ Includes subdomains in the HSTS policy. @@ -509,7 +509,7 @@ These settings configure forwarded headers for reverse proxy scenarios. Refer to ### ServiceControl/ForwardedHeaders.Enabled -_Added in version 6.10.0_ +_Added in version 6.11.0_ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc.). @@ -525,7 +525,7 @@ Enables processing of forwarded headers (X-Forwarded-For, X-Forwarded-Proto, etc ### ServiceControl/ForwardedHeaders.TrustAllProxies -_Added in version 6.10.0_ +_Added in version 6.11.0_ Trusts forwarded headers from any source. Set to `false` when using `KnownProxies` or `KnownNetworks`. @@ -544,7 +544,7 @@ Trusts forwarded headers from any source. Set to `false` when using `KnownProxie ### ServiceControl/ForwardedHeaders.KnownProxies -_Added in version 6.10.0_ +_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` @@ -560,7 +560,7 @@ A comma-separated list of trusted proxy IP addresses e.g., `10.0.0.5,10.0.0.6` ### ServiceControl/ForwardedHeaders.KnownNetworks -_Added in version 6.10.0_ +_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` @@ -580,7 +580,7 @@ These settings configure Cross-Origin Resource Sharing (CORS). Refer to the [hos ### ServiceControl/Cors.AllowAnyOrigin -_Added in version 6.10.0_ +_Added in version 6.11.0_ Allows requests from any origin. @@ -599,7 +599,7 @@ Allows requests from any origin. ### ServiceControl/Cors.AllowedOrigins -_Added in version 6.10.0_ +_Added in version 6.11.0_ A comma-separated list of allowed origins e.g., `https://servicepulse.yourcompany.com,https://admin.yourcompany.com` From ed74b388db0fb1b5405a65ea2cede2b0f261da51 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Wed, 4 Feb 2026 16:59:35 +0800 Subject: [PATCH 26/27] Add additional anonymous endpoint --- servicecontrol/security/index.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/servicecontrol/security/index.md b/servicecontrol/security/index.md index f76aa6bb0a0..a7cc63b1681 100644 --- a/servicecontrol/security/index.md +++ b/servicecontrol/security/index.md @@ -62,18 +62,19 @@ Certain endpoints remain accessible without authentication to support API discov ### Anonymous endpoints -The following endpoints remain anonymous to support API Discovery, health checks, 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 | +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 From 5846ce9ca530319daf3dd01002257d1135fa6086 Mon Sep 17 00:00:00 2001 From: Warwick Schroeder Date: Thu, 5 Feb 2026 19:08:24 +0800 Subject: [PATCH 27/27] Add additional info regarding TLS when using containers. --- .../tls-troubleshooting.include.md | 39 +++++++- servicecontrol/security/configuration/tls.md | 49 +++++++++ servicepulse/security/configuration/tls.md | 99 ++++++------------- 3 files changed, 119 insertions(+), 68 deletions(-) diff --git a/servicecontrol/security/configuration/tls-troubleshooting.include.md b/servicecontrol/security/configuration/tls-troubleshooting.include.md index 35f0e69f31e..18222003c25 100644 --- a/servicecontrol/security/configuration/tls-troubleshooting.include.md +++ b/servicecontrol/security/configuration/tls-troubleshooting.include.md @@ -40,7 +40,7 @@ **Symptom**: Browser displays "Your connection is not private" or similar certificate warnings. -**Cause**: The certificate is self-signed, expired, or doesn't match the hostname. +**Cause**: The client (browser or another container) doesn't trust the CA that signed the server's certificate. **Solutions**: @@ -51,3 +51,40 @@ - 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 index 7e18a3806d9..ceac017321a 100644 --- a/servicecontrol/security/configuration/tls.md +++ b/servicecontrol/security/configuration/tls.md @@ -50,6 +50,55 @@ When ServiceControl 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 +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: diff --git a/servicepulse/security/configuration/tls.md b/servicepulse/security/configuration/tls.md index bb26336d212..96d732abe7a 100644 --- a/servicepulse/security/configuration/tls.md +++ b/servicepulse/security/configuration/tls.md @@ -69,84 +69,49 @@ When ServicePulse handles TLS directly using a PFX certificate: **Container:** -```bash -docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ - -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=/certs/servicepulse.pfx \ - -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD={certificate-password} \ - -v /path/to/certs:/certs \ - ... - particular/servicepulse:latest -``` - -**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 -``` - -### Direct HTTPS with HSTS - -When ServicePulse handles TLS directly and you want to enable HSTS: - -**Container:** +> [!NOTE] +> The following is a docker compose snippets. For full examples, see the [Platform Container Examples repository](https://github.com/Particular/PlatformContainerExamples). ```bash -docker run -e SERVICEPULSE_HTTPS_ENABLED=true \ - -e SERVICEPULSE_HTTPS_CERTIFICATEPATH=/certs/servicepulse.pfx \ - -e SERVICEPULSE_HTTPS_CERTIFICATEPASSWORD={certificate-password} \ - -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ - -e SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS=31536000 \ - -v /path/to/certs:/certs \ - ... - particular/servicepulse:latest -``` - -**Windows Service:** - -```cmd -ServicePulse.Host.exe --httpsenabled=true --httpsenablehsts=true --httpshstsmaxageseconds=31536000 +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 ``` -### Reverse proxy with HTTP to HTTPS redirect - -When TLS is terminated at a reverse proxy and you want ServicePulse to redirect HTTP requests: +**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). -**Container:** +**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). -```bash -docker run -e SERVICEPULSE_HTTPS_REDIRECTHTTPTOHTTPS=true \ - -e SERVICEPULSE_HTTPS_PORT=443 \ - ... - particular/servicepulse:latest -``` +> [!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:** -```cmd -ServicePulse.Host.exe --httpsredirecthttptohttps=true --httpsport=443 -``` - -### Reverse proxy with HSTS - -When TLS is terminated at a reverse proxy and you want ServicePulse to add HSTS headers: - -**Container:** - -```bash -docker run -e SERVICEPULSE_HTTPS_ENABLEHSTS=true \ - -e SERVICEPULSE_HTTPS_HSTSMAXAGESECONDS=31536000 \ - -e SERVICEPULSE_HTTPS_HSTSINCLUDESUBDOMAINS=true \ - ... - particular/servicepulse:latest -``` - -**Windows Service:** +The Windows service uses Windows HttpListener which requires SSL certificate binding at the OS level: ```cmd -ServicePulse.Host.exe --httpsenablehsts=true --httpshstsmaxageseconds=31536000 --httpshstsincludesubdomains=true +netsh http add sslcert ipport=0.0.0.0:443 certhash={certificate-thumbprint} appid={application-guid} +ServicePulse.Host.exe --httpsenabled=true ``` ## Troubleshooting