@@ -168,6 +168,13 @@ class Component(PackageURLMixin, ORMBase):
168
168
secondaryjoin = components_association_table .c .child_component == id ,
169
169
)
170
170
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
+
171
178
def __init__ (self , purl : str , analysis : Analysis , repository : "Repository | None" ):
172
179
"""
173
180
Instantiate the software component using PURL identifier.
@@ -528,3 +535,31 @@ class HashDigest(ORMBase):
528
535
529
536
#: The many-to-one relationship with artifacts.
530
537
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