Skip to content

Add support for certificate-based variable substitution in the restrictions.yaml #475

@deluxetiky

Description

@deluxetiky

Describe the feature

Add support for certificate-based variable substitution in the restrictions.yaml configuration file, allowing dynamic access control based on client certificate attributes (particularly the Common Name/CN field).

The feature would enable using variables like ${cn} or ${cert.cn} in restriction rules, which would be automatically replaced with the actual CN value from the client's mTLS certificate during connection.

Example usage:

restrictions:
  - name: "Device access based on certificate CN"
    description: "Each device can only access resources matching its certificate CN"
    match:
      - !Any  # Match all mTLS connections
    allow:
      - !ReverseTunnel
        protocol:
          - Unix
        port:
          - 1..65535
        unix_path: "^/tmp/sockets/${cn}\\.sock$"  # CN variable substitution

This would allow a device with certificate CN "abcd1234" to only access /tmp/sockets/abcd1234.sock, while a device with CN "xyz5678" could only access /tmp/sockets/xyz5678.sock - all with a single configuration rule instead of duplicating rules for each device.

Describe the reason for such feature

Current Problem:
When managing multiple devices/clients with mTLS authentication, each device currently requires its own separate restriction rule in the configuration file:

restrictions:
  - name: "Device abcd1234"
    match:
      - !PathPrefix "^abcd1234$"
    allow:
      - !ReverseTunnel
        unix_path: "^/tmp/sockets/abcd1234\\.sock$"
  
  - name: "Device xyz5678"
    match:
      - !PathPrefix "^xyz5678$"
    allow:
      - !ReverseTunnel
        unix_path: "^/tmp/sockets/xyz5678\\.sock$"
  
  # ... repeat for every device

This approach doesn't scale well and has several issues:

  1. Maintenance Burden: For deployments with dozens or hundreds of devices (IoT scenarios, auto-scaling environments), manually maintaining individual rules becomes impractical
  2. Configuration Bloat: Large configuration files are error-prone and difficult to manage
  3. Dynamic Environments: Adding new devices requires server configuration changes and reloads
  4. Security: mTLS already provides strong device identification through certificates, but we can't leverage it for authorization without manual configuration

With This Feature:
A single rule could handle all devices dynamically, with the server automatically enforcing that each device can only access resources matching its certificate identity. This provides:

  • Scalability: One rule handles unlimited devices
  • Zero-touch provisioning: New devices automatically get appropriate access based on their certificates
  • Simplified management: Configuration remains clean and maintainable
  • Better security model: Directly ties mTLS authentication to authorization

Describe alternatives you've considered

Alternative 1: HTTP Upgrade Path Prefix per Device

  • Clients specify unique path prefixes matching their device IDs
  • Drawback: Requires coordination between certificate CN and path prefix; doesn't leverage mTLS identity; path prefix is less secure than certificate-based authentication

Alternative 2: External Authorization Service

  • Run a separate service that inspects certificates and makes routing decisions
  • Drawback: Adds complexity, additional infrastructure, latency, and potential failure points; defeats the purpose of wstunnel's simplicity

Alternative 3: Code Generation

  • Write scripts to auto-generate restriction rules from a device database
  • Drawback: Still requires configuration reloads when devices are added/removed; doesn't solve the fundamental scaling issue; adds complexity to the deployment pipeline

Alternative 4: Different Tool

  • Use a different tunneling solution with certificate-based authorization
  • Drawback: wstunnel is otherwise perfect for the use case; switching would lose all its benefits (WebSocket transport, firewall traversal, etc.)

Why None of These Work Well:
All alternatives either sacrifice security, add operational complexity, or don't actually solve the scalability problem. Certificate-based variable substitution is the most elegant solution that:

  • Leverages existing mTLS infrastructure
  • Requires no additional services or complexity
  • Scales effortlessly
  • Maintains security guarantees
  • Keeps configuration clean and maintainable

Additional Implementation Notes:

The feature could potentially support multiple certificate fields for maximum flexibility:

  • ${cn} - Common Name
  • ${cert.subject.cn} - Common Name (explicit)
  • ${cert.subject.ou} - Organizational Unit
  • ${cert.subject.o} - Organization
  • ${cert.serial} - Certificate serial number

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions