You can choose to provide your own metadata to Artifact Analysis to satisfy a specific business need. For example, an organization that provides security management for their customers' Docker containers can use Artifact Analysis to store and retrieve security-related metadata for those images.
The following steps show how to provide attestation metadata for your images using the Artifact Analysis API. You can use the same instructions to store and retrieve any kind of metadata that Artifact Analysis supports.
Before you begin
- Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Enable the Container Analysis API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init -
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Enable the Container Analysis API.
Roles required to enable APIs
To enable APIs, you need the Service Usage Admin IAM role (
roles/serviceusage.serviceUsageAdmin), which contains theserviceusage.services.enablepermission. Learn how to grant roles. -
Install the Google Cloud CLI.
-
If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.
-
To initialize the gcloud CLI, run the following command:
gcloud init - Learn how to set up access control for metadata in your project. Skip this step if you only consume metadata from occurrences created by Artifact Analysis container scanning.
Create notes and occurrences for projects
This section explains how you can create notes and occurrences. For this example, you will be using the ATTESTATION kind.
As a provider, you will create a note in your project for each attestation, and you will create an occurrence in your customer's project for an occurrence of that attestation.
Create notes
Use the following steps to create a note and give it a note ID.
API
Create a file named
note.jsonwith attestation description and details. The following code shows an examplenote.jsonfile:{ "shortDescription": "A brief Description of the note", "longDescription": "A longer description of the note", "kind": "ATTESTATION", "attestation": { "hint": { "humanReadableName": "my-attestation-authority" } } }See the notes API documentation for more information about the notes JSON representation.
Run the following curl command to create a note:
curl -v -H "Content-Type: application/json" -H \ "Authorization: Bearer $(gcloud auth print-access-token)" \ https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/notes?note_id=NOTE_ID -d @note.jsonWhere:
- PROVIDER_PROJECT_ID is your project ID.
- NOTE_ID specifies an identifier for your note. Use a string with a maximum length of 100 characters.
Java
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Java API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.Note;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Version;
import io.grafeas.v1.AttestationNote;
import java.io.IOException;
import java.lang.InterruptedException;
public class CreateNote {
// Creates and returns a new Note
public static Note createNote(String noteId, String projectId)
throws IOException, InterruptedException {
// String noteId = "my-note";
// String projectId = "my-project-id";
final String projectName = ProjectName.format(projectId);
Note newNote =
Note.newBuilder()
// Associate the Note with the metadata type
// https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types
// Here, we use the type "attestation"
.setAttestation(
AttestationNote.newBuilder()
.setHint(
AttestationNote.Hint.newBuilder()
.setHumanReadableName("my-attestation-authority")))
.build();
// Initialize client that will be used to send requests. After completing all of your requests,
// call the "close" method on the client to safely clean up any remaining background resources.
GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
Note result = client.createNote(projectName, noteId, newNote);
return result;
}
}
Go
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Go API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
import (
"context"
"fmt"
containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)
// createNote creates and returns a new attestation Note.
func createNote(noteID, projectID string) (*grafeaspb.Note, error) {
ctx := context.Background()
client, err := containeranalysis.NewClient(ctx)
if err != nil {
return nil, fmt.Errorf("NewClient: %w", err)
}
defer client.Close()
projectName := fmt.Sprintf("projects/%s", projectID)
req := &grafeaspb.CreateNoteRequest{
Parent: projectName,
NoteId: noteID,
Note: &grafeaspb.Note{
Type: &grafeaspb.Note_Attestation{
Attestation: &grafeaspb.AttestationNote{
Hint: &grafeaspb.AttestationNote_Hint{
HumanReadableName: "my-attestation-authority",
},
},
},
},
}
return client.GetGrafeasClient().CreateNote(ctx, req)
}
Node.js
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Node.js API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
/**
* TODO(developer): Uncomment these variables before running the sample
*/
// const projectId = 'your-project-id', // Your Google Cloud Project ID
// const noteId = 'my-note-id' // Id of the note
// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();
// Construct request
// Associate the Note with a metadata type
// https://cloud.google.com/container-registry/docs/container-analysis#supported_metadata_types
// Here, we use the type "attestation"
const formattedParent = client.getGrafeasClient().projectPath(projectId);
// Creates and returns a new Note
const [note] = await client.getGrafeasClient().createNote({
parent: formattedParent,
noteId: noteId,
note: {
attestation: {
hint: {
humanReadableName: 'my-attestation-authority',
},
},
},
});
console.log(`Note ${note.name} created.`);
Ruby
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Ruby API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
# note_id = "A user-specified identifier for the note"
# project_id = "Your Google Cloud project ID"
require "google/cloud/container_analysis"
# Initialize the client
client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
parent = client.project_path project: project_id
note = {
attestation: {
hint: {
human_readable_name: "attestation-authority"
}
}
}
response = client.create_note parent: parent, note_id: note_id, note: note
puts response.name
Python
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Python API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
from google.cloud.devtools import containeranalysis_v1
from grafeas.grafeas_v1 import types, Version
def create_note(note_id: str, project_id: str) -> types.grafeas.Note:
"""Creates and returns a new attestation note."""
# note_id = 'my-note'
# project_id = 'my-gcp-project'
client = containeranalysis_v1.ContainerAnalysisClient()
grafeas_client = client.get_grafeas_client()
project_name = f"projects/{project_id}"
note = {
"attestation": {
"hint": {
"human_readable_name": "attestation-authority",
}
}
}
response = grafeas_client.create_note(
parent=project_name, note_id=note_id, note=note
)
return response
Create occurrences for the notes
To create occurrences for a note:
API
Create a file named
occurrence.jsonwith attestation description and details. The following code shows an exampleoccurrence.jsonfile:{ "resourceUri": "your-resource-uri-here", "noteName": "projects/your-note-project/notes/your-note-id", "kind": "ATTESTATION", "attestation": { "serializedPayload": "eW91ci1wYXlsb2FkLWhlcmU=", "signatures": [ { "publicKeyId": "your-key-id-here", "signature": "eW91ci1zaWduYXR1cmUtaGVyZQ==" } ] } }See the notes API documentation for more information about the notes JSON representation.
Run the following curl command to create an occurrence:
curl -v -H "Content-Type: application/json" -H \ "Authorization: Bearer $(gcloud auth print-access-token)" \ https://containeranalysis.googleapis.com/v1/projects/PROVIDER_PROJECT_ID/occurrences/ -d @occurrence.jsonWhere:
- PROVIDER_PROJECT_ID is your project ID.
- NOTE_ID specifies an identifier for your note. Use a string with a maximum length of 100 characters.
Java
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Java API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
import com.google.cloud.devtools.containeranalysis.v1.ContainerAnalysisClient;
import com.google.protobuf.ByteString;
import io.grafeas.v1.AttestationOccurrence;
import io.grafeas.v1.GrafeasClient;
import io.grafeas.v1.NoteName;
import io.grafeas.v1.Occurrence;
import io.grafeas.v1.ProjectName;
import io.grafeas.v1.Signature;
import java.io.IOException;
public class CreateOccurrence {
// Creates and returns a new attestation Occurrence associated with an existing Note
public static Occurrence createOccurrence(
String resourceUrl, String noteId, String occProjectId, String noteProjectId)
throws IOException {
// String resourceUrl = "https://gcr.io/project/image@sha256:123";
// String noteId = "my-note";
// String occProjectId = "my-project-id";
// String noteProjectId = "my-project-id";
final NoteName noteName = NoteName.of(noteProjectId, noteId);
final String occProjectName = ProjectName.format(occProjectId);
Occurrence newOcc =
Occurrence.newBuilder()
.setNoteName(noteName.toString())
.setResourceUri(resourceUrl)
.setAttestation(
AttestationOccurrence.newBuilder()
.setSerializedPayload(ByteString.copyFrom("your-payload-here", "UTF-8"))
.addSignatures(
Signature.newBuilder()
.setPublicKeyId("your-key-id-here")
.setSignature(ByteString.copyFrom("your-signature-here", "UTF-8"))))
.build();
// Initialize client that will be used to send requests. After completing all of your requests,
// call the "close" method on the client to safely clean up any remaining background
// resources.
GrafeasClient client = ContainerAnalysisClient.create().getGrafeasClient();
Occurrence result = client.createOccurrence(occProjectName, newOcc);
return result;
}
}
Go
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Go API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
import (
"context"
"fmt"
containeranalysis "cloud.google.com/go/containeranalysis/apiv1"
grafeaspb "google.golang.org/genproto/googleapis/grafeas/v1"
)
// createsOccurrence creates and returns a new Occurrence of a previously created attestation note.
// Use this style of URL when you use Google Artifact Registry.
// resourceURL := "https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image"
// noteID := "my-note"
ctx := context.Background()
client, err := containeranalysis.NewClient(ctx)
if err != nil {
return nil, fmt.Errorf("NewClient: %w", err)
}
defer client.Close()
req := &grafeaspb.CreateOccurrenceRequest{
Parent: fmt.Sprintf("projects/%s", occProjectID),
Occurrence: &grafeaspb.Occurrence{
NoteName: fmt.Sprintf("projects/%s/notes/%s", noteProjectID, noteID),
// Attach the occurrence to the associated resource uri.
ResourceUri: resourceURL,
// Details about the attestation can be added here.
Details: &grafeaspb.Occurrence_Attestation{
Attestation: &grafeaspb.AttestationOccurrence{
SerializedPayload: []byte("..."),
Signatures: []*grafeaspb.Signature{
{
PublicKeyId: "...",
Signature: []byte("..."),
},
},
},
},
},
}
return client.GetGrafeasClient().CreateOccurrence(ctx, req)
}
Node.js
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Node.js API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
/**
* TODO(developer): Uncomment these variables before running the sample
*/
// const noteProjectId = 'your-project-id', // Your Google Cloud Project ID
// const noteId = 'my-note-id', // Id of the note
// const occurrenceProjectId = 'your-project-id', // The Google Cloud Project ID of the occurrence
// If you are using Google Artifact Registry
// const imageUrl = 'https://LOCATION-docker.pkg.dev/my-project/my-repo/my-image:123' // Image to attach metadata to
// Import the library and create a client
const {ContainerAnalysisClient} = require('@google-cloud/containeranalysis');
const client = new ContainerAnalysisClient();
// Construct request
const formattedParent = client
.getGrafeasClient()
.projectPath(occurrenceProjectId);
const formattedNote = client
.getGrafeasClient()
.notePath(noteProjectId, noteId);
// Creates and returns a new Occurrence associated with an existing Note
const [occurrence] = await client.getGrafeasClient().createOccurrence({
parent: formattedParent,
occurrence: {
noteName: formattedNote,
resourceUri: imageUrl,
attestation: {
serializedPayload: Buffer.from('your-payload-here').toString('base64'),
signatures: [
{
publicKeyId: 'your-key-id-here',
signature: Buffer.from('your-signature-here').toString('base64'),
},
],
},
},
});
console.log(`Occurrence created ${occurrence.name}.`);
return occurrence;
Ruby
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Ruby API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
# note_id = "A user-specified identifier for the note"
# project_id = "Your Google Cloud project ID"
# note_project = "The project that contains the note"
# occurrence_project = "The project that contains the occurrence"
require "google/cloud/container_analysis"
require "base64"
# Initialize the client
client = Google::Cloud::ContainerAnalysis.container_analysis.grafeas_client
note_path = client.note_path project: note_project, note: note_id
project_path = client.project_path project: occurrence_project
occurrence = {
note_name: note_path,
resource_uri: resource_url,
attestation: {
serialized_payload: Base64.encode64("your-payload-here"),
signatures: [
{
public_key_id: "your-key-id-here",
signature: Base64.encode64("your-signature-here")
}
]
}
}
response = client.create_occurrence parent: project_path, occurrence: occurrence
puts response.name
Python
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Python API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
import base64
from google.cloud.devtools import containeranalysis_v1
from grafeas.grafeas_v1 import types
def create_occurrence(
resource_url: str, note_id: str, occurrence_project: str, note_project: str
) -> types.grafeas.Occurrence:
"""Creates and returns a new occurrence of a previously
created attestation note."""
# note_id = 'my-note'
# project_id = 'my-gcp-project'
client = containeranalysis_v1.ContainerAnalysisClient()
grafeas_client = client.get_grafeas_client()
formatted_note = f"projects/{note_project}/notes/{note_id}"
formatted_project = f"projects/{occurrence_project}"
occurrence = {
"note_name": formatted_note,
"resource_uri": resource_url,
"attestation": {
"serialized_payload": base64.b64encode(b"your-payload-here").decode("utf-8"),
"signatures": [
{
"public_key_id": "your-key-id-here",
"signature": base64.b64encode(b"your-signature-here").decode("utf-8"),
}
],
},
}
return grafeas_client.create_occurrence(
parent=formatted_project, occurrence=occurrence
)
Get all occurrences for a specific note
You can view all occurrences of a specific attestation across your customer's
projects using notes.occurrences.list().
API
To list all the occurrences for a note, send a GET request as follows:
GET https://containeranalysis.googleapis.com/v1/projects/PROJECT_ID/notes/NOTE_ID/occurrences
Refer to the projects.notes.occurrences.list API endpoint
for complete details.
Java
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Java API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Go
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Go API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Node.js
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Node.js API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Ruby
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Ruby API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
Python
To learn how to install and use the client library for Artifact Analysis, see Artifact Analysis client libraries. For more information, see the Artifact Analysis Python API reference documentation.
To authenticate to Artifact Analysis, set up Application Default Credentials. For more information, see Set up authentication for a local development environment.
What's next
For instructions on how to view and filter notes and occurrences for container images, see Viewing vulnerability occurrences.
For instructions on how to set up notifications, see Pub/Sub notifications.