Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: refactor provenance level 3 check into analysis #817

Open
wants to merge 2 commits into
base: staging
Choose a base branch
from

Conversation

benmss
Copy link
Member

@benmss benmss commented Aug 7, 2024

No description provided.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 7, 2024
@benmss benmss force-pushed the benmss/refactor-provenance-level-3 branch from 0618836 to 4190dab Compare August 7, 2024 07:27
@benmss benmss force-pushed the benmss/refactor-provenance-level-3 branch from 4190dab to c0e88a4 Compare August 15, 2024 03:40
Signed-off-by: Ben Selwyn-Smith <[email protected]>
@benmss benmss marked this pull request as ready for review August 15, 2024 04:57
@@ -52,6 +52,8 @@ class ChecksOutputs(TypedDict):
"""The commit digest extracted from provenance, if applicable."""
provenance_verified: bool
"""True if the provenance exists and has been verified against a signed companion provenance."""
provenance_l3_verified: bool
"""True if the provenance exists and has been verified to the SLSA level 3 standard."""
Copy link
Member

@behnazh-w behnazh-w Aug 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the provenance-related metadata we are storing in the context object could use some abstraction. We can use (with adjustments if necessary) the Provenance mappings in our data model.

class Provenance(ORMBase):
"""ORM class for a provenance document."""
__tablename__ = "_provenance"
#: The primary key.
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) # noqa: A003
#: The foreign key to the software component.
component_id: Mapped[int] = mapped_column(Integer, ForeignKey(Component.id), nullable=False)
#: A many-to-one relationship with software components.
component: Mapped["Component"] = relationship(back_populates="provenance")
#: The SLSA version.
version: Mapped[str] = mapped_column(String, nullable=False)
#: The release tag commit sha.
release_commit_sha: Mapped[str] = mapped_column(String, nullable=True)
#: The release tag.
release_tag: Mapped[str] = mapped_column(String, nullable=True)
#: The provenance payload content in JSON format.
provenance_json: Mapped[str] = mapped_column(String, nullable=False)
#: A one-to-many relationship with the release artifacts.
artifact: Mapped[list["ReleaseArtifact"]] = relationship(back_populates="provenance")
class ReleaseArtifact(ORMBase):
"""The ORM class for release artifacts."""
__tablename__ = "_release_artifact"
#: The primary key.
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) # noqa: A003
#: The name of the artifact.
name: Mapped[str] = mapped_column(String, nullable=False)
#: The SLSA verification result.
slsa_verified: Mapped[bool] = mapped_column(Boolean, nullable=True)
#: The foreign key to the SLSA provenance.
provenance_id: Mapped[int] = mapped_column(Integer, ForeignKey(Provenance.id), nullable=True)
#: A many-to-one relationship with the SLSA provenance.
provenance: Mapped["Provenance"] = relationship(back_populates="artifact")
#: The one-to-many relationship with the hash digests for this artifact.
digests: Mapped[list["HashDigest"]] = relationship(back_populates="artifact")
class HashDigest(ORMBase):
"""ORM class for artifact digests."""
__tablename__ = "_hash_digest"
#: The primary key.
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) # noqa: A003
#: The hash digest value.
digest: Mapped[str] = mapped_column(String, nullable=False)
#: The hash digest algorithm.
digest_algorithm: Mapped[str] = mapped_column(String, nullable=False)
#: The foreign key to the release artifact.
artifact_id: Mapped[int] = mapped_column(Integer, ForeignKey(ReleaseArtifact.id), nullable=False)
#: The many-to-one relationship with artifacts.
artifact: Mapped["ReleaseArtifact"] = relationship(back_populates="digests", lazy="immediate")
class ProvenanceSubject(ORMBase):
"""A subject in a provenance that matches the user-provided PackageURL.
This subject may be later populated in VSAs during policy verification.
"""
__tablename__ = "_provenance_subject"
#: The primary key.
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True) # noqa: A003
#: The component id of the provenance subject.
component_id: Mapped[int] = mapped_column(
Integer,
ForeignKey("_component.id"),
nullable=False,
)
#: The required one-to-one relationship with a component.
component: Mapped[Component] = relationship(
back_populates="provenance_subject",
lazy="immediate",
)
#: The SHA256 hash of the subject.
sha256: Mapped[str] = mapped_column(String, nullable=False)
@classmethod
def from_purl_and_provenance(
cls,
purl: PackageURL,
provenance_payload: InTotoPayload,
) -> Self | None:
"""Create a ``ProvenanceSubject`` entry if there is a provenance subject matching the PURL.
Parameters
----------
purl : PackageURL
The PackageURL identifying the software component being analyzed.
provenance_payload : InTotoPayload
The provenance payload.
Returns
-------
Self | None
A ``ProvenanceSubject`` entry with the SHA256 digest of the provenance subject
matching the given PURL.
"""
subject_artifact_types: list[ProvenanceSubjectPURLMatcher] = [MavenSubjectPURLMatcher]
for subject_artifact_type in subject_artifact_types:
subject = subject_artifact_type.get_subject_in_provenance_matching_purl(
provenance_payload,
purl,
)
if subject is None:
return None
digest = subject["digest"]
if digest is None:
return None
sha256 = digest.get("sha256")
if not sha256:
return None
return cls(sha256=sha256)
return None
We can also associate a level for each provenance, and the provenance_verified would then indicate if the provenance has been verified together with the evidence.

provenance: InTotoPayload | None
"""The provenance payload for the target software component."""
provenance_repo_url: str | None
"""The repository URL extracted from provenance, if applicable."""
provenance_commit_digest: str | None
"""The commit digest extracted from provenance, if applicable."""
provenance_verified: bool
"""True if the provenance exists and has been verified against a signed companion provenance."""

We should also add back and store info about the assets: #819

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants