blob: 099c80c87b1f00ff7ed45d7f6242cc2a5ad2840e [file]
# Copyright 2024 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""API for interacting with Software Verifier.
To successfully authenticate to this API, you must have the
https://www.googleapis.com/auth/bcid_verify OAuth scope.
"""
from __future__ import annotations
from recipe_engine import recipe_api
# Usage of the bcid_verifier recipe_module will have significant downstream
# impact and to avoid any production outage, we pin the latest known good build
# of the tool here. Upstream changes are intentionally left out.
_LATEST_STABLE_VERSION = 'git_revision:c83273f7e3850f045420d836d5d92d64dcad3667'
VERIFY_FOR_ENFORCEMENT = "VERIFY_FOR_ENFORCEMENT"
VERIFY_FOR_LOGGING = "VERIFY_FOR_LOGGING"
class BcidVerifierApi(recipe_api.RecipeApi):
"""API for interacting with Software Verifier"""
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.verification_mode = VERIFY_FOR_ENFORCEMENT
@property
def bcid_verifier_path(self):
"""Returns the path to the bcid_verifier binary.
When the property is accessed the first time, the latest stable, released
version of bcid_verifier will be installed using CIPD.
"""
return self.m.cipd.ensure_tool(
"infra/tools/security/bcid_verifier/${platform}", _LATEST_STABLE_VERSION)
def verify_provenance(
self,
bcid_policy: str,
artifact_path: str,
attestation_path: str,
log_only_mode: bool = False,
):
"""
Calls the BCID Software Verifier API to verify provenance for an
artifact.
Args:
* bcid_policy: This field name is slightly misleading, and it would be
better if it was called resource_uri. This arg represents the full
ResourceURI to use when verifying this artifact. It should include both
the name of a valid BCID Policy or Resource Prefix, and the unique path
to the artifact protected by this verification. As an example, a call to
SoftwareVerifier to verify the provenance of a Chrome artifact before
signing might use the following structure.
bcid_policy: chrome_app://chrome/desktop/win/
artifact path: chrome-signed/desktop-5c0tCh/132.0.6834.0/win-clang/chrome.zip
Which would result in the following resource URI to use here:
chrome_app://chrome/desktop/win/chrome-signed/desktop-5c0tCh/132.0.6834.0/win-clang/chrome.zip
* artifact_path: Local file path to the artifact to be verified.
* attestation_path: Local file path to the attestation (intoto.jsonl) file
for the provided artifact.
* log_only_mode:
Whether to verify provenance in log only mode, and skip enforcement.
Enforcement fails closed, and if unable to receive a response from
Software Verifier, it will constitute a rejection. In log only mode,
a failed request or a failure to verify will not be considered a
failure.
"""
if log_only_mode:
self.verification_mode = VERIFY_FOR_LOGGING
args = [
self.bcid_verifier_path,
'-bcid-policy',
bcid_policy,
'-artifact-path',
artifact_path,
'-attestation-path',
attestation_path,
'verification-mode',
self.verification_mode,
]
self.m.step('bcid_verifier: verify provenance', args)