Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,14 @@ covcheck: test-cov
exit 0; \
fi

PHONY: test-cov covcheck pkgdocs
PHONY: test-cov covcheck pkgdocs check-spec-examples

# Confirm the spec examples in test_data match the published Security Insights release
SPEC_VERSION ?= v2.2.0
check-spec-examples:
@echo "Comparing test_data/spec-$(SPEC_VERSION) with the Security Insights $(SPEC_VERSION) examples ..."
@for f in v2/si/test_data/spec-$(SPEC_VERSION)/*.yml; do \
curl -sfL "https://raw.githubusercontent.com/ossf/security-insights/$(SPEC_VERSION)/examples/$$(basename $$f)" | diff -q - "$$f" >/dev/null \
|| { echo "$$f differs from the $(SPEC_VERSION) example"; exit 1; }; \
done
@echo "All spec examples match."
4 changes: 2 additions & 2 deletions v2/si/generated_types.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

79 changes: 79 additions & 0 deletions v2/si/spec_examples_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package si

import (
"net/http"
"net/http/httptest"
"os"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// The files in test_data/spec-v2.2.0 are unmodified copies of the examples
// published with Security Insights v2.2.0. Run `make check-spec-examples` to
// confirm they still match.
const specExamplesDir = "test_data/spec-v2.2.0/"

// specParentURL is the project-si-source in the reuse example.
const specParentURL = "https://raw.githubusercontent.com/example/repo/refs/heads/main/security-insights.yml"

func specExample(t *testing.T, name string) []byte {
t.Helper()
data, err := os.ReadFile(specExamplesDir + name)
require.NoError(t, err)
return data
}

func TestLoadSpecExamples(t *testing.T) {
t.Run("minimum", func(t *testing.T) {
si, err := Load(specExample(t, "example-minimum.yml"))
require.NoError(t, err)
require.NotNil(t, si.Project)
require.NotNil(t, si.Repository)
assert.Equal(t, "FooBar", si.Project.Name)
assert.Len(t, si.Project.Repositories, 1)
assert.Equal(t, "active", si.Repository.Status)
})

t.Run("full", func(t *testing.T) {
si, err := Load(specExample(t, "example-full.yml"))
require.NoError(t, err)
require.NotNil(t, si.Project)
require.NotNil(t, si.Repository)
assert.Equal(t, "FooBar", si.Project.Name)
assert.Len(t, si.Project.Repositories, 2)
assert.Equal(t, []string{"broken access control", "other"}, si.Project.VulnerabilityReporting.InScope)
assert.Equal(t, []string{"other"}, si.Project.VulnerabilityReporting.OutOfScope)
assert.Equal(t, "https://github.com/kubernetes/kubernetes", si.Repository.Url.String())
})

t.Run("multi-repository project", func(t *testing.T) {
si, err := Load(specExample(t, "example-multi-repository-project.yml"))
require.NoError(t, err)
require.NotNil(t, si.Project)
assert.Equal(t, "FooBar", si.Project.Name)
assert.Len(t, si.Project.Repositories, 2)
})

t.Run("multi-repository project reuse", func(t *testing.T) {
parent := specExample(t, "example-multi-repository-project.yml")
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, _ *http.Request) {
w.Header().Set("Content-Type", "application/yaml")
_, _ = w.Write(parent)
}))
defer server.Close()

child := string(specExample(t, "example-multi-repository-project-reuse.yml"))
require.Contains(t, child, specParentURL)
child = strings.Replace(child, specParentURL, server.URL, 1)

si, err := Load([]byte(child))
require.NoError(t, err)
require.NotNil(t, si.Project, "project should be inherited from project-si-source")
require.NotNil(t, si.Repository)
assert.Equal(t, "FooBar", si.Project.Name)
assert.Equal(t, "https://example.com/foobar/bar", si.Repository.Url.String())
})
}
156 changes: 156 additions & 0 deletions v2/si/test_data/spec-v2.2.0/example-full.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
header:
schema-version: 2.0.0
last-updated: '2025-03-01'
last-reviewed: '2025-04-01'
url: https://example.com/foo/bar/raw/branch/main/security-insights.yml
comment: |
This file contains all possible information for both project and repository,
though it is not required to include all of this information every time.
Nor is it required to include both a project and repository section if the project
section is intended to be inherited by repositories via header.project-si-source

project:
name: FooBar
homepage: https://example.com
funding: https://example.com/FUNDING.yml
roadmap: https://example.com/roadmap.html
steward:
uri: https://example.com
comment: |
Some description of the relationship between this project and its steward.
administrators:
- name: Joe Dohn
affiliation: Foo
email: joe.bob@email.com
social: https://social.example.com/joebob
primary: true
documentation:
quickstart-guide: https://example.com/quickstart
detailed-guide: https://example.com/user-guide
code-of-conduct: https://example.com/code-of-conduct.html
release-process: https://example.com/release-process
support-policy: https://example.com/support-policy
signature-verification: https://example.com/signature-verification
repositories:
- name: Foo
url: https://example.com/foobar/foo
comment: |
Foo is the core repo for FooBar.
- name: Bar
url: https://example.com/foobar/bar
comment: |
Bar is a subproject repo.
vulnerability-reporting:
reports-accepted: true
bug-bounty-available: true
bug-bounty-program: https://example.com/bugs.html
contact:
name: The security team at FooBar Enterprise provides security support for this project.
email: security@something.com
primary: true
policy: https://example.com/reporting.html
in-scope:
- broken access control
- other
out-of-scope:
- other
pgp-key: |
your-key-here
comment: |
Lorum ipsum...

repository:
url: https://github.com/kubernetes/kubernetes
status: active
bug-fixes-only: false
accepts-change-request: true
accepts-automated-change-request: true
no-third-party-packages: false
core-team:
- name: Alice White
affiliation: Foo Bar
email: alicewhite@example.com
social: https://social.example.com/alicewhite
primary: true
documentation:
contributing-guide: https://example.com/contributing-guide
review-policy: https://example.com/review-policy
security-policy: https://example.com/security-policy.html
governance: https://example.com/governance
dependency-management-policy: https://example.com/dependency-management-policy
license:
url: https://example.com/LICENSE
expression: MIT
release:
changelog: https://example.com/release/{version}#changelog
automated-pipeline: true
attestations:
- name: Release VEX
predicate-uri: https://intoto.VEX
location: https://example.com/release/{version}#vex
comment: Replace {version} with the actual version number for the release you want VEX data for.
- name: Release SBOM
predicate-uri: https://intoto.SPDX
location: https://example.com/release/{version}#spdx
comment: Replace {version} with the actual version number for the release you want an SBOM for.
- name: Maintainer Identity VSA
location: https://example.com/maintainer-identity
predicate-uri: https://slsa.dev/verification_summary/v1
comment: |
This is a VSA that details how trust identities were established for maintainers of the project.
- name: SCA Scan Results
location: https://example.com/test-results#{version}
predicate-uri: https://slsa.dev/test_results/{version}
comment: Results from SCA scan for a specific version
distribution-points:
- uri: https://example.com/foo
comment: GitHub Release Page
- uri: pkg:npm/foobar
comment: NPM Package
license:
url: https://example.com/release/{version}#license
expression: MIT AND Apache-2.0
security:
assessments:
self:
evidence: https://example.com/assessment.html
date: '2021-09-01'
comment: |
foo bar
third-party:
- evidence: https://example.com/artifact.html
date: '2021-09-01'
comment: |
foo bar
champions:
- name: Joe Bob
email: joe.bob@example.com
primary: true
tools:
- name: Dependabot
type: SCA
version: 1.2.3
rulesets:
- built-in
results:
adhoc:
name: Scheduled SCA Scan Results
predicate-uri: https://intoto.SCA
location: https://example.com/release/{version}#SCA
comment: Replace {version} with the actual version number for the release you want VEX data for.
ci:
name: PR SCA Scan Results
predicate-uri: https://intoto.SCA
location: https://example.com/release/{version}#SCA
comment: Replace {version} with the actual version number for the release you want VEX data for.
release:
name: Build & Release SCA Scan Results
predicate-uri: https://intoto.SCA
location: https://example.com/release/{version}#SCA
comment: Replace {version} with the actual version number for the release you want VEX data for.
integration:
adhoc: true
ci: true
release: true
comment: |
foo bar
46 changes: 46 additions & 0 deletions v2/si/test_data/spec-v2.2.0/example-minimum.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
header:
schema-version: 2.0.0
last-updated: '2025-03-01'
last-reviewed: '2025-04-01'
url: https://example.com/foo/bar/raw/branch/main/security-insights.yml
comment: |
This file contains the minimum information for both project and repository.
It not required to include both a project and repository section if the project
section is intended to be inherited by repositories via header.project-si-source

project:
name: FooBar
administrators:
- name: Joe Dohn
affiliation: Foo
email: joe.bob@example.com
social: https://social.example.com/joebob
primary: true
repositories:
- name: Foo
url: https://example.com/foobar/foo
comment: |
Foo is the core repo for FooBar.
vulnerability-reporting:
reports-accepted: true
bug-bounty-available: true

repository:
url: https://example.com/foobar/foo
status: active
accepts-change-request: true
accepts-automated-change-request: true
core-team:
- name: Alice White
affiliation: Foo Bar
email: alicewhite@email.com
social: https://social.example.com/alicewhite
primary: true
license:
url: https://example.com/LICENSE
expression: MIT
security:
assessments:
self:
comment: |
Self assessment has not yet been completed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Repository template for a multi-repository project
# This file would be stored in the https://example.com/foobar/bar repository
header:
schema-version: 2.0.0
last-updated: '2025-03-01'
last-reviewed: '2025-04-01'
url: https://example.com/foo/bar/raw/branch/main/security-insights.yml
project-si-source: https://raw.githubusercontent.com/example/repo/refs/heads/main/security-insights.yml

repository:
url: https://example.com/foobar/bar
status: active
accepts-change-request: true
accepts-automated-change-request: true
core-team:
- name: Alice White
affiliation: Foo Bar
email: alicewhite@email.com
social: https://social.example.com/alicewhite
primary: true
license:
url: https://example.com/LICENSE
expression: MIT
security:
assessments:
self:
comment: |
Self assessment has not yet been completed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Project and repository template for a multi-repository project
# This file would be stored in the https://example.com/foobar/foo repository
# and addressable via https://example.com/foobar/foo/security-insights.yml
header:
schema-version: 2.0.0
last-updated: '2025-03-01'
last-reviewed: '2025-04-01'
url: https://example.com/foo/bar/raw/branch/main/security-insights.yml
comment: |
This file contains the minimum information for both project and repository.
It not required to include both a project and repository section if the project
section is intended to be inherited by repositories via header.project-si-source

project:
name: FooBar
administrators:
- name: Joe Dohn
affiliation: Foo
email: joe.bob@example.com
social: https://social.example.com/joebob
primary: true
repositories:
- name: Foo
url: https://example.com/foobar/foo
comment: |
Foo is the core repo for FooBar.
- name: Bar
url: https://example.com/foobar/bar
comment: |
Bar is also part of the FooBar project.
vulnerability-reporting:
reports-accepted: true
bug-bounty-available: true

repository:
url: https://example.com/foobar/foo
status: active
accepts-change-request: true
accepts-automated-change-request: true
core-team:
- name: Alice White
affiliation: Foo Bar
email: alicewhite@email.com
social: https://social.example.com/alicewhite
primary: true
license:
url: https://example.com/LICENSE
expression: MIT
security:
assessments:
self:
comment: |
Self assessment has not yet been completed.
Loading