a (hacky, wip) multi-tenant oidc-terminating reverse proxy, written in anger on top of pingora
1syntax = "proto3";
2
3package config.format;
4
5// the root config
6message Config {
7 // the domains to serve
8 map<string, Domain> domains = 1;
9
10 // bind to tcp ports, with optional tls
11 repeated TCPBinding bind_to_tcp = 2;
12
13 // lower-level pingora config
14 Pingora pingora = 3;
15}
16
17message Domain {
18 // require oidc auth if this is set
19 optional OIDC oidc_auth = 1;
20
21 // https backends
22 repeated HTTPSBackend https = 3;
23 // http backends
24 repeated HTTPSBackend http = 7;
25 // unix domain socket backends
26 repeated UDSBackend uds = 4;
27
28 enum TLSMode {
29 // don't support redirects, they can be _very_ unsafe. just use hsts
30
31 // only allow https, no redirect
32 TLS_MODE_ONLY = 0;
33 // allow http, for testing purposes
34 TLS_MODE_UNSAFE_ALLOW_HTTP = 1;
35 }
36
37 TLSMode tls_mode = 5;
38
39 // set or clear headers on the backend request
40 ManageHeaders manage_headers = 6;
41}
42
43message OIDC {
44 // the base oidc discovery url, without the `.well-known/openid-configuration` part
45 //
46 // per [OIDC Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)
47 string discovery_url_base = 1;
48
49 string client_id = 2;
50 string client_secret_path = 3;
51
52 Scopes scopes = 4;
53 Claims claims = 5;
54
55 // per oidc core v1-with-errata-2§3.1.3.7 point 6, we _may_ skip validation
56 // of the id token if it was received over tls. which it will be, in our
57 // case. some folks may want to be extra paranoid, but generally you either
58 // trust tls, or you can't trust discovery, and thus can't trust the jwks info,
59 // so default this to false.
60 bool validate_with_jwk = 6;
61
62 // where to redirect to on logout
63 string logout_url = 7;
64}
65
66message Scopes {
67 repeated string optional = 1;
68 repeated string required = 2;
69}
70
71// information on how to process returned claims
72message Claims {
73 // map the given claims to a header in the backend request
74 //
75 // headers specified here with no corresponding claim value will be wiped
76 map<string, string> claim_to_header = 1;
77}
78
79// a standard https backend
80message HTTPSBackend {
81 // full ipv4 or v6 address, including port
82 string addr = 1;
83 // weight of this backend, if load-balancing
84 optional uint64 weight = 2;
85}
86
87// a unix domain socket backend
88message UDSBackend {
89 // path to the uds socket
90 string path = 1;
91 // weight of this backend, if load-balancing
92 optional uint64 weight = 2;
93}
94
95// these headers will be set if they are set to something
96//
97// either way, they will be wiped if the client tries to send them
98message ManageHeaders {
99 // set the given header to be the request host
100 optional string host = 1;
101 // set an `X-Forwarded-For`-style header, appending `,<remote_addr>` to any existing value
102 optional string x_forwarded_for = 2;
103 // set an `X-Forwarded-Proto`-style header to the original scheme of the request
104 optional string x_forwarded_proto = 3;
105 // set an `X-Real-IP`-style header (i.e. _just_ the remote address)
106 optional string remote_addr = 4;
107
108 // always clear these headers
109 repeated string always_clear = 5;
110}
111
112// equivalent to [`pingora::server::configuration::Config`]
113message Pingora {
114 uint64 version = 1;
115 bool daemon = 2;
116 optional string error_log = 3;
117 string pid_file = 4;
118 string upgrade_sock = 5;
119 optional string user = 6;
120 optional string group = 7;
121 uint64 threads = 8;
122 uint64 listener_tasks_per_fd = 9;
123 bool work_stealing = 10;
124 optional string ca_file = 11;
125 optional uint64 grace_period_seconds = 12;
126 optional uint64 graceful_shutdown_timeout_seconds = 13;
127 repeated string client_bind_to_ipv4 = 14;
128 repeated string client_bind_to_ipv6 = 15;
129 uint64 upstream_keepalive_pool_size = 16;
130 optional uint64 upstream_connect_offload_threadpools = 17;
131 optional uint64 upstream_connect_offload_thread_per_pool = 18;
132 bool upstream_debug_ssl_keylog = 19;
133 uint64 max_retries = 20;
134 optional uint64 upgrade_sock_connect_accept_max_retries = 21;
135
136}
137
138message TCPBinding {
139 // configure used tls settings
140 message TLS {
141 // path to the (public) tls certificate, with all intermediate certificates (fullchain.pem for most acme clients)
142 string cert_path = 1;
143 // path to the (privat) tls key
144 string key_path = 2;
145 }
146
147 // host an port to bind to
148 string addr = 1;
149 // tls, if desired
150 optional TLS tls = 2;
151
152 // TODO(feature): surface tcp options from pingora
153}