// Copyright 2019 The Grafeas Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

syntax = "proto3";

package grafeas.v1;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/protobuf/empty.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/timestamp.proto";
import "grafeas/v1/attestation.proto";
import "grafeas/v1/build.proto";
import "grafeas/v1/common.proto";
import "grafeas/v1/compliance.proto";
import "grafeas/v1/deployment.proto";
import "grafeas/v1/discovery.proto";
import "grafeas/v1/dsse_attestation.proto";
import "grafeas/v1/image.proto";
import "grafeas/v1/package.proto";
import "grafeas/v1/sbom.proto";
import "grafeas/v1/upgrade.proto";
import "grafeas/v1/vex.proto";
import "grafeas/v1/vulnerability.proto";

option go_package = "google.golang.org/genproto/googleapis/grafeas/v1;grafeas";
option java_multiple_files = true;
option java_package = "io.grafeas.v1";
option objc_class_prefix = "GRA";
option (google.api.resource_definition) = {
  type: "grafeas.io/Project"
  pattern: "projects/{project}"
};

// [Grafeas](https://grafeas.io) API.
//
// Retrieves analysis results of Cloud components such as Docker container
// images.
//
// Analysis results are stored as a series of occurrences. An `Occurrence`
// contains information about a specific analysis instance on a resource. An
// occurrence refers to a `Note`. A note contains details describing the
// analysis and is generally stored in a separate project, called a `Provider`.
// Multiple occurrences can refer to the same note.
//
// For example, an SSL vulnerability could affect multiple images. In this case,
// there would be one note for the vulnerability and an occurrence for each
// image with the vulnerability referring to that note.
service Grafeas {
  option (google.api.default_host) = "containeranalysis.googleapis.com";

  // Gets the specified occurrence.
  rpc GetOccurrence(GetOccurrenceRequest) returns (Occurrence) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/occurrences/*}"
      additional_bindings {
        get: "/v1/{name=projects/*/locations/*/occurrences/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists occurrences for the specified project.
  rpc ListOccurrences(ListOccurrencesRequest)
      returns (ListOccurrencesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*}/occurrences"
      additional_bindings {
        get: "/v1/{parent=projects/*/locations/*}/occurrences"
      }
    };
    option (google.api.method_signature) = "parent,filter";
  }

  // Deletes the specified occurrence. For example, use this method to delete an
  // occurrence when the occurrence is no longer applicable for the given
  // resource.
  rpc DeleteOccurrence(DeleteOccurrenceRequest)
      returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/occurrences/*}"
      additional_bindings {
        delete: "/v1/{name=projects/*/locations/*/occurrences/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new occurrence.
  rpc CreateOccurrence(CreateOccurrenceRequest) returns (Occurrence) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*}/occurrences"
      body: "occurrence"
      additional_bindings {
        post: "/v1/{parent=projects/*/locations/*}/occurrences"
        body: "occurrence"
      }
    };
    option (google.api.method_signature) = "parent,occurrence";
  }

  // Creates new occurrences in batch.
  rpc BatchCreateOccurrences(BatchCreateOccurrencesRequest)
      returns (BatchCreateOccurrencesResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*}/occurrences:batchCreate"
      body: "*"
      additional_bindings {
        post: "/v1/{parent=projects/*/locations/*}/occurrences:batchCreate"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,occurrences";
  }

  // Updates the specified occurrence.
  rpc UpdateOccurrence(UpdateOccurrenceRequest) returns (Occurrence) {
    option (google.api.http) = {
      patch: "/v1/{name=projects/*/occurrences/*}"
      body: "occurrence"
      additional_bindings {
        patch: "/v1/{name=projects/*/locations/*/occurrences/*}"
        body: "occurrence"
      }
    };
    option (google.api.method_signature) = "name,occurrence,update_mask";
  }

  // Gets the note attached to the specified occurrence. Consumer projects can
  // use this method to get a note that belongs to a provider project.
  rpc GetOccurrenceNote(GetOccurrenceNoteRequest) returns (Note) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/occurrences/*}/notes"
      additional_bindings {
        get: "/v1/{name=projects/*/locations/*/occurrences/*}/notes"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Gets the specified note.
  rpc GetNote(GetNoteRequest) returns (Note) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/notes/*}"
      additional_bindings { get: "/v1/{name=projects/*/locations/*/notes/*}" }
    };
    option (google.api.method_signature) = "name";
  }

  // Lists notes for the specified project.
  rpc ListNotes(ListNotesRequest) returns (ListNotesResponse) {
    option (google.api.http) = {
      get: "/v1/{parent=projects/*}/notes"
      additional_bindings { get: "/v1/{parent=projects/*/locations/*}/notes" }
    };
    option (google.api.method_signature) = "parent,filter";
  }

  // Deletes the specified note.
  rpc DeleteNote(DeleteNoteRequest) returns (google.protobuf.Empty) {
    option (google.api.http) = {
      delete: "/v1/{name=projects/*/notes/*}"
      additional_bindings {
        delete: "/v1/{name=projects/*/locations/*/notes/*}"
      }
    };
    option (google.api.method_signature) = "name";
  }

  // Creates a new note.
  rpc CreateNote(CreateNoteRequest) returns (Note) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*}/notes"
      body: "note"
      additional_bindings {
        post: "/v1/{parent=projects/*/locations/*}/notes"
        body: "note"
      }
    };
    option (google.api.method_signature) = "parent,note_id,note";
  }

  // Creates new notes in batch.
  rpc BatchCreateNotes(BatchCreateNotesRequest)
      returns (BatchCreateNotesResponse) {
    option (google.api.http) = {
      post: "/v1/{parent=projects/*}/notes:batchCreate"
      body: "*"
      additional_bindings {
        post: "/v1/{parent=projects/*/locations/*}/notes:batchCreate"
        body: "*"
      }
    };
    option (google.api.method_signature) = "parent,notes";
  }

  // Updates the specified note.
  rpc UpdateNote(UpdateNoteRequest) returns (Note) {
    option (google.api.http) = {
      patch: "/v1/{name=projects/*/notes/*}"
      body: "note"
      additional_bindings {
        patch: "/v1/{name=projects/*/locations/*/notes/*}"
        body: "note"
      }
    };
    option (google.api.method_signature) = "name,note,update_mask";
  }

  // Lists occurrences referencing the specified note. Provider projects can use
  // this method to get all occurrences across consumer projects referencing the
  // specified note.
  rpc ListNoteOccurrences(ListNoteOccurrencesRequest)
      returns (ListNoteOccurrencesResponse) {
    option (google.api.http) = {
      get: "/v1/{name=projects/*/notes/*}/occurrences"
      additional_bindings {
        get: "/v1/{name=projects/*/locations/*/notes/*}/occurrences"
      }
    };
    option (google.api.method_signature) = "name,filter";
  }
}

// An instance of an analysis type that has been found on a resource.
message Occurrence {
  option (google.api.resource) = {
    type: "grafeas.io/Occurrence"
    pattern: "projects/{project}/occurrences/{occurrence}"
  };

  // Output only. The name of the occurrence in the form of
  // `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]`.
  string name = 1;

  // Required. Immutable. A URI that represents the resource for which the
  // occurrence applies. For example,
  // `https://gcr.io/project/image@sha256:123abc` for a Docker image.
  string resource_uri = 2;

  // Required. Immutable. The analysis note associated with this occurrence, in
  // the form of `projects/[PROVIDER_ID]/notes/[NOTE_ID]`. This field can be
  // used as a filter in list requests.
  string note_name = 3;

  // Output only. This explicitly denotes which of the occurrence details are
  // specified. This field can be used as a filter in list requests.
  grafeas.v1.NoteKind kind = 4;

  // A description of actions that can be taken to remedy the note.
  string remediation = 5;

  // Output only. The time this occurrence was created.
  google.protobuf.Timestamp create_time = 6;

  // Output only. The time this occurrence was last updated.
  google.protobuf.Timestamp update_time = 7;

  // Required. Immutable. Describes the details of the note kind found on this
  // resource.
  oneof details {
    // Describes a security vulnerability.
    grafeas.v1.VulnerabilityOccurrence vulnerability = 8;
    // Describes a verifiable build.
    grafeas.v1.BuildOccurrence build = 9;
    // Describes how this resource derives from the basis in the associated
    // note.
    grafeas.v1.ImageOccurrence image = 10;
    // Describes the installation of a package on the linked resource.
    grafeas.v1.PackageOccurrence package = 11;
    // Describes the deployment of an artifact on a runtime.
    grafeas.v1.DeploymentOccurrence deployment = 12;
    // Describes when a resource was discovered.
    grafeas.v1.DiscoveryOccurrence discovery = 13;
    // Describes an attestation of an artifact.
    grafeas.v1.AttestationOccurrence attestation = 14;
    // Describes an available package upgrade on the linked resource.
    grafeas.v1.UpgradeOccurrence upgrade = 15;
    // Describes a compliance violation on a linked resource.
    grafeas.v1.ComplianceOccurrence compliance = 16;
    // Describes an attestation of an artifact using dsse.
    grafeas.v1.DSSEAttestationOccurrence dsse_attestation = 17;
    // Describes a specific SBOM reference occurrences.
    grafeas.v1.SBOMReferenceOccurrence sbom_reference = 19;
  }

  // https://github.com/secure-systems-lab/dsse
  grafeas.v1.Envelope envelope = 18;
}

// A type of analysis that can be done for a resource.
message Note {
  option (google.api.resource) = {
    type: "grafeas.io/Note"
    pattern: "projects/{project}/notes/{note}"
  };

  // Output only. The name of the note in the form of
  // `projects/[PROVIDER_ID]/notes/[NOTE_ID]`.
  string name = 1;

  // A one sentence description of this note.
  string short_description = 2;

  // A detailed description of this note.
  string long_description = 3;

  // Output only. The type of analysis. This field can be used as a filter in
  // list requests.
  grafeas.v1.NoteKind kind = 4;

  // URLs associated with this note.
  repeated grafeas.v1.RelatedUrl related_url = 5;

  // Time of expiration for this note. Empty if note does not expire.
  google.protobuf.Timestamp expiration_time = 6;

  // Output only. The time this note was created. This field can be used as a
  // filter in list requests.
  google.protobuf.Timestamp create_time = 7;

  // Output only. The time this note was last updated. This field can be used as
  // a filter in list requests.
  google.protobuf.Timestamp update_time = 8;

  // Other notes related to this note.
  repeated string related_note_names = 9;

  // Required. Immutable. The type of analysis this note represents.
  oneof type {
    // A note describing a package vulnerability.
    grafeas.v1.VulnerabilityNote vulnerability = 10;
    // A note describing build provenance for a verifiable build.
    grafeas.v1.BuildNote build = 11;
    // A note describing a base image.
    grafeas.v1.ImageNote image = 12;
    // A note describing a package hosted by various package managers.
    grafeas.v1.PackageNote package = 13;
    // A note describing something that can be deployed.
    grafeas.v1.DeploymentNote deployment = 14;
    // A note describing the initial analysis of a resource.
    grafeas.v1.DiscoveryNote discovery = 15;
    // A note describing an attestation role.
    grafeas.v1.AttestationNote attestation = 16;
    // A note describing available package upgrades.
    grafeas.v1.UpgradeNote upgrade = 17;
    // A note describing a compliance check.
    grafeas.v1.ComplianceNote compliance = 18;
    // A note describing a dsse attestation note.
    grafeas.v1.DSSEAttestationNote dsse_attestation = 19;
    // A note describing a vulnerability assessment.
    grafeas.v1.VulnerabilityAssessmentNote vulnerability_assessment = 20;
    // A note describing an SBOM reference.
    grafeas.v1.SBOMReferenceNote sbom_reference = 21;
  }
}

// Request to get an occurrence.
message GetOccurrenceRequest {
  // The name of the occurrence in the form of
  // `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Occurrence"
  ];
}

// Request to list occurrences.
message ListOccurrencesRequest {
  // The name of the project to list occurrences for in the form of
  // `projects/[PROJECT_ID]`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];

  // The filter expression.
  string filter = 2;

  // Number of occurrences to return in the list. Must be positive. Max allowed
  // page size is 1000. If not specified, page size defaults to 20.
  int32 page_size = 3;

  // Token to provide to skip to a particular spot in the list.
  string page_token = 4;
}

// Response for listing occurrences.
message ListOccurrencesResponse {
  // The occurrences requested.
  repeated Occurrence occurrences = 1;
  // The next pagination token in the list response. It should be used as
  // `page_token` for the following request. An empty value means no more
  // results.
  string next_page_token = 2;
}

// Request to delete an occurrence.
message DeleteOccurrenceRequest {
  // The name of the occurrence in the form of
  // `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Occurrence"
  ];
}

// Request to create a new occurrence.
message CreateOccurrenceRequest {
  // The name of the project in the form of `projects/[PROJECT_ID]`, under which
  // the occurrence is to be created.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];
  // The occurrence to create.
  Occurrence occurrence = 2 [(google.api.field_behavior) = REQUIRED];
}

// Request to update an occurrence.
message UpdateOccurrenceRequest {
  // The name of the occurrence in the form of
  // `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Occurrence"
  ];
  // The updated occurrence.
  Occurrence occurrence = 2 [(google.api.field_behavior) = REQUIRED];
  // The fields to update.
  google.protobuf.FieldMask update_mask = 3;
}

// Request to get a note.
message GetNoteRequest {
  // The name of the note in the form of
  // `projects/[PROVIDER_ID]/notes/[NOTE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Note"
  ];
}

// Request to get the note to which the specified occurrence is attached.
message GetOccurrenceNoteRequest {
  // The name of the occurrence in the form of
  // `projects/[PROJECT_ID]/occurrences/[OCCURRENCE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Occurrence"
  ];
}

// Request to list notes.
message ListNotesRequest {
  // The name of the project to list notes for in the form of
  // `projects/[PROJECT_ID]`.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];

  // The filter expression.
  string filter = 2;

  // Number of notes to return in the list. Must be positive. Max allowed page
  // size is 1000. If not specified, page size defaults to 20.
  int32 page_size = 3;

  // Token to provide to skip to a particular spot in the list.
  string page_token = 4;
}

// Response for listing notes.
message ListNotesResponse {
  // The notes requested.
  repeated Note notes = 1;
  // The next pagination token in the list response. It should be used as
  // `page_token` for the following request. An empty value means no more
  // results.
  string next_page_token = 2;
}

// Request to delete a note.
message DeleteNoteRequest {
  // The name of the note in the form of
  // `projects/[PROVIDER_ID]/notes/[NOTE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Note"
  ];
}

// Request to create a new note.
message CreateNoteRequest {
  // The name of the project in the form of `projects/[PROJECT_ID]`, under which
  // the note is to be created.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];
  // The ID to use for this note.
  string note_id = 2 [(google.api.field_behavior) = REQUIRED];
  // The note to create.
  Note note = 3 [(google.api.field_behavior) = REQUIRED];
}

// Request to update a note.
message UpdateNoteRequest {
  // The name of the note in the form of
  // `projects/[PROVIDER_ID]/notes/[NOTE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Note"
  ];
  // The updated note.
  Note note = 2 [(google.api.field_behavior) = REQUIRED];
  // The fields to update.
  google.protobuf.FieldMask update_mask = 3;
}

// Request to list occurrences for a note.
message ListNoteOccurrencesRequest {
  // The name of the note to list occurrences for in the form of
  // `projects/[PROVIDER_ID]/notes/[NOTE_ID]`.
  string name = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Note"
  ];
  // The filter expression.
  string filter = 2;
  // Number of occurrences to return in the list.
  int32 page_size = 3;
  // Token to provide to skip to a particular spot in the list.
  string page_token = 4;
}

// Response for listing occurrences for a note.
message ListNoteOccurrencesResponse {
  // The occurrences attached to the specified note.
  repeated Occurrence occurrences = 1;
  // Token to provide to skip to a particular spot in the list.
  string next_page_token = 2;
}

// Request to create notes in batch.
message BatchCreateNotesRequest {
  // The name of the project in the form of `projects/[PROJECT_ID]`, under which
  // the notes are to be created.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];

  // The notes to create. Max allowed length is 1000.
  map<string, Note> notes = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response for creating notes in batch.
message BatchCreateNotesResponse {
  // The notes that were created.
  repeated Note notes = 1;
}

// Request to create occurrences in batch.
message BatchCreateOccurrencesRequest {
  // The name of the project in the form of `projects/[PROJECT_ID]`, under which
  // the occurrences are to be created.
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference).type = "grafeas.io/Project"
  ];

  // The occurrences to create. Max allowed length is 1000.
  repeated Occurrence occurrences = 2 [(google.api.field_behavior) = REQUIRED];
}

// Response for creating occurrences in batch.
message BatchCreateOccurrencesResponse {
  // The occurrences that were created.
  repeated Occurrence occurrences = 1;
}
