@fulcrum_io/sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/LICENSE +98 -0
- package/README.md +94 -0
- package/dist/Icon/r +0 -0
- package/dist/index.d.ts +46 -0
- package/dist/index.js +144 -0
- package/package.json +46 -0
- package/proto/events.proto +197 -0
- package/proto/fulcrum/bridge/v1/bridge.proto +316 -0
- package/proto/fulcrum/checkpoint/v1/checkpoint_service.proto +368 -0
- package/proto/fulcrum/cost/v1/cost_service.proto +410 -0
- package/proto/fulcrum/envelope/v1/envelope.proto +162 -0
- package/proto/fulcrum/envelope/v1/envelope_service.proto +52 -0
- package/proto/fulcrum/eventstore/v1/eventstore.proto +254 -0
- package/proto/fulcrum/policy/v1/policy_service.proto +555 -0
- package/proto/fulcrum/tenant/v1/tenant_service.proto +57 -0
- package/proto/google/api/annotations.proto +31 -0
- package/proto/google/api/http.proto +370 -0
|
@@ -0,0 +1,555 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package fulcrum.policy.v1;
|
|
4
|
+
|
|
5
|
+
option go_package = "github.com/fulcrum-io/fulcrum/pkg/policy/v1";
|
|
6
|
+
|
|
7
|
+
import "google/api/annotations.proto";
|
|
8
|
+
import "google/protobuf/timestamp.proto";
|
|
9
|
+
import "google/protobuf/struct.proto";
|
|
10
|
+
|
|
11
|
+
// PolicyService provides policy management and evaluation capabilities.
|
|
12
|
+
// Supports creating policies, evaluating rules, and enforcing governance.
|
|
13
|
+
service PolicyService {
|
|
14
|
+
// Policy CRUD operations
|
|
15
|
+
rpc CreatePolicy(CreatePolicyRequest) returns (CreatePolicyResponse) {
|
|
16
|
+
option (google.api.http) = {
|
|
17
|
+
post: "/v1/policies"
|
|
18
|
+
body: "policy"
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
rpc GetPolicy(GetPolicyRequest) returns (GetPolicyResponse) {
|
|
23
|
+
option (google.api.http) = {
|
|
24
|
+
get: "/v1/policies/{policy_id}"
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
rpc UpdatePolicy(UpdatePolicyRequest) returns (UpdatePolicyResponse) {
|
|
29
|
+
option (google.api.http) = {
|
|
30
|
+
patch: "/v1/policies/{policy.policy_id}"
|
|
31
|
+
body: "policy"
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
rpc DeletePolicy(DeletePolicyRequest) returns (DeletePolicyResponse) {
|
|
36
|
+
option (google.api.http) = {
|
|
37
|
+
delete: "/v1/policies/{policy_id}"
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
rpc ListPolicies(ListPoliciesRequest) returns (ListPoliciesResponse) {
|
|
42
|
+
option (google.api.http) = {
|
|
43
|
+
get: "/v1/policies"
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Policy evaluation
|
|
48
|
+
rpc EvaluatePolicy(EvaluatePolicyRequest) returns (EvaluatePolicyResponse) {
|
|
49
|
+
option (google.api.http) = {
|
|
50
|
+
post: "/v1/policies/evaluate"
|
|
51
|
+
body: "*"
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Batch evaluation for multiple policies
|
|
56
|
+
rpc EvaluatePolicies(EvaluatePoliciesRequest) returns (EvaluatePoliciesResponse) {
|
|
57
|
+
option (google.api.http) = {
|
|
58
|
+
post: "/v1/policies/batch-evaluate"
|
|
59
|
+
body: "*"
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
rpc GetEvaluationHistory(GetEvaluationHistoryRequest) returns (GetEvaluationHistoryResponse) {
|
|
64
|
+
option (google.api.http) = {
|
|
65
|
+
get: "/v1/policies/{policy_id}/evaluations"
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Approval Workflow
|
|
70
|
+
rpc ListApprovals(ListApprovalsRequest) returns (ListApprovalsResponse) {
|
|
71
|
+
option (google.api.http) = {
|
|
72
|
+
get: "/v1/approvals"
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
rpc UpdateApproval(UpdateApprovalRequest) returns (UpdateApprovalResponse) {
|
|
77
|
+
option (google.api.http) = {
|
|
78
|
+
patch: "/v1/approvals/{approval_id}"
|
|
79
|
+
body: "*"
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Policy defines governance rules for agent execution.
|
|
85
|
+
message Policy {
|
|
86
|
+
// Unique policy identifier
|
|
87
|
+
string policy_id = 1;
|
|
88
|
+
|
|
89
|
+
// Tenant this policy applies to
|
|
90
|
+
string tenant_id = 2;
|
|
91
|
+
|
|
92
|
+
// Policy metadata
|
|
93
|
+
string name = 3;
|
|
94
|
+
string description = 4;
|
|
95
|
+
map<string, string> tags = 5;
|
|
96
|
+
|
|
97
|
+
// Policy rules
|
|
98
|
+
repeated PolicyRule rules = 6;
|
|
99
|
+
|
|
100
|
+
// Policy scope
|
|
101
|
+
PolicyScope scope = 7;
|
|
102
|
+
|
|
103
|
+
// Policy status
|
|
104
|
+
PolicyStatus status = 8;
|
|
105
|
+
|
|
106
|
+
// Enforcement level
|
|
107
|
+
EnforcementLevel enforcement = 9;
|
|
108
|
+
|
|
109
|
+
// Priority (higher = evaluated first)
|
|
110
|
+
int32 priority = 10;
|
|
111
|
+
|
|
112
|
+
// Timestamps
|
|
113
|
+
google.protobuf.Timestamp created_at = 11;
|
|
114
|
+
google.protobuf.Timestamp updated_at = 12;
|
|
115
|
+
google.protobuf.Timestamp effective_at = 13; // When policy becomes active
|
|
116
|
+
google.protobuf.Timestamp expires_at = 14; // Optional expiration
|
|
117
|
+
|
|
118
|
+
// Created by
|
|
119
|
+
string created_by = 15;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// PolicyRule represents a single rule within a policy.
|
|
123
|
+
message PolicyRule {
|
|
124
|
+
// Rule identifier (unique within policy)
|
|
125
|
+
string rule_id = 1;
|
|
126
|
+
|
|
127
|
+
// Rule name and description
|
|
128
|
+
string name = 2;
|
|
129
|
+
string description = 3;
|
|
130
|
+
|
|
131
|
+
// Rule conditions (all must match for rule to trigger)
|
|
132
|
+
repeated PolicyCondition conditions = 4;
|
|
133
|
+
|
|
134
|
+
// Actions to take when rule matches
|
|
135
|
+
repeated PolicyAction actions = 5;
|
|
136
|
+
|
|
137
|
+
// Rule type
|
|
138
|
+
RuleType rule_type = 6;
|
|
139
|
+
|
|
140
|
+
// Rule enabled/disabled
|
|
141
|
+
bool enabled = 7;
|
|
142
|
+
|
|
143
|
+
// Priority within policy (higher = evaluated first)
|
|
144
|
+
int32 priority = 8;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// PolicyCondition defines when a rule should trigger.
|
|
148
|
+
message PolicyCondition {
|
|
149
|
+
// Condition type determines which fields are used
|
|
150
|
+
ConditionType condition_type = 1;
|
|
151
|
+
|
|
152
|
+
// Field to evaluate (e.g., "user.role", "model.id", "tool.name")
|
|
153
|
+
string field = 2;
|
|
154
|
+
|
|
155
|
+
// Operator for comparison
|
|
156
|
+
ConditionOperator operator = 3;
|
|
157
|
+
|
|
158
|
+
// Value to compare against
|
|
159
|
+
oneof value {
|
|
160
|
+
string string_value = 4;
|
|
161
|
+
int64 int_value = 5;
|
|
162
|
+
double float_value = 6;
|
|
163
|
+
bool bool_value = 7;
|
|
164
|
+
google.protobuf.ListValue list_value = 8;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Additional values for multi-value operators
|
|
168
|
+
repeated string values = 9;
|
|
169
|
+
|
|
170
|
+
// Nested conditions for complex logic (AND/OR)
|
|
171
|
+
repeated PolicyCondition nested_conditions = 10;
|
|
172
|
+
|
|
173
|
+
// Logical operator for nested conditions
|
|
174
|
+
LogicalOperator logical_operator = 11;
|
|
175
|
+
|
|
176
|
+
// Negate the condition
|
|
177
|
+
bool negate = 12;
|
|
178
|
+
|
|
179
|
+
// Semantic evaluation fields
|
|
180
|
+
string semantic_intent = 20; // Human-readable intent description
|
|
181
|
+
string semantic_model = 21; // LLM model to use (e.g., "llama3.2")
|
|
182
|
+
float semantic_confidence_threshold = 22; // Minimum confidence to match
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// PolicyAction defines what to do when a rule matches.
|
|
186
|
+
message PolicyAction {
|
|
187
|
+
// Action type
|
|
188
|
+
ActionType action_type = 1;
|
|
189
|
+
|
|
190
|
+
// Action parameters (flexible structure)
|
|
191
|
+
map<string, string> parameters = 2;
|
|
192
|
+
|
|
193
|
+
// Message to return to user
|
|
194
|
+
string message = 3;
|
|
195
|
+
|
|
196
|
+
// Severity level
|
|
197
|
+
SeverityLevel severity = 4;
|
|
198
|
+
|
|
199
|
+
// Stop evaluation after this action
|
|
200
|
+
bool terminal = 5;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// PolicyScope defines where a policy applies.
|
|
204
|
+
message PolicyScope {
|
|
205
|
+
// Workflows this policy applies to
|
|
206
|
+
repeated string workflow_ids = 1;
|
|
207
|
+
|
|
208
|
+
// Execution phases where policy is evaluated
|
|
209
|
+
repeated ExecutionPhase phases = 2;
|
|
210
|
+
|
|
211
|
+
// User roles this policy applies to
|
|
212
|
+
repeated string roles = 3;
|
|
213
|
+
|
|
214
|
+
// Model restrictions
|
|
215
|
+
repeated string model_ids = 4;
|
|
216
|
+
|
|
217
|
+
// Tool restrictions
|
|
218
|
+
repeated string tool_names = 5;
|
|
219
|
+
|
|
220
|
+
// Apply to all workflows (if true, workflow_ids ignored)
|
|
221
|
+
bool apply_to_all = 6;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// EvaluationResult represents the outcome of policy evaluation.
|
|
225
|
+
message EvaluationResult {
|
|
226
|
+
// Policy evaluated
|
|
227
|
+
string policy_id = 1;
|
|
228
|
+
|
|
229
|
+
// Evaluation outcome
|
|
230
|
+
EvaluationDecision decision = 2;
|
|
231
|
+
|
|
232
|
+
// Rules that matched
|
|
233
|
+
repeated RuleMatch matched_rules = 3;
|
|
234
|
+
|
|
235
|
+
// Actions to execute
|
|
236
|
+
repeated PolicyAction actions = 4;
|
|
237
|
+
|
|
238
|
+
// Evaluation metadata
|
|
239
|
+
string message = 5;
|
|
240
|
+
map<string, string> metadata = 6;
|
|
241
|
+
|
|
242
|
+
// Evaluation timing
|
|
243
|
+
google.protobuf.Timestamp evaluated_at = 7;
|
|
244
|
+
int64 evaluation_duration_ms = 8;
|
|
245
|
+
|
|
246
|
+
// Context that was evaluated
|
|
247
|
+
EvaluationContext context = 9;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// RuleMatch represents a rule that matched during evaluation.
|
|
251
|
+
message RuleMatch {
|
|
252
|
+
string rule_id = 1;
|
|
253
|
+
string rule_name = 2;
|
|
254
|
+
repeated string matched_conditions = 3;
|
|
255
|
+
int32 priority = 4;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// EvaluationContext provides data for policy evaluation.
|
|
259
|
+
message EvaluationContext {
|
|
260
|
+
// Tenant and workflow
|
|
261
|
+
string tenant_id = 1;
|
|
262
|
+
string workflow_id = 2;
|
|
263
|
+
string envelope_id = 3;
|
|
264
|
+
|
|
265
|
+
// User context
|
|
266
|
+
string user_id = 4;
|
|
267
|
+
repeated string user_roles = 5;
|
|
268
|
+
|
|
269
|
+
// Execution context
|
|
270
|
+
ExecutionPhase phase = 6;
|
|
271
|
+
string model_id = 7;
|
|
272
|
+
repeated string tool_names = 8;
|
|
273
|
+
|
|
274
|
+
// Content to evaluate
|
|
275
|
+
string input_text = 9;
|
|
276
|
+
string output_text = 10;
|
|
277
|
+
|
|
278
|
+
// Additional context (flexible)
|
|
279
|
+
map<string, string> attributes = 11;
|
|
280
|
+
|
|
281
|
+
// Timestamp
|
|
282
|
+
google.protobuf.Timestamp timestamp = 12;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// Enums
|
|
286
|
+
|
|
287
|
+
// PolicyStatus indicates policy state
|
|
288
|
+
enum PolicyStatus {
|
|
289
|
+
POLICY_STATUS_UNSPECIFIED = 0;
|
|
290
|
+
POLICY_STATUS_DRAFT = 1;
|
|
291
|
+
POLICY_STATUS_ACTIVE = 2;
|
|
292
|
+
POLICY_STATUS_INACTIVE = 3;
|
|
293
|
+
POLICY_STATUS_ARCHIVED = 4;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// EnforcementLevel defines how strictly policy is enforced
|
|
297
|
+
enum EnforcementLevel {
|
|
298
|
+
ENFORCEMENT_LEVEL_UNSPECIFIED = 0;
|
|
299
|
+
ENFORCEMENT_LEVEL_AUDIT = 1; // Log only, don't block
|
|
300
|
+
ENFORCEMENT_LEVEL_WARN = 2; // Warn but allow
|
|
301
|
+
ENFORCEMENT_LEVEL_BLOCK = 3; // Block execution
|
|
302
|
+
ENFORCEMENT_LEVEL_TERMINATE = 4; // Terminate execution immediately
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// RuleType categorizes policy rules
|
|
306
|
+
enum RuleType {
|
|
307
|
+
RULE_TYPE_UNSPECIFIED = 0;
|
|
308
|
+
RULE_TYPE_RBAC = 1; // Role-based access control
|
|
309
|
+
RULE_TYPE_CONTENT_FILTER = 2; // Content filtering
|
|
310
|
+
RULE_TYPE_TOOL_ALLOWLIST = 3; // Tool access control
|
|
311
|
+
RULE_TYPE_MODEL_RESTRICTION = 4; // Model usage restrictions
|
|
312
|
+
RULE_TYPE_RATE_LIMIT = 5; // Rate limiting
|
|
313
|
+
RULE_TYPE_COST_CONTROL = 6; // Cost-based controls
|
|
314
|
+
RULE_TYPE_CUSTOM = 7; // Custom rule type
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// ConditionType defines the type of condition
|
|
318
|
+
enum ConditionType {
|
|
319
|
+
CONDITION_TYPE_UNSPECIFIED = 0;
|
|
320
|
+
CONDITION_TYPE_FIELD_MATCH = 1; // Simple field comparison
|
|
321
|
+
CONDITION_TYPE_REGEX = 2; // Regex pattern matching
|
|
322
|
+
CONDITION_TYPE_RANGE = 3; // Numeric range
|
|
323
|
+
CONDITION_TYPE_IN_LIST = 4; // Value in list
|
|
324
|
+
CONDITION_TYPE_CONTAINS = 5; // String contains
|
|
325
|
+
CONDITION_TYPE_STARTS_WITH = 6; // String starts with
|
|
326
|
+
CONDITION_TYPE_ENDS_WITH = 7; // String ends with
|
|
327
|
+
CONDITION_TYPE_LOGICAL = 8; // AND/OR of nested conditions
|
|
328
|
+
CONDITION_TYPE_STATISTICAL_SPIKE = 9; // Deviation from historical baseline
|
|
329
|
+
CONDITION_TYPE_EXTERNAL_CALL = 10; // Fetch data from external API/DB
|
|
330
|
+
CONDITION_TYPE_SEMANTIC = 11; // LLM-based intent evaluation
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
// ConditionOperator defines comparison operators
|
|
334
|
+
enum ConditionOperator {
|
|
335
|
+
CONDITION_OPERATOR_UNSPECIFIED = 0;
|
|
336
|
+
CONDITION_OPERATOR_EQUALS = 1;
|
|
337
|
+
CONDITION_OPERATOR_NOT_EQUALS = 2;
|
|
338
|
+
CONDITION_OPERATOR_GREATER_THAN = 3;
|
|
339
|
+
CONDITION_OPERATOR_LESS_THAN = 4;
|
|
340
|
+
CONDITION_OPERATOR_GREATER_EQUAL = 5;
|
|
341
|
+
CONDITION_OPERATOR_LESS_EQUAL = 6;
|
|
342
|
+
CONDITION_OPERATOR_MATCHES = 7; // Regex match
|
|
343
|
+
CONDITION_OPERATOR_CONTAINS = 8; // String/list contains
|
|
344
|
+
CONDITION_OPERATOR_IN = 9; // Value in list
|
|
345
|
+
CONDITION_OPERATOR_NOT_IN = 10; // Value not in list
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// LogicalOperator combines multiple conditions
|
|
349
|
+
enum LogicalOperator {
|
|
350
|
+
LOGICAL_OPERATOR_UNSPECIFIED = 0;
|
|
351
|
+
LOGICAL_OPERATOR_AND = 1;
|
|
352
|
+
LOGICAL_OPERATOR_OR = 2;
|
|
353
|
+
LOGICAL_OPERATOR_NOT = 3;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// ActionType defines what action to take
|
|
357
|
+
enum ActionType {
|
|
358
|
+
ACTION_TYPE_UNSPECIFIED = 0;
|
|
359
|
+
ACTION_TYPE_ALLOW = 1; // Allow execution
|
|
360
|
+
ACTION_TYPE_DENY = 2; // Block execution
|
|
361
|
+
ACTION_TYPE_WARN = 3; // Warn but allow
|
|
362
|
+
ACTION_TYPE_MODIFY = 4; // Modify request
|
|
363
|
+
ACTION_TYPE_REDIRECT = 5; // Redirect to different model/tool
|
|
364
|
+
ACTION_TYPE_AUDIT = 6; // Log for audit
|
|
365
|
+
ACTION_TYPE_THROTTLE = 7; // Rate limit
|
|
366
|
+
ACTION_TYPE_REQUIRE_APPROVAL = 8; // Require human approval
|
|
367
|
+
ACTION_TYPE_NOTIFY = 9; // Notify external service (Slack/Teams)
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// SeverityLevel indicates action severity
|
|
371
|
+
enum SeverityLevel {
|
|
372
|
+
SEVERITY_LEVEL_UNSPECIFIED = 0;
|
|
373
|
+
SEVERITY_LEVEL_INFO = 1;
|
|
374
|
+
SEVERITY_LEVEL_LOW = 2;
|
|
375
|
+
SEVERITY_LEVEL_MEDIUM = 3;
|
|
376
|
+
SEVERITY_LEVEL_HIGH = 4;
|
|
377
|
+
SEVERITY_LEVEL_CRITICAL = 5;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// ExecutionPhase defines when policy is evaluated
|
|
381
|
+
enum ExecutionPhase {
|
|
382
|
+
EXECUTION_PHASE_UNSPECIFIED = 0;
|
|
383
|
+
EXECUTION_PHASE_PRE_EXECUTION = 1; // Before execution starts
|
|
384
|
+
EXECUTION_PHASE_PRE_LLM_CALL = 2; // Before each LLM call
|
|
385
|
+
EXECUTION_PHASE_POST_LLM_CALL = 3; // After each LLM call
|
|
386
|
+
EXECUTION_PHASE_PRE_TOOL_CALL = 4; // Before each tool call
|
|
387
|
+
EXECUTION_PHASE_POST_TOOL_CALL = 5; // After each tool call
|
|
388
|
+
EXECUTION_PHASE_POST_EXECUTION = 6; // After execution completes
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// EvaluationDecision is the final policy decision
|
|
392
|
+
enum EvaluationDecision {
|
|
393
|
+
EVALUATION_DECISION_UNSPECIFIED = 0;
|
|
394
|
+
EVALUATION_DECISION_ALLOW = 1; // Execution allowed
|
|
395
|
+
EVALUATION_DECISION_DENY = 2; // Execution blocked
|
|
396
|
+
EVALUATION_DECISION_WARN = 3; // Warning issued
|
|
397
|
+
EVALUATION_DECISION_REQUIRE_APPROVAL = 4; // Needs approval
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
// Request/Response messages
|
|
401
|
+
|
|
402
|
+
message CreatePolicyRequest {
|
|
403
|
+
Policy policy = 1;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
message CreatePolicyResponse {
|
|
407
|
+
Policy policy = 1;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
message GetPolicyRequest {
|
|
411
|
+
string policy_id = 1;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
message GetPolicyResponse {
|
|
415
|
+
Policy policy = 1;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
message UpdatePolicyRequest {
|
|
419
|
+
Policy policy = 1;
|
|
420
|
+
repeated string update_mask = 2;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
message UpdatePolicyResponse {
|
|
424
|
+
Policy policy = 1;
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
message DeletePolicyRequest {
|
|
428
|
+
string policy_id = 1;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
message DeletePolicyResponse {
|
|
432
|
+
bool success = 1;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
message ListPoliciesRequest {
|
|
436
|
+
// Filter by tenant
|
|
437
|
+
string tenant_id = 1;
|
|
438
|
+
|
|
439
|
+
// Filter by status
|
|
440
|
+
PolicyStatus status = 2;
|
|
441
|
+
|
|
442
|
+
// Filter by rule type
|
|
443
|
+
RuleType rule_type = 3;
|
|
444
|
+
|
|
445
|
+
// Pagination
|
|
446
|
+
int32 page_size = 4;
|
|
447
|
+
string page_token = 5;
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
message ListPoliciesResponse {
|
|
451
|
+
repeated Policy policies = 1;
|
|
452
|
+
string next_page_token = 2;
|
|
453
|
+
int32 total_count = 3;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
message EvaluatePolicyRequest {
|
|
457
|
+
// Policy to evaluate
|
|
458
|
+
string policy_id = 1;
|
|
459
|
+
|
|
460
|
+
// Context for evaluation
|
|
461
|
+
EvaluationContext context = 2;
|
|
462
|
+
|
|
463
|
+
// Dry run (don't execute actions)
|
|
464
|
+
bool dry_run = 3;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
message EvaluatePolicyResponse {
|
|
468
|
+
EvaluationResult result = 1;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
message EvaluatePoliciesRequest {
|
|
472
|
+
// Policies to evaluate (in priority order if empty, all active policies)
|
|
473
|
+
repeated string policy_ids = 1;
|
|
474
|
+
|
|
475
|
+
// Context for evaluation
|
|
476
|
+
EvaluationContext context = 2;
|
|
477
|
+
|
|
478
|
+
// Stop on first deny
|
|
479
|
+
bool stop_on_deny = 3;
|
|
480
|
+
|
|
481
|
+
// Dry run
|
|
482
|
+
bool dry_run = 4;
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
message EvaluatePoliciesResponse {
|
|
486
|
+
// All evaluation results
|
|
487
|
+
repeated EvaluationResult results = 1;
|
|
488
|
+
|
|
489
|
+
// Final decision (aggregate)
|
|
490
|
+
EvaluationDecision final_decision = 2;
|
|
491
|
+
|
|
492
|
+
// All actions to execute
|
|
493
|
+
repeated PolicyAction actions = 3;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
message GetEvaluationHistoryRequest {
|
|
497
|
+
// Policy to get history for
|
|
498
|
+
string policy_id = 1;
|
|
499
|
+
|
|
500
|
+
// Time range
|
|
501
|
+
google.protobuf.Timestamp start_time = 2;
|
|
502
|
+
google.protobuf.Timestamp end_time = 3;
|
|
503
|
+
|
|
504
|
+
// Filter by decision
|
|
505
|
+
EvaluationDecision decision = 4;
|
|
506
|
+
|
|
507
|
+
// Pagination
|
|
508
|
+
int32 page_size = 5;
|
|
509
|
+
string page_token = 6;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
message GetEvaluationHistoryResponse {
|
|
513
|
+
repeated EvaluationResult evaluations = 1;
|
|
514
|
+
string next_page_token = 2;
|
|
515
|
+
int32 total_count = 3;
|
|
516
|
+
}
|
|
517
|
+
|
|
518
|
+
// Approval messages
|
|
519
|
+
message Approval {
|
|
520
|
+
string approval_id = 1;
|
|
521
|
+
string evaluation_id = 2;
|
|
522
|
+
string policy_id = 3;
|
|
523
|
+
string envelope_id = 4;
|
|
524
|
+
string status = 5; // PENDING, APPROVED, REJECTED
|
|
525
|
+
string reviewer_id = 6;
|
|
526
|
+
string review_note = 7;
|
|
527
|
+
google.protobuf.Timestamp created_at = 8;
|
|
528
|
+
map<string, string> metadata = 9;
|
|
529
|
+
string policy_name = 10; // Joined field convenience
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
message ListApprovalsRequest {
|
|
533
|
+
string tenant_id = 1;
|
|
534
|
+
string status = 2; // e.g., "PENDING"
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
message ListApprovalsResponse {
|
|
538
|
+
repeated Approval approvals = 1;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
message UpdateApprovalRequest {
|
|
542
|
+
string approval_id = 1;
|
|
543
|
+
string status = 2; // APPROVED, REJECTED
|
|
544
|
+
string review_note = 3;
|
|
545
|
+
string reviewer_id = 4;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
message UpdateApprovalResponse {
|
|
549
|
+
Approval approval = 1;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
// PolicyList is a wrapper for a list of policies, used primarily for caching.
|
|
553
|
+
message PolicyList {
|
|
554
|
+
repeated Policy policies = 1;
|
|
555
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
syntax = "proto3";
|
|
2
|
+
|
|
3
|
+
package fulcrum.tenant.v1;
|
|
4
|
+
|
|
5
|
+
import "google/protobuf/timestamp.proto";
|
|
6
|
+
|
|
7
|
+
option go_package = "github.com/fulcrum-io/fulcrum/pkg/tenant/v1;tenantv1";
|
|
8
|
+
|
|
9
|
+
service TenantService {
|
|
10
|
+
// CreateApiKey creates a new API key for the authenticated tenant.
|
|
11
|
+
rpc CreateApiKey(CreateApiKeyRequest) returns (CreateApiKeyResponse);
|
|
12
|
+
|
|
13
|
+
// ListApiKeys lists all API keys for the authenticated tenant.
|
|
14
|
+
rpc ListApiKeys(ListApiKeysRequest) returns (ListApiKeysResponse);
|
|
15
|
+
|
|
16
|
+
// RevokeApiKey revokes (deletes) an API key by ID.
|
|
17
|
+
rpc RevokeApiKey(RevokeApiKeyRequest) returns (RevokeApiKeyResponse);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
message ApiKey {
|
|
21
|
+
string id = 1;
|
|
22
|
+
string name = 2;
|
|
23
|
+
string key_hint = 3; // e.g. "abcd...1234"
|
|
24
|
+
repeated string scopes = 4;
|
|
25
|
+
google.protobuf.Timestamp expires_at = 5;
|
|
26
|
+
google.protobuf.Timestamp created_at = 6;
|
|
27
|
+
google.protobuf.Timestamp last_used_at = 7;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
message CreateApiKeyRequest {
|
|
31
|
+
string name = 1;
|
|
32
|
+
repeated string scopes = 2;
|
|
33
|
+
int64 expires_in_seconds = 3; // Optional: TTL. If 0, never expires.
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
message CreateApiKeyResponse {
|
|
37
|
+
ApiKey key = 1;
|
|
38
|
+
string key_secret = 2; // The raw key secret. ONLY returned here.
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
message ListApiKeysRequest {
|
|
42
|
+
int32 page_size = 1;
|
|
43
|
+
string page_token = 2;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
message ListApiKeysResponse {
|
|
47
|
+
repeated ApiKey keys = 1;
|
|
48
|
+
string next_page_token = 2;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
message RevokeApiKeyRequest {
|
|
52
|
+
string key_id = 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
message RevokeApiKeyResponse {
|
|
56
|
+
bool success = 1;
|
|
57
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
// Copyright 2025 Google LLC
|
|
2
|
+
//
|
|
3
|
+
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
// you may not use this file except in compliance with the License.
|
|
5
|
+
// You may obtain a copy of the License at
|
|
6
|
+
//
|
|
7
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
//
|
|
9
|
+
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
// See the License for the specific language governing permissions and
|
|
13
|
+
// limitations under the License.
|
|
14
|
+
|
|
15
|
+
syntax = "proto3";
|
|
16
|
+
|
|
17
|
+
package google.api;
|
|
18
|
+
|
|
19
|
+
import "google/api/http.proto";
|
|
20
|
+
import "google/protobuf/descriptor.proto";
|
|
21
|
+
|
|
22
|
+
option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
|
|
23
|
+
option java_multiple_files = true;
|
|
24
|
+
option java_outer_classname = "AnnotationsProto";
|
|
25
|
+
option java_package = "com.google.api";
|
|
26
|
+
option objc_class_prefix = "GAPI";
|
|
27
|
+
|
|
28
|
+
extend google.protobuf.MethodOptions {
|
|
29
|
+
// See `HttpRule`.
|
|
30
|
+
HttpRule http = 72295728;
|
|
31
|
+
}
|