From 04751543110262a2ebe145d874379a78c1031d38 Mon Sep 17 00:00:00 2001 From: dzeusking-dev Date: Fri, 4 Sep 2026 15:36:06 +0200 Subject: [PATCH 1/2] chore: add OpenSSF trust baseline --- .bestpractices.json | 32 ++ .github/workflows/dependency-review.yml | 19 ++ .github/workflows/scorecard.yml | 42 +++ GOVERNANCE.md | 5 + MAINTAINERS.md | 7 + README.md | 388 ++++++++++++------------ SUPPORT.md | 5 + docs/SECURITY-TRUST.md | 11 + security-insights.yml | 57 ++++ 9 files changed, 373 insertions(+), 193 deletions(-) create mode 100644 .bestpractices.json create mode 100644 .github/workflows/dependency-review.yml create mode 100644 .github/workflows/scorecard.yml create mode 100644 GOVERNANCE.md create mode 100644 MAINTAINERS.md create mode 100644 SUPPORT.md create mode 100644 docs/SECURITY-TRUST.md create mode 100644 security-insights.yml diff --git a/.bestpractices.json b/.bestpractices.json new file mode 100644 index 0000000..3b14dc5 --- /dev/null +++ b/.bestpractices.json @@ -0,0 +1,32 @@ +{ + "osps_do_01_01": "Met", + "osps_do_01_01_justification": "Install, usage and safety semantics are documented in README.md and docs/USAGE.md.", + "osps_do_02_01": "Met", + "osps_do_02_01_justification": "Defects use repository issue templates and SUPPORT.md.", + "osps_gv_02_01": "Met", + "osps_gv_02_01_justification": "Public issues and pull requests are enabled.", + "osps_gv_03_01": "Met", + "osps_gv_03_01_justification": "See https://github.com/gexiro-global/forgeguard/blob/main/CONTRIBUTING.md", + "osps_le_02_01": "Met", + "osps_le_02_01_justification": "Apache-2.0 source license.", + "osps_le_02_02": "Met", + "osps_le_02_02_justification": "Release packaging includes the Apache-2.0 license.", + "osps_le_03_01": "Met", + "osps_le_03_01_justification": "See https://github.com/gexiro-global/forgeguard/blob/main/LICENSE", + "osps_le_03_02": "Met", + "osps_le_03_02_justification": "The license is included in source distributions and wheels.", + "osps_qa_01_01": "Met", + "osps_qa_01_01_justification": "Canonical public source: https://github.com/gexiro-global/forgeguard", + "osps_qa_01_02": "Met", + "osps_qa_01_02_justification": "GitHub publishes the repository commit history.", + "osps_qa_02_01": "Met", + "osps_qa_02_01_justification": "Direct dependencies are declared in pyproject.toml.", + "osps_qa_04_01": "N/A", + "osps_qa_04_01_justification": "ForgeGuard is a single-repository project.", + "osps_qa_05_01": "Met", + "osps_qa_05_01_justification": "Generated executables are built in CI and not committed.", + "osps_qa_05_02": "Met", + "osps_qa_05_02_justification": "Tracked images are documentation/brand assets, not executable binaries.", + "osps_vm_02_01": "Met", + "osps_vm_02_01_justification": "See https://github.com/gexiro-global/forgeguard/blob/main/SECURITY.md" +} diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml new file mode 100644 index 0000000..fb481f3 --- /dev/null +++ b/.github/workflows/dependency-review.yml @@ -0,0 +1,19 @@ +name: Dependency review + +on: + pull_request: + +permissions: + contents: read + +jobs: + review: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: Check out repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Review dependency changes + uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v5.0.0 + with: + fail-on-severity: high diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml new file mode 100644 index 0000000..30ecaa3 --- /dev/null +++ b/.github/workflows/scorecard.yml @@ -0,0 +1,42 @@ +name: OpenSSF Scorecard + +on: + branch_protection_rule: + schedule: + - cron: "43 5 * * 3" + push: + branches: [main] + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + contents: read + security-events: write + id-token: write + steps: + - name: Check out repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + - name: Run OpenSSF Scorecard + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 + with: + results_file: results.sarif + results_format: sarif + publish_results: true + - name: Preserve SARIF result + uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 + with: + name: openssf-scorecard-sarif + path: results.sarif + retention-days: 5 + if-no-files-found: error + - name: Upload SARIF to code scanning + uses: github/codeql-action/upload-sarif@cdf488f595d80d6e07e03d4674febd5ab45fa938 # v4.37.9 + with: + sarif_file: results.sarif diff --git a/GOVERNANCE.md b/GOVERNANCE.md new file mode 100644 index 0000000..e663d79 --- /dev/null +++ b/GOVERNANCE.md @@ -0,0 +1,5 @@ +# Governance + +ForgeGuard is maintained by Gexiro Global Enterprises Ltd. The maintainer reviews issues and pull requests, decides scope and releases, and may reject changes that add unauthorized discovery, exploit behavior, state-changing probes or ambiguous PASS conclusions. + +Changes are proposed through GitHub pull requests and must pass CI. The current single-maintainer structure is disclosed in [MAINTAINERS.md](MAINTAINERS.md); no independent review, response-time guarantee or certification is claimed. diff --git a/MAINTAINERS.md b/MAINTAINERS.md new file mode 100644 index 0000000..ba56d32 --- /dev/null +++ b/MAINTAINERS.md @@ -0,0 +1,7 @@ +# Maintainers + +| Maintainer | Role | Contact | +|---|---|---| +| `@dzeusking-dev` | Project owner and release maintainer | [GitHub](https://github.com/dzeusking-dev) | + +Security reports must use [SECURITY.md](SECURITY.md), not public issues. diff --git a/README.md b/README.md index 20796de..41d0262 100644 --- a/README.md +++ b/README.md @@ -1,195 +1,197 @@ -# forgeguard - -[![CI](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml) -[![PyPI](https://img.shields.io/pypi/v/forgeguard.svg)](https://pypi.org/project/forgeguard/) -[![Python](https://img.shields.io/pypi/pyversions/forgeguard.svg)](https://pypi.org/project/forgeguard/) +# forgeguard + +[![CI](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml) +[![PyPI](https://img.shields.io/pypi/v/forgeguard.svg)](https://pypi.org/project/forgeguard/) +[![Python](https://img.shields.io/pypi/pyversions/forgeguard.svg)](https://pypi.org/project/forgeguard/) [![License: Apache-2.0](https://img.shields.io/pypi/l/forgeguard.svg)](https://github.com/gexiro-global/forgeguard/blob/main/LICENSE) -Read-only security posture self-check for one explicitly authorized self-hosted Gitea instance. - -ForgeGuard gives Gitea operators repeatable evidence about version posture, the fixed-version baseline for CVE-2026-27771, anonymous OCI registry-root behavior, and anonymous responses on a small allowlist of repository/API paths. It uses no exploit probes, performs no internet-wide discovery, and does not request private package contents, manifests, or blobs. - -Official product page: [gexiro.com/forgeguard](https://gexiro.com/forgeguard) - -## Supported scope in 0.2.2 - -ForgeGuard 0.2.2 supports self-hosted Gitea. Gitea-specific conclusions require the trusted operator declaration `--product gitea`; a compatible version endpoint or `--known-version` alone does not confirm product identity. - -Forgejo is not supported. An explicit Forgejo version marker overrides a conflicting Gitea declaration and fails safe as unsupported. ForgeGuard does not apply Gitea version or advisory conclusions to that target. - -One invocation accepts one target URL and refuses to run without the operator's `--authorized` affirmation. - -## What it checks - -- Informational product/version evidence. -- CVE-2026-27771 affected/fixed/unknown version posture for operator-confirmed Gitea. -- Anonymous OCI `/v2/` registry-root response posture as an independent observation. -- Repository browsing posture on the allowlisted `/explore/repos` path. -- Anonymous HTTP responses on the two allowlisted repository and user-search API paths. -- Non-overlapping score ownership between the browsing and API observations. -- Markdown and JSON evidence with deterministic scoring and explicit completeness. - -## Evidence and completeness semantics - -- `PASS` means evidence supports only the named checked condition. -- `WARN` or `FAIL` means the named observation produced an actionable result. -- `INFO / UNDETERMINED` means evidence was insufficient or ambiguous. -- If any core check is undetermined, the final assessment is `value: null`, `grade: "N/A"`, `assessed: false` rather than a normal A–F grade. -- HTTP 404, redirects, 429, 5xx and network failures do not become PASS. -- A CVE version result does not prove exploitability, compromise, or data exposure. -- OCI `/v2/` HTTP 200 does not prove access to private packages, manifests, or blobs. -- ForgeGuard does not infer `REQUIRE_SIGNIN_VIEW` or any specific configuration key from HTTP behavior. -- Registration posture is not checked in 0.2.2. - -## What it does not do - -- No mass scanning or target discovery. -- No exploit proof of concept. -- No unauthenticated third-party assessment. -- No private repository, package, blob, manifest, or layer retrieval. -- No state-changing remote requests. -- No AI in scoring. -- No security certification, vulnerability oracle, or guarantee of complete security. - -## Install - -```bash -python -m pip install forgeguard -``` - -Or install the latest source revision: - -```bash -python -m pip install "git+https://github.com/gexiro-global/forgeguard.git" -``` - -For local development: - -```bash -git clone https://github.com/gexiro-global/forgeguard.git -cd forgeguard -python -m pip install -e ".[dev]" -``` - -Raw source-tree execution can inherit metadata from a different installed ForgeGuard distribution. Install the source/editable package before relying on runtime version metadata. - -## Quickstart - -```bash -mkdir -p reports -forgeguard scan \ - --url https://git.example.com \ - --authorized \ - --product gitea \ - --out ./reports/scan_report.md -``` - -Use a version from trusted operator inventory when the authorized version endpoint is intentionally hidden: - -```bash -forgeguard scan \ - --url https://git.example.com/gitea \ - --authorized \ - --product gitea \ - --known-version 1.26.2 \ - --format md,json \ - --out ./reports/scan_report.md -``` - -`--out` names the Markdown artifact. JSON replaces that suffix with `.json`; -ForgeGuard refuses a dual-format invocation if both names resolve to the same file. - -Omitting `--product` keeps the product unknown and prevents a Gitea-specific A–F grade, even if a generic version value is returned. - -Target URLs must use HTTP or HTTPS, include a hostname, and contain no embedded credentials, query, fragment, decoded `.`/`..` segment, or backslash separator at any of eight decoded layers. Excessive nested encoding is refused. Legal subpaths such as `/team/gitea` are preserved. - -## Token handling - -Prefer an environment variable so the token is not placed directly in shell history or process arguments: - -```bash -FORGEGUARD_TOKEN='replace-with-authorized-token' \ - forgeguard scan \ - --url https://git.example.com \ - --authorized \ - --product gitea -``` - -The backward-compatible `--token` option remains available, but ForgeGuard emits a security warning because command-line values may be visible in shell history or process listings. Tokens are used only for the authorized version read and are not included in Markdown or JSON reports. - -## Synthetic before/after - -The synthetic example uses an operator-confirmed Gitea target and explicit 401/403 access-control observations. It does not claim that ForgeGuard tested exploitation or private data access. - -**Before** — Gitea `1.26.1`, within the affected version range: - -```text -Product: gitea 1.26.1 | Score: 80/100 (B) -Summary: critical 0 | high 1 | medium 0 | low 0 | pass 4 -Top action: P1 - Upgrade Gitea to >=1.26.2 -``` - -**After** — Gitea `1.26.2`, at the first fixed release: - -```text -Product: gitea 1.26.2 | Score: 100/100 (A) -Summary: critical 0 | high 0 | medium 0 | low 0 | pass 5 -Top action: None - no FAIL or WARN findings and all core checks were assessed. -``` - -| Finding | Affected version (1.26.1) | First fixed release (1.26.2) | -|---|---|---| -| FG-VER — version evidence | PASS / informational | PASS / informational | -| FG-CVE-27771 — version posture | FAIL / HIGH | PASS | -| FG-SIGNIN / FG-REG / FG-ANON | PASS | PASS | -| Assessment | complete | complete | -| **Score** | **80/100 (B)** | **100/100 (A)** | - -Full mechanically generated artifacts: - -- [Affected version Markdown](examples/scan_report_affected_pre_update.md) -- [Affected version JSON](examples/scan_result_affected_pre_update.json) -- [First fixed release Markdown](examples/scan_report_patched_post_update.md) -- [First fixed release JSON](examples/scan_result_patched_post_update.json) - -## Scoring - -Scoring is deterministic and does not use AI. `FG-VER` is informational. `FG-CVE-27771` is the only finding that penalizes the CVE affected-version condition, so the same version fact is not counted twice. - -Likewise, `FG-SIGNIN` owns only the browser path and `FG-ANON` owns only the API paths, so one HTTP observation cannot be charged twice. - -FAIL findings subtract the full severity weight: critical 40, high 20, medium 10, low 4. WARN findings subtract `int(weight * 0.35)`. A–F grades are emitted only when every core check is assessed. Otherwise the assessment is N/A, not zero and not A. - -The score summarizes only ForgeGuard's limited checks. It is not a complete hardening, exploitability, compromise, registration, or private-artifact assessment. See [Scoring](docs/SCORING.md). - -## Security and ethics - -Run ForgeGuard only on a Gitea instance you own or are explicitly authorized to assess. ForgeGuard uses read-only HTTP GET requests to an exact allowlist and stops at version, root-response, and status-code evidence. - -See [Authorized Use](AUTHORIZED_USE.md), [Security Policy](SECURITY.md), and [Security Model](docs/SECURITY_MODEL.md). - -## Commercial hardening - -Gexiro offers a paid Hardening Report for authorized Gitea operators who want human review of bounded evidence, explicit limitations, prioritized findings, and a practical remediation plan. - -A Remediation Sprint is a separate engagement: scope and acceptance criteria are frozen first, changes begin only after explicit approval, and the result includes before/after verification. Scope expansion, third-party targets, and remote changes require separate written authorization. - -ForgeGuard remains usable as a free OSS CLI without a hosted account or control plane. Heavy SaaS and recurring monitoring are not offered at this stage. - -[Request a scoped ForgeGuard Hardening Report](mailto:contact@gexiro.com?subject=ForgeGuard%20Hardening%20Report) - -## Roadmap - -Forgejo support and registration posture are future, product-specific work and are not implemented in 0.2.2. See [ROADMAP.md](ROADMAP.md). - -## License - -Apache-2.0. See [LICENSE](LICENSE). - -Built and maintained by [Gexiro Global Enterprises Ltd](https://gexiro.com). - -Part of the [Gexiro open-source toolkit](https://github.com/gexiro-global). - -ForgeGuard by Gexiro - -Not affiliated with Gitea, Forgejo, Codeberg, GitHub, or GitLab. +[Security and trust evidence](docs/SECURITY-TRUST.md) documents the project's policies and automated checks. No certification or badge level is claimed. + +Read-only security posture self-check for one explicitly authorized self-hosted Gitea instance. + +ForgeGuard gives Gitea operators repeatable evidence about version posture, the fixed-version baseline for CVE-2026-27771, anonymous OCI registry-root behavior, and anonymous responses on a small allowlist of repository/API paths. It uses no exploit probes, performs no internet-wide discovery, and does not request private package contents, manifests, or blobs. + +Official product page: [gexiro.com/forgeguard](https://gexiro.com/forgeguard) + +## Supported scope in 0.2.2 + +ForgeGuard 0.2.2 supports self-hosted Gitea. Gitea-specific conclusions require the trusted operator declaration `--product gitea`; a compatible version endpoint or `--known-version` alone does not confirm product identity. + +Forgejo is not supported. An explicit Forgejo version marker overrides a conflicting Gitea declaration and fails safe as unsupported. ForgeGuard does not apply Gitea version or advisory conclusions to that target. + +One invocation accepts one target URL and refuses to run without the operator's `--authorized` affirmation. + +## What it checks + +- Informational product/version evidence. +- CVE-2026-27771 affected/fixed/unknown version posture for operator-confirmed Gitea. +- Anonymous OCI `/v2/` registry-root response posture as an independent observation. +- Repository browsing posture on the allowlisted `/explore/repos` path. +- Anonymous HTTP responses on the two allowlisted repository and user-search API paths. +- Non-overlapping score ownership between the browsing and API observations. +- Markdown and JSON evidence with deterministic scoring and explicit completeness. + +## Evidence and completeness semantics + +- `PASS` means evidence supports only the named checked condition. +- `WARN` or `FAIL` means the named observation produced an actionable result. +- `INFO / UNDETERMINED` means evidence was insufficient or ambiguous. +- If any core check is undetermined, the final assessment is `value: null`, `grade: "N/A"`, `assessed: false` rather than a normal A–F grade. +- HTTP 404, redirects, 429, 5xx and network failures do not become PASS. +- A CVE version result does not prove exploitability, compromise, or data exposure. +- OCI `/v2/` HTTP 200 does not prove access to private packages, manifests, or blobs. +- ForgeGuard does not infer `REQUIRE_SIGNIN_VIEW` or any specific configuration key from HTTP behavior. +- Registration posture is not checked in 0.2.2. + +## What it does not do + +- No mass scanning or target discovery. +- No exploit proof of concept. +- No unauthenticated third-party assessment. +- No private repository, package, blob, manifest, or layer retrieval. +- No state-changing remote requests. +- No AI in scoring. +- No security certification, vulnerability oracle, or guarantee of complete security. + +## Install + +```bash +python -m pip install forgeguard +``` + +Or install the latest source revision: + +```bash +python -m pip install "git+https://github.com/gexiro-global/forgeguard.git" +``` + +For local development: + +```bash +git clone https://github.com/gexiro-global/forgeguard.git +cd forgeguard +python -m pip install -e ".[dev]" +``` + +Raw source-tree execution can inherit metadata from a different installed ForgeGuard distribution. Install the source/editable package before relying on runtime version metadata. + +## Quickstart + +```bash +mkdir -p reports +forgeguard scan \ + --url https://git.example.com \ + --authorized \ + --product gitea \ + --out ./reports/scan_report.md +``` + +Use a version from trusted operator inventory when the authorized version endpoint is intentionally hidden: + +```bash +forgeguard scan \ + --url https://git.example.com/gitea \ + --authorized \ + --product gitea \ + --known-version 1.26.2 \ + --format md,json \ + --out ./reports/scan_report.md +``` + +`--out` names the Markdown artifact. JSON replaces that suffix with `.json`; +ForgeGuard refuses a dual-format invocation if both names resolve to the same file. + +Omitting `--product` keeps the product unknown and prevents a Gitea-specific A–F grade, even if a generic version value is returned. + +Target URLs must use HTTP or HTTPS, include a hostname, and contain no embedded credentials, query, fragment, decoded `.`/`..` segment, or backslash separator at any of eight decoded layers. Excessive nested encoding is refused. Legal subpaths such as `/team/gitea` are preserved. + +## Token handling + +Prefer an environment variable so the token is not placed directly in shell history or process arguments: + +```bash +FORGEGUARD_TOKEN='replace-with-authorized-token' \ + forgeguard scan \ + --url https://git.example.com \ + --authorized \ + --product gitea +``` + +The backward-compatible `--token` option remains available, but ForgeGuard emits a security warning because command-line values may be visible in shell history or process listings. Tokens are used only for the authorized version read and are not included in Markdown or JSON reports. + +## Synthetic before/after + +The synthetic example uses an operator-confirmed Gitea target and explicit 401/403 access-control observations. It does not claim that ForgeGuard tested exploitation or private data access. + +**Before** — Gitea `1.26.1`, within the affected version range: + +```text +Product: gitea 1.26.1 | Score: 80/100 (B) +Summary: critical 0 | high 1 | medium 0 | low 0 | pass 4 +Top action: P1 - Upgrade Gitea to >=1.26.2 +``` + +**After** — Gitea `1.26.2`, at the first fixed release: + +```text +Product: gitea 1.26.2 | Score: 100/100 (A) +Summary: critical 0 | high 0 | medium 0 | low 0 | pass 5 +Top action: None - no FAIL or WARN findings and all core checks were assessed. +``` + +| Finding | Affected version (1.26.1) | First fixed release (1.26.2) | +|---|---|---| +| FG-VER — version evidence | PASS / informational | PASS / informational | +| FG-CVE-27771 — version posture | FAIL / HIGH | PASS | +| FG-SIGNIN / FG-REG / FG-ANON | PASS | PASS | +| Assessment | complete | complete | +| **Score** | **80/100 (B)** | **100/100 (A)** | + +Full mechanically generated artifacts: + +- [Affected version Markdown](examples/scan_report_affected_pre_update.md) +- [Affected version JSON](examples/scan_result_affected_pre_update.json) +- [First fixed release Markdown](examples/scan_report_patched_post_update.md) +- [First fixed release JSON](examples/scan_result_patched_post_update.json) + +## Scoring + +Scoring is deterministic and does not use AI. `FG-VER` is informational. `FG-CVE-27771` is the only finding that penalizes the CVE affected-version condition, so the same version fact is not counted twice. + +Likewise, `FG-SIGNIN` owns only the browser path and `FG-ANON` owns only the API paths, so one HTTP observation cannot be charged twice. + +FAIL findings subtract the full severity weight: critical 40, high 20, medium 10, low 4. WARN findings subtract `int(weight * 0.35)`. A–F grades are emitted only when every core check is assessed. Otherwise the assessment is N/A, not zero and not A. + +The score summarizes only ForgeGuard's limited checks. It is not a complete hardening, exploitability, compromise, registration, or private-artifact assessment. See [Scoring](docs/SCORING.md). + +## Security and ethics + +Run ForgeGuard only on a Gitea instance you own or are explicitly authorized to assess. ForgeGuard uses read-only HTTP GET requests to an exact allowlist and stops at version, root-response, and status-code evidence. + +See [Authorized Use](AUTHORIZED_USE.md), [Security Policy](SECURITY.md), and [Security Model](docs/SECURITY_MODEL.md). + +## Commercial hardening + +Gexiro offers a paid Hardening Report for authorized Gitea operators who want human review of bounded evidence, explicit limitations, prioritized findings, and a practical remediation plan. + +A Remediation Sprint is a separate engagement: scope and acceptance criteria are frozen first, changes begin only after explicit approval, and the result includes before/after verification. Scope expansion, third-party targets, and remote changes require separate written authorization. + +ForgeGuard remains usable as a free OSS CLI without a hosted account or control plane. Heavy SaaS and recurring monitoring are not offered at this stage. + +[Request a scoped ForgeGuard Hardening Report](mailto:contact@gexiro.com?subject=ForgeGuard%20Hardening%20Report) + +## Roadmap + +Forgejo support and registration posture are future, product-specific work and are not implemented in 0.2.2. See [ROADMAP.md](ROADMAP.md). + +## License + +Apache-2.0. See [LICENSE](LICENSE). + +Built and maintained by [Gexiro Global Enterprises Ltd](https://gexiro.com). + +Part of the [Gexiro open-source toolkit](https://github.com/gexiro-global). + +ForgeGuard by Gexiro + +Not affiliated with Gitea, Forgejo, Codeberg, GitHub, or GitLab. diff --git a/SUPPORT.md b/SUPPORT.md new file mode 100644 index 0000000..ce47da3 --- /dev/null +++ b/SUPPORT.md @@ -0,0 +1,5 @@ +# Support + +Use [GitHub Issues](https://github.com/gexiro-global/forgeguard/issues) for reproducible defects and usage questions. Include the ForgeGuard and Python versions and a synthetic or redacted reproduction against a system you are authorized to assess. + +Security vulnerabilities belong in a private report under [SECURITY.md](SECURITY.md). Do not publish credentials, private endpoints or third-party data. diff --git a/docs/SECURITY-TRUST.md b/docs/SECURITY-TRUST.md new file mode 100644 index 0000000..aff7c41 --- /dev/null +++ b/docs/SECURITY-TRUST.md @@ -0,0 +1,11 @@ +# Security and trust evidence + +This page is an evidence index, not a certification. The evidence does not prove the project is vulnerability-free, does not establish a SLSA level, and does not imply OpenSSF affiliation or endorsement. Tool output describes observed posture; it is not proof of compromise or absence of compromise. + +- [Security policy](../SECURITY.md), [security model](SECURITY_MODEL.md) and [authorized-use boundary](../AUTHORIZED_USE.md) +- [Contribution process](../CONTRIBUTING.md), [governance](../GOVERNANCE.md), [maintainers](../MAINTAINERS.md) and [support](../SUPPORT.md) +- CI runs lint, format, compile, tests, dependency checks and exact-wheel smoke checks. +- GitHub default CodeQL setup is active; dependency review, Dependabot, secret scanning and OpenSSF Scorecard supplement it. +- Third-party actions are pinned to immutable commit SHAs with version comments. + +The Scorecard badge is intentionally withheld until a successful default-branch run has produced a public API result. `.bestpractices.json` contains evidence-backed automation proposals only; it is not an OpenSSF Best Practices or OSPS Baseline claim. A human must review any badge submission. diff --git a/security-insights.yml b/security-insights.yml new file mode 100644 index 0000000..7465f8e --- /dev/null +++ b/security-insights.yml @@ -0,0 +1,57 @@ +header: + schema-version: 2.2.0 + last-updated: '2026-09-04' + last-reviewed: '2026-09-04' + url: https://raw.githubusercontent.com/gexiro-global/forgeguard/main/security-insights.yml + comment: This single-repository file reports current practices and makes no certification claim. +project: + name: ForgeGuard + homepage: https://gexiro.com/forgeguard + administrators: + - name: dzeusking-dev + affiliation: Gexiro Global Enterprises Ltd. + social: https://github.com/dzeusking-dev + primary: true + documentation: + quickstart-guide: https://github.com/gexiro-global/forgeguard#quickstart + detailed-guide: https://github.com/gexiro-global/forgeguard/blob/main/docs/USAGE.md + code-of-conduct: https://github.com/gexiro-global/forgeguard/blob/main/CODE_OF_CONDUCT.md + support-policy: https://github.com/gexiro-global/forgeguard/blob/main/SUPPORT.md + repositories: + - name: forgeguard + url: https://github.com/gexiro-global/forgeguard + comment: Canonical source and release repository. + vulnerability-reporting: + reports-accepted: true + bug-bounty-available: false + policy: https://github.com/gexiro-global/forgeguard/blob/main/SECURITY.md +repository: + url: https://github.com/gexiro-global/forgeguard + status: active + accepts-change-request: true + accepts-automated-change-request: true + no-third-party-packages: false + core-team: + - name: dzeusking-dev + affiliation: Gexiro Global Enterprises Ltd. + social: https://github.com/dzeusking-dev + primary: true + documentation: + contributing-guide: https://github.com/gexiro-global/forgeguard/blob/main/CONTRIBUTING.md + review-policy: https://github.com/gexiro-global/forgeguard/blob/main/GOVERNANCE.md + security-policy: https://github.com/gexiro-global/forgeguard/blob/main/SECURITY.md + governance: https://github.com/gexiro-global/forgeguard/blob/main/GOVERNANCE.md + dependency-management-policy: https://github.com/gexiro-global/forgeguard/blob/main/docs/SECURITY-TRUST.md + license: + url: https://github.com/gexiro-global/forgeguard/blob/main/LICENSE + expression: Apache-2.0 + release: + changelog: https://github.com/gexiro-global/forgeguard/blob/main/CHANGELOG.md + automated-pipeline: true + distribution-points: + - uri: https://pypi.org/project/forgeguard/ + comment: Published Python package. + security: + assessments: + self: + comment: Maintainer self-assessment only; no independent audit is claimed. From 46b58655def7b72dafb8f1d853be0712d3ab06b4 Mon Sep 17 00:00:00 2001 From: dzeusking-dev Date: Fri, 4 Sep 2026 15:37:17 +0200 Subject: [PATCH 2/2] chore: keep README diff minimal Signed-off-by: Bartosz Joachimiak <262029076+dzeusking-dev@users.noreply.github.com> --- README.md | 388 +++++++++++++++++++++++++++--------------------------- 1 file changed, 194 insertions(+), 194 deletions(-) diff --git a/README.md b/README.md index 41d0262..7f6969c 100644 --- a/README.md +++ b/README.md @@ -1,197 +1,197 @@ -# forgeguard - -[![CI](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml) -[![PyPI](https://img.shields.io/pypi/v/forgeguard.svg)](https://pypi.org/project/forgeguard/) -[![Python](https://img.shields.io/pypi/pyversions/forgeguard.svg)](https://pypi.org/project/forgeguard/) +# forgeguard + +[![CI](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml/badge.svg)](https://github.com/gexiro-global/forgeguard/actions/workflows/ci.yml) +[![PyPI](https://img.shields.io/pypi/v/forgeguard.svg)](https://pypi.org/project/forgeguard/) +[![Python](https://img.shields.io/pypi/pyversions/forgeguard.svg)](https://pypi.org/project/forgeguard/) [![License: Apache-2.0](https://img.shields.io/pypi/l/forgeguard.svg)](https://github.com/gexiro-global/forgeguard/blob/main/LICENSE) [Security and trust evidence](docs/SECURITY-TRUST.md) documents the project's policies and automated checks. No certification or badge level is claimed. - -Read-only security posture self-check for one explicitly authorized self-hosted Gitea instance. - -ForgeGuard gives Gitea operators repeatable evidence about version posture, the fixed-version baseline for CVE-2026-27771, anonymous OCI registry-root behavior, and anonymous responses on a small allowlist of repository/API paths. It uses no exploit probes, performs no internet-wide discovery, and does not request private package contents, manifests, or blobs. - -Official product page: [gexiro.com/forgeguard](https://gexiro.com/forgeguard) - -## Supported scope in 0.2.2 - -ForgeGuard 0.2.2 supports self-hosted Gitea. Gitea-specific conclusions require the trusted operator declaration `--product gitea`; a compatible version endpoint or `--known-version` alone does not confirm product identity. - -Forgejo is not supported. An explicit Forgejo version marker overrides a conflicting Gitea declaration and fails safe as unsupported. ForgeGuard does not apply Gitea version or advisory conclusions to that target. - -One invocation accepts one target URL and refuses to run without the operator's `--authorized` affirmation. - -## What it checks - -- Informational product/version evidence. -- CVE-2026-27771 affected/fixed/unknown version posture for operator-confirmed Gitea. -- Anonymous OCI `/v2/` registry-root response posture as an independent observation. -- Repository browsing posture on the allowlisted `/explore/repos` path. -- Anonymous HTTP responses on the two allowlisted repository and user-search API paths. -- Non-overlapping score ownership between the browsing and API observations. -- Markdown and JSON evidence with deterministic scoring and explicit completeness. - -## Evidence and completeness semantics - -- `PASS` means evidence supports only the named checked condition. -- `WARN` or `FAIL` means the named observation produced an actionable result. -- `INFO / UNDETERMINED` means evidence was insufficient or ambiguous. -- If any core check is undetermined, the final assessment is `value: null`, `grade: "N/A"`, `assessed: false` rather than a normal A–F grade. -- HTTP 404, redirects, 429, 5xx and network failures do not become PASS. -- A CVE version result does not prove exploitability, compromise, or data exposure. -- OCI `/v2/` HTTP 200 does not prove access to private packages, manifests, or blobs. -- ForgeGuard does not infer `REQUIRE_SIGNIN_VIEW` or any specific configuration key from HTTP behavior. -- Registration posture is not checked in 0.2.2. - -## What it does not do - -- No mass scanning or target discovery. -- No exploit proof of concept. -- No unauthenticated third-party assessment. -- No private repository, package, blob, manifest, or layer retrieval. -- No state-changing remote requests. -- No AI in scoring. -- No security certification, vulnerability oracle, or guarantee of complete security. - -## Install - -```bash -python -m pip install forgeguard -``` - -Or install the latest source revision: - -```bash -python -m pip install "git+https://github.com/gexiro-global/forgeguard.git" -``` - -For local development: - -```bash -git clone https://github.com/gexiro-global/forgeguard.git -cd forgeguard -python -m pip install -e ".[dev]" -``` - -Raw source-tree execution can inherit metadata from a different installed ForgeGuard distribution. Install the source/editable package before relying on runtime version metadata. - -## Quickstart - -```bash -mkdir -p reports -forgeguard scan \ - --url https://git.example.com \ - --authorized \ - --product gitea \ - --out ./reports/scan_report.md -``` - -Use a version from trusted operator inventory when the authorized version endpoint is intentionally hidden: - -```bash -forgeguard scan \ - --url https://git.example.com/gitea \ - --authorized \ - --product gitea \ - --known-version 1.26.2 \ - --format md,json \ - --out ./reports/scan_report.md -``` - -`--out` names the Markdown artifact. JSON replaces that suffix with `.json`; -ForgeGuard refuses a dual-format invocation if both names resolve to the same file. - -Omitting `--product` keeps the product unknown and prevents a Gitea-specific A–F grade, even if a generic version value is returned. - -Target URLs must use HTTP or HTTPS, include a hostname, and contain no embedded credentials, query, fragment, decoded `.`/`..` segment, or backslash separator at any of eight decoded layers. Excessive nested encoding is refused. Legal subpaths such as `/team/gitea` are preserved. - -## Token handling - -Prefer an environment variable so the token is not placed directly in shell history or process arguments: - -```bash -FORGEGUARD_TOKEN='replace-with-authorized-token' \ - forgeguard scan \ - --url https://git.example.com \ - --authorized \ - --product gitea -``` - -The backward-compatible `--token` option remains available, but ForgeGuard emits a security warning because command-line values may be visible in shell history or process listings. Tokens are used only for the authorized version read and are not included in Markdown or JSON reports. - -## Synthetic before/after - -The synthetic example uses an operator-confirmed Gitea target and explicit 401/403 access-control observations. It does not claim that ForgeGuard tested exploitation or private data access. - -**Before** — Gitea `1.26.1`, within the affected version range: - -```text -Product: gitea 1.26.1 | Score: 80/100 (B) -Summary: critical 0 | high 1 | medium 0 | low 0 | pass 4 -Top action: P1 - Upgrade Gitea to >=1.26.2 -``` - -**After** — Gitea `1.26.2`, at the first fixed release: - -```text -Product: gitea 1.26.2 | Score: 100/100 (A) -Summary: critical 0 | high 0 | medium 0 | low 0 | pass 5 -Top action: None - no FAIL or WARN findings and all core checks were assessed. -``` - -| Finding | Affected version (1.26.1) | First fixed release (1.26.2) | -|---|---|---| -| FG-VER — version evidence | PASS / informational | PASS / informational | -| FG-CVE-27771 — version posture | FAIL / HIGH | PASS | -| FG-SIGNIN / FG-REG / FG-ANON | PASS | PASS | -| Assessment | complete | complete | -| **Score** | **80/100 (B)** | **100/100 (A)** | - -Full mechanically generated artifacts: - -- [Affected version Markdown](examples/scan_report_affected_pre_update.md) -- [Affected version JSON](examples/scan_result_affected_pre_update.json) -- [First fixed release Markdown](examples/scan_report_patched_post_update.md) -- [First fixed release JSON](examples/scan_result_patched_post_update.json) - -## Scoring - -Scoring is deterministic and does not use AI. `FG-VER` is informational. `FG-CVE-27771` is the only finding that penalizes the CVE affected-version condition, so the same version fact is not counted twice. - -Likewise, `FG-SIGNIN` owns only the browser path and `FG-ANON` owns only the API paths, so one HTTP observation cannot be charged twice. - -FAIL findings subtract the full severity weight: critical 40, high 20, medium 10, low 4. WARN findings subtract `int(weight * 0.35)`. A–F grades are emitted only when every core check is assessed. Otherwise the assessment is N/A, not zero and not A. - -The score summarizes only ForgeGuard's limited checks. It is not a complete hardening, exploitability, compromise, registration, or private-artifact assessment. See [Scoring](docs/SCORING.md). - -## Security and ethics - -Run ForgeGuard only on a Gitea instance you own or are explicitly authorized to assess. ForgeGuard uses read-only HTTP GET requests to an exact allowlist and stops at version, root-response, and status-code evidence. - -See [Authorized Use](AUTHORIZED_USE.md), [Security Policy](SECURITY.md), and [Security Model](docs/SECURITY_MODEL.md). - -## Commercial hardening - -Gexiro offers a paid Hardening Report for authorized Gitea operators who want human review of bounded evidence, explicit limitations, prioritized findings, and a practical remediation plan. - -A Remediation Sprint is a separate engagement: scope and acceptance criteria are frozen first, changes begin only after explicit approval, and the result includes before/after verification. Scope expansion, third-party targets, and remote changes require separate written authorization. - -ForgeGuard remains usable as a free OSS CLI without a hosted account or control plane. Heavy SaaS and recurring monitoring are not offered at this stage. - -[Request a scoped ForgeGuard Hardening Report](mailto:contact@gexiro.com?subject=ForgeGuard%20Hardening%20Report) - -## Roadmap - -Forgejo support and registration posture are future, product-specific work and are not implemented in 0.2.2. See [ROADMAP.md](ROADMAP.md). - -## License - -Apache-2.0. See [LICENSE](LICENSE). - -Built and maintained by [Gexiro Global Enterprises Ltd](https://gexiro.com). - -Part of the [Gexiro open-source toolkit](https://github.com/gexiro-global). - -ForgeGuard by Gexiro - -Not affiliated with Gitea, Forgejo, Codeberg, GitHub, or GitLab. + +Read-only security posture self-check for one explicitly authorized self-hosted Gitea instance. + +ForgeGuard gives Gitea operators repeatable evidence about version posture, the fixed-version baseline for CVE-2026-27771, anonymous OCI registry-root behavior, and anonymous responses on a small allowlist of repository/API paths. It uses no exploit probes, performs no internet-wide discovery, and does not request private package contents, manifests, or blobs. + +Official product page: [gexiro.com/forgeguard](https://gexiro.com/forgeguard) + +## Supported scope in 0.2.2 + +ForgeGuard 0.2.2 supports self-hosted Gitea. Gitea-specific conclusions require the trusted operator declaration `--product gitea`; a compatible version endpoint or `--known-version` alone does not confirm product identity. + +Forgejo is not supported. An explicit Forgejo version marker overrides a conflicting Gitea declaration and fails safe as unsupported. ForgeGuard does not apply Gitea version or advisory conclusions to that target. + +One invocation accepts one target URL and refuses to run without the operator's `--authorized` affirmation. + +## What it checks + +- Informational product/version evidence. +- CVE-2026-27771 affected/fixed/unknown version posture for operator-confirmed Gitea. +- Anonymous OCI `/v2/` registry-root response posture as an independent observation. +- Repository browsing posture on the allowlisted `/explore/repos` path. +- Anonymous HTTP responses on the two allowlisted repository and user-search API paths. +- Non-overlapping score ownership between the browsing and API observations. +- Markdown and JSON evidence with deterministic scoring and explicit completeness. + +## Evidence and completeness semantics + +- `PASS` means evidence supports only the named checked condition. +- `WARN` or `FAIL` means the named observation produced an actionable result. +- `INFO / UNDETERMINED` means evidence was insufficient or ambiguous. +- If any core check is undetermined, the final assessment is `value: null`, `grade: "N/A"`, `assessed: false` rather than a normal A–F grade. +- HTTP 404, redirects, 429, 5xx and network failures do not become PASS. +- A CVE version result does not prove exploitability, compromise, or data exposure. +- OCI `/v2/` HTTP 200 does not prove access to private packages, manifests, or blobs. +- ForgeGuard does not infer `REQUIRE_SIGNIN_VIEW` or any specific configuration key from HTTP behavior. +- Registration posture is not checked in 0.2.2. + +## What it does not do + +- No mass scanning or target discovery. +- No exploit proof of concept. +- No unauthenticated third-party assessment. +- No private repository, package, blob, manifest, or layer retrieval. +- No state-changing remote requests. +- No AI in scoring. +- No security certification, vulnerability oracle, or guarantee of complete security. + +## Install + +```bash +python -m pip install forgeguard +``` + +Or install the latest source revision: + +```bash +python -m pip install "git+https://github.com/gexiro-global/forgeguard.git" +``` + +For local development: + +```bash +git clone https://github.com/gexiro-global/forgeguard.git +cd forgeguard +python -m pip install -e ".[dev]" +``` + +Raw source-tree execution can inherit metadata from a different installed ForgeGuard distribution. Install the source/editable package before relying on runtime version metadata. + +## Quickstart + +```bash +mkdir -p reports +forgeguard scan \ + --url https://git.example.com \ + --authorized \ + --product gitea \ + --out ./reports/scan_report.md +``` + +Use a version from trusted operator inventory when the authorized version endpoint is intentionally hidden: + +```bash +forgeguard scan \ + --url https://git.example.com/gitea \ + --authorized \ + --product gitea \ + --known-version 1.26.2 \ + --format md,json \ + --out ./reports/scan_report.md +``` + +`--out` names the Markdown artifact. JSON replaces that suffix with `.json`; +ForgeGuard refuses a dual-format invocation if both names resolve to the same file. + +Omitting `--product` keeps the product unknown and prevents a Gitea-specific A–F grade, even if a generic version value is returned. + +Target URLs must use HTTP or HTTPS, include a hostname, and contain no embedded credentials, query, fragment, decoded `.`/`..` segment, or backslash separator at any of eight decoded layers. Excessive nested encoding is refused. Legal subpaths such as `/team/gitea` are preserved. + +## Token handling + +Prefer an environment variable so the token is not placed directly in shell history or process arguments: + +```bash +FORGEGUARD_TOKEN='replace-with-authorized-token' \ + forgeguard scan \ + --url https://git.example.com \ + --authorized \ + --product gitea +``` + +The backward-compatible `--token` option remains available, but ForgeGuard emits a security warning because command-line values may be visible in shell history or process listings. Tokens are used only for the authorized version read and are not included in Markdown or JSON reports. + +## Synthetic before/after + +The synthetic example uses an operator-confirmed Gitea target and explicit 401/403 access-control observations. It does not claim that ForgeGuard tested exploitation or private data access. + +**Before** — Gitea `1.26.1`, within the affected version range: + +```text +Product: gitea 1.26.1 | Score: 80/100 (B) +Summary: critical 0 | high 1 | medium 0 | low 0 | pass 4 +Top action: P1 - Upgrade Gitea to >=1.26.2 +``` + +**After** — Gitea `1.26.2`, at the first fixed release: + +```text +Product: gitea 1.26.2 | Score: 100/100 (A) +Summary: critical 0 | high 0 | medium 0 | low 0 | pass 5 +Top action: None - no FAIL or WARN findings and all core checks were assessed. +``` + +| Finding | Affected version (1.26.1) | First fixed release (1.26.2) | +|---|---|---| +| FG-VER — version evidence | PASS / informational | PASS / informational | +| FG-CVE-27771 — version posture | FAIL / HIGH | PASS | +| FG-SIGNIN / FG-REG / FG-ANON | PASS | PASS | +| Assessment | complete | complete | +| **Score** | **80/100 (B)** | **100/100 (A)** | + +Full mechanically generated artifacts: + +- [Affected version Markdown](examples/scan_report_affected_pre_update.md) +- [Affected version JSON](examples/scan_result_affected_pre_update.json) +- [First fixed release Markdown](examples/scan_report_patched_post_update.md) +- [First fixed release JSON](examples/scan_result_patched_post_update.json) + +## Scoring + +Scoring is deterministic and does not use AI. `FG-VER` is informational. `FG-CVE-27771` is the only finding that penalizes the CVE affected-version condition, so the same version fact is not counted twice. + +Likewise, `FG-SIGNIN` owns only the browser path and `FG-ANON` owns only the API paths, so one HTTP observation cannot be charged twice. + +FAIL findings subtract the full severity weight: critical 40, high 20, medium 10, low 4. WARN findings subtract `int(weight * 0.35)`. A–F grades are emitted only when every core check is assessed. Otherwise the assessment is N/A, not zero and not A. + +The score summarizes only ForgeGuard's limited checks. It is not a complete hardening, exploitability, compromise, registration, or private-artifact assessment. See [Scoring](docs/SCORING.md). + +## Security and ethics + +Run ForgeGuard only on a Gitea instance you own or are explicitly authorized to assess. ForgeGuard uses read-only HTTP GET requests to an exact allowlist and stops at version, root-response, and status-code evidence. + +See [Authorized Use](AUTHORIZED_USE.md), [Security Policy](SECURITY.md), and [Security Model](docs/SECURITY_MODEL.md). + +## Commercial hardening + +Gexiro offers a paid Hardening Report for authorized Gitea operators who want human review of bounded evidence, explicit limitations, prioritized findings, and a practical remediation plan. + +A Remediation Sprint is a separate engagement: scope and acceptance criteria are frozen first, changes begin only after explicit approval, and the result includes before/after verification. Scope expansion, third-party targets, and remote changes require separate written authorization. + +ForgeGuard remains usable as a free OSS CLI without a hosted account or control plane. Heavy SaaS and recurring monitoring are not offered at this stage. + +[Request a scoped ForgeGuard Hardening Report](mailto:contact@gexiro.com?subject=ForgeGuard%20Hardening%20Report) + +## Roadmap + +Forgejo support and registration posture are future, product-specific work and are not implemented in 0.2.2. See [ROADMAP.md](ROADMAP.md). + +## License + +Apache-2.0. See [LICENSE](LICENSE). + +Built and maintained by [Gexiro Global Enterprises Ltd](https://gexiro.com). + +Part of the [Gexiro open-source toolkit](https://github.com/gexiro-global). + +ForgeGuard by Gexiro + +Not affiliated with Gitea, Forgejo, Codeberg, GitHub, or GitLab.