...
1syntax = "proto3";
2
3package io.linkerd.proxy.inbound;
4
5option go_package = "github.com/linkerd/linkerd2-proxy-api/go/inbound";
6
7import "google/protobuf/duration.proto";
8import "grpc_route.proto";
9import "http_route.proto";
10import "meta.proto";
11import "net.proto";
12
13/// An API exposed to the linkerd2-proxy to configure the inbound proxy with per-port configuration
14///
15/// Proxies are expected to watch policies for each known port. As policies change, proxies update
16/// their behavior for newly accepted connections.
17///
18/// The unary `GetPort` endpoint is exposed as a convenience for clients to query policies for
19/// diagnostic purposes.
20service InboundServerPolicies {
21 /// Gets the inbound server policy for a given workload port.
22 rpc GetPort(PortSpec) returns (Server) {}
23
24 /// Watches the inbound server policy for a given workload port.
25 rpc WatchPort(PortSpec) returns (stream Server) {}
26}
27
28message PortSpec {
29 // Identifies a proxy workload (e.g., pod name).
30 string workload = 1;
31
32 // An inbound port on _workload_.
33 uint32 port = 2;
34}
35
36message Server {
37 // If set, indicates how the proxy should proxy connections on the specified
38 // port.
39 ProxyProtocol protocol = 1;
40
41 // Indicates the IP addresses on which the proxy may receive connections.
42 // Connections targetting other IP addresses will be dropped.
43 repeated io.linkerd.proxy.net.IPAddress server_ips = 2;
44
45 // Configures a proxy to allow connections from the specified clients.
46 //
47 // If unset, no connections are permitted.
48 repeated Authz authorizations = 3;
49
50 // Descriptive labels to be added to metrics, etc.
51 //
52 // A control plane SHOULD return the same keys in all policies. That is, we do
53 // NOT want to return arbitrary pod labels in this field.
54 map<string, string> labels = 4;
55}
56
57message ProxyProtocol {
58 oneof kind {
59 Detect detect = 1;
60 Opaque opaque = 2;
61 Tls tls = 3;
62 Http1 http1 = 4;
63 Http2 http2 = 5;
64 Grpc grpc = 6;
65 }
66
67 message Detect {
68 google.protobuf.Duration timeout = 1;
69
70 // If the protocol detected as HTTP, a list of HTTP routes that should be
71 // matched.
72 repeated HttpRoute http_routes = 3;
73
74 // Never implemented.
75 reserved 2;
76 }
77
78 message Http1 {
79 repeated HttpRoute routes = 2;
80
81 // Never implemented.
82 reserved 1;
83 }
84
85 message Http2 {
86 repeated HttpRoute routes = 2;
87
88 // Never implemented.
89 reserved 1;
90 }
91
92 message Grpc {
93 repeated GrpcRoute routes = 2;
94
95 // Never implemented.
96 reserved 1;
97 }
98
99 message Opaque {
100 // TODO: opaque TLS settings (versions, algorithms, SNI)
101 }
102
103 message Tls {}
104}
105
106message Authz {
107 // Limits this authorization to client addresses in the provided networks.
108 //
109 // Must have at least one network, otherwise the authorization must be
110 // ignored. An authorization matches all clients by including an explicit
111 // match on, i.e., `[0.0.0.0/0, 0::/0]``.
112 repeated Network networks = 1;
113
114 // Must be set.
115 Authn authentication = 2;
116
117 // Descriptive labels to be added to metrics, etc.
118 //
119 // A control plane SHOULD return the same keys in all authorizations. That is,
120 // we do NOT want to return arbitrary pod labels in this field.
121 //
122 // `labels` should be considered deprecated. `metadata` is preferred. However,
123 // controllers should continue to set `labels` for compatibility with older
124 // proxies.
125 map<string, string> labels = 3;
126
127 // If set, describes an Authorization configuration. Replaces the free-from
128 // `labels` field.
129 io.linkerd.proxy.meta.Metadata metadata = 4;
130}
131
132// Describes a network of authorized clients.
133message Network {
134 io.linkerd.proxy.net.IPNetwork net = 1;
135 repeated io.linkerd.proxy.net.IPNetwork except = 2;
136}
137
138message Authn {
139 oneof permit {
140 PermitUnauthenticated unauthenticated = 1;
141
142 // If set, requires that the connection is transported over mesh TLS.
143 PermitMeshTLS meshTLS = 2;
144 }
145
146 // TODO(ver) identify authentication resources?
147 // io.linkerd.proxy.meta.Metadata metadata = 3;
148
149 message PermitUnauthenticated {}
150
151 message PermitMeshTLS {
152 oneof clients {
153 // Indicates that client identities are not required.
154 PermitUnauthenticated unauthenticated = 1;
155
156 // Indicates that mutually-authenticated connections are permitted from
157 // clients with matching identities.
158 PermitClientIdentities identities = 2;
159 }
160
161 message PermitClientIdentities {
162 // A list of literal identities.
163 repeated Identity identities = 1;
164
165 // A list of identity suffixes.
166 //
167 // If this contains an empty suffix, all identities are matched.
168 repeated IdentitySuffix suffixes = 2;
169 }
170 }
171}
172
173message Identity { string name = 1; }
174
175// Encodes a DNS-like name suffix as sequence of parts.
176//
177// An empty list is equivalent to `.` (matching all names); the list `["foo",
178// "bar"]` is equivalent to "foo.bar." (matching `*.foo.bar`), etc.
179message IdentitySuffix { repeated string parts = 1; }
180
181// Inbound-specific HTTP route configuration (based on the
182// [Gateway API](https://gateway-api.sigs.k8s.io/v1alpha2/references/spec/#gateway.networking.k8s.io/v1alpha2.HTTPRoute)).
183message HttpRoute {
184 io.linkerd.proxy.meta.Metadata metadata = 1;
185
186 // If empty, the host value is ignored.
187 repeated io.linkerd.proxy.http_route.HostMatch hosts = 2;
188
189 // Extends the list of authorizations on the `Server` with authorizations
190 // specific to this route.
191 repeated Authz authorizations = 3;
192
193 // Must have at least one rule.
194 repeated Rule rules = 4;
195
196 message Rule {
197 repeated io.linkerd.proxy.http_route.HttpRouteMatch matches = 1;
198 repeated Filter filters = 2;
199 }
200
201 message Filter {
202 oneof kind {
203 io.linkerd.proxy.http_route.HttpFailureInjector failure_injector = 1;
204 io.linkerd.proxy.http_route.RequestHeaderModifier request_header_modifier = 2;
205 io.linkerd.proxy.http_route.RequestRedirect redirect = 3;
206 }
207 }
208}
209
210// Inbound-specific gRPC route configuration.
211message GrpcRoute {
212 io.linkerd.proxy.meta.Metadata metadata = 1;
213
214 // If empty, the host value is ignored.
215 repeated io.linkerd.proxy.http_route.HostMatch hosts = 2;
216
217 // The server MUST return at least one authorization, otherwise all requests
218 // to this route will fail with an unauthorized response.
219 repeated Authz authorizations = 3;
220
221 // Must have at least one rule.
222 repeated Rule rules = 4;
223
224 message Rule {
225 repeated io.linkerd.proxy.grpc_route.GrpcRouteMatch matches = 1;
226 repeated Filter filters = 2;
227 }
228
229 message Filter {
230 oneof kind {
231 io.linkerd.proxy.grpc_route.GrpcFailureInjector failure_injector = 1;
232 io.linkerd.proxy.http_route.RequestHeaderModifier request_header_modifier = 2;
233 }
234 }
235}
View as plain text