Skip to content

Latest commit

 

History

History
192 lines (150 loc) · 18.2 KB

20240508-S-sidecar-endpoint-tls.md

File metadata and controls

192 lines (150 loc) · 18.2 KB

Dapr endpoint env and TLS support in SDKs

  • Author(s): Artur Souza (@artursouza), Josh van Leeuwen (@JoshVanL)
  • State: Ready for Implementation
  • Updated: 05/08/2024

Overview

This is a design proposal to support remote or shared Dapr APIs.

This will allow applications to talk to a remote or shared sidecar, without having to rely on localhost sidecar running per app instance. It means the communication will likely require TLS communication.

Background

Motivation

  • Applications to communicate to Dapr APIs without a local sidecar.

Goals

  • Dapr users can talk to a remote Dapr API without using CLI or any other tool, by just running the application with environment variables.
  • System administrators don't need to have different configurations per application based on programming language, meaning the same environment variables will work with every SDK - exception is when SDK only supports HTTP or GRPC, but sysadmin can simply always setup environment variables for both protocols to guarantee consistency.

Current Shortfalls

  • Inconsistency on setting up Dapr's sidecar endpoint on each SDK.
  • Not every SDK support a secure endpoint.

Related Items

Related proposals

Formalizing the proposal here from this issue.

Expectations and alternatives

  • What is in scope for this proposal?
  • SDKs to support a consistent pair of environment variables to setup Dapr API
  • SDKs to support TLS endpoints for Dapr API
  • What is deliberately not in scope?
  • SSL certificate pinning
  • Have consistency of other environment variables for SDK (DAPR_HOST, DAPR_SIDECAR_IP, etc)
  • Have consistency of how Dapr client is instanciated on each SDK
  • What alternatives have been considered, and why do they not solve the problem?
  1. Leave every SDK as-is:
  • Not every SDK offers an environment variable to configure Dapr endpoint, forcing configuration in code
  • Environment variables per SDK, forcing sysadmin to know about each application's language use
  • Not every SDK supports TLS endpoint
  1. Add TLS support only, giving each SDK room to decide on how to expose it to the user
  • Not every SDK offers an environment variable to configure Dapr endpoint, forcing configuration in code
  • Environment variables per SDK, forcing sysadmin to know about each application's language use
  • Are there any trade-offs being made? (space for time, for example)
  1. Leaving existing environment variables for host and port as-is per SDK, but driving consistency on this new way.
  2. Not changing Dapr's DAPR_HOST (or equivalent), DAPR_HTTP_PORT and DAPR_GRPC_PORT.
  • What advantages / disadvantages does this proposal have? Pros:
  • Bring consistency in Dapr API endpoint configuration cross SDKs
  • Add support for TLS endpoint

Cons:

  • Does not address existing inconsistencies in client instantiation and env variables
  • Needs to define a priority between new env variables and old ones

Implementation Details

Design

  • DAPR_GRPC_ENDPOINT defines entire endpoint for gRPC, not just host: dapr-grpc.mycompany.com. No port in the URL defaults to 443.
  • DAPR_HTTP_ENDPOINT defines entire endpoint for HTTP, not just host: https://dapr-http.mycompany.com
  • Port is parsed from the hostport string (dapr.mycompany.com:8080) or via the default port of the protocol used in the URL (80 for plaintext and 443 for TLS)
  • DAPR_GRPC_ENDPOINT and DAPR_HTTP_ENDPOINT can be set at the same time since some SDKs (Java, as of now) supports both protocols at the same time and app can pick which one to use.
  • DAPR_HTTP_ENDPOINT must be parsed and the protocol will be used by SDK to determine if communication is over TLS (if not done automatically). In summary, https means secure channel.
  • DAPR_GRPC_ENDPOINT must be parsed and the query parameter will be used to determine whether the endpoint uses TLS. In summary, ?tls=true means to use TLS. An empty query parameter defaults TLS to false. SDKs should error on unrecognised or invalid query parameters.
  • DAPR_GRPC_ENDPOINT and DAPR_HTTP_ENDPOINT have priority over existing DAPR_HOST and DAPR_HTTP_PORT or DAPR_GRPC_PORT environment variables. Application's hardcoded values passed via constructor takes priority over any environment variable. In summary, this is the priority list (highest on top):
    1. Values passed via constructor or builder method.
    2. Properties or any other language specific configuration framework.
    3. DAPR_GRPC_ENDPOINT and DAPR_HTTP_ENDPOINT
    4. Existing DAPR_HOST (or equivalent, defaulting to 127.0.0.1) + DAPR_HTTP_PORT or DAPR_GRPC_PORT

DAPR_GRPC_ENDPOINT host port parsing example:

myhost => port=443 tls=false resolver=dns
myhost?tls=false => port=443 tls=false resolver=dns
myhost:443 => port=443 tls=false resolver=dns
myhost:1003 => port=1003 tls=false resolver=dns
myhost:1003?tls=true => port=1003 tls=true resolver=dns
dns://myhost:1003?tls=true => port=1003 tls=true resolver=dns
unix://my.sock => port=<no concept of port> tls=false resolver=unix
unix://my.sock?tls=true => port=<no concept of port> tls=true resolver=unix
http://myhost => port=80 tls=false resolver=dns
https://myhost => port=443 tls=true resolver=dns

Example of implementation

https://github.com/dapr/java-sdk/blob/76aec01e9aa4af7a72b910d77685ddd3f0bf86f3/sdk/src/main/java/io/dapr/client/DaprClientBuilder.java#L172C3-L192

Feature lifecycle outline

  • Compatability guarantees This feature should allow localhost definition too http://127.0.0.1:3500, for example.

  • This feature should continue to allow using other resolvers other than DNS (e.g. unix://).

  • Deprecation / co-existence with existing functionality This feature takes priority over existing (inconsistent) environment variables from each SDK. If app provides a hardcoded value for Dapr endpoint (via constructor, for example), it takes priority. Use of existing DAPR_API_TOKEN environment variables is highly encouraged for remote API but not required.

  • SDKs will continue to accept the old behaviour of DAPR_GRPC_ENPOINTwith the scheme valuehttpsto signal to use TLS. Where a value contains both thehttpsscheme and?tls=false` query, SDKs will error and refuse to connect.

  • Feature flags N/A

Acceptance Criteria

How will success be measured?

  • Performance targets N/A

  • Compabitility requirements Same environment variables work with any SDK - except if protocol is not supported by given SDK.

  • Metrics N/A

Completion Checklist

What changes or actions are required to make this proposal complete?

  • SDK changes
    • Add support for new environment variable
    • Add integration testing on each SDK when possible
  • Documentation

Test matrix

URL Endpoint string to pass to grpc client Hostname Port TLS Error
:5000 dns:localhost:5000 localhost 5000 FALSE
:5000?tls=false dns:localhost:5000 localhost 5000 FALSE
:5000?tls=true dns:localhost:5000 localhost 5000 TRUE
myhost dns:myhost:443 myhost 443 FALSE
myhost?tls=false dns:myhost:443 myhost 443 FALSE
myhost?tls=true dns:myhost:443 myhost 443 TRUE
myhost:443 dns:myhost:443 myhost 443 FALSE
myhost:443?tls=false dns:myhost:443 myhost 443 FALSE
myhost:443?tls=true dns:myhost:443 myhost 443 TRUE
http://myhost dns:myhost:80 myhost 80 FALSE
http://myhost?tls=false the tls query parameter is not supported for http(s) endpoints: 'tls=false'
http://myhost?tls=true the tls query parameter is not supported for http(s) endpoints: 'tls=true'
http://myhost:443 dns:myhost:443 myhost 443 FALSE
http://myhost:443?tls=false the tls query parameter is not supported for http(s) endpoints: 'tls=false'
http://myhost:443?tls=true the tls query parameter is not supported for http(s) endpoints: 'tls=true'
http://myhost:5000 dns:myhost:5000 myhost 5000 FALSE
http://myhost:5000?tls=false the tls query parameter is not supported for http(s) endpoints: 'tls=false'
http://myhost:5000?tls=true the tls query parameter is not supported for http(s) endpoints: 'tls=true'
https://myhost:443 dns:myhost:443 myhost 443 TRUE
https://myhost:443?tls=false the tls query parameter is not supported for http(s) endpoints: 'tls=false'
https://myhost:443?tls=true the tls query parameter is not supported for http(s) endpoints: 'tls=true'
dns:myhost dns:myhost:443 myhost 443 FALSE
dns:myhost?tls=false dns:myhost:443 myhost 443 FALSE
dns:myhost?tls=true dns:myhost:443 myhost 443 TRUE
dns://myauthority:53/myhost dns://myauthority:53/myhost:443 myhost 443 FALSE
dns://myauthority:53/myhost?tls=false dns://myauthority:53/myhost:443 myhost 443 FALSE
dns://myauthority:53/myhost?tls=true dns://myauthority:53/myhost:443 myhost 443 TRUE
dns://myhost invalid dns authority 'myhost' in URL 'dns://myhost'
unix:my.sock unix:my.sock my.sock FALSE
unix:my.sock?tls=true unix:my.sock my.sock TRUE
unix://my.sock unix://my.sock my.sock FALSE
unix://my.sock?tls=true unix://my.sock my.sock TRUE
unix-abstract:my.sock unix-abstract:my.sock my.sock FALSE
unix-abstract:my.sock?tls=true unix-abstract:my.sock my.sock TRUE
vsock:mycid:5000 vsock:mycid:5000 mycid 5000 FALSE
vsock:mycid:5000?tls=true vsock:mycid:5000 mycid 5000 TRUE
[2001:db8:1f70::999:de8:7648:6e8] dns:[2001:db8:1f70::999:de8:7648:6e8]:443 [2001:db8:1f70::999:de8:7648:6e8] 443 FALSE
dns:[2001:db8:1f70::999:de8:7648:6e8]:5000 dns:[2001:db8:1f70::999:de8:7648:6e8]:5000 [2001:db8:1f70::999:de8:7648:6e8] 5000 FALSE
dns:[2001:db8:1f70::999:de8:7648:6e8]:5000?abc=[] Error: query parameters are not supported for gRPC endpoints: 'abc=[]'
dns://myauthority:53/[2001:db8:1f70::999:de8:7648:6e8] dns://myauthority:53/[2001:db8:1f70::999:de8:7648:6e8]:443 [2001:db8:1f70::999:de8:7648:6e8] 443 FALSE
dns:[2001:db8:1f70::999:de8:7648:6e8] dns:[2001:db8:1f70::999:de8:7648:6e8]:443 [2001:db8:1f70::999:de8:7648:6e8] 443 FALSE
https://[2001:db8:1f70::999:de8:7648:6e8] dns:[2001:db8:1f70::999:de8:7648:6e8]:80 [2001:db8:1f70::999:de8:7648:6e8] 80 TRUE
https://[2001:db8:1f70::999:de8:7648:6e8]:5000 dns:[2001:db8:1f70::999:de8:7648:6e8]:5000 [2001:db8:1f70::999:de8:7648:6e8] 5000 TRUE
host:5000/v1/dapr paths are not supported for gRPC endpoints: '/v1/dapr'
host:5000/?a=1 paths are not supported for gRPC endpoints: '/'
inv-scheme://myhost invalid scheme 'inv-scheme' in URL 'inv-scheme://myhost'
inv-scheme:myhost:5000 invalid scheme 'inv-scheme' in URL 'inv-scheme:myhost:5000'