xref: /aosp_15_r20/external/googleapis/google/cloud/policysimulator/v1/simulator.proto (revision d5c09012810ac0c9f33fe448fb6da8260d444cc9)
1// Copyright 2023 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
15syntax = "proto3";
16
17package google.cloud.policysimulator.v1;
18
19import "google/api/annotations.proto";
20import "google/api/client.proto";
21import "google/api/field_behavior.proto";
22import "google/api/resource.proto";
23import "google/cloud/policysimulator/v1/explanations.proto";
24import "google/iam/v1/policy.proto";
25import "google/longrunning/operations.proto";
26import "google/protobuf/timestamp.proto";
27import "google/rpc/status.proto";
28import "google/type/date.proto";
29
30option cc_enable_arenas = true;
31option csharp_namespace = "Google.Cloud.PolicySimulator.V1";
32option go_package = "cloud.google.com/go/policysimulator/apiv1/policysimulatorpb;policysimulatorpb";
33option java_multiple_files = true;
34option java_outer_classname = "SimulatorProto";
35option java_package = "com.google.cloud.policysimulator.v1";
36option php_namespace = "Google\\Cloud\\PolicySimulator\\V1";
37option ruby_package = "Google::Cloud::PolicySimulator::V1";
38
39// Policy Simulator API service.
40//
41// Policy Simulator is a collection of endpoints for creating, running, and
42// viewing a [Replay][google.cloud.policysimulator.v1.Replay]. A
43// [Replay][google.cloud.policysimulator.v1.Replay] is a type of simulation that
44// lets you see how your principals' access to resources might change if you
45// changed your IAM policy.
46//
47// During a [Replay][google.cloud.policysimulator.v1.Replay], Policy Simulator
48// re-evaluates, or replays, past access attempts under both the current policy
49// and  your proposed policy, and compares those results to determine how your
50// principals' access might change under the proposed policy.
51service Simulator {
52  option (google.api.default_host) = "policysimulator.googleapis.com";
53  option (google.api.oauth_scopes) =
54      "https://www.googleapis.com/auth/cloud-platform";
55
56  // Gets the specified [Replay][google.cloud.policysimulator.v1.Replay]. Each
57  // `Replay` is available for at least 7 days.
58  rpc GetReplay(GetReplayRequest) returns (Replay) {
59    option (google.api.http) = {
60      get: "/v1/{name=projects/*/locations/*/replays/*}"
61      additional_bindings { get: "/v1/{name=folders/*/locations/*/replays/*}" }
62      additional_bindings {
63        get: "/v1/{name=organizations/*/locations/*/replays/*}"
64      }
65    };
66    option (google.api.method_signature) = "name";
67  }
68
69  // Creates and starts a [Replay][google.cloud.policysimulator.v1.Replay] using
70  // the given [ReplayConfig][google.cloud.policysimulator.v1.ReplayConfig].
71  rpc CreateReplay(CreateReplayRequest) returns (google.longrunning.Operation) {
72    option (google.api.http) = {
73      post: "/v1/{parent=projects/*/locations/*}/replays"
74      body: "replay"
75      additional_bindings {
76        post: "/v1/{parent=folders/*/locations/*}/replays"
77        body: "replay"
78      }
79      additional_bindings {
80        post: "/v1/{parent=organizations/*/locations/*}/replays"
81        body: "replay"
82      }
83    };
84    option (google.api.method_signature) = "parent,replay";
85    option (google.longrunning.operation_info) = {
86      response_type: "Replay"
87      metadata_type: "ReplayOperationMetadata"
88    };
89  }
90
91  // Lists the results of running a
92  // [Replay][google.cloud.policysimulator.v1.Replay].
93  rpc ListReplayResults(ListReplayResultsRequest)
94      returns (ListReplayResultsResponse) {
95    option (google.api.http) = {
96      get: "/v1/{parent=projects/*/locations/*/replays/*}/results"
97      additional_bindings {
98        get: "/v1/{parent=folders/*/locations/*/replays/*}/results"
99      }
100      additional_bindings {
101        get: "/v1/{parent=organizations/*/locations/*/replays/*}/results"
102      }
103    };
104    option (google.api.method_signature) = "parent";
105  }
106}
107
108// A resource describing a `Replay`, or simulation.
109message Replay {
110  option (google.api.resource) = {
111    type: "policysimulator.googleapis.com/Replay"
112    pattern: "projects/{project}/locations/{location}/replays/{replay}"
113    pattern: "folders/{folder}/locations/{location}/replays/{replay}"
114    pattern: "organizations/{organization}/locations/{location}/replays/{replay}"
115  };
116
117  // Summary statistics about the replayed log entries.
118  message ResultsSummary {
119    // The total number of log entries replayed.
120    int32 log_count = 1;
121
122    // The number of replayed log entries with no difference between
123    // baseline and simulated policies.
124    int32 unchanged_count = 2;
125
126    // The number of replayed log entries with a difference between baseline and
127    // simulated policies.
128    int32 difference_count = 3;
129
130    // The number of log entries that could not be replayed.
131    int32 error_count = 4;
132
133    // The date of the oldest log entry replayed.
134    google.type.Date oldest_date = 5;
135
136    // The date of the newest log entry replayed.
137    google.type.Date newest_date = 6;
138  }
139
140  // The current state of the [Replay][google.cloud.policysimulator.v1.Replay].
141  enum State {
142    // Default value. This value is unused.
143    STATE_UNSPECIFIED = 0;
144
145    // The `Replay` has not started yet.
146    PENDING = 1;
147
148    // The `Replay` is currently running.
149    RUNNING = 2;
150
151    // The `Replay` has successfully completed.
152    SUCCEEDED = 3;
153
154    // The `Replay` has finished with an error.
155    FAILED = 4;
156  }
157
158  // Output only. The resource name of the `Replay`, which has the following
159  // format:
160  //
161  // `{projects|folders|organizations}/{resource-id}/locations/global/replays/{replay-id}`,
162  // where `{resource-id}` is the ID of the project, folder, or organization
163  // that owns the Replay.
164  //
165  // Example:
166  // `projects/my-example-project/locations/global/replays/506a5f7f-38ce-4d7d-8e03-479ce1833c36`
167  string name = 1 [(google.api.field_behavior) = OUTPUT_ONLY];
168
169  // Output only. The current state of the `Replay`.
170  State state = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
171
172  // Required. The configuration used for the `Replay`.
173  ReplayConfig config = 3 [(google.api.field_behavior) = REQUIRED];
174
175  // Output only. Summary statistics about the replayed log entries.
176  ResultsSummary results_summary = 5
177      [(google.api.field_behavior) = OUTPUT_ONLY];
178}
179
180// The result of replaying a single access tuple against a simulated state.
181message ReplayResult {
182  option (google.api.resource) = {
183    type: "policysimulator.googleapis.com/ReplayResult"
184    pattern: "projects/{project}/locations/{location}/replays/{replay}/results/{replay_result}"
185    pattern: "folders/{folder}/locations/{location}/replays/{replay}/results/{replay_result}"
186    pattern: "organizations/{organization}/locations/{location}/replays/{replay}/results/{replay_result}"
187  };
188
189  // The result of replaying the access tuple.
190  oneof result {
191    // The difference between the principal's access under the current
192    // (baseline) policies and the principal's access under the proposed
193    // (simulated) policies.
194    //
195    // This field is only included for access tuples that were successfully
196    // replayed and had different results under the current policies and the
197    // proposed policies.
198    ReplayDiff diff = 5;
199
200    // The error that caused the access tuple replay to fail.
201    //
202    // This field is only included for access tuples that were not replayed
203    // successfully.
204    google.rpc.Status error = 6;
205  }
206
207  // The resource name of the `ReplayResult`, in the following format:
208  //
209  // `{projects|folders|organizations}/{resource-id}/locations/global/replays/{replay-id}/results/{replay-result-id}`,
210  // where `{resource-id}` is the ID of the project, folder, or organization
211  // that owns the [Replay][google.cloud.policysimulator.v1.Replay].
212  //
213  // Example:
214  // `projects/my-example-project/locations/global/replays/506a5f7f-38ce-4d7d-8e03-479ce1833c36/results/1234`
215  string name = 1;
216
217  // The [Replay][google.cloud.policysimulator.v1.Replay] that the access tuple
218  // was included in.
219  string parent = 2 [(google.api.resource_reference) = {
220    type: "policysimulator.googleapis.com/Replay"
221  }];
222
223  // The access tuple that was replayed. This field includes information about
224  // the principal, resource, and permission that were involved in the access
225  // attempt.
226  AccessTuple access_tuple = 3;
227
228  // The latest date this access tuple was seen in the logs.
229  google.type.Date last_seen_date = 4;
230}
231
232// Request message for
233// [Simulator.CreateReplay][google.cloud.policysimulator.v1.Simulator.CreateReplay].
234message CreateReplayRequest {
235  // Required. The parent resource where this
236  // [Replay][google.cloud.policysimulator.v1.Replay] will be created. This
237  // resource must be a project, folder, or organization with a location.
238  //
239  // Example: `projects/my-example-project/locations/global`
240  string parent = 1 [(google.api.field_behavior) = REQUIRED];
241
242  // Required. The [Replay][google.cloud.policysimulator.v1.Replay] to create.
243  // Set `Replay.ReplayConfig` to configure the replay.
244  Replay replay = 2 [(google.api.field_behavior) = REQUIRED];
245}
246
247// Metadata about a Replay operation.
248message ReplayOperationMetadata {
249  // Time when the request was received.
250  google.protobuf.Timestamp start_time = 1;
251}
252
253// Request message for
254// [Simulator.GetReplay][google.cloud.policysimulator.v1.Simulator.GetReplay].
255message GetReplayRequest {
256  // Required. The name of the [Replay][google.cloud.policysimulator.v1.Replay]
257  // to retrieve, in the following format:
258  //
259  // `{projects|folders|organizations}/{resource-id}/locations/global/replays/{replay-id}`,
260  // where `{resource-id}` is the ID of the project, folder, or organization
261  // that owns the `Replay`.
262  //
263  // Example:
264  // `projects/my-example-project/locations/global/replays/506a5f7f-38ce-4d7d-8e03-479ce1833c36`
265  string name = 1 [
266    (google.api.field_behavior) = REQUIRED,
267    (google.api.resource_reference) = {
268      type: "policysimulator.googleapis.com/Replay"
269    }
270  ];
271}
272
273// Request message for
274// [Simulator.ListReplayResults][google.cloud.policysimulator.v1.Simulator.ListReplayResults].
275message ListReplayResultsRequest {
276  // Required. The [Replay][google.cloud.policysimulator.v1.Replay] whose
277  // results are listed, in the following format:
278  //
279  // `{projects|folders|organizations}/{resource-id}/locations/global/replays/{replay-id}`
280  //
281  // Example:
282  // `projects/my-project/locations/global/replays/506a5f7f-38ce-4d7d-8e03-479ce1833c36`
283  string parent = 1 [
284    (google.api.field_behavior) = REQUIRED,
285    (google.api.resource_reference) = {
286      type: "policysimulator.googleapis.com/Replay"
287    }
288  ];
289
290  // The maximum number of
291  // [ReplayResult][google.cloud.policysimulator.v1.ReplayResult] objects to
292  // return. Defaults to 5000.
293  //
294  // The maximum value is 5000; values above 5000 are rounded down to 5000.
295  int32 page_size = 2;
296
297  // A page token, received from a previous
298  // [Simulator.ListReplayResults][google.cloud.policysimulator.v1.Simulator.ListReplayResults]
299  // call. Provide this token to retrieve the next page of results.
300  //
301  // When paginating, all other parameters provided to
302  // [Simulator.ListReplayResults[] must match the call that provided the page
303  // token.
304  string page_token = 3;
305}
306
307// Response message for
308// [Simulator.ListReplayResults][google.cloud.policysimulator.v1.Simulator.ListReplayResults].
309message ListReplayResultsResponse {
310  // The results of running a [Replay][google.cloud.policysimulator.v1.Replay].
311  repeated ReplayResult replay_results = 1;
312
313  // A token that you can use to retrieve the next page of
314  // [ReplayResult][google.cloud.policysimulator.v1.ReplayResult] objects. If
315  // this field is omitted, there are no subsequent pages.
316  string next_page_token = 2;
317}
318
319// The configuration used for a
320// [Replay][google.cloud.policysimulator.v1.Replay].
321message ReplayConfig {
322  // The source of the logs to use for a
323  // [Replay][google.cloud.policysimulator.v1.Replay].
324  enum LogSource {
325    // An unspecified log source.
326    // If the log source is unspecified, the
327    // [Replay][google.cloud.policysimulator.v1.Replay] defaults to using
328    // `RECENT_ACCESSES`.
329    LOG_SOURCE_UNSPECIFIED = 0;
330
331    // All access logs from the last 90 days. These logs may not include logs
332    // from the most recent 7 days.
333    RECENT_ACCESSES = 1;
334  }
335
336  // A mapping of the resources that you want to simulate policies for and the
337  // policies that you want to simulate.
338  //
339  // Keys are the full resource names for the resources. For example,
340  // `//cloudresourcemanager.googleapis.com/projects/my-project`.
341  // For examples of full resource names for Google Cloud services, see
342  // https://cloud.google.com/iam/help/troubleshooter/full-resource-names.
343  //
344  // Values are [Policy][google.iam.v1.Policy] objects representing the policies
345  // that you want to simulate.
346  //
347  // Replays automatically take into account any IAM policies inherited through
348  // the resource hierarchy, and any policies set on descendant resources. You
349  // do not need to include these policies in the policy overlay.
350  map<string, google.iam.v1.Policy> policy_overlay = 1;
351
352  // The logs to use as input for the
353  // [Replay][google.cloud.policysimulator.v1.Replay].
354  LogSource log_source = 2;
355}
356
357// The difference between the results of evaluating an access tuple under
358// the current (baseline) policies and under the proposed (simulated) policies.
359// This difference explains how a principal's access could change if the
360// proposed policies were applied.
361message ReplayDiff {
362  // A summary and comparison of the principal's access under the current
363  // (baseline) policies and the proposed (simulated) policies for a single
364  // access tuple.
365  //
366  // The evaluation of the principal's access is reported in the
367  // [AccessState][google.cloud.policysimulator.v1.AccessState] field.
368  AccessStateDiff access_diff = 2;
369}
370
371// A summary and comparison of the principal's access under the current
372// (baseline) policies and the proposed (simulated) policies for a single
373// access tuple.
374message AccessStateDiff {
375  // How the principal's access, specified in the AccessState field, changed
376  // between the current (baseline) policies and proposed (simulated) policies.
377  enum AccessChangeType {
378    // Default value. This value is unused.
379    ACCESS_CHANGE_TYPE_UNSPECIFIED = 0;
380
381    // The principal's access did not change.
382    // This includes the case where both baseline and simulated are UNKNOWN,
383    // but the unknown information is equivalent.
384    NO_CHANGE = 1;
385
386    // The principal's access under both the current policies and the proposed
387    // policies is `UNKNOWN`, but the unknown information differs between them.
388    UNKNOWN_CHANGE = 2;
389
390    // The principal had access under the current policies (`GRANTED`), but will
391    // no longer have access after the proposed changes (`NOT_GRANTED`).
392    ACCESS_REVOKED = 3;
393
394    // The principal did not have access under the current policies
395    // (`NOT_GRANTED`), but will have access after the proposed changes
396    // (`GRANTED`).
397    ACCESS_GAINED = 4;
398
399    // This result can occur for the following reasons:
400    //
401    // * The principal had access under the current policies (`GRANTED`), but
402    //   their access after the proposed changes is `UNKNOWN`.
403    //
404    // * The principal's access under the current policies is `UNKNOWN`, but
405    // they
406    //   will not have access after the proposed changes (`NOT_GRANTED`).
407    ACCESS_MAYBE_REVOKED = 5;
408
409    // This result can occur for the following reasons:
410    //
411    // * The principal did not have access under the current policies
412    //   (`NOT_GRANTED`), but their access after the proposed changes is
413    //   `UNKNOWN`.
414    //
415    // * The principal's access under the current policies is `UNKNOWN`, but
416    // they will have access after the proposed changes (`GRANTED`).
417    ACCESS_MAYBE_GAINED = 6;
418  }
419
420  // The results of evaluating the access tuple under the current (baseline)
421  // policies.
422  //
423  // If the [AccessState][google.cloud.policysimulator.v1.AccessState] couldn't
424  // be fully evaluated, this field explains why.
425  ExplainedAccess baseline = 1;
426
427  // The results of evaluating the access tuple under the proposed (simulated)
428  // policies.
429  //
430  // If the AccessState couldn't be fully evaluated, this field explains why.
431  ExplainedAccess simulated = 2;
432
433  // How the principal's access, specified in the AccessState field, changed
434  // between the current (baseline) policies and proposed (simulated) policies.
435  AccessChangeType access_change = 3;
436}
437
438// Details about how a set of policies, listed in
439// [ExplainedPolicy][google.cloud.policysimulator.v1.ExplainedPolicy], resulted
440// in a certain [AccessState][google.cloud.policysimulator.v1.AccessState] when
441// replaying an access tuple.
442message ExplainedAccess {
443  // Whether the principal in the access tuple has permission to access the
444  // resource in the access tuple under the given policies.
445  AccessState access_state = 1;
446
447  // If the [AccessState][google.cloud.policysimulator.v1.AccessState] is
448  // `UNKNOWN`, this field contains the policies that led to that result.
449  //
450  // If the `AccessState` is `GRANTED` or `NOT_GRANTED`, this field is
451  // omitted.
452  repeated ExplainedPolicy policies = 2;
453
454  // If the [AccessState][google.cloud.policysimulator.v1.AccessState] is
455  // `UNKNOWN`, this field contains a list of errors explaining why the result
456  // is `UNKNOWN`.
457  //
458  // If the `AccessState` is `GRANTED` or `NOT_GRANTED`, this field is
459  // omitted.
460  repeated google.rpc.Status errors = 3;
461}
462