diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4676d54e..6de7ceeb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,22 +8,17 @@ permissions: contents: read jobs: - main: - name: Validate Template with Schema + ci: + name: CI checks runs-on: ubuntu-latest steps: - uses: actions/checkout@v4.2.2 - name: Setup Cue uses: cue-lang/setup-cue@v1.0.0 - with: - cue-version: 0.11.0 - - - name: Validate our security-insights.yml - run: cue vet .github/security-insights.yml schema.cue - - name: Validate template-full.yml - run: cue vet template-full.yml schema.cue + - name: Validate schema.cue + run: make lintcue - - name: Validate template-minimum.yml - run: cue vet template-minimum.yml schema.cue + - name: Validate example files against schema + run: make lintyml diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..a69e0dd0 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +cue_types_gen.go diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..a3319f2b --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +lintcue: + @echo " > Linting CUE schema ..." + @cue eval schema.cue --all-errors --verbose + +lintyml: + @echo " > Linting YAML files ..." + @echo " > Linting .github/security-insights.yml ..." + @cue vet .github/security-insights.yml schema.cue + @echo " > Linting template-full.yml ..." + cue vet template-full.yml schema.cue + @echo " > Linting template-minimum.yml ..." + cue vet template-minimum.yml schema.cue + @echo " > Linting template-multi-repository-project-reuse.yml ..." + cue vet template-multi-repository-project-reuse.yml schema.cue + @echo " > Linting template-multi-repository-project.yml ..." + cue vet template-multi-repository-project.yml schema.cue + +cuegen: + @echo " > Generating types from cue schema ..." + @cue exp gengotypes schema.cue + +PHONY: lintcue lintyml cuegen \ No newline at end of file diff --git a/docs/versioning-policy.md b/docs/versioning-policy.md index f9f07769..ff891496 100644 --- a/docs/versioning-policy.md +++ b/docs/versioning-policy.md @@ -16,6 +16,8 @@ The Security Insights Specification uses a semantic versioning (SemVer) scheme t ## 3. Version Release Process +Whenever a new version of the specification is released, a new version of the ossf/si-tooling project should also be released. + ### 3.1. Major Releases A major release (e.g., from `1.X.X` to `2.X.X`) signifies significant changes that may require a substantial update to the Security Insights specification. Major releases may include: diff --git a/schema.cue b/schema.cue index 0544b728..2c41ade7 100644 --- a/schema.cue +++ b/schema.cue @@ -1,4 +1,5 @@ -//// Definitions //// +package security_insights_spec +@go("si") // this doesn't appropriately override the package name in the generated code currently due to a bug in cue import ( "time" @@ -9,147 +10,303 @@ import ( #Date: time.Format("2006-01-02") #SchemaVersion: =~"^[1-9]+\\.[0-9]+\\.[0-9]+$" +// Assessment represents the results of a security assessment, including comments, evidence, and date. #Assessment: { + + // Notes or commentary about the findings or purpose of the assessment. comment: string + + // The name or identifier of the assessment artifact. name?: string + + // The URL where the assessment report or artifact is located. evidence?: #URL + + // The date the assessment was published. date?: #Date } #Attestation: { + + // The name or identifier of the attestation. name: string + + // A web location where the attestation can be found. location: #URL - "predicate-uri": string + + // A URI to a resource describing the attestation’s predicate or specification. + "predicate-uri": string @go(PredicateURI) + + // Additional context or instructions for using the attestation. comment?: string } #Contact: { + + // The contact person's name. name: string + + // Indicates whether this admin is the first point of contact for inquiries. Only one entry should be marked as primary. primary: bool + + // The entity with which the contact is affiliated, such as a school or employer. affiliation?: string + + // A preferred email address to reach the contact. email?: #Email + + // A social media handle or profile for the contact. social?: string } #License: { + + // A web address where the license can be found. url: #URL + + // The SPDX license expression for the license. expression: string } #Link: { + + // A link to a resource, not restricted to http/s. uri: string + + // Instructions or information about the link. comment: string } -//// Schema //// +// The ProjectRepository object describes a repository that is part of a project, including its name, comment, and URL. +#ProjectRepository: { + // The name or short label of the repository. + name: string + + // Explanation of the repository purpose or contents and its relation to the rest of the project. + comment: string + + // The URL where the repository is hosted. + url: #URL +} + +#SecurityInsights: { + header: #Header + project?: #Project + repository?: #Repository +} + +// The Header object captures high-level metadata about the schema. +#Header: { -header: { - "last-reviewed": #Date - "last-updated": #Date - "schema-version": #SchemaVersion - url: #URL + // The date when the document or data was last reviewed. + "last-reviewed": #Date @go(LastReviewed) + + // The date when the document or data was last updated. + "last-updated": #Date @go(LastUpdated) + + // The version of the schema being used. + "schema-version": #SchemaVersion @go(SchemaVersion) + + // The primary reference URL for this schema’s origin or repository. + url: #URL @go(URL) + + // Additional information about the schema. comment?: string - "project-si-source"?: #URL + + // A URL to the security insights file that contains project information for this file to inherit. + "project-si-source"?: #URL @go(ProjectSISource) } -project?: { +// The Project object describes the overall project, including basic info, documentation links, repositories, vulnerability reporting, and security details. +#Project: { + + // The name of the project. name: string + + // A path to the project’s landing page. This may be a project website, a version control system repository, or a project/organization page in the VCS. homepage?: #URL + + // A URL pointing to a roadmap or schedule for planned features and releases. roadmap?: #URL + + // A URL to information about sponsorships, donations, or other funding topics. funding?: #URL + + // This field is to communicate the relationship between the project and "a legal person, other than a manufacturer, that has the purpose or objective of systematically providing support on a sustained basis for the development of specific products with digital elements, qualifying as free and open-source software and intended for commercial activities, and that ensures the viability of those products" This definition is drawn from the [European Union Cyber Resilience Act, Article 3](https://eur-lex.europa.eu/eli/reg/2024/2847/oj/eng#art_3). steward?: #Link + + // A list of 1 or more individuals who have administrative access to the project's resources. + administrators: [#Contact, ...] @go(,type=[]Contact) - administrators: [#Contact, ...] - - repositories: [{ - name: string - comment: string - url: #URL - }, ...] + // A list of 1 or more repositories that are part of this project, including the repository this file is published in. + repositories: [#ProjectRepository, ...] @go(,type=[]ProjectRepository) + // An object describing how security vulnerabilities can be reported and how they are handled by the project. "vulnerability-reporting": { - "reports-accepted": bool - "bug-bounty-available": bool - "bug-bounty-program"?: #URL + + // Indicates whether this project currently accepts vulnerability reports. + "reports-accepted": bool @go(ReportsAccepted) + + // Specifies whether a bug bounty program is offered. + "bug-bounty-available": bool @go(BugBountyAvailable) + + // Path to a page providing details about any bug bounty program. + "bug-bounty-program"?: #URL @go(BugBountyProgram) + + // Point of contact for reporting vulnerabilities. This may be a single person or a mailgroup. contact?: #Contact + + // Additional comments or instructions about vulnerability reporting. comment?: string - "security-policy"?: #URL - "pgp-key"?: string - "in-scope"?: [...string] - "out-of-scope"?: [...string] - } + // Path to a page containing guidelines for security-related disclosures. + "security-policy"?: #URL @go(SecurityPolicy) + + // The PGP public key for secure communication. + "pgp-key"?: string @go(PGPKey) + // A list of issues or components that are covered by the vulnerability reporting process. + "in-scope"?: [...string] @go(InScope) + + // A list of issues or components not covered by the vulnerability reporting process. + "out-of-scope"?: [...string] @go(OutOfScope) + } @go(VulnerabilityReporting) + + // An object containing references to key documentation URLs. documentation?: { - "detailed-guide"?: #URL - "code-of-conduct"?: #URL - "quickstart-guide"?: #URL - "release-process"?: #URL - "support-policy"?: #URL - "signature-verification"?: #URL + // URL to more extensive or advanced documentation. + "detailed-guide"?: #URL @go(DetailedGuide) + + // URL to the document outlining contributor and user conduct guidelines. + "code-of-conduct"?: #URL @go(CodeOfConduct) + + // URL to a concise guide to basic functionality for new users. + "quickstart-guide"?: #URL @go(QuickstartGuide) + + // URL describing how releases are planned, prepared, and published. + "release-process"?: #URL @go(ReleaseProcess) + + // URL to documentation describing how releases are supported. See [Recommendations for publishing End-of-life dates and support timelines](https://endoflife.date/recommendations) for best practices. + "support-policy"?: #URL @go(SupportPolicy) + + // URL to documentation explaining how to verify digital signatures on assets. + "signature-verification"?: #URL @go(SignatureVerification) } } -repository?: { +// The Repository object specifies repository-related configurations, including status, policies, team members, documentation, license, releases, and security posture. +#Repository: { + + // Indicates the repository’s current [Repo Status](https://repostatus.org). status: "active" | "abandoned" | "concept" | "inactive" | "moved" | "suspended" | "unsupported" | "WIP" + // The main URL for this repository. url: #URL - "accepts-change-request": bool - "accepts-automated-change-request": bool - "bug-fixes-only"?: bool - "no-third-party-packages"?: bool - "core-team": [#Contact, ...] + // Indicates whether the repository currently accepts any change requests. + "accepts-change-request": bool @go(AcceptsChangeRequest) + // Indicates whether the repository accepts automated or machine-generated change requests. + "accepts-automated-change-request": bool @go(AcceptsAutomatedChangeRequest) + + // Specifies whether the repository only accepts bug-fixes and not feature work. + "bug-fixes-only"?: bool @go(BugFixesOnly) + + // Indicates whether the repository universally avoids package dependencies from outside of the project. + "no-third-party-packages"?: bool @go(NoThirdPartyPackages) + + // A list of 1 or more core team members for this repository, such as maintainers or approvers. + "core-team": [#Contact, ...] @go(CoreTeam,type=[]Contact) + + // The license information for this repository. license: #License + // An object describing security-related artifacts, champions, and tooling for the repository. security: { + + // An object describing security assessments for the repository. assessments: { + // Results of the contributor team's assessment of software produced by this repository. self: #Assessment - "third-party"?: [...#Assessment] + + // Results of third-party assessments of software produced by this repository. + "third-party"?: [...#Assessment] @go(ThirdPartyAssessment) } + // A list of core team members who advocate for continuous improvement of security practices. These individuals may take responsibility for security reviews, training, interfacing with stakeholders on security topics, or other similar activities. champions?: [...#Contact] + // A list of objects describing security-related tools used in the repository. tools?: [...{ + + // The name of the tool. name: string + + // The general category or type of the tool. type: "fuzzing" | "container" | "secret" | "SCA" | "SAST" | "other" + + // The version of the tool that is used. version?: string + + // Additional notes about the tool’s usage or configuration. comment?: string - rulesets: ["default"] | [...string] + // The set of rules or configurations applied by the tool. If customization is not enabled, the only value here should be "default". + rulesets: ["default"] | [...string] @go(,type=[]string) + // An object describing how the tool is integrated with the project. integration: { + + // Indicates whether the tool is used in a scheduled process or supports an on-demand. adhoc: bool + + // Indicates whether the tool is used in the continuous integration process. ci: bool + + // Indicates whether the tool is run before or during the release process. release: bool } results: { + + // Results of scheduled or on-demand security scans. adhoc?: #Attestation + + // Results of security scans run in the continuous integration process. ci?: #Attestation + + // Results of security scans run in the build and release process. release?: #Attestation } }] } + // Documentation links for the repository, including links to contributing guides, dependency management policies, governance documents, and review policies. documentation?: { - "contributing-guide"?: #URL - "dependency-management-policy"?: #URL + // URL to a document outlining the process for contributing to the repository. + "contributing-guide"?: #URL @go(ContributingGuide) + // URL to a document outlining the process for managing dependencies in the repository. + "dependency-management-policy"?: #URL @go(DependencyManagementPolicy) + // URL to any governance documents regarding roles, responsibilities, processes, and decision-making. governance?: #URL - "review-policy"?: #URL - "security-policy"?: #URL + // URL to a document outlining the process for reviewing changes to the repository. + "review-policy"?: #URL @go(ReviewPolicy) + // URL with information about the repository's security, including the policy for reporting security vulnerabilities. + "security-policy"?: #URL @go(SecurityPolicy) } + // Release describes the release process for the repository. release?: { - "automated-pipeline": bool - - "distribution-points": [#Link, ...] - + // Indicates if the repository uses an automated release pipeline. + "automated-pipeline": bool @go(AutomatedPipeline) + // A list of 1 or more links describing where the repository’s releases are distributed. This may be the VCS releases page, a package manager, or other distribution points. + "distribution-points": [#Link, ...] @go(DistributionPoints,type=[]Link) + // A URL to the repository’s release changelog. The URL value should include placeholders such as `{version}` if relevant. changelog?: #URL + // Describes the license details specifically for releases. This should be used when the release license differs from the repository license. license?: #License - + // List of attestations for the repository’s releases. attestations?: [...#Attestation] } }