Skip to content

Commit 902798a

Browse files
ivanauthclaude
andcommitted
feat: allow underscore prefix for definition, relation, and permission identifiers
Updates regex patterns across all API protos to allow identifiers to begin with an underscore (`_`). This enables a convention for marking identifiers as "private" or "internal". Use cases: - **Synthetic permissions**: Permissions that exist only to compose other permissions - **Internal relations**: Relations not meant to be directly referenced by application code - **Implementation details**: Parts of your schema that may change without affecting the public API Example: ```zed definition document { relation viewer: user relation _internal_viewer: user // Private synthetic permission permission _can_view = viewer + _internal_viewer // Public permission permission view = _can_view } ``` Companion PR to authzed/spicedb#2733 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <[email protected]>
1 parent e64729d commit 902798a

File tree

4 files changed

+42
-42
lines changed

4 files changed

+42
-42
lines changed

authzed/api/v1/core.proto

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,11 @@ message Relationship {
2323
// relation is how the resource and subject are related.
2424
string relation = 2 [
2525
(validate.rules).string = {
26-
pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$"
26+
pattern: "^[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
2727
max_bytes: 64
2828
},
2929
(buf.validate.field).string = {
30-
pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$"
30+
pattern: "^[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
3131
max_bytes: 64
3232
}
3333
];
@@ -81,11 +81,11 @@ message SubjectReference {
8181
];
8282
string optional_relation = 2 [
8383
(validate.rules).string = {
84-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
84+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
8585
max_bytes: 64
8686
},
8787
(buf.validate.field).string = {
88-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
88+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
8989
max_bytes: 64
9090
}
9191
];
@@ -95,11 +95,11 @@ message SubjectReference {
9595
message ObjectReference {
9696
string object_type = 1 [
9797
(validate.rules).string = {
98-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
98+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
9999
max_bytes: 128
100100
},
101101
(buf.validate.field).string = {
102-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
102+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
103103
max_bytes: 128
104104
}
105105
];

authzed/api/v1/experimental_service.proto

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -140,11 +140,11 @@ message ExperimentalRegisterRelationshipCounterRequest {
140140
// name is the name of the counter being registered.
141141
string name = 1 [
142142
(validate.rules).string = {
143-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
143+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
144144
max_bytes: 64
145145
},
146146
(buf.validate.field).string = {
147-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
147+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
148148
max_bytes: 64
149149
}
150150
];
@@ -163,11 +163,11 @@ message ExperimentalCountRelationshipsRequest {
163163
// name is the name of the counter whose count is being requested.
164164
string name = 1 [
165165
(validate.rules).string = {
166-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
166+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
167167
max_bytes: 64
168168
},
169169
(buf.validate.field).string = {
170-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
170+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
171171
max_bytes: 64
172172
}
173173
];
@@ -198,11 +198,11 @@ message ExperimentalUnregisterRelationshipCounterRequest {
198198
// name is the name of the counter being unregistered.
199199
string name = 1 [
200200
(validate.rules).string = {
201-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
201+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
202202
max_bytes: 64
203203
},
204204
(buf.validate.field).string = {
205-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
205+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
206206
max_bytes: 64
207207
}
208208
];
@@ -229,11 +229,11 @@ message BulkCheckPermissionRequestItem {
229229

230230
string permission = 2 [
231231
(validate.rules).string = {
232-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
232+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
233233
max_bytes: 64
234234
},
235235
(buf.validate.field).string = {
236-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
236+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
237237
max_bytes: 64
238238
}
239239
];

authzed/api/v1/permission_service.proto

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -201,11 +201,11 @@ message RelationshipFilter {
201201
// NOTE: It is not prefixed with "optional_" for legacy compatibility.
202202
string resource_type = 1 [
203203
(validate.rules).string = {
204-
pattern: "^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$"
204+
pattern: "^(([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
205205
max_bytes: 128
206206
},
207207
(buf.validate.field).string = {
208-
pattern: "^(([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9])?$"
208+
pattern: "^(([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
209209
max_bytes: 128
210210
}
211211
];
@@ -239,11 +239,11 @@ message RelationshipFilter {
239239
// relation is the *optional* relation of the relationship.
240240
string optional_relation = 3 [
241241
(validate.rules).string = {
242-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
242+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
243243
max_bytes: 64
244244
},
245245
(buf.validate.field).string = {
246-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
246+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
247247
max_bytes: 64
248248
}
249249
];
@@ -260,23 +260,23 @@ message SubjectFilter {
260260
message RelationFilter {
261261
string relation = 1 [
262262
(validate.rules).string = {
263-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
263+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
264264
max_bytes: 64
265265
},
266266
(buf.validate.field).string = {
267-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
267+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
268268
max_bytes: 64
269269
}
270270
];
271271
}
272272

273273
string subject_type = 1 [
274274
(validate.rules).string = {
275-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
275+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
276276
max_bytes: 128
277277
},
278278
(buf.validate.field).string = {
279-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
279+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
280280
max_bytes: 128
281281
}
282282
];
@@ -482,11 +482,11 @@ message CheckPermissionRequest {
482482
// the check.
483483
string permission = 3 [
484484
(validate.rules).string = {
485-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
485+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
486486
max_bytes: 64
487487
},
488488
(buf.validate.field).string = {
489-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
489+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
490490
max_bytes: 64
491491
}
492492
];
@@ -582,11 +582,11 @@ message CheckBulkPermissionsRequestItem {
582582

583583
string permission = 2 [
584584
(validate.rules).string = {
585-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
585+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
586586
max_bytes: 64
587587
},
588588
(buf.validate.field).string = {
589-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
589+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
590590
max_bytes: 64
591591
}
592592
];
@@ -663,11 +663,11 @@ message ExpandPermissionTreeRequest {
663663
// expansion for the resource.
664664
string permission = 3 [
665665
(validate.rules).string = {
666-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
666+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
667667
max_bytes: 64
668668
},
669669
(buf.validate.field).string = {
670-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
670+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
671671
max_bytes: 64
672672
}
673673
];
@@ -692,11 +692,11 @@ message LookupResourcesRequest {
692692
// be returned.
693693
string resource_object_type = 2 [
694694
(validate.rules).string = {
695-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
695+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
696696
max_bytes: 128
697697
},
698698
(buf.validate.field).string = {
699-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
699+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
700700
max_bytes: 128
701701
}
702702
];
@@ -705,11 +705,11 @@ message LookupResourcesRequest {
705705
// must Check.
706706
string permission = 3 [
707707
(validate.rules).string = {
708-
pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$"
708+
pattern: "^[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
709709
max_bytes: 64
710710
},
711711
(buf.validate.field).string = {
712-
pattern: "^[a-z][a-z0-9_]{1,62}[a-z0-9]$"
712+
pattern: "^[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
713713
max_bytes: 64
714714
}
715715
];
@@ -802,11 +802,11 @@ message LookupSubjectsRequest {
802802
// the subjects.
803803
string permission = 3 [
804804
(validate.rules).string = {
805-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
805+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
806806
max_bytes: 64
807807
},
808808
(buf.validate.field).string = {
809-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
809+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
810810
max_bytes: 64
811811
}
812812
];
@@ -815,23 +815,23 @@ message LookupSubjectsRequest {
815815
// be returned.
816816
string subject_object_type = 4 [
817817
(validate.rules).string = {
818-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
818+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
819819
max_bytes: 128
820820
},
821821
(buf.validate.field).string = {
822-
pattern: "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
822+
pattern: "^([a-z_][a-z0-9_]{1,61}[a-z0-9]/)*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
823823
max_bytes: 128
824824
}
825825
];
826826

827827
// optional_subject_relation is the optional relation for the subject.
828828
string optional_subject_relation = 5 [
829829
(validate.rules).string = {
830-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
830+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
831831
max_bytes: 64
832832
},
833833
(buf.validate.field).string = {
834-
pattern: "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
834+
pattern: "^([a-z_][a-z0-9_]{1,62}[a-z0-9])?$"
835835
max_bytes: 64
836836
}
837837
];

authzed/api/v1/watch_service.proto

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,14 @@ message WatchRequest {
4545
(buf.validate.field).repeated.min_items = 0,
4646
(validate.rules).repeated.items.string = {
4747
pattern:
48-
"^([a-z][a-z0-9_]{1,62}[a-z0-9]/"
49-
")*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
48+
"^([a-z_][a-z0-9_]{1,62}[a-z0-9]/"
49+
")*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
5050
max_bytes: 128
5151
},
5252
(buf.validate.field).repeated.items.string = {
5353
pattern:
54-
"^([a-z][a-z0-9_]{1,62}[a-z0-9]/"
55-
")*[a-z][a-z0-9_]{1,62}[a-z0-9]$"
54+
"^([a-z_][a-z0-9_]{1,62}[a-z0-9]/"
55+
")*[a-z_][a-z0-9_]{1,62}[a-z0-9]$"
5656
max_bytes: 128
5757
}
5858
];

0 commit comments

Comments
 (0)