blob: faf6ddaa5d8bcab871736581dc7fbdb8b5eddc1b [file] [log] [blame]
Serge Bazanski32d73482021-02-01 23:49:17 +01001// Copyright 2020 The Monogon Project Authors.
2//
3// SPDX-License-Identifier: Apache-2.0
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17syntax = "proto3";
18package metropolis.proto.api;
19option go_package = "source.monogon.dev/metropolis/proto/api";
20
Serge Bazanski9ffa1f92021-09-01 15:42:23 +020021import "metropolis/proto/ext/authorization.proto";
22
Serge Bazanski32d73482021-02-01 23:49:17 +010023// Authentication, authorization and accounting.
24service AAA {
25 // Escrow is an endpoint used to retrieve short-lived access credentials to
26 // the cluster. These short-lived access credentials are x509 certificates
27 // that can then be used to directly authenticate to other RPC methods
28 // exposed by Metropolis. This short-lived certificate may or may not be
29 // fully self-standing cryptographically - this depends on the policy and
30 // other configuration of the system. The returned short-lived certificate
31 // may even be used as proofs within next Escrow calls in the case of more
32 // complex flows.
33 //
34 // The client in this RPC is an end-user of the cluster, be it a human or
35 // automated process that runs outside of a Metropolis cluster.
36 //
37 // To retrieve this short-lived certificate, the client must provide
38 // different kind of proofs to the server. Upon connecting and receiving
39 // the initial message from the client, the server will send a list of
40 // proof requests, detailing proofs that the client must need to fulfill to
41 // retrieve the requested credentials. Which proofs are requested depends
42 // on the configuration of the client. The way to fulfill these proofs
43 // depend on their kind, with some being provided in-band (eg. access
44 // credentials, U2F codes), some being provided out of band (eg. an RPC
45 // channel opened from a given IP address or with a given existing TLS
46 // certificate), and some dependent on external systems (eg. SSO).
47 //
48 // If the requested identity within the first EscrowFromClient is not
49 // defined, the server may:
50 //
51 // - Abort the connection immediately with an error about an unknown
52 // identity being requested.
53 // - Continue processing the Escrow RPC as if the identity existed, and
54 // either gather enough other proofs to be able to trust the client
55 // enough to abort it saying that the identity is unknown; or continue
56 // and pretend that the other proofs submitted by the client are
57 // invalid.
58 //
59 // Once the proofs are fulfilled by the client, the server will send an
60 // x509 PEM-encoded certificate that the client can use in subsequent
61 // calls to other Metropolis services.
62 //
63 // TODO(q3k): SPIFFE compatibility for short-lived certificates?
64 //
65 // This escrow flow can thus be used to implement several typical flows
66 // used for 'logging in' cluster users:
67 //
68 // Example: Username and password login
69 //
70 // This shows the simplest possible message flow for a simple interactive
71 // password authentication.
72 //
73 // Client Server
74 // | |
75 // | .---------------------------. |
76 // |----------| parameters < |-------->>>|
77 // | | requested_identity_name: | |
78 // | | "janedoe" | |
79 // | | public_key: | |
80 // | | "DEADBEEF..." | |
81 // | | > | |
82 // | '---------------------------' |
83 // | |
84 // | .---------------------------. |
85 // |<<<-------| needed < |-----------|
86 // | | kind: PLAINTEXT_PASSWORD | |
87 // | | > | |
88 // | '---------------------------' |
89 // | |
90 // | .---------------------------. |
91 // |----------| proofs < |-------->>>|
92 // | | plaintext_password: ".." | |
93 // | | > | |
94 // | '---------------------------' |
95 // | |
96 // | .---------------------------. |
97 // |<<<-------| fulfilled < |-----------|
98 // | | kind: PLAINTEXT_PASSWORD | |
99 // | | > | |
100 // | | emitted_certificate: | |
101 // | | "DEADFOOD..." | |
102 // | '---------------------------' |
103 // | |
104 // |<<<---------------- close ----------------------- |
105 // | |
106 //
107 // Example: multi-phase OIDC with hardware assessment (simplified):
108 //
109 // This first requests a certificate that's valid for one day, and requires
110 // the interactive use of a browser. Then, shorter-term certificates
111 // (actually used to perform RPCs) are requested on demand, their lifetime
112 // corresponding to the access tokens emitted by the IdP, but requiring
113 // no interactive browser access or reconfirmations by the user.
114 //
115 // Client Server
116 // | |
117 // | .--------------------------------------. |
118 // |<<<--| Exchange OIDC login proof and TPM |-->>>|
119 // | | assessment for week-long certificate,| |<--> IdP
120 // | | retrieve 1-day long certificate | |<--> User
121 // | | binding user to a refresh token on | | Browser
122 // | | the server. | |
123 // | '--------------------------------------' |
124 // | |
125 // | .--------------------------------------. | -.
126 // |<<<--| Exchange earlier certificate and TPM |-->>>|<--> IdP
127 // | | hardware assessment for 10-minute | | |
128 // | | long self-standing cryptographic | | > Repeats as
129 // | | certificate used to access other | | | long as
130 // | | services | | \ possible.
131 // | '--------------------------------------' | -'
132 //
133 // FAQ: How does this relate to access via web browsers?
134 //
135 // This flow is explicitly designed to be non dependent on web browers for
136 // security reasons. Due to these requirements, we cannot port this flow to
137 // always also work on browsers. Instead, we focus on the best that a
138 // standalone application on the client side can give us, eg. being able to
139 // use TLS client certificates, perform hardware attestation, and even talk
140 // to HSMs.
141 //
142 // In addition to this gRPC Escrow flow, an alternative flow geared
143 // especially towards web browser access (and eg. bearer token
144 // authentication and OAuth/OpenIDC integration) will be developed for
145 // users whose cluster policy allows for browser access. Both, however,
146 // will lead to retrieving identities from with the same namespace of
147 // entities.
148 //
Serge Bazanski9ffa1f92021-09-01 15:42:23 +0200149 rpc Escrow(stream EscrowFromClient) returns (stream EscrowFromServer) {
150 option (metropolis.proto.ext.authorization) = {
151 // The AAA implementation performs its own checks as needed, so the
152 // RPC middleware should allow everything through.
153 allow_unauthenticated: true
154 };
155 }
Serge Bazanski32d73482021-02-01 23:49:17 +0100156}
157
158message EscrowFromClient {
159 // Parameters used for the entirety of the escrow flow. These must be set
160 // only during the first EscrowFromClient message, and are ignored in
161 // further messages.
162 message Parameters {
163 // The requested identity name. This is currently opaque and not defined,
164 // but corresponds to the future 'Entity' system that Metropolis will
165 // implement. Required.
166 string requested_identity_name = 1;
167
168 // Public key for which the short-lived certificate will be issued.
169 // Currently, this must be an ed25519 public key's raw bytes (32
170 // bytes). In the future, other x509 signature algorithms might be
171 // supported.
172 // This key does not have to be the same key as the one that is part of
173 // the presented certificate during the Escrow RPC (if any). However,
174 // some proofs might have stricter requirements.
175 bytes public_key = 2;
176 }
177 Parameters parameters = 1;
178
179 // Proofs. These should only be submitted by the client after the server
180 // requests them, but if they are submitted within the first
181 // EscrowFromClientMessage they will be interpreted too. The problem with
182 // ahead of time proofs is that different a proof request from the server
183 // might parametrize the request in a way that would elicit a different
184 // answer from the client, so care must be taken to ensure that the
185 // requests from the server are verified against the assumption that the
186 // client makes (if any). Ideally, the client should be fully reactive to
187 // requested proofs, and not hardcode any behaviour.
188 message Proofs {
189 // Plaintext password in response to KIND_PLAINTEXT_PASSWORD proof
190 // request.
191 string plaintext_password = 1;
192 }
193 Proofs proofs = 2;
194}
195
196message EscrowFromServer {
197 // A proof requested from the server. Within an Escrow RPC, proofs can be
198 // either 'needed' or 'fulfilled'. Each proof has a kind, and kinds within
199 // all proof requests (either needed or fulfilled) are unique.
200 message ProofRequest {
201 enum Kind {
202 KIND_INVALID = 0;
203 // The client needs to present a long-lived 'refresh' certificate.
204 // If this is in `needed`, it means the client did not present a
205 // certificate and will need to abort this RPC and connect with one
206 // presented.
207 // If the client presents an invalid certificate, the Escrow RPC
208 // will fail.
209 KIND_REFRESH_CERTIFICATE = 1;
210 // The client needs to present a static, plaintext password/token.
211 // This can be fulfilled by setting
212 // EscrowFromClient.proofs.plaintext_password.
213 // If the client presents an invalid password, the Escrow RPC will
214 // fail.
215 KIND_PLAINTEXT_PASSWORD = 2;
216
217 // Future possibilities:
218 // // One-or-two-sided hardware assessment via TPM.
219 // KIND_HARDWARE_ASSESMENT_EXCHANGE = ...
220 // // Making the client proove that the certificate is stored on
221 // // some secure element.
222 // KIND_PRIVATE_KEY_IN_SECURE_ELEMENT = ...
223 // // Making the client go through an OIDC login flow, with the
224 // // server possibly storing the resulting refresh/access tokens.
225 // KIND_OIDC_FLOW_COMPLETION = ...
226 };
227 Kind kind = 1;
228 }
229 // Proofs that the server requests from the client which the client has not
230 // yet fulfilled. Within the lifecycle of the Escrow RPC, the needed proofs
231 // will only move from needed to fulfilled as the client submits more
232 // proofs.
233 repeated ProofRequest needed = 1;
234 // Proofs that the server accepted from the client.
235 repeated ProofRequest fulfilled = 2;
236
237 // If all proof requests are fulfilled, the bytes of the emitted PEM
238 // certificate.
239 bytes emitted_certificate = 3;
240}
241
242// Protobuf-encoded data that is part of certificates emitted by the
243// Metropolis CA. Encoded as protobuf and inserted into a Subject Alternative
244// Name of type otherName with type-id:
245//
246// 2.25.205720787499610521842135044124912906832.1.1
247//
248// TODO(q3k): register something under 1.3.6.1.4.1 and alloacte some OID within
249// that instead of relying on UUIDs within 2.25?
250message CertificateSAN {
251 // Validity descrises how consumers of this certificate should treat the
252 // information contained within it. Currently there's two kinds of
253 // validities, the difference between them being whether or not the
254 // certificate needs to actively be checked for revocation or not.
255 enum Validity {
256 VALIDITY_INVALID = 0;
257 // Certificate must only be used by components that can verify with
258 // Metropolis that it hasn't been revoked. The method (OCSP, CRL)
259 // intentionally left blank for now.
260 VALIDITY_ONLINE = 1;
261 // Certificate can be trusted on cryptographic basis alone as long as
262 // it hasn't expired, without consulting revocation system.
263 VALIDITY_OFFLINE = 2;
264 }
265 Validity validity = 1;
266
267 // Assertions are facts stated about the bearer of this certificate by the
268 // CA that emitted it - in this case, the Metropolis cluster that emitted
269 // it. Each assertion details exactly one fact of one kind, and there can
270 // be multiple assertions of any given kind.
271 message Assertion {
272 // IdentityConfirmed asserts that the emitter of this certificate has
273 // received all the required proofs at the time of issuance to confirm
274 // that the bearer of this certificate is the entity described by the
275 // identity name.
276 message IdentityConfirmed {
277 string name = 1;
278 };
279 // MetropolisRPCAllowed means that that connections established to
280 // Metropolis RPC endpoints will proceed. If given, IdentityConfirmed
281 // must also be given.
282 message MetropolisRPCAllowed {
283 // Future possibilities: scoping to only some (low privilege) RPC
284 // methods, ...
285 };
286 oneof kind {
287 IdentityConfirmed identity_confirmed = 1;
288 MetropolisRPCAllowed metropolis_rpc_allowed = 2;
289 // Future possibilties:
290 // OIDCIdentityConfirmed ...
291 // TPMColocationConfirmed ...
292 // SourceAddressConfirmed ...
293 // ReportedClientConfiguration ...
294 };
295 }
296 repeated Assertion assertions = 2;
297}