Skip to content

Conversation

Horusiath
Copy link
Contributor

Breaking Changes

I've exposed a Watch/Unwatch methods into separate ICanWatch interface. It's now implemented by IActorContext, Inboxable and F# actors. Since Inboxable.Watch had previously void as return type, now it returns actor reference (also have an Unwatch method, which was not present before). I've also removed a watch function from F# API (it has been replaced by monitor, mentioned below).

Also some of the F# modules (Configuration, Strategy) now require qualified access - calling their functions without module prefix was unclear and could result in enigmatic code i.e. load vs Configuration.load.

New F# functions

  1. Configuration.load() - alias to ConfigurationFactory.Load method.
  2. monitor/demonitor functions - similar to Watch/Unwatch (naming inspired by Erlang). Can operate directly on Inbox or Actor instances.
  3. pub, sub, unsub functions - Publish/Subscribe functions. Reason for abbreviation is that Pub/Sub is also a popular naming shortcut for related pattern.
  4. Scheduling functions - schedule and scheduleOnce work on functions, while scheduleTell and scheduleTellOnce work on message passed to actor refs. Moreover they take native F# functions as a parameters, so that explicit conversion to System.Action is no longer necessary.

README.md for F# project

All F# API functions, grouped and explained with examples. I hope, that this could be a foundation to the F# API Documentation on Akka.NET home page.

…Watch interface to expose Watch/Unwatch feature
rogeralsing added a commit that referenced this pull request Jan 10, 2015
F# API - README + more changes
@rogeralsing rogeralsing merged commit d2612c6 into akkadotnet:dev Jan 10, 2015
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the F# API should use static members with optional arguments in cases like this. (An F# API still looks valuable for it's use of F# function types, and removing the subtyping).

Note that F# API design can and should use members when appropriate, especially for metadata-rich APIs (think of List.map as "low metadata" and FSHarp.Charting or this API as "high metadat"). Indeed there are many elements of the language relevant to API design such as optional arguments which are only supported on members.

@dsyme
Copy link

dsyme commented Feb 5, 2015

I added a bunch of comments about the F# API. Don't take them the wrong way - in many ways it's looking fantastic!

@Horusiath
Copy link
Contributor Author

Thank you @dsyme :)

@Horusiath Horusiath deleted the fsapi-dev-2 branch March 23, 2016 14:07
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2025
**Problem**: Akka.Remote server starts successfully even when the application
lacks permissions to access the SSL certificate's private key. The server appears
healthy but fails when clients attempt to connect, making issues hard to diagnose.

**Root Cause**: Certificate loading in DotNettyTransportSettings only validates
that the certificate EXISTS in the Windows certificate store, not whether the
application can ACCESS the private key. Private key access is checked separately
by Windows ACL, which can fail even when Certificate.HasPrivateKey returns true.

**Solution**:
1. Add ValidateCertificate() method to SslSettings class that:
   - Checks Certificate.HasPrivateKey
   - Actually tests private key access with GetRSAPrivateKey() (not just presence)
   - Throws ConfigurationException with clear error message on failure

2. Call validation in Listen() method before server socket binds:
   - Ensures fail-fast behavior at startup
   - Prevents server from running in broken state
   - Provides clear error message for administrators

3. Add comprehensive tests:
   - Server should fail at startup with inaccessible private key
   - Server should start successfully with valid certificate
   - Server should start successfully without SSL

**Impact**:
- Existing misconfigured deployments will now fail at startup (correct behavior)
- Clear error messages guide administrators to fix permissions
- No breaking changes for correctly configured systems
- Related to Freshdesk akkadotnet#538 (BNSF Railway)

Fixes akkadotnet#538
Aaronontheweb added a commit that referenced this pull request Oct 2, 2025
…7847)

* Fix: Validate SSL certificate private key access at server startup

**Problem**: Akka.Remote server starts successfully even when the application
lacks permissions to access the SSL certificate's private key. The server appears
healthy but fails when clients attempt to connect, making issues hard to diagnose.

**Root Cause**: Certificate loading in DotNettyTransportSettings only validates
that the certificate EXISTS in the Windows certificate store, not whether the
application can ACCESS the private key. Private key access is checked separately
by Windows ACL, which can fail even when Certificate.HasPrivateKey returns true.

**Solution**:
1. Add ValidateCertificate() method to SslSettings class that:
   - Checks Certificate.HasPrivateKey
   - Actually tests private key access with GetRSAPrivateKey() (not just presence)
   - Throws ConfigurationException with clear error message on failure

2. Call validation in Listen() method before server socket binds:
   - Ensures fail-fast behavior at startup
   - Prevents server from running in broken state
   - Provides clear error message for administrators

3. Add comprehensive tests:
   - Server should fail at startup with inaccessible private key
   - Server should start successfully with valid certificate
   - Server should start successfully without SSL

**Impact**:
- Existing misconfigured deployments will now fail at startup (correct behavior)
- Clear error messages guide administrators to fix permissions
- No breaking changes for correctly configured systems
- Related to Freshdesk #538 (BNSF Railway)

Fixes #538

* Update DotNettyTlsHandshakeFailureSpec to validate fail-fast behavior

**Changes**:
1. Renamed first test to `Server_should_fail_at_startup_with_certificate_without_private_key`
   - Now validates that server FAILS AT STARTUP with bad certificate
   - Tests fail-fast behavior instead of runtime TLS handshake failure

2. Removed redundant `Server_side_tls_handshake_failure_should_shutdown_server` test
   - This test validated the OLD (incorrect) behavior where server starts successfully
   - Now impossible with fail-fast validation in place
   - Scenario already covered by the updated first test

3. Kept `Client_side_tls_handshake_failure_should_shutdown_client` unchanged
   - Still valid - tests client-side validation failure
   - Not affected by server startup validation

**Result**: Tests now validate correct fail-fast behavior at server startup

* Add ECDSA private key validation and improve disposal pattern

Addresses review feedback from @Arkatufus:

**Changes**:
1. Check both RSA and ECDSA private keys
   - SslStream supports both RSA and ECDSA certificates
   - GetRSAPrivateKey() returns null for ECDSA certs (and vice versa)
   - Validation now checks both key types to match TLS handler behavior

2. Use `using` statements for proper disposal
   - Prevents resource leaks if exception is thrown
   - Both rsaKey and ecdsaKey are properly disposed
   - Exception-safe resource management

**TLS Handler Relationship**:
The TLS handler uses `TlsHandler.Server(Settings.Ssl.Certificate)` which
internally extracts either RSA or ECDSA private keys via SslStream. Our
validation now matches this behavior by checking both key types.

**Behavior**:
- RSA certificate: GetRSAPrivateKey() succeeds, GetECDsaPrivateKey() returns null ✅
- ECDSA certificate: GetECDsaPrivateKey() succeeds, GetRSAPrivateKey() returns null ✅
- Neither accessible: Both return null, validation fails with clear error ✅
- Permission denied: CryptographicException caught, clear error message ✅
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2025
…kkadotnet#7847)

* Fix: Validate SSL certificate private key access at server startup

**Problem**: Akka.Remote server starts successfully even when the application
lacks permissions to access the SSL certificate's private key. The server appears
healthy but fails when clients attempt to connect, making issues hard to diagnose.

**Root Cause**: Certificate loading in DotNettyTransportSettings only validates
that the certificate EXISTS in the Windows certificate store, not whether the
application can ACCESS the private key. Private key access is checked separately
by Windows ACL, which can fail even when Certificate.HasPrivateKey returns true.

**Solution**:
1. Add ValidateCertificate() method to SslSettings class that:
   - Checks Certificate.HasPrivateKey
   - Actually tests private key access with GetRSAPrivateKey() (not just presence)
   - Throws ConfigurationException with clear error message on failure

2. Call validation in Listen() method before server socket binds:
   - Ensures fail-fast behavior at startup
   - Prevents server from running in broken state
   - Provides clear error message for administrators

3. Add comprehensive tests:
   - Server should fail at startup with inaccessible private key
   - Server should start successfully with valid certificate
   - Server should start successfully without SSL

**Impact**:
- Existing misconfigured deployments will now fail at startup (correct behavior)
- Clear error messages guide administrators to fix permissions
- No breaking changes for correctly configured systems
- Related to Freshdesk akkadotnet#538 (BNSF Railway)

Fixes akkadotnet#538

* Update DotNettyTlsHandshakeFailureSpec to validate fail-fast behavior

**Changes**:
1. Renamed first test to `Server_should_fail_at_startup_with_certificate_without_private_key`
   - Now validates that server FAILS AT STARTUP with bad certificate
   - Tests fail-fast behavior instead of runtime TLS handshake failure

2. Removed redundant `Server_side_tls_handshake_failure_should_shutdown_server` test
   - This test validated the OLD (incorrect) behavior where server starts successfully
   - Now impossible with fail-fast validation in place
   - Scenario already covered by the updated first test

3. Kept `Client_side_tls_handshake_failure_should_shutdown_client` unchanged
   - Still valid - tests client-side validation failure
   - Not affected by server startup validation

**Result**: Tests now validate correct fail-fast behavior at server startup

* Add ECDSA private key validation and improve disposal pattern

Addresses review feedback from @Arkatufus:

**Changes**:
1. Check both RSA and ECDSA private keys
   - SslStream supports both RSA and ECDSA certificates
   - GetRSAPrivateKey() returns null for ECDSA certs (and vice versa)
   - Validation now checks both key types to match TLS handler behavior

2. Use `using` statements for proper disposal
   - Prevents resource leaks if exception is thrown
   - Both rsaKey and ecdsaKey are properly disposed
   - Exception-safe resource management

**TLS Handler Relationship**:
The TLS handler uses `TlsHandler.Server(Settings.Ssl.Certificate)` which
internally extracts either RSA or ECDSA private keys via SslStream. Our
validation now matches this behavior by checking both key types.

**Behavior**:
- RSA certificate: GetRSAPrivateKey() succeeds, GetECDsaPrivateKey() returns null ✅
- ECDSA certificate: GetECDsaPrivateKey() succeeds, GetRSAPrivateKey() returns null ✅
- Neither accessible: Both return null, validation fails with clear error ✅
- Permission denied: CryptographicException caught, clear error message ✅
Aaronontheweb added a commit that referenced this pull request Oct 2, 2025
…7847) (#7848)

* Fix: Validate SSL certificate private key access at server startup

**Problem**: Akka.Remote server starts successfully even when the application
lacks permissions to access the SSL certificate's private key. The server appears
healthy but fails when clients attempt to connect, making issues hard to diagnose.

**Root Cause**: Certificate loading in DotNettyTransportSettings only validates
that the certificate EXISTS in the Windows certificate store, not whether the
application can ACCESS the private key. Private key access is checked separately
by Windows ACL, which can fail even when Certificate.HasPrivateKey returns true.

**Solution**:
1. Add ValidateCertificate() method to SslSettings class that:
   - Checks Certificate.HasPrivateKey
   - Actually tests private key access with GetRSAPrivateKey() (not just presence)
   - Throws ConfigurationException with clear error message on failure

2. Call validation in Listen() method before server socket binds:
   - Ensures fail-fast behavior at startup
   - Prevents server from running in broken state
   - Provides clear error message for administrators

3. Add comprehensive tests:
   - Server should fail at startup with inaccessible private key
   - Server should start successfully with valid certificate
   - Server should start successfully without SSL

**Impact**:
- Existing misconfigured deployments will now fail at startup (correct behavior)
- Clear error messages guide administrators to fix permissions
- No breaking changes for correctly configured systems
- Related to Freshdesk #538 (BNSF Railway)

Fixes #538

* Update DotNettyTlsHandshakeFailureSpec to validate fail-fast behavior

**Changes**:
1. Renamed first test to `Server_should_fail_at_startup_with_certificate_without_private_key`
   - Now validates that server FAILS AT STARTUP with bad certificate
   - Tests fail-fast behavior instead of runtime TLS handshake failure

2. Removed redundant `Server_side_tls_handshake_failure_should_shutdown_server` test
   - This test validated the OLD (incorrect) behavior where server starts successfully
   - Now impossible with fail-fast validation in place
   - Scenario already covered by the updated first test

3. Kept `Client_side_tls_handshake_failure_should_shutdown_client` unchanged
   - Still valid - tests client-side validation failure
   - Not affected by server startup validation

**Result**: Tests now validate correct fail-fast behavior at server startup

* Add ECDSA private key validation and improve disposal pattern

Addresses review feedback from @Arkatufus:

**Changes**:
1. Check both RSA and ECDSA private keys
   - SslStream supports both RSA and ECDSA certificates
   - GetRSAPrivateKey() returns null for ECDSA certs (and vice versa)
   - Validation now checks both key types to match TLS handler behavior

2. Use `using` statements for proper disposal
   - Prevents resource leaks if exception is thrown
   - Both rsaKey and ecdsaKey are properly disposed
   - Exception-safe resource management

**TLS Handler Relationship**:
The TLS handler uses `TlsHandler.Server(Settings.Ssl.Certificate)` which
internally extracts either RSA or ECDSA private keys via SslStream. Our
validation now matches this behavior by checking both key types.

**Behavior**:
- RSA certificate: GetRSAPrivateKey() succeeds, GetECDsaPrivateKey() returns null ✅
- ECDSA certificate: GetECDsaPrivateKey() succeeds, GetRSAPrivateKey() returns null ✅
- Neither accessible: Both return null, validation fails with clear error ✅
- Permission denied: CryptographicException caught, clear error message ✅
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2025
Implements mutual TLS (mTLS) authentication as a defense-in-depth security
measure for Akka.Remote TLS connections. When enabled, both client and server
must present valid certificates with accessible private keys during the TLS
handshake, ensuring symmetric authentication.

Key Changes:
- Add require-mutual-authentication config option (default: true)
- Update SslSettings to include RequireMutualAuthentication property
- Modify client TLS handler to provide certificate only when mutual TLS enabled
- Modify server TLS handler to require and validate client certificates when enabled
- Add comprehensive test suite for mutual TLS scenarios

Security Benefits:
- Prevents nodes with inaccessible private keys from connecting as clients
- Ensures complete bidirectional authentication (not just server-side)
- Works in conjunction with startup certificate validation for fail-fast behavior
- Provides defense-in-depth security for production deployments

Configuration:
  akka.remote.dot-netty.tcp.ssl {
    require-mutual-authentication = true  # Default: secure by default
  }

Set to false only if your environment cannot support client certificate authentication.

Related: Freshdesk akkadotnet#538 - TLS certificate private key validation
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2025
Major overhaul of the security documentation to reflect new TLS features
and provide comprehensive security guidance for production deployments.

Changes:
- Document new startup certificate validation feature (v1.5.52+)
- Document new mutual TLS authentication support (v1.5.52+)
- Add detailed suppress-validation guidance with security implications
- Provide Windows Certificate Store configuration examples
- Include PowerShell scripts for certificate management
- Add troubleshooting section for common TLS issues
- Update configuration examples from insecure to secure defaults
- Fix deprecated external links (Microsoft Learn, IETF, OWASP)
- Add security analysis for different configuration levels
- Include migration guide for upgrading to mutual TLS
- Add best practices summary with 10 key recommendations
- Document common pitfalls and their solutions

Security improvements:
- Changed example configs to use suppress-validation = false by default
- Added warnings about using suppress-validation = true in production
- Emphasized defense-in-depth with VPNs + TLS + mutual TLS
- Documented proper self-signed certificate usage for development

The documentation now provides clear guidance on:
- What TLS protects against (and what it doesn't)
- When to use mutual TLS vs standard TLS
- How to properly configure certificates in production
- How to troubleshoot common certificate permission issues

Related: Freshdesk akkadotnet#538 - TLS certificate validation improvements
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 2, 2025
Added configurable mutual TLS (mTLS) authentication for Akka.Remote to provide bidirectional certificate validation between client and server nodes. This feature enhances security by ensuring both sides of a connection authenticate with valid certificates.

Changes:
- Added `require-mutual-authentication` config option (defaults to true for security-by-default)
- Updated DotNettyTransport to enforce mutual TLS in both client and server pipelines
- Added comprehensive test suite for mutual TLS scenarios
- Updated security documentation with detailed TLS/mTLS configuration guidance
- Added code samples for various TLS configurations (standard, mutual, Windows cert store)
- Included Mermaid sequence diagrams for TLS vs mTLS flows (pending Mermaid support on site)

The implementation ensures backward compatibility while encouraging secure defaults. When mutual TLS is disabled, the system falls back to standard server-only authentication.

Related to Freshdesk ticket akkadotnet#538
Aaronontheweb added a commit that referenced this pull request Oct 3, 2025
* Add mutual TLS authentication support for DotNetty transport

Implements mutual TLS (mTLS) authentication as a defense-in-depth security
measure for Akka.Remote TLS connections. When enabled, both client and server
must present valid certificates with accessible private keys during the TLS
handshake, ensuring symmetric authentication.

Key Changes:
- Add require-mutual-authentication config option (default: true)
- Update SslSettings to include RequireMutualAuthentication property
- Modify client TLS handler to provide certificate only when mutual TLS enabled
- Modify server TLS handler to require and validate client certificates when enabled
- Add comprehensive test suite for mutual TLS scenarios

Security Benefits:
- Prevents nodes with inaccessible private keys from connecting as clients
- Ensures complete bidirectional authentication (not just server-side)
- Works in conjunction with startup certificate validation for fail-fast behavior
- Provides defense-in-depth security for production deployments

Configuration:
  akka.remote.dot-netty.tcp.ssl {
    require-mutual-authentication = true  # Default: secure by default
  }

Set to false only if your environment cannot support client certificate authentication.

Related: Freshdesk #538 - TLS certificate private key validation

* Update Akka.Remote security documentation

Major overhaul of the security documentation to reflect new TLS features
and provide comprehensive security guidance for production deployments.

Changes:
- Document new startup certificate validation feature (v1.5.52+)
- Document new mutual TLS authentication support (v1.5.52+)
- Add detailed suppress-validation guidance with security implications
- Provide Windows Certificate Store configuration examples
- Include PowerShell scripts for certificate management
- Add troubleshooting section for common TLS issues
- Update configuration examples from insecure to secure defaults
- Fix deprecated external links (Microsoft Learn, IETF, OWASP)
- Add security analysis for different configuration levels
- Include migration guide for upgrading to mutual TLS
- Add best practices summary with 10 key recommendations
- Document common pitfalls and their solutions

Security improvements:
- Changed example configs to use suppress-validation = false by default
- Added warnings about using suppress-validation = true in production
- Emphasized defense-in-depth with VPNs + TLS + mutual TLS
- Documented proper self-signed certificate usage for development

The documentation now provides clear guidance on:
- What TLS protects against (and what it doesn't)
- When to use mutual TLS vs standard TLS
- How to properly configure certificates in production
- How to troubleshoot common certificate permission issues

Related: Freshdesk #538 - TLS certificate validation improvements

* Add proper code samples for TLS configuration documentation

- Create TlsConfigurationSample.cs with proper HOCON configuration examples
- Update security.md to reference code samples using DocFX syntax
- Add context explaining when TLS is needed vs optional
- Remove poorly designed region tags from test file

The documentation now follows Akka.NET documentation guidelines with
proper code references instead of inline configuration blocks.

* feat(remote): implement mutual TLS authentication support

Added configurable mutual TLS (mTLS) authentication for Akka.Remote to provide bidirectional certificate validation between client and server nodes. This feature enhances security by ensuring both sides of a connection authenticate with valid certificates.

Changes:
- Added `require-mutual-authentication` config option (defaults to true for security-by-default)
- Updated DotNettyTransport to enforce mutual TLS in both client and server pipelines
- Added comprehensive test suite for mutual TLS scenarios
- Updated security documentation with detailed TLS/mTLS configuration guidance
- Added code samples for various TLS configurations (standard, mutual, Windows cert store)
- Included Mermaid sequence diagrams for TLS vs mTLS flows (pending Mermaid support on site)

The implementation ensures backward compatibility while encouraging secure defaults. When mutual TLS is disabled, the system falls back to standard server-only authentication.

Related to Freshdesk ticket #538

* Fix markdown linting issues in security documentation

* Fix remaining markdown linting issues - convert bold text to proper headings

* Fix title case issues in security.md documentation

- Fixed all heading title case to comply with markdownlint-rule-titlecase
- Changed 'suppress-validation' to 'Suppress-Validation' in headings
- Fixed error message headings to use proper title case
- All CI/CD checks should now pass

* Add Tailscale and ZeroTier to cSpell dictionary

Added VPN provider names to the accepted words list to fix CI spellcheck failures

* Address PR review feedback on mutual TLS implementation

- Fixed binary compatibility by adding overloaded SslSettings constructor
- Added config test to verify RequireMutualAuthentication defaults to true
- Added test for mutual TLS failure when client has no certificate
- Added test to verify mutual TLS can be disabled for backward compatibility
- Enhanced DotNettyMutualTlsSpec with more comprehensive test scenarios

* Add test for mutual TLS failure with different certificates

- Generated new self-signed certificate (akka-client-cert.pfx) for testing
- Modified CreateConfig to accept custom certificate paths
- Added test to verify mutual TLS fails when client and server have different valid certificates
- This ensures proper certificate validation in mutual TLS mode

* Add client certificate for mutual TLS testing

- Generated new self-signed certificate (akka-client-cert.pfx) to test scenarios where client and server have different valid certificates
- Added certificate to project file as build output
- Force-added certificate to git (normally ignored by .gitignore)

* fixed `RemoteConfigSpec`

* Fix RemoteConfigSpec and add SSL defaults test

- Added new test SSL_should_have_secure_defaults_when_enabled to verify secure defaults when SSL is enabled
- Removed SSL checks from non-SSL test Remoting_should_contain_correct_heliosTCP_values_in_ReferenceConf
- Fixed certificate path resolution using full path
- Tests now properly verify that require-mutual-authentication defaults to true and suppress-validation defaults to false

* remove redundant tests

* Restore DotNettySslSetupSpec and add mutual TLS Setup API test

- Restored DotNettySslSetupSpec which tests SSL configuration via Setup API
- This is distinct from HOCON-based configuration tested in DotNettySslSupportSpec
- Added test for configuring mutual TLS via DotNettySslSetup
- Enhanced TestActorSystemSetup to support mutual authentication parameter

* Fix DotNettySslSetupSpec compilation errors

- Removed unsupported requireMutualAuth parameter from DotNettySslSetup constructor
- Updated test to combine Setup API certificate with HOCON mutual TLS configuration
- Fixed shutdown method call to use correct API

* Revert "Fix DotNettySslSetupSpec compilation errors"

This reverts commit 6503391.

* Revert "Restore DotNettySslSetupSpec and add mutual TLS Setup API test"

This reverts commit b23c3cd.

* Revert "remove redundant tests"

This reverts commit 7a7f3ca.
Aaronontheweb added a commit to Aaronontheweb/akka.net that referenced this pull request Oct 3, 2025
…#7851)

* Add mutual TLS authentication support for DotNetty transport

Implements mutual TLS (mTLS) authentication as a defense-in-depth security
measure for Akka.Remote TLS connections. When enabled, both client and server
must present valid certificates with accessible private keys during the TLS
handshake, ensuring symmetric authentication.

Key Changes:
- Add require-mutual-authentication config option (default: true)
- Update SslSettings to include RequireMutualAuthentication property
- Modify client TLS handler to provide certificate only when mutual TLS enabled
- Modify server TLS handler to require and validate client certificates when enabled
- Add comprehensive test suite for mutual TLS scenarios

Security Benefits:
- Prevents nodes with inaccessible private keys from connecting as clients
- Ensures complete bidirectional authentication (not just server-side)
- Works in conjunction with startup certificate validation for fail-fast behavior
- Provides defense-in-depth security for production deployments

Configuration:
  akka.remote.dot-netty.tcp.ssl {
    require-mutual-authentication = true  # Default: secure by default
  }

Set to false only if your environment cannot support client certificate authentication.

Related: Freshdesk akkadotnet#538 - TLS certificate private key validation

* Update Akka.Remote security documentation

Major overhaul of the security documentation to reflect new TLS features
and provide comprehensive security guidance for production deployments.

Changes:
- Document new startup certificate validation feature (v1.5.52+)
- Document new mutual TLS authentication support (v1.5.52+)
- Add detailed suppress-validation guidance with security implications
- Provide Windows Certificate Store configuration examples
- Include PowerShell scripts for certificate management
- Add troubleshooting section for common TLS issues
- Update configuration examples from insecure to secure defaults
- Fix deprecated external links (Microsoft Learn, IETF, OWASP)
- Add security analysis for different configuration levels
- Include migration guide for upgrading to mutual TLS
- Add best practices summary with 10 key recommendations
- Document common pitfalls and their solutions

Security improvements:
- Changed example configs to use suppress-validation = false by default
- Added warnings about using suppress-validation = true in production
- Emphasized defense-in-depth with VPNs + TLS + mutual TLS
- Documented proper self-signed certificate usage for development

The documentation now provides clear guidance on:
- What TLS protects against (and what it doesn't)
- When to use mutual TLS vs standard TLS
- How to properly configure certificates in production
- How to troubleshoot common certificate permission issues

Related: Freshdesk akkadotnet#538 - TLS certificate validation improvements

* Add proper code samples for TLS configuration documentation

- Create TlsConfigurationSample.cs with proper HOCON configuration examples
- Update security.md to reference code samples using DocFX syntax
- Add context explaining when TLS is needed vs optional
- Remove poorly designed region tags from test file

The documentation now follows Akka.NET documentation guidelines with
proper code references instead of inline configuration blocks.

* feat(remote): implement mutual TLS authentication support

Added configurable mutual TLS (mTLS) authentication for Akka.Remote to provide bidirectional certificate validation between client and server nodes. This feature enhances security by ensuring both sides of a connection authenticate with valid certificates.

Changes:
- Added `require-mutual-authentication` config option (defaults to true for security-by-default)
- Updated DotNettyTransport to enforce mutual TLS in both client and server pipelines
- Added comprehensive test suite for mutual TLS scenarios
- Updated security documentation with detailed TLS/mTLS configuration guidance
- Added code samples for various TLS configurations (standard, mutual, Windows cert store)
- Included Mermaid sequence diagrams for TLS vs mTLS flows (pending Mermaid support on site)

The implementation ensures backward compatibility while encouraging secure defaults. When mutual TLS is disabled, the system falls back to standard server-only authentication.

Related to Freshdesk ticket akkadotnet#538

* Fix markdown linting issues in security documentation

* Fix remaining markdown linting issues - convert bold text to proper headings

* Fix title case issues in security.md documentation

- Fixed all heading title case to comply with markdownlint-rule-titlecase
- Changed 'suppress-validation' to 'Suppress-Validation' in headings
- Fixed error message headings to use proper title case
- All CI/CD checks should now pass

* Add Tailscale and ZeroTier to cSpell dictionary

Added VPN provider names to the accepted words list to fix CI spellcheck failures

* Address PR review feedback on mutual TLS implementation

- Fixed binary compatibility by adding overloaded SslSettings constructor
- Added config test to verify RequireMutualAuthentication defaults to true
- Added test for mutual TLS failure when client has no certificate
- Added test to verify mutual TLS can be disabled for backward compatibility
- Enhanced DotNettyMutualTlsSpec with more comprehensive test scenarios

* Add test for mutual TLS failure with different certificates

- Generated new self-signed certificate (akka-client-cert.pfx) for testing
- Modified CreateConfig to accept custom certificate paths
- Added test to verify mutual TLS fails when client and server have different valid certificates
- This ensures proper certificate validation in mutual TLS mode

* Add client certificate for mutual TLS testing

- Generated new self-signed certificate (akka-client-cert.pfx) to test scenarios where client and server have different valid certificates
- Added certificate to project file as build output
- Force-added certificate to git (normally ignored by .gitignore)

* fixed `RemoteConfigSpec`

* Fix RemoteConfigSpec and add SSL defaults test

- Added new test SSL_should_have_secure_defaults_when_enabled to verify secure defaults when SSL is enabled
- Removed SSL checks from non-SSL test Remoting_should_contain_correct_heliosTCP_values_in_ReferenceConf
- Fixed certificate path resolution using full path
- Tests now properly verify that require-mutual-authentication defaults to true and suppress-validation defaults to false

* remove redundant tests

* Restore DotNettySslSetupSpec and add mutual TLS Setup API test

- Restored DotNettySslSetupSpec which tests SSL configuration via Setup API
- This is distinct from HOCON-based configuration tested in DotNettySslSupportSpec
- Added test for configuring mutual TLS via DotNettySslSetup
- Enhanced TestActorSystemSetup to support mutual authentication parameter

* Fix DotNettySslSetupSpec compilation errors

- Removed unsupported requireMutualAuth parameter from DotNettySslSetup constructor
- Updated test to combine Setup API certificate with HOCON mutual TLS configuration
- Fixed shutdown method call to use correct API

* Revert "Fix DotNettySslSetupSpec compilation errors"

This reverts commit 6503391.

* Revert "Restore DotNettySslSetupSpec and add mutual TLS Setup API test"

This reverts commit b23c3cd.

* Revert "remove redundant tests"

This reverts commit 7a7f3ca.
Aaronontheweb added a commit that referenced this pull request Oct 3, 2025
)

* Add mutual TLS authentication support for DotNetty transport

Implements mutual TLS (mTLS) authentication as a defense-in-depth security
measure for Akka.Remote TLS connections. When enabled, both client and server
must present valid certificates with accessible private keys during the TLS
handshake, ensuring symmetric authentication.

Key Changes:
- Add require-mutual-authentication config option (default: true)
- Update SslSettings to include RequireMutualAuthentication property
- Modify client TLS handler to provide certificate only when mutual TLS enabled
- Modify server TLS handler to require and validate client certificates when enabled
- Add comprehensive test suite for mutual TLS scenarios

Security Benefits:
- Prevents nodes with inaccessible private keys from connecting as clients
- Ensures complete bidirectional authentication (not just server-side)
- Works in conjunction with startup certificate validation for fail-fast behavior
- Provides defense-in-depth security for production deployments

Configuration:
  akka.remote.dot-netty.tcp.ssl {
    require-mutual-authentication = true  # Default: secure by default
  }

Set to false only if your environment cannot support client certificate authentication.

Related: Freshdesk #538 - TLS certificate private key validation

* Update Akka.Remote security documentation

Major overhaul of the security documentation to reflect new TLS features
and provide comprehensive security guidance for production deployments.

Changes:
- Document new startup certificate validation feature (v1.5.52+)
- Document new mutual TLS authentication support (v1.5.52+)
- Add detailed suppress-validation guidance with security implications
- Provide Windows Certificate Store configuration examples
- Include PowerShell scripts for certificate management
- Add troubleshooting section for common TLS issues
- Update configuration examples from insecure to secure defaults
- Fix deprecated external links (Microsoft Learn, IETF, OWASP)
- Add security analysis for different configuration levels
- Include migration guide for upgrading to mutual TLS
- Add best practices summary with 10 key recommendations
- Document common pitfalls and their solutions

Security improvements:
- Changed example configs to use suppress-validation = false by default
- Added warnings about using suppress-validation = true in production
- Emphasized defense-in-depth with VPNs + TLS + mutual TLS
- Documented proper self-signed certificate usage for development

The documentation now provides clear guidance on:
- What TLS protects against (and what it doesn't)
- When to use mutual TLS vs standard TLS
- How to properly configure certificates in production
- How to troubleshoot common certificate permission issues

Related: Freshdesk #538 - TLS certificate validation improvements

* Add proper code samples for TLS configuration documentation

- Create TlsConfigurationSample.cs with proper HOCON configuration examples
- Update security.md to reference code samples using DocFX syntax
- Add context explaining when TLS is needed vs optional
- Remove poorly designed region tags from test file

The documentation now follows Akka.NET documentation guidelines with
proper code references instead of inline configuration blocks.

* feat(remote): implement mutual TLS authentication support

Added configurable mutual TLS (mTLS) authentication for Akka.Remote to provide bidirectional certificate validation between client and server nodes. This feature enhances security by ensuring both sides of a connection authenticate with valid certificates.

Changes:
- Added `require-mutual-authentication` config option (defaults to true for security-by-default)
- Updated DotNettyTransport to enforce mutual TLS in both client and server pipelines
- Added comprehensive test suite for mutual TLS scenarios
- Updated security documentation with detailed TLS/mTLS configuration guidance
- Added code samples for various TLS configurations (standard, mutual, Windows cert store)
- Included Mermaid sequence diagrams for TLS vs mTLS flows (pending Mermaid support on site)

The implementation ensures backward compatibility while encouraging secure defaults. When mutual TLS is disabled, the system falls back to standard server-only authentication.

Related to Freshdesk ticket #538

* Fix markdown linting issues in security documentation

* Fix remaining markdown linting issues - convert bold text to proper headings

* Fix title case issues in security.md documentation

- Fixed all heading title case to comply with markdownlint-rule-titlecase
- Changed 'suppress-validation' to 'Suppress-Validation' in headings
- Fixed error message headings to use proper title case
- All CI/CD checks should now pass

* Add Tailscale and ZeroTier to cSpell dictionary

Added VPN provider names to the accepted words list to fix CI spellcheck failures

* Address PR review feedback on mutual TLS implementation

- Fixed binary compatibility by adding overloaded SslSettings constructor
- Added config test to verify RequireMutualAuthentication defaults to true
- Added test for mutual TLS failure when client has no certificate
- Added test to verify mutual TLS can be disabled for backward compatibility
- Enhanced DotNettyMutualTlsSpec with more comprehensive test scenarios

* Add test for mutual TLS failure with different certificates

- Generated new self-signed certificate (akka-client-cert.pfx) for testing
- Modified CreateConfig to accept custom certificate paths
- Added test to verify mutual TLS fails when client and server have different valid certificates
- This ensures proper certificate validation in mutual TLS mode

* Add client certificate for mutual TLS testing

- Generated new self-signed certificate (akka-client-cert.pfx) to test scenarios where client and server have different valid certificates
- Added certificate to project file as build output
- Force-added certificate to git (normally ignored by .gitignore)

* fixed `RemoteConfigSpec`

* Fix RemoteConfigSpec and add SSL defaults test

- Added new test SSL_should_have_secure_defaults_when_enabled to verify secure defaults when SSL is enabled
- Removed SSL checks from non-SSL test Remoting_should_contain_correct_heliosTCP_values_in_ReferenceConf
- Fixed certificate path resolution using full path
- Tests now properly verify that require-mutual-authentication defaults to true and suppress-validation defaults to false

* remove redundant tests

* Restore DotNettySslSetupSpec and add mutual TLS Setup API test

- Restored DotNettySslSetupSpec which tests SSL configuration via Setup API
- This is distinct from HOCON-based configuration tested in DotNettySslSupportSpec
- Added test for configuring mutual TLS via DotNettySslSetup
- Enhanced TestActorSystemSetup to support mutual authentication parameter

* Fix DotNettySslSetupSpec compilation errors

- Removed unsupported requireMutualAuth parameter from DotNettySslSetup constructor
- Updated test to combine Setup API certificate with HOCON mutual TLS configuration
- Fixed shutdown method call to use correct API

* Revert "Fix DotNettySslSetupSpec compilation errors"

This reverts commit 6503391.

* Revert "Restore DotNettySslSetupSpec and add mutual TLS Setup API test"

This reverts commit b23c3cd.

* Revert "remove redundant tests"

This reverts commit 7a7f3ca.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants