Skip to content

Commit c4d25dd

Browse files
committed
Merge remote-tracking branch 'origin/1682-left-pane-file-tree' into 1682-left-pane-file-tree
2 parents 4c5e620 + 8e2559f commit c4d25dd

22 files changed

+690
-31
lines changed

CHANGELOG.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,17 @@
11
Changelog
22
=========
33

4+
v35.3.0 (unreleased)
5+
--------------------
6+
7+
- Enhanced scorecard compliance support with:
8+
* New ``scorecard_compliance_alert`` in project ``extra_data``.
9+
* ``/api/projects/{id}/scorecard_compliance/`` API endpoint.
10+
* Scorecard compliance integration in ``check-compliance`` management command.
11+
* UI template support for scorecard compliance alert.
12+
* ``evaluate_scorecard_compliance()`` pipe function for compliance evaluation.
13+
https://github.com/aboutcode-org/scancode.io/pull/1800
14+
415
v35.2.0 (2025-08-01)
516
--------------------
617

docs/installation.rst

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,40 @@ create an **environment file**, and **build the Docker image**::
5555
As the ``docker-compose`` v1 command is officially deprecated by Docker, you will
5656
only find references to the ``docker compose`` v2 command in this documentation.
5757

58+
.. note::
59+
If you intend to run an Android deploy to develop project, ``Java``, ``jadx
60+
v1.5.0`` and ``android-inspector`` must be installed in the Docker image by
61+
adding the following lines to the ``Dockerfile`` and rebuilding the Docker
62+
image:
63+
64+
Add at line 65 after `apt-get` command::
65+
66+
# Install Java and utilities to install jadx
67+
RUN apt-get update \
68+
&& apt-get install -y --no-install-recommends \
69+
openjdk-17-jre-headless \
70+
unzip \
71+
wget
72+
73+
# Download and extract jadx
74+
RUN wget https://github.com/skylot/jadx/releases/download/v1.5.0/jadx-1.5.0.zip \
75+
&& unzip -d /usr jadx-1.5.0.zip
76+
77+
# Remove jadx archive and installed utilities
78+
RUN apt-get remove -y unzip wget \
79+
&& apt-get clean \
80+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* \
81+
&& rm jadx-1.5.0.zip
82+
83+
Add at end of file::
84+
85+
# Install android-inspector
86+
RUN pip install --no-cache-dir android-inspector
87+
88+
Rebuild the image::
89+
90+
docker compose build
91+
5892
Run the App
5993
^^^^^^^^^^^
6094

@@ -293,6 +327,20 @@ For the :ref:`pipeline_collect_strings_gettext` pipeline, `gettext <https://www.
293327

294328
brew install gettext
295329

330+
For the Android deploy to develop pipeline, `jadx <https://github.com/skylot/jadx>` and `Java <https://openjdk.org/index.html>`_ are needed.
331+
332+
* On **Linux** install it using::
333+
334+
# Ensure that you are in the scancode.io directory
335+
sudo apt-get install openjdk-21-jre # Install Java 21
336+
wget https://github.com/skylot/jadx/releases/download/v1.5.0/jadx-1.5.0.zip # Download jadx v1.5.0
337+
unzip -qd jadx-1.5.0 jadx-1.5.0.zip # Extract jadx-1.5.0.zip
338+
export PATH=$PATH:`pwd`/jadx-1.5.0/bin/jadx:`pwd`/jadx-1.5.0/lib # add jadx-1.5.0 binary and libraries to your path
339+
340+
* On **MacOS** install it using Homebrew::
341+
342+
brew install jadx
343+
296344
Clone and Configure
297345
^^^^^^^^^^^^^^^^^^^
298346

@@ -326,6 +374,11 @@ Clone and Configure
326374

327375
make envfile
328376

377+
* If you intend to run an Android deploy to develop project, install the pipeline::
378+
379+
source .venv/bin/activate
380+
pip install android-inspector
381+
329382
Database
330383
^^^^^^^^
331384

docs/policies.rst

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,43 @@ Accepted values for the alert level:
9191
- ``warning``
9292
- ``error``
9393

94+
Creating Scorecard Thresholds Files
95+
-----------------------------------
96+
97+
A valid scorecard thresholds file is required to **enable OpenSSF Scorecard compliance features**.
98+
99+
The scorecard thresholds file, by default named ``policies.yml``, is a **YAML file** with a
100+
structure similar to the following:
101+
102+
.. code-block:: yaml
103+
104+
scorecard_score_thresholds:
105+
9.0: ok
106+
7.0: warning
107+
0: error
108+
109+
- In the example above, the keys ``9.0``, ``7.0``, and ``0`` are numeric threshold values
110+
representing **minimum scorecard scores**.
111+
- The values ``error``, ``warning``, and ``ok`` are the **compliance alert levels** that
112+
will be triggered if the project's scorecard score meets or exceeds the
113+
corresponding threshold.
114+
- The thresholds must be listed in **strictly descending order**.
115+
116+
How it works:
117+
118+
- If the scorecard score is **9.0 or above**, the alert is **``ok``**.
119+
- If the scorecard score is **7.0 to 8.9**, the alert is **``warning``**.
120+
- If the scorecard score is **below 7.0**, the alert is **``error``**.
121+
122+
You can adjust the threshold values and alert levels to match your organization's
123+
security compliance requirements.
124+
125+
Accepted values for the alert level:
126+
127+
- ``ok``
128+
- ``warning``
129+
- ``error``
130+
94131
App Policies
95132
------------
96133

docs/rest-api.rst

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,31 @@ Data:
518518
"license_clarity_compliance_alert": "warning"
519519
}
520520
521+
.. _rest_api_scorecard_compliance:
522+
523+
Scorecard Compliance
524+
^^^^^^^^^^^^^^^^^^^^
525+
526+
This action returns the **scorecard compliance alert** for a project.
527+
528+
The scorecard compliance alert is a single value (``ok``, ``warning``, or ``error``)
529+
that summarizes the project's **OpenSSF Scorecard security compliance status**,
530+
based on the thresholds defined in the ``policies.yml`` file.
531+
532+
``GET /api/projects/6461408c-726c-4b70-aa7a-c9cc9d1c9685/scorecard_compliance/``
533+
534+
Data:
535+
- ``scorecard_compliance_alert``: The overall scorecard compliance alert
536+
for the project.
537+
538+
Possible values: ``ok``, ``warning``, ``error``.
539+
540+
.. code-block:: json
541+
542+
{
543+
"scorecard_compliance_alert": "warning"
544+
}
545+
521546
Reset
522547
^^^^^
523548

docs/tutorial_license_policies.rst

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,51 @@ The ``license_clarity_compliance_alert`` value (e.g., ``"error"``, ``"warning"``
128128
is computed automatically based on the thresholds you configured and reflects the
129129
overall license clarity status of the scanned codebase.
130130

131+
Scorecard Compliance Thresholds and Alerts
132+
------------------------------------------
133+
134+
ScanCode.io also supports **OpenSSF Scorecard compliance thresholds**, allowing you to enforce
135+
minimum security standards for open source packages in your codebase. This is managed
136+
through the ``scorecard_score_thresholds`` section in your ``policies.yml`` file.
137+
138+
Defining Scorecard Thresholds
139+
-----------------------------
140+
141+
Add a ``scorecard_score_thresholds`` section to your ``policies.yml`` file, for example:
142+
143+
.. code-block:: yaml
144+
145+
scorecard_score_thresholds:
146+
9.0: ok
147+
7.0: warning
148+
0: error
149+
150+
Scorecard Compliance in Results
151+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
152+
153+
When you run a the addon pipeline fetch_scores with scorecard thresholds defined in your
154+
``policies.yml``, the computed scorecard compliance alert is included in the project's
155+
``extra_data`` field.
156+
157+
For example:
158+
159+
.. code-block:: json
160+
161+
"extra_data": {
162+
"md5": "d23df4a4",
163+
"sha1": "3e9b61cc98c",
164+
"size": 3095,
165+
"sha256": "abacfc8bcee59067",
166+
"sha512": "208f6a83c83a4c770b3c0",
167+
"filename": "cuckoo_filter-1.0.6.tar.gz",
168+
"sha1_git": "3fdb0f82ad59",
169+
"scorecard_compliance_alert": "warning"
170+
}
171+
172+
The ``scorecard_compliance_alert`` value (e.g., ``"error"``, ``"warning"``, or ``"ok"``)
173+
is computed automatically based on the thresholds you configured and reflects the
174+
overall security compliance status of the OpenSSF Scorecard scores for packages in the scanned codebase.
175+
131176
Run the ``check-compliance`` command
132177
------------------------------------
133178

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ dependencies = [
6060
"extractcode[full]==31.0.0",
6161
"commoncode==32.3.0",
6262
"Beautifulsoup4[chardet]==4.13.4",
63-
"packageurl-python==0.17.2",
63+
"packageurl-python==0.17.3",
6464
# Workaround issue https://github.com/aboutcode-org/scancode.io/issues/1795
6565
"fingerprints==1.2.3",
6666
"normality==2.6.1",

scanpipe/api/views.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -497,6 +497,22 @@ def license_clarity_compliance(self, request, *args, **kwargs):
497497
clarity_alert = project.get_license_clarity_compliance_alert()
498498
return Response({"license_clarity_compliance_alert": clarity_alert})
499499

500+
@action(detail=True, methods=["get"])
501+
def scorecard_compliance(self, request, *args, **kwargs):
502+
"""
503+
Retrieve the scorecard compliance alert for a project.
504+
505+
This endpoint returns the scorecard compliance alert stored in the
506+
project's extra_data.
507+
508+
Example:
509+
GET /api/projects/{project_id}/scorecard_compliance/
510+
511+
"""
512+
project = self.get_object()
513+
scorecard_alert = project.get_scorecard_compliance_alert()
514+
return Response({"scorecard_compliance_alert": scorecard_alert})
515+
500516

501517
class RunViewSet(mixins.RetrieveModelMixin, viewsets.GenericViewSet):
502518
"""Add actions to the Run viewset."""

scanpipe/management/commands/check-compliance.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,12 @@ def check_compliance(self, fail_level):
7777
clarity_alert = self.project.get_license_clarity_compliance_alert()
7878
has_clarity_issue = clarity_alert not in (None, "ok")
7979

80-
total_issues = count + (1 if has_clarity_issue else 0)
80+
scorecard_alert = self.project.get_scorecard_compliance_alert()
81+
has_scorecard_issue = scorecard_alert not in (None, "ok")
82+
83+
total_issues = (
84+
count + (1 if has_clarity_issue else 0) + (1 if has_scorecard_issue else 0)
85+
)
8186

8287
if total_issues and self.verbosity > 0:
8388
self.stderr.write(f"{total_issues} compliance issues detected.")
@@ -92,6 +97,10 @@ def check_compliance(self, fail_level):
9297
self.stderr.write("[license clarity]")
9398
self.stderr.write(f" > {clarity_alert.upper()}")
9499

100+
if has_scorecard_issue:
101+
self.stderr.write("[scorecard compliance]")
102+
self.stderr.write(f" > {scorecard_alert.upper()}")
103+
95104
return total_issues > 0
96105

97106
def check_vulnerabilities(self):

scanpipe/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,6 +1554,13 @@ def get_license_clarity_compliance_alert(self):
15541554
"""
15551555
return self.extra_data.get("license_clarity_compliance_alert")
15561556

1557+
def get_scorecard_compliance_alert(self):
1558+
"""
1559+
Return the scorecard compliance alert value for the project,
1560+
or None if not set.
1561+
"""
1562+
return self.extra_data.get("scorecard_compliance_alert")
1563+
15571564
def get_license_policy_index(self):
15581565
"""Return the policy license index for this project instance."""
15591566
if policies_dict := self.get_policies_dict():

scanpipe/pipelines/deploy_to_develop.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ def steps(cls):
7676
cls.map_javascript,
7777
cls.map_javascript_symbols,
7878
cls.map_javascript_strings,
79+
cls.get_symbols_from_binaries,
7980
cls.map_elf,
8081
cls.map_macho,
8182
cls.map_winpe,
@@ -197,6 +198,14 @@ def map_javascript_strings(self):
197198
"""Map deployed JavaScript, TypeScript to its sources using string literals."""
198199
d2d.map_javascript_strings(project=self.project, logger=self.log)
199200

201+
def get_symbols_from_binaries(self):
202+
"""Extract symbols from Elf, Mach0 and windows binaries for mapping."""
203+
d2d.extract_binary_symbols(
204+
project=self.project,
205+
options=self.selected_groups,
206+
logger=self.log,
207+
)
208+
200209
@optional_step("Elf")
201210
def map_elf(self):
202211
"""Map ELF binaries to their sources using dwarf paths and symbols."""
@@ -215,8 +224,9 @@ def map_winpe(self):
215224

216225
@optional_step("Go")
217226
def map_go(self):
218-
"""Map Go binaries to their sources using paths."""
227+
"""Map Go binaries to their sources using paths and symbols."""
219228
d2d.map_go_paths(project=self.project, logger=self.log)
229+
d2d.map_go_binaries_with_symbols(project=self.project, logger=self.log)
220230

221231
@optional_step("Rust")
222232
def map_rust(self):

0 commit comments

Comments
 (0)