@@ -168,6 +168,13 @@ class Component(PackageURLMixin, ORMBase):
168168 secondaryjoin = components_association_table .c .child_component == id ,
169169 )
170170
171+ #: The optional one-to-one relationship with a provenance subject in case this
172+ #: component represents a subject in a provenance.
173+ provenance_subject : Mapped ["ProvenanceSubject | None" ] = relationship (
174+ back_populates = "component" ,
175+ lazy = "immediate" ,
176+ )
177+
171178 def __init__ (self , purl : str , analysis : Analysis , repository : "Repository | None" ):
172179 """
173180 Instantiate the software component using PURL identifier.
@@ -528,3 +535,31 @@ class HashDigest(ORMBase):
528535
529536 #: The many-to-one relationship with artifacts.
530537 artifact : Mapped ["ReleaseArtifact" ] = relationship (back_populates = "digests" , lazy = "immediate" )
538+
539+
540+ class ProvenanceSubject (ORMBase ):
541+ """A subject in a provenance that matches the user-provided PackageURL.
542+
543+ This subject may be later populated in VSAs during policy verification.
544+ """
545+
546+ __tablename__ = "_provenance_subject"
547+
548+ #: The primary key.
549+ id : Mapped [int ] = mapped_column (Integer , primary_key = True , autoincrement = True ) # noqa: A003
550+
551+ #: The component id of the provenance subject.
552+ component_id : Mapped [int ] = mapped_column (
553+ Integer ,
554+ ForeignKey ("_component.id" ),
555+ nullable = False ,
556+ )
557+
558+ #: The required one-to-one relationship with a component.
559+ component : Mapped [Component ] = relationship (
560+ back_populates = "provenance_subject" ,
561+ lazy = "immediate" ,
562+ )
563+
564+ #: The SHA256 hash of the subject.
565+ sha256 : Mapped [str ] = mapped_column (String , nullable = False )
0 commit comments