-
-
Notifications
You must be signed in to change notification settings - Fork 0
Security and Maturity Self Assessment
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.
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.
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/SUGGESTEDcriterion 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/Awith the justification given here. -
Partial — a
SUGGESTED(never aMUST) criterion only partly satisfied; noted honestly. Neither blocks the badge. - Unmet — none.
Legend in the tables below: M = MUST, S = SHOULD, · = SUGGESTED.
| 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. |
| 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 asX.Y.Z-betacannot be the shipped numeric version. The scheme is documented and monotonic, so at registration this SUGGESTED item can reasonably be answeredMetwith that justification. It is recorded here asPartialonly to be precise that it is not literally SemVer/CalVer.
| 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 advisories — SECURITY.md. |
| vulnerability_report_response | M | Met | SECURITY.md: "An initial response within a few days" — within the required ≤ 14 days. |
| ID | Lvl | Status | Evidence |
|---|---|---|---|
| build | M | Met |
dotnet build / dotnet publish — CONTRIBUTING.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 .editorconfig — Review 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 error — Review Gate. |
| 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 error — Review 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 verify — SECURITY.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). |
| 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 actions — Review 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. |
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):
- Crypto — TLS-only fetches; AES-256-GCM secrets at rest; no weak-primitive acceptance (SHA-1 XML-DSig rejected). (Security Model)
- Signed, provenance-bearing releases — a signed SLSA v1.1 Build L3 attestation + MD5/SHA-256 sidecars on every stable release — .github/workflows/build.yml, SECURITY.md.
- SHA-pinned GitHub Actions across all workflows, audited by zizmor — .github/workflows/zizmor.yml.
- OpenSSF Scorecard weekly, publishing to code scanning — .github/workflows/scorecard.yml.
- Dependabot on both NuGet and github-actions, with a 7-day cooldown — .github/dependabot.yml.
-
dependency-review (required,
fail-on-severity: low) + a transitive vulnerable-dependency scan + locked-mode restore — .github/workflows/dependency-review.yml, Review Gate. -
Static analysis applied and gating — CodeQL (
security-extended) + the Opengrep invariant ruleset +--warnaserror. (Review Gate) -
CODEOWNERS-enforced review requests + branch protection on
main— .github/CODEOWNERS. - Trojan-Source / Unicode guard (CVE-2021-42574) — .github/workflows/unicode-guard.yml.
- A written, class-by-class review-gate coverage analysis — Review Gate.
- Documented governance, support, privacy and CRA position — GOVERNANCE.md, SECURITY.md (support window + CRA), docs/PRIVACY.md, docs/SECURITY-REMEDIATION-POLICY.md.
- Coordinated vulnerability handling — private advisory flow.
- Unique version control + immutable, single-use release tags.
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).
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.
| 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.
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.
| 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 |
Registration and self-certification are a maintainer web action, not a code change:
- 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/Aitems with the justifications recorded here). - 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.
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.
Repository · Issues · Releases · Security policy — report vulnerabilities privately, never in a public issue. Pages describe what is implemented today; if the wiki disagrees with the code, the code wins.
Getting started
- Installation
- Provider Setup
- Hardening & Options Reference
- Migrating from 9p4
- Troubleshooting
- Rollback
How it works
Security
- Security Model
- Security Conformance (ASVS / RFC 9700)
- Threat Model
- SSO-Only Login — design record
- Single Logout — design record
Standards & process (internal / maintainer)