Skip to content

OpenSSF Best Practices — Self-Attestation Notes

This document mirrors the answers given for the OpenSSF Best Practices Badge questionnaire at https://www.bestpractices.dev/projects/\<PROJECT_ID>. Use it to keep answers in sync with the repo as it evolves. Replace <PROJECT_ID> throughout once the maintainer completes submission.

Criteria reference: https://www.bestpractices.dev/en/criteria/0 Submission date: pending Level achieved: pending


Submission checklist (maintainer action)

  1. Sign in at https://www.bestpractices.dev/ with your GitHub account.
  2. Click "Add new project". Project URL: https://github.com/adamdost-0/linux-update-cds.
  3. Use the answers in the sections below to fill the form (~10 min).
  4. After submission, replace the <PROJECT_ID> placeholder in the README badge line:
    [![OpenSSF Best Practices](https://www.bestpractices.dev/projects/<PROJECT_ID>/badge)](https://www.bestpractices.dev/projects/<PROJECT_ID>)
    
    The README already contains a <!-- TODO: replace after p4-best-practices-badge --> marker on the badge row; swap the placeholder badge for the real one.
  5. Update this doc with submission date and level achieved.

Current README badge (unstaged rewrite already contains):

[![OpenSSF Best Practices](https://img.shields.io/badge/OpenSSF_Best_Practices-pending-lightgrey)](https://www.bestpractices.dev/) <!-- TODO: replace after p4-best-practices-badge -->
Replace with the real badge URL once <PROJECT_ID> is known.


Gap summary (items needing attention before/during submission)

# Criterion Status Action required
1 version_unique — unique version per release ⚠️ Partial No formal releases yet. Tag the first release (v0.1.0) using git tag and gh release create before answering "Met".
2 version_semver — SemVer/CalVer suggested ⚠️ Suggested Adopt SemVer (v0.1.0) for first release; update squad-release.yml.
3 version_tags — git tags for releases ⚠️ Suggested Create annotated git tags for each release (git tag -a v0.1.0 -m "first release").
4 test_most — broad test coverage ⚠️ Partial Only transfer_bundle.py has unit tests. Add smoke tests for reconcile_pulp.py, validate_upstream.py, stage_e2e_runtime.py.
5 tests_are_added — evidence tests followed ⚠️ Partial Recent commits lack dedicated test additions; document test evidence in PR descriptions going forward.
6 dynamic_analysis — dynamic analysis tool ⚠️ Not yet (SUGGESTED) No fuzzing or DAST in place. Silver-level requirement but recommended even at passing. Add bandit for dynamic-context analysis or schedule a DAST scan.
7 dynamic_analysis_enable_assertions — assertions in test builds ⚠️ Not yet (SUGGESTED) Python assert statements are stripped in optimized builds (-O). Consider pytest with assertion rewriting enabled in CI.

Passing-level criteria

Basics

Basic project website content

  • description_goodMet The project website (GitHub repo) succinctly describes the software: "A solution accelerator that stands up a governed, auditable Ubuntu apt mirror on Azure — built on Pulp 3 and deployable to both Azure Commercial and Azure Government with a single parameter flip." Evidence: README.md (working tree), DEPLOYMENT.md.

  • interactMet How to obtain, report bugs, and contribute is documented in README.md and CONTRIBUTING.md. GitHub Issues (with templates in .github/ISSUE_TEMPLATE/) serve as the feedback channel.

  • contributionMet CONTRIBUTING.md fully describes the contribution process (fork → branch → DCO sign-off → PR against main). URL: https://github.com/adamdost-0/linux-update-cds/blob/main/CONTRIBUTING.md

  • contribution_requirementsMet (SUGGESTED → Met) CONTRIBUTING.md § "Code Style" documents language-level conventions: Black + ruff for Python, shellcheck for shell, lowerCamelCase + @description() for Bicep, terraform fmt for Terraform. Pre-commit hooks enforce them automatically.

FLOSS license

  • floss_licenseMet The project is released under Apache License 2.0 — a well-known FLOSS license. Evidence: LICENSE file at repository root.

  • floss_license_osiMet (SUGGESTED → Met) Apache-2.0 is approved by the Open Source Initiative.

  • license_locationMet LICENSE is at the root of the source repository. URL: https://github.com/adamdost-0/linux-update-cds/blob/main/LICENSE

Documentation

  • documentation_basicsMet Comprehensive documentation exists: README.md (quickstart, architecture), DEPLOYMENT.md (full operator guide), docs/runbooks/ (10+ operational runbooks), docs/architecture/.

  • documentation_interfaceMet External interfaces (CLI arguments, env vars, REST endpoints, config keys) are documented in DEPLOYMENT.md, docs/runbooks/local-validation.md, docs/runbooks/low-side-config.md, and inline --help output for all Python automation scripts.

Other

  • sites_httpsMet GitHub.com enforces HTTPS for all repository and download URLs. All container images are distributed via ghcr.io (HTTPS). No HTTP-only download paths exist.

  • discussionMet GitHub Issues are enabled on the public repository. Issues are searchable, addressable by URL, open to new participants, and require no proprietary client software. URL: https://github.com/adamdost-0/linux-update-cds/issues

  • englishMet All documentation, comments, and issue templates are in English. Bug reports and comments in English are accepted.

  • maintainedMet Repository has active commits (most recent: 2025 series). Workflows, security docs, and changelogs are kept current. The project is pre-v1.0 and under active development.


Change Control

Public version-controlled source repository

  • repo_publicMet Repository is publicly readable at https://github.com/adamdost-0/linux-update-cds.

  • repo_trackMet Git tracks all changes with author identity, timestamp, and commit message. Every commit carries a DCO Signed-off-by trailer (enforced by DCO GitHub App per CONTRIBUTING.md).

  • repo_interimMet Regular commits exist between any potential releases; the repo does not contain only final release snapshots.

  • repo_distributedMet (SUGGESTED → Met) Git is used as the VCS; GitHub hosts the canonical remote.

Unique version numbering

  • version_unique ⚠️ Not yet fully met — action required CHANGELOG.md follows Keep a Changelog with an [Unreleased] section, but no formal releases or version tags exist yet. The criterion requires a unique identifier per release intended for users. Action: tag first release as v0.1.0 before answering "Met" on the questionnaire.

  • version_semver ⚠️ Not yet met (SUGGESTED) No releases tagged. Plan to adopt SemVer (vMAJOR.MINOR.PATCH) for all future releases. Document in squad-release.yml once the release workflow is wired up.

  • version_tags ⚠️ Not yet met (SUGGESTED) No git tags exist. Plan to create annotated tags for each release: git tag -a v0.1.0 -m "Release v0.1.0" && git push origin v0.1.0.

Release notes

  • release_notesMet (or N/A for continuous delivery) CHANGELOG.md follows Keep a Changelog and documents changes in human-readable form under [Unreleased]. When formal releases are cut, the [Unreleased] section will be promoted to a versioned entry. N/A may also be selected since the project is a single-deployment accelerator under continuous development. URL: https://github.com/adamdost-0/linux-update-cds/blob/main/CHANGELOG.md

  • release_notes_vulnsN/A No public releases have been made; no CVEs apply to the project results at this time.


Reporting

Bug-reporting process

  • report_processMet Bug reporting is via GitHub Issues with structured templates in .github/ISSUE_TEMPLATE/ (including bug.yml and deployment-failure.yml). URL: https://github.com/adamdost-0/linux-update-cds/issues/new/choose

  • report_trackerMet (SHOULD → Met) GitHub Issues is used as the issue tracker. Labels enforce categorisation via squad-label-enforce.yml workflow.

  • report_responsesMet (or N/A — project too new for historical data) The project is newly public; no bug reports exist in the 2–12 month window. When reports arrive, the maintainer commits to acknowledging them within 5 business days (per SECURITY.md response targets). Select N/A on the questionnaire if no reports have been submitted yet.

  • enhancement_responsesMet (SHOULD; or N/A — no enhancement requests yet) Same as above. Select N/A or Met depending on actual issue history at submission time.

  • report_archiveMet GitHub Issues are publicly archived and searchable. URL: https://github.com/adamdost-0/linux-update-cds/issues?q=

Vulnerability report process

  • vulnerability_report_processMet SECURITY.md at the repository root documents the full vulnerability reporting process, including the GitHub Security Advisories channel, response targets, scope, and safe harbour. URL: https://github.com/adamdost-0/linux-update-cds/blob/main/SECURITY.md

  • vulnerability_report_privateMet GitHub Security Advisories (private vulnerability reporting) is the designated private channel. No PGP key is needed — GitHub's infrastructure provides end-to-end confidentiality. URL: https://github.com/adamdost-0/linux-update-cds/security/advisories/new

  • vulnerability_report_responseMet (or N/A — no reports yet) No vulnerability reports have been received. When received, initial triage target is 5 business days (per SECURITY.md), well within the 14-day requirement. Select N/A if no reports exist.


Quality

Working build system

  • buildN/A (with justification) The project produces infrastructure-as-code (Bicep, Docker Compose) and Python automation scripts — not compiled binaries. No build step is required to "use" the software. The Bicep pre-commit hook (az bicep build --file ... --stdout) validates template syntax as a quality gate, not a binary build.

  • build_common_toolsN/A (same justification)

  • build_floss_toolsN/A (same justification)

Automated test suite

  • testMet tests/test_transfer_bundle.py — a unittest-based suite for the transfer bundle automation script — is publicly released as FLOSS (Apache-2.0). CI runs it via automation/validate-ci.sh using python3 -m unittest discover -s tests -p "test_*.py" on every PR and push. CONTRIBUTING.md § "Local Validation Before Opening a PR" documents how to run the tests.

  • test_invocationMet (SHOULD → Met) Standard Python invocation: python3 -m unittest discover -s tests -p "test_*.py". Also invokable via bash automation/validate-ci.sh.

  • test_most ⚠️ Partially met (SUGGESTED) test_transfer_bundle.py covers the bundle pack/sign/verify/import flow. Bootstrap scripts reconcile_pulp.py, validate_upstream.py, and stage_e2e_runtime.py are exercised at the integration/E2E level (see docs/evidence/) but lack dedicated unit tests. Recommend adding unit tests for argument parsing and error paths in each script.

  • test_continuous_integrationMet (SUGGESTED → Met) squad-ci.yml runs on every PR and push to main. It invokes validate-ci.sh which includes the Python test suite, syntax checks, and secrets hygiene. codeql.yml runs on every push to main and weekly.

New functionality testing

  • test_policyMet CONTRIBUTING.md § "Tests" states: "Add or update tests under tests/ for any logic change. New bootstrap scripts must include a smoke test that at minimum runs --help and validates argument parsing."

  • tests_are_added ⚠️ Partially met test_transfer_bundle.py demonstrates the policy being followed for transfer_bundle.py. The most recent significant changes (gitleaks integration, pre-commit hooks, Bicep modules) are primarily infrastructure/tooling changes where test additions are documented as N/A or covered by CI gating. Maintainer should ensure future PRs include test evidence in the PR description.

  • tests_documented_addedMet (SUGGESTED → Met) Test policy is explicitly documented in CONTRIBUTING.md § "Tests".

Warning flags

  • warningsMet Multiple linter/checker tools are enabled:
  • Python: ruff (rules: E, F, I, B, UP, S, RUF) + black (formatting) — enforced via pre-commit and CI.
  • Shell: shellcheck — enforced via pre-commit.
  • Bicep: az bicep build syntax validation — enforced via pre-commit. Evidence: .pre-commit-config.yaml, pyproject.toml [tool.ruff.lint].

  • warnings_fixedMet Pre-commit hooks block commits with unfixed warnings. CI (validate-ci.sh) enforces the same. The ruff --fix flag auto-fixes safe issues; remaining violations must be resolved before merge.

  • warnings_strictMet (SUGGESTED → Met) ruff is configured with security rules (S), bug detection (B), and upgrade suggestions (UP). shellcheck uses default strict mode. Bicep build with --stdout validates all template structures.


Security

Secure development knowledge

  • know_secure_designMet The project is designed for FedRAMP High / DoD IL4–IL6 air-gapped environments. Design decisions reflect secure-by-default principles: Managed Identity over credentials, private endpoints only, CMK encryption, TLS 1.2+ minimum, no public IPs. Evidence: docs/architecture/, DEPLOYMENT.md, .github/copilot-instructions.md (security baseline section).

  • know_common_errorsMet SECURITY.md documents known vulnerability classes and mitigations. The project explicitly addresses: credential leakage (gitleaks, pre-commit, no hardcoded secrets), injection (input validation in Python scripts, shellcheck), MITM (HTTPS-only, private endpoints), and broken crypto (TLS 1.2+ mandated, no MD5/RC4).

Use basic good cryptographic practices

  • crypto_publishedMet (or N/A — project does not implement crypto) The project delegates all cryptography to Azure platform services and Python's standard library (ssl, hashlib). TLS (via HTTPS) and SSH are the only protocols used — both are publicly published and reviewed.

  • crypto_callMet (N/A applicable — project is not a crypto library) No custom crypto implementations. All cryptographic functions are performed by Azure services, Python ssl/hashlib, and OpenSSL.

  • crypto_flossMet (N/A applicable) All cryptographic dependencies (Python ssl, OpenSSL, Azure SDK) are FLOSS-implementable.

  • crypto_keylengthMet (N/A applicable) TLS 1.2+ minimum is enforced throughout (DEPLOYMENT.md, Bicep configurations). Azure Key Vault defaults to RSA-2048 / AES-256, both NIST-approved through 2030+. The project explicitly rejects weaker configurations.

  • crypto_workingMet (N/A applicable) No broken algorithms (MD4, MD5, RC4, single-DES) are used. SECURITY.md explicitly prohibits them. SHA-256+ and AES-256 are the project defaults.

  • crypto_weaknessesMet (SHOULD; N/A applicable) SHA-1 and CBC-mode SSH are not used. TLS 1.2+ with ECDHE key exchange is the minimum.

  • crypto_pfsN/A The project is an infrastructure automation tool, not a protocol implementation. PFS is provided by the underlying TLS stack (Azure HTTPS / ECDHE cipher suites).

  • crypto_password_storageN/A The project does not store user passwords. Authentication is delegated to Azure AD (Managed Identity / Service Principal) and to Pulp's upstream auth stack. The Pulp admin password is stored in Azure Key Vault (a secret vault, not a custom hash store).

  • crypto_randomN/A The project does not generate cryptographic keys or nonces directly. All key generation is delegated to Azure Key Vault (az keyvault secret set, RSA key generation) and the Azure platform.

Secured delivery against man-in-the-middle (MITM) attacks

  • delivery_mitmMet The project is distributed via GitHub (HTTPS). Container images are distributed via GHCR (HTTPS). The documented image build pattern (az acr build) runs inside Azure, avoiding public-internet pushes from the operator workstation.

  • delivery_unsignedMet No checksums are retrieved over plain HTTP and used without signature verification. All package downloads use HTTPS (GitHub, PyPI in the connected environment). The .gitleaks.toml and pre-commit configuration ensure no unsigned HTTP download scripts are introduced.

Publicly known vulnerabilities fixed

  • vulnerabilities_fixed_60_daysMet No publicly known unpatched CVEs of medium or higher severity exist for the project's own source code. Dependency vulnerabilities are monitored via GitHub Dependabot and CodeQL.

  • vulnerabilities_critical_fixedMet (SHOULD → Met) SECURITY.md commits to fixing critical vulnerabilities rapidly after triage. Response timeline is communicated to the reporter after initial triage (≤5 business days).

Other security issues

  • no_leaked_credentialsMet
  • gitleaks.yml workflow scans every push and PR against main using gitleaks-action (pinned SHA ff98106e4c7b2bc287b24eaf42907196329070c7) and project-specific .gitleaks.toml.
  • pre-commit hook (gitleaks at v8.30.1) blocks commits locally.
  • squad-ci.yml runs additional regex-based secret pattern detection on every PR.
  • No private keys, passwords, or tokens exist in any tracked files per git ls-files audit.

Analysis

Static code analysis

  • static_analysisMet Multiple static analysis tools are applied before any release:
  • CodeQL (codeql.yml) — GitHub's semantic code analysis for Python, using security-extended and security-and-quality query suites. Runs on every push to main, every PR, and weekly on schedule.
  • ruff — Python linter with security rules (S-prefix, bandit-equivalent).
  • shellcheck — Static analysis for all shell scripts. All three run in CI on every PR.

  • static_analysis_common_vulnerabilitiesMet (SUGGESTED → Met)

  • CodeQL security-extended queries cover OWASP Top 10 and CWE-mapped vulnerability classes for Python (injection, path traversal, insecure deserialization, etc.).
  • ruff S-rules map to bandit checks (hardcoded passwords, subprocess injection, assert removal, etc.).

  • static_analysis_fixedMet (or N/A — no findings to date) CI blocks merges when static analysis findings are present. CodeQL findings are surfaced as PR annotations and must be resolved or dismissed with justification before merge.

  • static_analysis_oftenMet (SUGGESTED → Met) Static analysis (ruff via pre-commit) runs on every commit locally. CodeQL and ruff run on every PR and push to main in CI. CodeQL also runs weekly on schedule.

Dynamic code analysis

  • dynamic_analysis ⚠️ Not yet met (SUGGESTED) No dynamic analysis tool (fuzzer, DAST, runtime instrumentation) is currently applied before releases. This is a SUGGESTED criterion at passing level. Recommendation for a future sprint:
  • Add pytest-hypothesis for property-based testing of Python argument parsing and bundle operations.
  • Add bandit as a runtime dynamic context check.
  • For silver level: add OWASP ZAP or a similar DAST scanner against the Pulp API.

  • dynamic_analysis_unsafeN/A The project produces Python scripts and Bicep/YAML infrastructure templates. Python is a memory-safe language; no C/C++ code exists in the repository.

  • dynamic_analysis_enable_assertions ⚠️ Not yet configured (SUGGESTED) Python assert statements are used in test files. pytest rewrites assertions for detailed output. However, no explicit assertion-heavy test configuration is documented. Recommendation: add pytest to the test infrastructure and document assertion-enabled test runs in CI.

  • dynamic_analysis_fixedN/A No dynamic analysis tool is in use; no dynamic analysis findings exist.


Badge markdown (paste into README once PROJECT_ID is known)

[![OpenSSF Best Practices](https://www.bestpractices.dev/projects/<PROJECT_ID>/badge)](https://www.bestpractices.dev/projects/<PROJECT_ID>)

Replace the existing placeholder badge line in README.md:

[![OpenSSF Best Practices](https://img.shields.io/badge/OpenSSF_Best_Practices-pending-lightgrey)](https://www.bestpractices.dev/) <!-- TODO: replace after p4-best-practices-badge -->

Attestation record

Field Value
Project URL https://github.com/adamdost-0/linux-update-cds
License Apache-2.0
Badge level targeted Passing
Submission date pending
Project ID assigned pending
Attested by maintainer GitHub username
Last reviewed 2025-07