-
Notifications
You must be signed in to change notification settings - Fork 4
/
ovgs.proto
365 lines (323 loc) · 13.6 KB
/
ovgs.proto
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
// Copyright (c) 2023 Arista Networks, Inc.
// Use of this source code is governed by the BSD 2-Clause License
// that can be found in the LICENSE file.
syntax = "proto3";
package ovgs.v1;
import "google/protobuf/timestamp.proto";
option go_package = "github.com/aristanetworks/ownership-voucher-grpc/ovgs";
// The OVGS service defines a heirarchy of 'groups', which are identified by a
// group_id (allocated by the server). Each group can have several child groups;
// Pinned Domain Certs are associated to a group, serial numbers can be assigned to a
// group (which serves to limit the set of Users who can issue vouchers for those
// serial numbers to Users who have the necessary permissions in that group)
// Groups are created by users (except the root group, more on this later) and roles
// are assigned to users (limiting the set of operations a user can invoke) per group.
// Any permissions accorded by these roles on a group are heirarchical in nature.
// Users are uniquely identified by the tuple username, user_type, org_id.
// Note that the creation of a User is external to the ovgs service. Users may be
// created by any mechanism that the service implementor may offer. It is assumed
// that all such Users are known to ovgs, which only deals with the assignment of
// roles to them.
// Root group - Each customer/org is assigned a name. The org_id can be constructed
// as "org-" + org name. A root group with org_id as the group_id is pre-created
// and all serial numbers owned by the org are added to this root group. Moreover,
// an initial User is given ADMIN role over this root group as part of the setup,
// which can then be used to bootstrap the rest of the org tree - add more users,
// create child groups, assign serials to them, add certs and finally, issue
// vouchers for a serial number.
enum UserRole {
USER_ROLE_UNSPECIFIED = 0;
// Internal to the service
USER_ROLE_SUPPORT = 1;
// Read write to everything
USER_ROLE_ADMIN = 2;
// Read everything, write certs and serials
USER_ROLE_ASSIGNER = 3;
// Read only
USER_ROLE_REQUESTOR = 4;
}
enum AccountType {
ACCOUNT_TYPE_UNSPECIFIED = 0;
// USER represents a user account, tied to their identity, as specified by the
// authentication mechanism provided
ACCOUNT_TYPE_USER = 1;
// SERVICE_ACCOUNT provides an identity that is not tied to a human/user and is intended for
// programmatic access from any app/service (say the bootstrap server) to the ovgs service
// This can typically be achieved by creating service accounts (with some name), and issuing
// long lived tokens against that service account name
ACCOUNT_TYPE_SERVICE_ACCOUNT = 2;
}
// User/service accounts are assumed to have been created by some mechanism outside of
// ovgs, but are known to it. This service only deals with the assignment of roles to
// these existing user/service accounts.
message User {
// Username or Service Account name.
string username = 1;
// User account type
AccountType user_type = 2;
// org_id = "org-" + org name. A calling User will know their org_id.
string org_id = 3;
// Role of the user, one of ADMIN, ASSIGNER or REQUESTOR.
UserRole user_role = 4;
}
// A component uniquely identifies a part for which a voucher can be issued
message Component {
// ien is the vendor's IANA Enterprise Number. 30065 is Arista Networks's ien.
string ien = 1;
string serial_number = 2;
}
// The group heirarchy is rooted at the root group (group_id = org_id)
message CreateGroupRequest {
// Parent group ID, it could be org ID or a group ID.
string parent = 1;
// Description of the group.
string description = 2;
}
message CreateGroupResponse {
string group_id = 1;
}
message GetGroupRequest {
string group_id = 1;
}
message GetGroupResponse {
// Group id
string group_id = 1;
// list of certificate ids associated with the group.
repeated string cert_ids = 2;
// list of components in the group.
repeated Component components = 3;
// list of users in the group.
repeated User users = 4;
// list of group ids that are children of this group.
repeated string child_group_ids = 5;
// Description of group
string description = 6;
}
message DeleteGroupRequest {
string group_id = 1;
}
message DeleteGroupResponse {
}
// Roles are assigned to users in the context of a group, giving them
// certain permissions (as defined by that role) within the group.
// A User can assign a role to another User only if it has a role with
// equal or higher privileges. The following assignments are possible -
// Caller Role | Assignable Roles
// ADMIN | ADMIN, ASSIGNER, REQUESTOR
// ASSIGNER | ASSIGNER, REQUESTOR
// REQUESTOR | NA (cannot assign roles)
message AddUserRoleRequest {
// username or service account name
string username = 1;
// user account type
AccountType user_type = 2;
// org_id = "org-" + org name
string org_id = 3;
// Group id to assign to the user. Must be set.
string group_id = 4;
// role of the user, one of ADMIN, ASSIGNER or REQUESTOR.
UserRole user_role = 5;
}
message AddUserRoleResponse {
}
message RemoveUserRoleRequest {
// username or service account name
string username = 1;
// user account type
AccountType user_type = 2;
// org_id = "org-" + org name
string org_id = 3;
string group_id = 4;
}
message RemoveUserRoleResponse {
}
message GetUserRoleRequest {
// username or service account name
string username = 1;
// user type
AccountType user_type = 2;
// org_id = "org-" + org name
string org_id = 3;
}
message GetUserRoleResponse {
// mapping from a group to user's role in that group
map<string, UserRole> groups = 1;
}
// Domain certs contain PDCs assigned to groups.
message CreateDomainCertRequest {
string group_id = 1;
bytes certificate_der = 2;
bool revocation_checks = 3;
google.protobuf.Timestamp expiry_time = 4;
}
message CreateDomainCertResponse {
string cert_id = 1;
}
message GetDomainCertRequest {
string cert_id = 1;
}
message GetDomainCertResponse {
string cert_id = 1;
string group_id = 2;
bytes certificate_der = 3;
bool revocation_checks = 4;
google.protobuf.Timestamp expiry_time = 5;
}
message DeleteDomainCertRequest {
string cert_id = 1;
}
message DeleteDomainCertResponse {
}
message AddSerialRequest {
Component component = 1;
string group_id = 2;
}
message AddSerialResponse {
}
message RemoveSerialRequest {
Component component = 1;
string group_id = 2;
}
message RemoveSerialResponse {
}
message GetSerialRequest {
Component component = 1;
}
message GetSerialResponse {
// TPM's (if applicable) endorsement key in ASN.1 DER encoded format
bytes public_key_der = 1;
// List of groups the serial number belongs to.
repeated string group_ids = 2;
// SKU mac address
string mac_addr = 3;
// SKU/Hardware model name
string model = 4;
}
message GetOwnershipVoucherRequest {
// Serial number for the part to fetch OV.
Component component = 1;
// Certificate ID to use for OV.
string cert_id = 2;
// Lifetime of the OV.
google.protobuf.Timestamp lifetime = 3;
}
message GetOwnershipVoucherResponse {
// Voucher in binary CMS format (rfc5652)
bytes voucher_cms = 1;
// TPM's (if applicable) endorsement key in ASN.1 DER encoded format
bytes public_key_der = 2;
}
service OwnershipVoucherService {
// CreateGroup creates a group as a child of an existing group.
// Errors will be returned:
// INVALID_ARGUMENT if either parent or description is empty
// NOT_FOUND if the parent group doesn't exist, as specified in request
// ALREADY_EXISTS if a group already exists with the same parent group
// and description.
// PERMISSION_DENIED if the user doesn't have access to the parent group
// Roles with permission to invoke this = ADMIN
rpc CreateGroup(CreateGroupRequest) returns (CreateGroupResponse);
// DeleteGroup deletes a named group. All associated cert_ids and child
// groups must have been deleted and all associated components must have
// been removed before the group can be deleted.
// Errors will be returned:
// INVALID_ARGUMENT if group_id = root group (the precreated root group
// cannot be deleted) or if cert_ids, users, or child_group_ids is
// non-empty.
// NOT_FOUND if the group doesn't exist
// PERMISSION_DENIED if user doesn't have access to parent group
// Roles with permission to invoke this = ADMIN
rpc DeleteGroup(DeleteGroupRequest) returns (DeleteGroupResponse);
// GetGroup returns the domain-certs (keyed by id), components,
// user/role mappings for that group, and the child_group_ids.
// Errors will be returned:
// NOT_FOUND if the group doesn't exist
// PERMISSION_DENIED if the user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER, REQUESTOR
rpc GetGroup(GetGroupRequest) returns (GetGroupResponse);
// AddUserRole will assign a role to a user in a named group.
// Username is unique to an username, org_id, user_type tuple.
// Errors will be returned:
// INVALID_ARGUMENT if any field is empty
// NOT_FOUND if the group doesn't exist, as specified in the request
// FAILED_PRECONDITION if any of user tuple (username, org_id, user_type)
// or group_id do not exist.
// ALREADY_EXISTS if user already exists in the group
// PERMISSION_DENIED if the user doesn't have access to the group.
// Roles with permission to invoke this = ADMIN
rpc AddUserRole(AddUserRoleRequest) returns (AddUserRoleResponse);
// RemoveUserRole removes a role from a user in a named group.
// Username is unique to an username, org_id, user_type tuple.
// Errors will be returned:
// INVALID_ARGUMENT if any field is empty
// NOT_FOUND if the group doesn't exist or if the user tuple is not a
// member of the group.
// PERMISSION_DENIED if user doesn't have access to the group
// Roles with permission to invoke this = ADMIN
rpc RemoveUserRole(RemoveUserRoleRequest) returns (RemoveUserRoleResponse);
// GetUserRole returns the roles the user is assigned in the group.
// Username is unique to an username, org_id, user_type tuple.
// A user can only view roles of another user in the groups that
// it has a role assigned to.
// Errors will be returned:
// INVALID_ARGUMENT if any field is empty
// NOT_FOUND if the group doesn't exist or the user tuple is not a member.
// Roles with permission to invoke this = ADMIN, ASSIGNER, REQUESTOR
rpc GetUserRole(GetUserRoleRequest) returns (GetUserRoleResponse);
// AddSerial assigns the component to the group.
// Errors will be returned:
// INVALID_ARGUMENT if any field of component or group_id is empty or the
// IEN isn't applicable for the voucher issuer.
// NOT_FOUND if the component or group_id doesn't exist
// ALREADY_EXISTS if component is already a member of the group.
// PERMISSION_DENIED if the user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER
rpc AddSerial(AddSerialRequest) returns (AddSerialResponse);
// RemoveSerial removes the component from the group.
// Errors will be returned:
// INVALID_ARGUMENT if any field of component or group_id is empty or the
// IEN isn't applicable for the voucher issuer.
// NOT_FOUND if the component or group_id doesn't exist
// PERMISSION_DENIED if user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER
rpc RemoveSerial(RemoveSerialRequest) returns (RemoveSerialResponse);
// GetSerial returns component, groups the component belongs to.
// Errors will be returned:
// INVALID_ARGUMENT if any field of component or group_id is empty or the
// IEN isn't applicable for the voucher issuer.
// NOT_FOUND if the component doesn't exist.
// PERMISSION_DENIED if the user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER, REQUESTOR
rpc GetSerial(GetSerialRequest) returns (GetSerialResponse);
// CreateDomainCert creates the certificate in the group.
// Errors will be returned:
// INVALID_ARGUMENT if expiry_time is empty or in the past, the
// supplied cert is invalid (such expired or malformed), or any of the
// fields are empty.
// NOT_FOUND if the group_id doesn't exist.
// ALREADY_EXISTS if the certificate_der,revocation_checks,expiry_time
// tuple already exists in the group.
// PERMISSION_DENIED if the user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER
rpc CreateDomainCert(CreateDomainCertRequest) returns (CreateDomainCertResponse);
// DeleteDomainCert deletes the cert_id.
// Errors will be returned:
// NOT_FOUND if the cert_id doesn't exist
// PERMISSION_DENIED if user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER
rpc DeleteDomainCert(DeleteDomainCertRequest) returns (DeleteDomainCertResponse);
// GetDomainCert returns the details of the cert_id.
// NOT_FOUND if the cert_id doesn't exist.
// PERMISSION_DENIED if user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER, REQUESTOR
rpc GetDomainCert(GetDomainCertRequest) returns (GetDomainCertResponse);
// GetOwnershipVoucher issues an ownership voucher for the component (if it
// exists/if applicable)
// Errors will be returned:
// INVALID_ARGUMENT if any field of the request is empty, lifetime is in
// the past, or the IEN supplied isn't applicable for the voucher issuer
// FAILED_PRECONDITION if the component or cert_id do not exist.
// PERMISSION_DENIED if user doesn't have access to the group
// Roles with permission to invoke this = ADMIN, ASSIGNER, REQUESTOR
rpc GetOwnershipVoucher(GetOwnershipVoucherRequest) returns (GetOwnershipVoucherResponse);
}