@@ -9,6 +9,7 @@ import "google/api/annotations.proto";
99import "validate/validate.proto" ;
1010
1111import "authzed/api/v1/core.proto" ;
12+ import "authzed/api/v1/permission_service.proto" ;
1213
1314// SchemaService implements operations on a Permissions System's Schema.
1415service SchemaService {
@@ -31,6 +32,49 @@ service SchemaService {
3132 body : "*"
3233 };
3334 }
35+
36+ // ReflectSchema reflects the current schema stored in SpiceDB, returning a structural
37+ // form of the schema for use by client tooling.
38+ rpc ReflectSchema (ReflectSchemaRequest )
39+ returns (ReflectSchemaResponse ) {
40+ option (google.api.http ) = {
41+ post : "/v1/schema/reflectschema"
42+ body : "*"
43+ };
44+ }
45+
46+ // ComputablePermissions returns the set of permissions that compute based off a relation
47+ // in the current schema. For example, if the schema has a relation `viewer` and a permission
48+ // `view` defined as `permission view = viewer + editor`, then the
49+ // computable permissions for the relation `viewer` will include `view`.
50+ rpc ComputablePermissions (ComputablePermissionsRequest )
51+ returns (ComputablePermissionsResponse ) {
52+ option (google.api.http ) = {
53+ post : "/v1/schema/permissions/computable"
54+ body : "*"
55+ };
56+ }
57+
58+ // DependentRelations returns the set of relations and permissions that used
59+ // to compute a permission, recursively, in the current schema. It is the
60+ // inverse of the ComputablePermissions API.
61+ rpc DependentRelations (DependentRelationsRequest )
62+ returns (DependentRelationsResponse ) {
63+ option (google.api.http ) = {
64+ post : "/v1/schema/permissions/dependent"
65+ body : "*"
66+ };
67+ }
68+
69+ // DiffSchema returns the difference between the specified schema and the current
70+ // schema stored in SpiceDB.
71+ rpc DiffSchema (DiffSchemaRequest )
72+ returns (DiffSchemaResponse ) {
73+ option (google.api.http ) = {
74+ post : "/v1/schema/diffschema"
75+ body : "*"
76+ };
77+ }
3478}
3579
3680// ReadSchemaRequest returns the schema from the database.
@@ -60,3 +104,196 @@ message WriteSchemaResponse {
60104 // written_at is the ZedToken at which the schema was written.
61105 ZedToken written_at = 1 [ (validate.rules ) .message.required = true ];
62106}
107+
108+ // Reflection types ////////////////////////////////////////////
109+
110+ message ReflectSchemaRequest {
111+ Consistency consistency = 1 ;
112+
113+ // optional_filters defines optional filters that are applied in
114+ // an OR fashion to the schema, before being returned
115+ repeated ReflectionSchemaFilter optional_filters = 2 ;
116+ }
117+
118+ message ReflectSchemaResponse {
119+ // definitions are the definitions defined in the schema.
120+ repeated ReflectionDefinition definitions = 1 ;
121+
122+ // caveats are the caveats defined in the schema.
123+ repeated ReflectionCaveat caveats = 2 ;
124+
125+ // read_at is the ZedToken at which the schema was read.
126+ ZedToken read_at = 3 ;
127+ }
128+
129+ // ReflectionSchemaFilter is a filter that can be applied to the schema on reflection.
130+ message ReflectionSchemaFilter {
131+ // optional_definition_name_filter is a prefix that is matched against the definition name.
132+ string optional_definition_name_filter = 1 ;
133+
134+ // optional_caveat_name_filter is a prefix that is matched against the caveat name.
135+ string optional_caveat_name_filter = 2 ;
136+
137+ // optional_relation_name_filter is a prefix that is matched against the relation name.
138+ string optional_relation_name_filter = 3 ;
139+
140+ // optional_permission_name_filter is a prefix that is matched against the permission name.
141+ string optional_permission_name_filter = 4 ;
142+ }
143+
144+ // ReflectionDefinition is the representation of a definition in the schema.
145+ message ReflectionDefinition {
146+ string name = 1 ;
147+
148+ // comment is a human-readable comments on the definition. Will include
149+ // delimiter characters.
150+ string comment = 2 ;
151+
152+ repeated ReflectionRelation relations = 3 ;
153+ repeated ReflectionPermission permissions = 4 ;
154+ }
155+
156+ // ReflectionCaveat is the representation of a caveat in the schema.
157+ message ReflectionCaveat {
158+ string name = 1 ;
159+
160+ // comment is a human-readable comments on the caveat. Will include
161+ // delimiter characters.
162+ string comment = 2 ;
163+
164+ repeated ReflectionCaveatParameter parameters = 3 ;
165+ string expression = 4 ;
166+ }
167+
168+ // ReflectionCaveatParameter is the representation of a parameter in a caveat.
169+ message ReflectionCaveatParameter {
170+ string name = 1 ;
171+
172+ // type is the type of the parameter. Will be a string representing the
173+ // type, e.g. `int` or `list<string>`
174+ string type = 2 ;
175+ string parent_caveat_name = 3 ;
176+ }
177+
178+ // ReflectionRelation is the representation of a relation in the schema.
179+ message ReflectionRelation {
180+ string name = 1 ;
181+ string comment = 2 ;
182+ string parent_definition_name = 3 ;
183+ repeated ReflectionTypeReference subject_types = 4 ;
184+ }
185+
186+ // ReflectionTypeReference is the representation of a type reference in the schema.
187+ message ReflectionTypeReference {
188+ // subject_definition_name is the name of the subject's definition.
189+ string subject_definition_name = 1 ;
190+
191+ // optional_caveat_name is the name of the caveat that is applied to the subject, if any.
192+ string optional_caveat_name = 2 ;
193+
194+ oneof typeref {
195+ // is_terminal_subject is true if the subject is terminal, meaning it is referenced directly vs a sub-relation.
196+ bool is_terminal_subject = 3 ;
197+
198+ // optional_relation_name is the name of the relation that is applied to the subject, if any.
199+ string optional_relation_name = 4 ;
200+
201+ // is_public_wildcard is true if the subject is a public wildcard.
202+ bool is_public_wildcard = 5 ;
203+ }
204+ }
205+
206+ // ReflectionPermission is the representation of a permission in the schema.
207+ message ReflectionPermission {
208+ string name = 1 ;
209+
210+ // comment is a human-readable comments on the permission. Will include
211+ // delimiter characters.
212+ string comment = 2 ;
213+ string parent_definition_name = 3 ;
214+ }
215+
216+ message ComputablePermissionsRequest {
217+ Consistency consistency = 1 ;
218+ string definition_name = 2 ;
219+ string relation_name = 3 ;
220+
221+ // optional_definition_name_match is a prefix that is matched against the definition name(s)
222+ // for the permissions returned.
223+ // If not specified, will be ignored.
224+ string optional_definition_name_filter = 4 ;
225+ }
226+
227+ // ReflectionRelationReference is a reference to a relation or permission in the schema.
228+ message ReflectionRelationReference {
229+ string definition_name = 1 ;
230+ string relation_name = 2 ;
231+ bool is_permission = 3 ;
232+ }
233+
234+ message ComputablePermissionsResponse {
235+ repeated ReflectionRelationReference permissions = 1 ;
236+
237+ // read_at is the ZedToken at which the schema was read.
238+ ZedToken read_at = 2 ;
239+ }
240+
241+ message DependentRelationsRequest {
242+ Consistency consistency = 1 ;
243+ string definition_name = 2 ;
244+ string permission_name = 3 ;
245+ }
246+
247+ message DependentRelationsResponse {
248+ repeated ReflectionRelationReference relations = 1 ;
249+
250+ // read_at is the ZedToken at which the schema was read.
251+ ZedToken read_at = 2 ;
252+ }
253+
254+ message DiffSchemaRequest {
255+ Consistency consistency = 1 ;
256+ string comparison_schema = 2 ;
257+ }
258+
259+ message DiffSchemaResponse {
260+ repeated ReflectionSchemaDiff diffs = 1 ;
261+
262+ // read_at is the ZedToken at which the schema was read.
263+ ZedToken read_at = 2 ;
264+ }
265+
266+ message ReflectionRelationSubjectTypeChange {
267+ ReflectionRelation relation = 1 ;
268+ ReflectionTypeReference changed_subject_type = 2 ;
269+ }
270+
271+ message ReflectionCaveatParameterTypeChange {
272+ ReflectionCaveatParameter parameter = 1 ;
273+ string previous_type = 2 ;
274+ }
275+
276+ // ReflectionSchemaDiff is the representation of a diff between two schemas.
277+ message ReflectionSchemaDiff {
278+ oneof diff {
279+ ReflectionDefinition definition_added = 1 ;
280+ ReflectionDefinition definition_removed = 2 ;
281+ ReflectionDefinition definition_doc_comment_changed = 3 ;
282+ ReflectionRelation relation_added = 4 ;
283+ ReflectionRelation relation_removed = 5 ;
284+ ReflectionRelation relation_doc_comment_changed = 6 ;
285+ ReflectionRelationSubjectTypeChange relation_subject_type_added = 7 ;
286+ ReflectionRelationSubjectTypeChange relation_subject_type_removed = 8 ;
287+ ReflectionPermission permission_added = 9 ;
288+ ReflectionPermission permission_removed = 10 ;
289+ ReflectionPermission permission_doc_comment_changed = 11 ;
290+ ReflectionPermission permission_expr_changed = 12 ;
291+ ReflectionCaveat caveat_added = 13 ;
292+ ReflectionCaveat caveat_removed = 14 ;
293+ ReflectionCaveat caveat_doc_comment_changed = 15 ;
294+ ReflectionCaveat caveat_expr_changed = 16 ;
295+ ReflectionCaveatParameter caveat_parameter_added = 17 ;
296+ ReflectionCaveatParameter caveat_parameter_removed = 18 ;
297+ ReflectionCaveatParameterTypeChange caveat_parameter_type_changed = 19 ;
298+ }
299+ }
0 commit comments