Skip to content

Security and Maturity Self Assessment

iderex edited this page Jul 20, 2026 · 1 revision

Security & maturity self-assessment (OpenSSF Best Practices · Silver/Gold · OSPS Baseline)

One continuous self-assessment of this project against the OpenSSF maturity tiers: the OpenSSF Best Practices badge at passing level (Part 1), the controls already in place that reach beyond passing toward Silver/Gold/OSPS (Part 2), and an honest map of the higher tiers — Best Practices Silver and Gold and the OSPS Baseline (L1/L2/L3) — including the criteria a solo, AI-assisted project structurally cannot meet (Part 3), so nothing is implied-met.

This is a maintainer self-assessment and readiness statement, not a claim that any badge has been awarded. A badge is awarded only after the maintainer registers the project and completes the self-certification questionnaire (What the maintainer must do); this repository does not display a real badge ID until then.


Part 1 — OpenSSF Best Practices, passing level

This part maps every criterion of the OpenSSF Best Practices badge (passing level) to the concrete evidence in this repository, so the self-assessment at bestpractices.dev can be filled in honestly and quickly. It also flags the few criteria that are Met (N/A) or Partial, with the reason and, where relevant, how to close the gap.

Status: ready to register. No passing-level MUST is unmet. Two SUGGESTED criteria are Partial, and three criteria are answered N/A with justification — none of which block the badge.

Summary

Passing level has 67 criteria across six categories. Assessment against this repository:

Category Criteria Met Met (N/A) Partial Unmet
Basics 13 13 0 0 0
Change Control 9 8 0 1 0
Reporting 8 8 0 0 0
Quality 13 12 0 1 0
Security 16 14 2 0 0
Analysis 8 7 1 0 0
Total 67 62 3 2 0
  • Met — a MUST/SHOULD/SUGGESTED criterion satisfied by a concrete control in this repo, with the evidence linked below.
  • Met (N/A) — genuinely not applicable to this project; the questionnaire answer is N/A with the justification given here.
  • Partial — a SUGGESTED (never a MUST) criterion only partly satisfied; noted honestly. Neither blocks the badge.
  • Unmet — none.

Legend in the tables below: M = MUST, S = SHOULD, · = SUGGESTED.

Basics

ID Lvl Status Evidence
description_good M Met README.md opening paragraph — one-line description of what the plugin does (SSO for Jellyfin over OIDC / SAML).
interact M Met README.md (Installing, Configuration, Contributing) and CONTRIBUTING.md explain how to obtain and how to give feedback; GitHub Issues is the feedback channel.
contribution M Met CONTRIBUTING.md — full contribution process (issue → branch → tests → PR).
contribution_requirements S Met CONTRIBUTING.md (build/test/format commands, branch naming, own-every-line rule) + .github/pull_request_template.md checklist.
floss_license M Met GNU GPL v3.0 — LICENSE.txt.
floss_license_osi · Met GPL-3.0 is OSI-approved and FSF-approved.
license_location M Met LICENSE.txt at the repository root (standard location; GitHub detects it).
documentation_basics M Met README.md, the Wiki, and Provider Setup.
documentation_interface M Met Provider Setup (per-provider setup), the admin-API usage note in README.md, and the Login Flow page.
sites_https M Met Project site and manifests are served by GitHub / raw.githubusercontent.com over HTTPS/TLS only.
discussion M Met GitHub Issues — searchable, publicly archived discussion of changes and bugs.
english S Met All repository artifacts are in English (see CONTRIBUTING.md styleguide).
maintained M Met Active: regular commits, a released 4.2.x line, an issue-driven flow, and a security-report SLA. Self-attested at registration.

Change control

ID Lvl Status Evidence
repo_public M Met Public Git repository on GitHub.
repo_track M Met Git records what/who/when for every change.
repo_interim M Met PR-only main with interim commits per PR; branches reviewed before release. CONTRIBUTING.md, Review Gate.
repo_distributed · Met Git (distributed VCS).
version_unique M Met Three-part X.Y.Z version scheme, unique per release — CHANGELOG.md, build.yaml.
version_semver · Partial Uses a documented three-part X.Y.Z scheme (breaking / feature / bug-fix-or-security), the Jellyfin-plugin convention — not strict SemVer or CalVer. Monotonic and meaningful, but this SUGGESTED criterion may be answered Met with the justification in CHANGELOG.md, or left unmet. See the note below the table.
version_tags · Met Releases are tagged (X.Y.Z-stable) — see the tag trigger in .github/workflows/publish.yml.
release_notes M Met CHANGELOG.md (human-readable per-release summary) plus auto-generated GitHub release notes (generate_release_notes: true in publish.yml).
release_notes_vulns M Met Security fixes share the Z digit with bug-fixes; CHANGELOG.md documents them with their issue numbers (e.g. the #626 authorization fix in 4.2.1.0).

version_semver note. The shipped version is three-part X.Y.Z; the channel and Jellyfin generation are a suffix on the git tag / release name only. Jellyfin's plugin version field is numeric (it pads to four octets, the fourth carrying only the beta run number), so a SemVer pre-release string such as X.Y.Z-beta cannot be the shipped numeric version. The scheme is documented and monotonic, so at registration this SUGGESTED item can reasonably be answered Met with that justification. It is recorded here as Partial only to be precise that it is not literally SemVer/CalVer.

Reporting

ID Lvl Status Evidence
report_process M Met CONTRIBUTING.md (Reporting Bugs) + issue templates.
report_tracker S Met GitHub Issues.
report_responses M Met Issue-driven flow; the maintainer triages and responds. Self-attested from the issue history at registration.
enhancement_responses S Met Enhancement requests are tracked and triaged as issues with priority: labels.
report_archive M Met GitHub Issues is a public, permanent, searchable archive of reports and responses.
vulnerability_report_process M Met SECURITY.md publishes the reporting process; linked from README.md.
vulnerability_report_private M Met Private reporting via GitHub security advisoriesSECURITY.md.
vulnerability_report_response M Met SECURITY.md: "An initial response within a few days" — within the required ≤ 14 days.

Quality

ID Lvl Status Evidence
build M Met dotnet build / dotnet publishCONTRIBUTING.md, .github/workflows/build.yml.
build_common_tools · Met .NET SDK + MSBuild (common, standard tooling).
build_floss_tools S Met The .NET SDK is FLOSS (MIT); the build needs no proprietary tool.
test M Met xUnit suite SSO-Auth.Tests (FLOSS) + PropertyTests (FsCheck).
test_invocation S Met dotnet test — the standard invocation for .NET.
test_most · Partial A "growing xUnit suite over the security-critical paths" plus property tests and weekly Stryker mutation testing scoped to the SAML/OIDC core — strong on the critical surface, but branch coverage across the whole codebase is not asserted. Honest Partial for this SUGGESTED item.
test_continuous_integration · Met CI builds and tests every PR — .github/workflows/dotnet.yml.
test_policy M Met Policy: a negative test for every fail-closed branch — CONTRIBUTING.md, Review Gate (Correctness).
tests_are_added M Met Recent evidence: e.g. the 4.2.1.0 (#626) fix corrected a test to assert the explicit deny — CHANGELOG.md; PRs add tests with changes.
tests_documented_added · Met The test expectation is documented in CONTRIBUTING.md and the PR template.
warnings M Met TreatWarningsAsErrors (Directory.Build.props) + Roslyn analyzers (Roslynator, Meziantou, StyleCop), severities pinned in .editorconfigReview Gate.
warnings_fixed M Met dotnet build --warnaserror in CI makes any warning a build failure — CONTRIBUTING.md.
warnings_strict · Met AnalysisMode Recommended, AnalysisModeSecurity=All, Security-category rules at errorReview Gate.

Security

ID Lvl Status Evidence
know_secure_design M Met Security-first design and threat model — Threat Model, SSO-Only Login Design; fail-closed principle throughout. Self-attested.
know_common_errors M Met STRIDE threat model and adversarial-review lenses citing ASVS — Threat Model, Review Gate. Self-attested.
crypto_published M Met Standard published protocols/algorithms only: OpenID Connect, SAML 2.0, AES-256-GCM for secret-at-rest — README.md (Security).
crypto_call S Met Crypto is delegated to platform/library code (.NET crypto, Duende IdentityModel OIDC client, AspNetSaml) rather than re-implemented — README.md (Credits).
crypto_floss M Met All crypto is implementable with FLOSS (.NET runtime crypto; the named libraries are FLOSS).
crypto_keylength M Met AES-256-GCM for secrets at rest; TLS key lengths meet NIST minimums. Signature validation rejects weak algorithms.
crypto_working M Met Fail-closed validation rejects SHA-1 (weak) signatures and other broken configurations — README.md (Security), Security Model wiki.
crypto_weaknesses S Met SHA-1-signed assertions are rejected; CA5369-class rules are at errorReview Gate.
crypto_pfs S Met Delivery/download runs over TLS that supports PFS (GitHub). The plugin implements no key-agreement protocol of its own, so no additional PFS obligation applies.
crypto_password_storage M Met (N/A) The plugin performs SSO — user authentication is delegated to the identity provider; it stores no user authentication passwords. IdP client secrets are stored as AES-256-GCM ssoenc:v1: envelopes (not password hashes). Answer N/A with this justification.
crypto_random M Met CSPRNG-only randomness is enforced as an Opengrep repo-invariant — tools/opengrep/rules.yml, Review Gate (Security).
delivery_mitm M Met HTTPS delivery + per-asset .sha256/.md5 sidecars + a signed SLSA v1.1 Build L3 provenance attestation — SECURITY.md, .github/workflows/build.yml.
delivery_unsigned M Met No hashes/keys are fetched over plain HTTP; release verification is checksum + gh attestation verifySECURITY.md.
vulnerabilities_fixed_60_days M Met No medium-or-higher vulnerability is publicly known unpatched > 60 days; security fixes ship immediately and are never batched — SECURITY.md. Self-attested.
vulnerabilities_critical_fixed S Met Security work outranks feature work; fixes released as soon as ready — SECURITY.md.
no_leaked_credentials M Met GitHub secret scanning + push protection enabled; config secrets redacted on export (SecretEnvelope) — SECURITY.md, Review Gate (Secret).

Analysis

ID Lvl Status Evidence
static_analysis M Met CodeQL (security-extended) + Opengrep repo-invariant rules on every PR — .github/workflows/codeql.yml, .github/workflows/opengrep.yml.
static_analysis_common_vulnerabilities · Met CodeQL security-extended runs ~135 taint/dataflow queries across csharp, javascript-typescript, and actionsReview Gate.
static_analysis_fixed M Met Findings are triaged and fixed; CodeQL/analyzer results block or gate merges (e.g. the CA5369 catch-and-fix) — Review Gate.
static_analysis_often · Met CodeQL and Opengrep run on every push and PR (not merely daily) — see the workflow triggers.
dynamic_analysis · Met SharpFuzz coverage-guided fuzzing of the SAML/OIDC parse surface — .github/workflows/fuzz.yml.
dynamic_analysis_unsafe · Met (N/A) C# is a memory-safe language; a memory-safety dynamic tool is not applicable. Answer N/A.
dynamic_analysis_enable_assertions · Met (N/A) No separate assertion-heavy dynamic build is used; the fuzz harness exercises the parse surface directly. SUGGESTED, answered N/A.
dynamic_analysis_fixed M Met Fuzz-surfaced crashes are triaged and fixed like any security finding — SECURITY.md, Review Gate.

Part 2 — Beyond passing: controls already in place (Silver / Gold / OSPS signals)

Several controls exceed the passing level and pre-stage the Silver/Gold badges and the OSPS Baseline. This is the single evidence list the higher-tier map in Part 3 draws on (it is stated once here, not repeated per tier):


Part 3 — Silver, Gold, and OSPS Baseline map

An honest mapping of this project against the higher OpenSSF tiers (Best Practices Silver and Gold) and the OSPS Baseline (L1/L2/L3). Part 1 covers the entry badge and Part 2 lists the controls already in place; this part adds the tiers above, and — the point of it — states plainly the criteria a solo, AI-assisted project structurally cannot meet, so nothing is implied-met.

Three dispositions per criterion: Met (evidence in Part 2), Planned (tracked issue), Structurally N/A (a one-maintainer AI-assisted project cannot meet it; the honest disposition and compensating controls are named).

Read this first — who reviews the code

Human review here is single-maintainer + AI-assisted. The four accounts in .github/CODEOWNERS are the maintainer's own team, not independent auditors — the file says so, and this page repeats it because a badge assessor scanning CODEOWNERS could otherwise misread it as multi-person independent review. There is one person with authority (GOVERNANCE.md). Every criterion below that assumes ≥2 independent humans is dispositioned as Structurally N/A, with the compensating controls named — never quietly checked.

Structurally N/A (one-maintainer, AI-assisted — cannot be met by design)

Tier Criterion Why N/A Compensating controls
Gold bus_factor — "a bus factor of 2 or more" One maintainer Everything to build/test/release is in-repo (reproducible CI, documented pipeline, no private build secrets); GPL-3.0 guarantees the community can fork and continue (this project is such a continuation of the archived 9p4); intent to archive-with-notice rather than go silently stale — see GOVERNANCE.md § Continuity
Gold contributors_unassociated — "at least two unassociated significant contributors" Solo project Same as above; the fork path keeps the project continuable by others
Gold two_person_review — "≥50% of proposed modifications reviewed before release by a person other than the author" Single author; the CODEOWNERS accounts are the maintainer's own AI-assisted team, not independent reviewers The adversarial multi-lens /security-review (independent refute-by-default lenses on every security-touching change — see Review Gate), mutation testing, SAST (CodeQL + the Opengrep invariant ruleset), warnings-as-errors build, and SLSA v1.1 Build L3 provenance stand in for a second human
OSPS Baseline L3 OSPS-QA-07.01 — non-author approval before merge Same as two_person_review Same compensating controls; the merge gate is CI + the adversarial lens review + the maintainer
OSPS Baseline L2/L3 OSPS-AC-03.01 — no admin bypass of required checks Admin-merge is currently used to land on green during the internal gate Tracked as a hardening item in #715 (remove the admin always-bypass, require all gating checks) — not claimed met here

These are disclosed, not worked around. A one-person project has a real bus factor of one; the mitigations reduce the continuity risk, they do not manufacture a second reviewer.

Met (evidence in-repo)

The higher-tier criteria this project already satisfies — crypto, signed provenance-bearing releases, supply-chain hardening, gating static analysis, documented governance/support/privacy/CRA, coordinated vulnerability handling, and immutable single-use release tags — are the controls listed once in Part 2.

Planned (tracked)

Area Criterion Issue
Test coverage test_statement_coverage90 / test_branch_coverage80 (Gold) #718, #713
Reproducible build build_reproducible (Gold) #764
SBOM CycloneDX per release (OSPS-QA-02.02) #729
VEX OpenVEX for triaged/non-exploitable findings #763
Per-file licensing SPDX + copyright headers #747
Sign-off DCO with automated check #746
Required-check hardening remove admin bypass #715
Badge completion Silver/Gold questionnaire fill OpenSSF project 13660

What the maintainer must do

Registration and self-certification are a maintainer web action, not a code change:

  1. Register the project at bestpractices.dev (OpenSSF project 13660) and complete the passing-level self-certification questionnaire, answering each criterion from the evidence in Part 1 (the Partial/N/A items with the justifications recorded here).
  2. Once passing is awarded, continue into the Silver and Gold questionnaires, claiming only the criteria evidenced in Part 2 and disposing of the Structurally N/A ones honestly.

The badge ID is displayed only after the questionnaire is actually filed — this repository claims no awarded badge until then.

Maintenance

Keep this assessment in sync with the controls it cites: when a workflow, policy, or document referenced here changes — or a control lands, or an issue closes — update the matching row or bullet. Never promote a Structurally N/A row to Met without an actual second independent human; the honesty of this page is its whole value. The mapping is only useful if it stays true — the same rule Review Gate states for itself.

Clone this wiki locally