discovery-media-player

遵循以下最佳实践的项目将能够自愿的自我认证,并显示他们已经实现了核心基础设施计划(OpenSSF)徽章。

没有一套可以保证软件永远不会有缺陷或漏洞的做法;如果规范或假设是错误的,即使合适的方法也可能失败。也没有哪些做法可以保证一个项目能够维持健康和运作良好的开发者社区。但是,遵循最佳做法可以帮助改善项目的成果。例如,一些做法可以在发布之前进行多人评估,这可以帮助您找到其他难以找到的技术漏洞,并帮助建立信任,并希望不同公司的开发人员之间进行重复的交互。要获得徽章,必须满足所有“必须”和“禁止”的条款,满足所有“应该”条款或有合适的理由,所有“建议”条款必须满足或未满足(至少希望考虑)。欢迎通过 GitHub网站创建问题或提出请求进行反馈。另外还有一个一般讨论邮件列表

如果这是您的项目,请在项目页面上显示您的基准徽章状态!基准徽章状态如下所示: 项目14197的基准徽章等级为baseline-2 以下是如何嵌入基准徽章:
您可以通过将其嵌入到Markdown文件中来显示您的基准徽章状态:
[![OpenSSF Baseline](https://www.bestpractices.dev/projects/14197/baseline)](https://www.bestpractices.dev/projects/14197)
或者将其嵌入到HTML中:
<a href="https://www.bestpractices.dev/projects/14197"><img src="https://www.bestpractices.dev/projects/14197/baseline"></a>


这些是基准等级3的标准。 这些是标准版本 v2026.02.19。

Baseline Series: 基准等级1 基准等级2 基准等级3

        

 基本

  • 常规

    请注意,其他项目可能使用相同的名称。

    Self-hosted document viewer: per-recipient tracked links, reading analytics, live presentation. The core knows nothing about the app hosting it.

    请使用 SPDX许可证表达格式;例子包括“Apache-2.0”,“BSD-2-Clause”,“BSD-3-Clause”,“GPL-2.0+”,“LGPL-3.0 +”,“MIT”和“(BSD-2-Clause OR Ruby)”。
    如果有多种语言,请将它们列为逗号分隔值(可选空格),并将它们从最多到最少使用。如果有长列表,请至少列出前三个最常见的列表。如果没有语言(例如,这是仅文档或仅测试项目),请使用单个字符“ - ”。请使用每种语言的常规大小写,例如“JavaScript”。
    通用平台枚举(CPE)是用于信息技术系统,软件和软件包的结构化命名方案。在报告漏洞时,它可用于多个系统和数据库。

 控制 20/21

  • 控制


    当在CI/CD管道中为作业分配权限时,源代码或配置必须仅分配相应活动所需的最低权限。 [OSPS-AC-04.02]
    配置项目的CI/CD流水线,默认为用户和服务分配最低可用权限,仅在特定任务需要时才提升权限。在某些版本控制系统中,这可以在组织或代码仓库级别实现。如果不行,请在流水线的顶层设置权限。

    Every job is granted the minimum for its activity, and the workflow that publishes is the strictest. release.yml declares permissions: {} at workflow level — no scope at all — then grants per job: the verification job contents: read plus actions: read because it queries the Actions API, the publish job contents: read plus id-token: write for OIDC and nothing else, the announce job contents: write alone to create the Release. ci.yml is contents: read throughout, scorecard.yml read-all. The release pipeline is deliberately split into four jobs with disjoint permissions so that the job holding a write scope is never the job that executes downloaded code.



    接受可信协作者输入的 CI/CD 流水线在流水线中使用该输入之前,必须对其进行清理和验证。 [OSPS-BR-01.04]
    CI/CD 流水线应对显式工作流执行中的所有协作者输入进行清理(引用、转义或在期望值时退出)。虽然协作者通常是可信的,但工作流的手动输入无法经过审查,可能被账户劫持或内部威胁所滥用。

    The only collaborator input this project accepts is the tag on a workflow_dispatch of release.yml and image.yml. It was already not injectable — TAG is read as a shell environment variable, never interpolated with ${{ }} inside a run block, the same rule applied to untrusted input in cla.yml — and it is now validated as well: the first step of the release pipeline, before any repository access, rejects anything that is not the vX.Y.Z form this project tags, and image.yml has carried the same check. Validation is separate from injectability: a typo previously travelled as far as the checkout to fail on a message about a missing ref, and a compromised collaborator account had a free-text field on the workflow that publishes.



    当创建正式发布版本时,该发布版本中的所有资产必须明确关联到发布标识符或资产的其他唯一标识符。 [OSPS-BR-02.02]
    为项目生成的每个软件资产分配唯一的版本标识符,遵循一致的命名约定或编号方案。示例包括SemVer、CalVer或git提交ID。

    Every asset carries the release identifier. The npm tarball is named discovery-media-player-<version>.tgz and is published under that exact version. The container image is pushed on the immutable versioned tag first, with latest promoted afterwards by atomic retag rather than pushed during the build. The GitHub Release is the tag itself, and the CycloneDX SBOM attached to it is named discovery-media-player-<tag>.cdx.json — an SBOM detached from the version it describes describes nothing. CI refuses a tag whose version does not match package.json, and refuses a tag on a commit that is not an ancestor of main.



    项目必须定义管理项目使用的秘密和凭证的策略。该策略应包括存储、访问和轮换秘密和凭证的指南。 [OSPS-BR-07.02]
    记录项目内如何管理和使用秘密和凭证。这应包括如何存储秘密(例如,使用秘密管理工具)、如何控制访问以及如何轮换或更新秘密的详细信息。确保敏感信息不会硬编码在源代码中或存储在版本控制系统中。

    docs/SECURITY-PRACTICES.md defines the policy, and its rule is that the project holds no long-lived secret and does not want one. It tabulates every credential, who holds it and how long it lives: npm publishing held by nobody because OIDC issues an identity per run, GHCR push scoped per job, no signing key at all because Sigstore signs against the workflow identity, and the operator's own secrets which never transit through this project. Storing: never in version control, enforced by tools/secrets-en-clair.mjs in CI and pre-push, with .env.example carrying names and no values. Accessing: the resource list in MAINTAINERS.md, granted only after the vetting policy in the same file. Rotating: a table of triggers, with the standing rule that a leaked credential is revoked first and removed second, because a pushed secret is disclosed and rewriting history does not recall it.



    当项目已发布版本时,项目文档必须包含验证发布资产完整性和真实性的说明。 [OSPS-DO-03.01]
    项目中的说明应包含所使用技术、要运行的命令以及预期输出的信息。如果可能,避免将此文档存储在构建和发布流水线的相同位置,以避免单一漏洞同时危及软件和验证软件完整性的文档。

    docs/VERIFYING-RELEASES.md gives the technology, the commands and the expected output for each asset: npm audit signatures for the package, with the verified registry signature and verified attestation lines a consumer should see; gh attestation verify against the OCI reference for the image, plus docker buildx imagetools inspect to read its embedded SBOM and provenance; and gh release download for the CycloneDX SBOM attached to each GitHub Release. A table states what each check proves and, deliberately, what it does not — a verification that is oversold is worse than none, because it stops people looking further. The document also tells readers to fetch it from a source other than the artifact they are checking.



    当项目已发布版本时,项目文档必须包含验证软件发布作者的预期身份的说明。 [OSPS-DO-03.02]
    预期身份可能采用用于签名的密钥ID、来自sigstore证书的颁发者和身份或其他类似形式。如果可能,避免将此文档存储在构建和发布流水线的相同位置,以避免单一漏洞同时危及软件和验证软件完整性的文档。

    docs/VERIFYING-RELEASES.md carries an explicit identity table for the expected signer. Because publication is signed by a workflow rather than a person, what must match is the Sigstore issuer https://token.actions.githubusercontent.com, the source repository github.com/Juli1artha/discovery-media-player, the workflow .github/workflows/release.yml, and a commit belonging to main — which CI enforces separately by refusing to publish a tag whose commit is not an ancestor. The document states plainly that a signature which verifies but names a different repository or workflow is not this project's release, and that a failing check is handled as an incident through SECURITY.md rather than as a support question.



    当项目已发布版本时,项目文档必须包含关于每个发布版本支持范围和持续时间的描述性声明。 [OSPS-DO-04.01]
    为了传达项目发布的软件资产的支持范围和持续时间,项目应有SUPPORT.md文件、SECURITY.md中的"支持"部分或其他文档,说明支持生命周期,包括每个发布版本的预期支持持续时间、提供的支持类型(例如,错误修复、安全更新)以及获取支持的任何相关策略或程序。

    SECURITY.md states the scope and duration in a table rather than by implication: the latest release is supported for bug fixes and security fixes, anything earlier for neither. The reasoning is given — the project is young, releases are small and frequent, there is one maintainer, and a long-term support branch would be a promise nobody here could keep. It also says what makes the abrupt cutoff workable: upgrading is npm update or a new image tag, and where a database migration is genuinely required, docs/MIGRATIONS.md documents it and the running instance says so rather than degrading silently.



    当项目已发布版本时,项目文档必须提供描述性声明说明何时发布版本或版本将不再接收安全更新。 [OSPS-DO-05.01]
    为了传达安全修复的支持范围和持续时间,项目应有SUPPORT.md或其他文档,说明项目的安全更新策略。

    SECURITY.md says exactly when security updates stop: a version stops receiving them the moment the next release is published. There is no backporting — a fix is delivered as a new release, never as a patch to an older line — so a consumer three versions behind when an advisory lands upgrades to current rather than waiting for a fix on their line. The changelog for each version names the security-relevant changes it carries, so what is gained by moving is visible before moving. The document also commits to changing that table first, before any wider support promise is made elsewhere.



    在活跃期间,项目文档必须有一个策略,要求在授予对敏感资源的提升权限之前审查代码协作者。 [OSPS-GV-04.01]
    在项目文档中发布可执行的策略,要求在授予对敏感资源(例如合并批准或访问秘密)的提升权限之前审查和批准代码协作者。建议审查包括建立可证明的身份血统,例如确认贡献者与已知可信组织的关联。

    MAINTAINERS.md carries a Granting access policy: nobody receives escalated permissions — merge rights on main, repository settings, publishing, or the security mailbox — without being reviewed first, before the grant rather than after. It states what is examined and in what order: a record of merged pull requests over a period long enough to see how the person behaves when they disagree with review (explicitly not a commit count), the CLA already signed, 2FA confirmed rather than assumed, and the smallest grant that does the job, with access to a secret granted per resource rather than as a bundle. Grants are recorded in the same pull request that makes them, and the policy notes the one place it is currently weaker than it reads: with a single maintainer, the person applying it is the person it would be applied to — which is why it was written before anyone is waiting on it.



    当项目已发布版本时,所有编译的已发布软件资产必须附带软件物料清单。 [OSPS-QA-02.02]
    建议在构建时使用经过准确性审查的工具自动生成SBOM。这使用户能够以标准化的方式将此数据与其环境中的其他项目一起提取。

    Both compiled assets ship with an SBOM. The container image is built with sbom: true and provenance: mode=max, so its bill of materials travels as an attestation readable with docker buildx imagetools inspect. The npm package now carries one too: the release workflow generates a CycloneDX SBOM with npm sbom from the same production tree the tarball is published from, verifies it is well-formed CycloneDX with at least one component rather than an empty file, and attaches it to the GitHub Release named discovery-media-player-<tag>.cdx.json. It is generated with --ignore-scripts, because the announcing job is the only one holding contents: write and installing dependencies that execute their own scripts there would hand downloaded code exactly the privilege the four-job split removes. docs/VERIFYING-RELEASES.md tells consumers how to fetch and use it.



    当项目已发布包含多个源代码仓库的版本时,所有子项目必须执行与主代码库一样严格或更严格的安全要求。 [OSPS-QA-04.02]
    项目生成并编译到发布版本中的任何其他子项目代码仓库必须根据相应代码库的状态和意图执行安全要求。除了遵循相应的OSPS基线要求外,这还可能包括要求进行安全审查、确保其没有漏洞以及确保其没有已知的安全问题。

    The project is a single repository. No subproject codebase is compiled into a release, and nothing outside github.com/Juli1artha/discovery-media-player contributes source to the published npm package or container image, so there is no additional codebase whose security requirements could be looser than the primary one.



    在活跃期间,项目文档必须清楚地记录测试何时以及如何运行。 [OSPS-QA-06.02]
    在贡献文档中添加一个章节,说明如何在本地运行测试以及如何在CI/CD管道中运行测试。文档应说明测试的测试内容以及如何解释测试结果。

    CONTRIBUTING.md documents when and how the tests run, in a table naming each of the four benches, the command that invokes it, what it proves that the others cannot, and when it runs — all four on every push and pull request, on Node 22 and 24 for the unit bench. It lists what runs alongside them (lint, typecheck, CodeQL, the blocking dependency-vulnerability check, and the repository's own guards), states that all of it must pass before a pull request can merge and that pull requests are the only way into main, and explains how to read a failure: an ::error:: names your branch, while GARDE NON CONCLUANTE means the guard could not look and the fix is in the guard or its environment, not in your change.



    在活跃期间,项目的文档必须包含一项政策,即对项目生成的软件的所有重大更改都应该在自动化测试套件中添加或更新功能测试。 [OSPS-QA-06.03]
    在贡献文档中添加一个章节,说明添加或更新测试的政策。该政策应说明什么是重大更改以及应该添加或更新哪些测试。

    The policy is CONTRIBUTING.md's stated one rule: a behaviour worth keeping is worth a test that fails without it. It extends to the test's name, which must say which failure it prevents rather than that it tests the happy path — a test that does not will be asked about in review. AGENTS.md repeats it among the conventions that only review enforces. The history shows it applied: the suite stands at 1515 tests across 144 files, and the credential guard added during this badge review shipped with 21 tests of its own, covering both what it catches and what it deliberately lets pass.



    当向主分支提交时,项目的版本控制系统必须在合并之前要求至少一名非作者人工审批更改。 [OSPS-QA-07.01]
    配置项目的版本控制系统,要求在合并到发布分支或主分支之前至少有一名非作者人工审批更改。这可以通过要求拉取请求在合并之前必须由至少另一位协作者审查和批准来实现。

    Not met: this control requires a non-author human approval before merging, and there is one maintainer — every change is authored by the only person who could approve it, and an AI review is not counted as a human one. What already exists is everything around the missing person: the review standards a second maintainer would apply (CONTRIBUTING.md, "How review is conducted"), the vetting path for granting rights (MAINTAINERS.md), and recruiting that person as the public roadmap's first item. https://github.com/Juli1artha/discovery-media-player/blob/main/ROADMAP.md



    当项目发布版本时,项目必须执行威胁建模和攻击面分析,以理解和防护针对系统内关键代码路径、函数和交互的攻击。 [OSPS-SA-03.02]
    威胁建模是一项活动,其中项目查看代码库、相关流程和基础设施、接口、关键组件,并"像黑客一样思考",集思广益探讨系统可能如何被破坏或受到损害。每个识别的威胁都会被列出,以便项目可以考虑如何主动避免或关闭可能出现的任何漏洞/脆弱点。确保为新功能或破坏性更改更新此分析。

    docs/THREAT-MODEL.md is the threat model and attack-surface analysis. It is organised by asset rather than by feature — documents, reading data, host credentials, in descending order of what their loss would cost an operator — because a model arranged by feature reassures its author and finds nothing. It tabulates every entry point an unauthenticated stranger can reach, then works through eight attack paths: reading a document without being its recipient, server-side request forgery through the file proxy (named the highest-value target, with the realised failure mode of a plausible typo widening the guard), taking or spying on a live presentation, crossing the host boundary, XSS against the nonce-based CSP, reaching the database directly, compromising the supply chain, and denial of service. Each names its residual risk, including the ones deliberately left standing — a link forwarded by its legitimate recipient, and compromise of the single maintainer account. It is reviewed when a feature changes what an actor can do or the host contract breaks.



    在活跃期间,软件组件中不影响项目的任何漏洞必须在VEX文档中予以说明,并以不可利用性细节补充漏洞报告。 [OSPS-VM-04.02]
    建立VEX供给源,传达已知漏洞的可利用性状态,包括评估细节或任何阻止易受攻击代码执行的缓解措施。

    There is nothing to account for in a VEX document. npm audit reports zero vulnerabilities across both the production and development trees, so no known vulnerability in a component has been assessed as non-exploitable here, and a VEX statement would have no subject. The policy for when that changes is written down rather than left open: docs/DEPENDENCIES.md states that a finding may be suppressed only as not exploitable in this project — never as won't fix — that the suppression records why the vulnerable path cannot be reached, who decided and when, and that the non-exploitability assessment is published with the release carrying it, in that version's changelog section and alongside the SBOM attached to the GitHub Release, so a consumer scanning our SBOM can distinguish a real exposure from one already assessed.



    在活跃期间,项目文档必须包含一项政策,定义与漏洞和许可证相关的SCA发现的修复阈值。 [OSPS-VM-05.01]
    在项目中记录一项政策,定义与漏洞和许可证相关的SCA发现的修复阈值。包括识别、优先级排序和修复这些发现的流程。

    docs/DEPENDENCIES.md defines the thresholds, and gives each one a reason rather than a number alone. Production tree: no known vulnerability at any severity — it runs on the operator's machine beside their commercial documents and under their credentials, and it holds one dependency, so tolerating anything there would be choosing to ship a known hole in code we can read in full. Development tree: nothing High or Critical — it never leaves the repository, and blocking on a moderate in a test plugin would stall delivery of real fixes for a threat that reaches no instance, while teaching people to route around the check. Licences are held to the same bar: FLOSS and compatible with AGPL-3.0-or-later distribution, and a licence that changes under us is treated as a finding at the same thresholds.



    在活跃期间,项目文档必须包含一项政策,在任何发布之前解决SCA违规问题。 [OSPS-VM-05.02]
    在项目中记录一项政策,在任何发布之前解决适用的软件组成分析结果,并添加状态检查以验证在发布之前符合该政策。

    docs/DEPENDENCIES.md states the release rule: no release goes out carrying a violation of either threshold. It is enforced structurally rather than remembered — the check runs on every commit, a tag can only publish a commit that is an ancestor of main, and every commit on main has passed it. The document also says what happens when an advisory lands against an already-published version: the fix goes out as a release of its own rather than waiting for the next feature, which is consistent with the support policy in SECURITY.md, where a fix is always a new release and never a backport.



    在活跃期间,对项目代码库的所有更改必须根据记录的恶意依赖项和依赖项中已知漏洞的政策自动评估,然后在违规的情况下阻止,除非声明并抑制为不可利用。 [OSPS-VM-05.03]
    在项目的版本控制系统中创建一个状态检查,对代码库的所有更改运行软件组成分析工具。要求状态检查在更改可以合并之前必须通过。

    ci.yml carries a blocking software-composition check on every push and every pull request, evaluated against the documented thresholds and required before merge: npm audit --omit=dev --audit-level=low for the production tree and npm audit --audit-level=high for the development tree, each failing with an error naming which tree breached and pointing at docs/DEPENDENCIES.md. Because pull requests are the only route into main and the check is required, a change introducing a vulnerable or malicious dependency is blocked rather than reported. Suppression is possible only as a recorded non-exploitability assessment, per the policy in the same document. Integrity of what is installed is enforced alongside it: npm ci only, against a committed lockfile carrying an integrity hash per package, with actions pinned to commit SHAs and base images to digests.



    在活跃期间,项目文档必须包含一项政策,定义SAST发现的修复阈值。 [OSPS-VM-06.01]
    在项目中记录一项政策,定义静态应用程序安全测试(SAST)发现的修复阈值。包括识别、优先级排序和修复这些发现的流程。

    docs/SECURITY-PRACTICES.md defines the SAST thresholds in a table: Critical and High must be resolved before the pull request merges and block any release; Medium before the next release, as a fix or a written suppression but never silence; Low and Note triaged within the release cycle and acceptable with a recorded reason. A fourth row overrides the others — any severity in a security-critical path (the file proxy, the access wall, share revocation, the presentation control token, CSP handling) blocks the merge regardless of the tool's own rating, because severity ratings are generic and this codebase is not: a medium in the component that fetches a caller-supplied URL server-side is not a medium here. Suppression is allowed only as not exploitable, with the reason, the decider and the date, and never as a repository-wide rule disablement.



    在活跃期间,对项目代码库的所有更改必须根据记录的安全弱点政策自动评估,并在违规的情况下阻止,除非声明并抑制为不可利用。 [OSPS-VM-06.02]
    在项目的版本控制系统中创建一个状态检查,对代码库的所有更改运行静态应用程序安全测试(SAST)工具。要求状态检查在更改可以合并之前必须通过。

    Every change is automatically evaluated and blocked on violation. CodeQL runs the javascript-typescript security query suites on every pull request and every push to main, is a named required check, and is blocking on the publication path; a weekly scheduled run additionally applies new rules to code that has not changed. Alongside it on the same trigger: ESLint with typescript-eslint, tsc under strict with noUnusedLocals, noUnusedParameters and noFallthroughCasesInSwitch, and the repository's own static guards over the workflow YAML, the Dockerfile, the published surface and every tracked file. Because pull requests are the only way into main and these are required checks, a violation blocks the merge. Suppression is governed by the policy in docs/SECURITY-PRACTICES.md and is available only as a recorded non-exploitability assessment. Current state: zero outstanding findings across all of them.



该数据可在社区数据许可协议 – 许可性,版本 2.0 (CDLA-Permissive-2.0)下获取。这意味着数据接收方可以共享数据,无论是否经过修改,只要数据接收方在共享数据时提供本协议文本。请注明Julien Arthapignet和OpenSSF最佳实践徽章贡献者。

项目徽章条目拥有者: Julien Arthapignet.
最后更新于 2026-08-22 00:19:58 UTC, 最后更新于 2026-08-25 12:37:10 UTC。 最后在 2026-08-22 07:59:01 UTC 获得通过徽章。