mirror of
https://github.com/cozystack/cozystack.git
synced 2026-10-23 03:27:50 +09:00
docs(security): correct scanner, Renovate and support-line claims after internal review
Two internal reviews of the previous commit found that it overstated several controls. Corrections, all verified against the tree and the GitHub API: CodeQL is not a required status check on main — the required checks are pre-commit and E2E Tests — so the questionnaire no longer says it gates merges. SECURITY.md and the security self-assessment already hedged this correctly and the GTR now matches them. Renovate does not cover Helm charts: helm-values is disabled repo-wide because many image refs are assembled by the cozy-lib.image helper rather than written literally in values.yaml. Say so, and say that the curated platform component images are bumped by maintainers per release rather than by a bot. The rewritten supported-versions table narrowed the support window to the latest two minors, which contradicts practice — several 1.x lines receive patch releases concurrently. Restate it as a description of what the project actually does, keyed to active release branches rather than to version numbers. The CVE-scanning pipeline is described more precisely: noise filters run before issue creation, discovery reads direct Go requirements with transitive coverage coming from the filesystem scan, and render-time image refs are a known blind spot. Its SLAs are labelled as targets rather than measured attainment, and the confidentiality claim is narrowed from the whole repository to per-CVE findings and triage state, since the policy documents and scripts hold no vulnerability data and are what actually evidences the control. SBOM and provenance are stated from the build tooling rather than from an issue title: provenance is explicitly disabled and SBOM generation is implemented but defaulted off. zizmor is added as a third gating scanner in both documents. Also close markers that repository evidence settles: the in-tree security self-assessment, threat model and incident-response documents; no default audit policy is shipped; and there is no top-level NOTICE file, which is stated as a compliance gap rather than deferred. Fix the phantom OWNERS reference at its source in CONTRIBUTOR_LADDER.md, and add current CI health next to the e2e workflow links so the red nightly run is disclosed rather than discovered. Assisted-By: Claude <noreply@anthropic.com> Signed-off-by: Timur Tukaev <timur.tukaev@aenix.io>
This commit is contained in:
1 parent
be8c6e507f
commit
d30d638575
4 files changed
+35
-24
No files matched your search
@@ -91,7 +91,7 @@ Reviewers have all the rights and responsibilities of a Contributor, plus:
|
||||
|
||||
|
||||
The process of becoming a Reviewer is:
|
||||
1. The contributor is nominated by opening a PR against the appropriate repository, which adds their GitHub username to the OWNERS file for one or more directories.
|
||||
1. The contributor is nominated by opening a PR against the appropriate repository, which adds their GitHub username to `.github/CODEOWNERS` for one or more paths, and to the Reviewers section of `MAINTAINERS.md`.
|
||||
2. At least two members of the team that owns that repository or main directory, who are already Approvers, approve the PR.
|
||||
|
||||
|
||||
|
||||
+16
-13
@@ -7,9 +7,9 @@
|
||||
- **Template Version:** v1.0
|
||||
- **Description:** Cozystack is a free, Apache-2.0 open-source platform and framework for building clouds. It turns a set of bare-metal servers into a system with a native Kubernetes REST API for spawning Kubernetes clusters, Databases-as-a-Service, virtual machines, load balancers, HTTP-caching and other services. It is a CNCF Sandbox project and a Certified Kubernetes distribution.
|
||||
|
||||
> **Status: DRAFT — work in progress.** This questionnaire is being actively completed and reviewed. Everything that can be sourced from the repository has been answered and verified against it; the remaining `[maintainers: …]` markers are of two kinds, and only the first kind blocks submission.
|
||||
> **Status: DRAFT — work in progress.** This questionnaire is being actively completed and reviewed. Answers that repository evidence settles have been written and verified against the tree; the remaining `[maintainers: …]` markers are of two kinds, and only the first kind blocks submission. Some editorial markers are certainly still closable from the tree — reviewers should treat an open marker as "not yet checked" rather than "checked and unanswerable".
|
||||
>
|
||||
> **Substantive gaps — need measurement or a decision, cannot be sourced from the repo:** (1) load/scale test results and tested maximums (nodes, tenants, VMs, PVs) with methodology; (2) whether the project publishes reference SLOs/SLIs or treats them as adopter-defined; (3) measured baseline resource overhead of the platform components; (4) the upgrade→downgrade→upgrade CI matrix and its results; (5) whether platform upgrades trigger Talos node reboots; (6) the security-response-team rotation and diversity policy, which is not documented anywhere today; (7) how much of the organization-wide CVE-scanning pipeline is exposed for TOC review, given that the repository holding it is private by design.
|
||||
> **Substantive gaps — need measurement, publication or a decision:** (1) load/scale test results and tested maximums (nodes, tenants, VMs, PVs) with methodology; (2) whether the project publishes reference SLOs/SLIs or treats them as adopter-defined; (3) measured baseline resource overhead of the platform components; (4) the upgrade→downgrade→upgrade CI matrix and its results; (5) whether platform upgrades trigger Talos node reboots; (6) the security-response-team rotation and diversity policy — a rotating Security Champion role with a 6-month term and a handoff overlap **is** defined in the CVE-scanning pipeline's own governance document, but that document is unpublished, the current holder of the role is unassigned, and nothing about rotation or diversity appears in the public `SECURITY.md`; (7) publication of the CVE-scanning pipeline's policy documents and aggregate reports, without which the SCA answer below is not verifiable by a reviewer outside the organization.
|
||||
>
|
||||
> **Editorial markers** — the rest are requests to link an existing document or confirm a detail, and are resolved as the corresponding docs are located or written.
|
||||
>
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
### Scope
|
||||
|
||||
* **Roadmap / scope / maintainer ladder.** Scope for mid-to-long-term features is managed in the open on the public [GitHub Project board](https://github.com/orgs/cozystack/projects/1), GitHub Issues/Discussions, the CNCF Slack `#cozystack` channel, Telegram, and the regular Cozystack community meetings. Roles and decision-making are defined in [GOVERNANCE.md](https://github.com/cozystack/cozystack/blob/main/GOVERNANCE.md): four roles — **Users, Contributors, Directors, Maintainers** — decide by consensus, falling back to a simple-majority vote (one vote per Maintainer and Director). The promotion path is defined in [CONTRIBUTOR_LADDER.md](https://github.com/cozystack/cozystack/blob/main/CONTRIBUTOR_LADDER.md): **Community Participant → Contributor → Reviewer → Maintainer**, with concrete criteria (Reviewer: ≥15 PRs/yr, ≥20 reviews, ≥6 months, two sponsors from different employers; Maintainer: ≥6 months as Reviewer, ≥10 h/month), promotions are done by pull request against the roster files in the repository root and `.github/`: [`.github/CODEOWNERS`](https://github.com/cozystack/cozystack/blob/main/.github/CODEOWNERS) records the area-scoped Reviewer role and gates merges on the matching paths, and [`MAINTAINERS.md`](https://github.com/cozystack/cozystack/blob/main/MAINTAINERS.md) records the project-wide Maintainer roster (Active and Emeritus sections). The two sets are deliberately different: a Reviewer owns a code area, a Maintainer is responsible for the whole project.
|
||||
* **Roadmap / scope / maintainer ladder.** Scope for mid-to-long-term features is managed in the open on the public [GitHub Project board](https://github.com/orgs/cozystack/projects/1), GitHub Issues/Discussions, the CNCF Slack `#cozystack` channel, Telegram, and the regular Cozystack community meetings. Roles and decision-making are defined in [GOVERNANCE.md](https://github.com/cozystack/cozystack/blob/main/GOVERNANCE.md): four roles — **Users, Contributors, Directors, Maintainers** — decide by consensus, falling back to a simple-majority vote (one vote per Maintainer and Director). The promotion path is defined in [CONTRIBUTOR_LADDER.md](https://github.com/cozystack/cozystack/blob/main/CONTRIBUTOR_LADDER.md): **Community Participant → Contributor → Reviewer → Maintainer**, with concrete criteria (Reviewer: ≥15 PRs/yr, ≥20 reviews, ≥6 months, two sponsors from different employers; Maintainer: ≥6 months as Reviewer, ≥10 h/month), promotions are done by pull request against the roster files in the repository root and `.github/`: [`.github/CODEOWNERS`](https://github.com/cozystack/cozystack/blob/main/.github/CODEOWNERS) records the area-scoped Reviewer role and gates merges on the matching paths, and [`MAINTAINERS.md`](https://github.com/cozystack/cozystack/blob/main/MAINTAINERS.md) carries three sections — Active Maintainers, Reviewers and Emeritus Maintainers — naming people, while `CODEOWNERS` is the authoritative path-to-Reviewer mapping. The two sets are deliberately different: a Reviewer owns a code area, a Maintainer is responsible for the whole project.
|
||||
* **Target personas.** (1) Platform/infrastructure engineers and SRE/DevOps teams building private or public clouds; (2) service providers / hosting companies / data centers offering IaaS, DBaaS and Managed-Kubernetes; (3) enterprises consolidating workloads on bare metal and seeking a self-hosted public-cloud alternative or a VMware replacement.
|
||||
* **Primary use case.** Turn bare-metal servers into a multi-tenant cloud exposing a Kubernetes-native REST API for self-service provisioning of tenant Kubernetes clusters, VMs, managed databases, load balancers and caching.
|
||||
* **Additional use cases.** Private/hybrid cloud; managed-services platform for providers; dev/test environments; AI-ready GPU infrastructure; on-prem VMware/vSphere replacement.
|
||||
@@ -62,17 +62,18 @@
|
||||
|
||||
### Security
|
||||
|
||||
* **Security self-assessment.** Cozystack has completed a **Security Self-Assessment** submitted with the Incubation application ([cncf/toc#1916](https://github.com/cncf/toc/issues/1916)), reviewed with TAG Security. `[maintainers: link the versioned SSA document in the repo / tag-security assessments]`
|
||||
* **Security self-assessment.** Cozystack has completed a **Security Self-Assessment** submitted with the Incubation application ([cncf/toc#1916](https://github.com/cncf/toc/issues/1916)), reviewed with TAG Security. The assessment is maintained in-tree at [`docs/security/self-assessment.md`](https://github.com/cozystack/cozystack/blob/main/docs/security/self-assessment.md), alongside a [threat model](https://github.com/cozystack/cozystack/blob/main/docs/security/threat-model.md) and an [incident-response process](https://github.com/cozystack/cozystack/blob/main/docs/security/incident-response.md). Where this questionnaire and the self-assessment overlap, the self-assessment is the more detailed source and the two are kept consistent.
|
||||
* **Cloud Native Security Tenets.**
|
||||
* *How satisfied:* secure-by-default (RBAC, per-tenant NetworkPolicies, isolated tenant API servers, immutable Talos nodes with no SSH/shell, minimal host attack surface); defense-in-depth via network segmentation (Cilium/Kube-OVN); automated TLS via **cert-manager**; secret management via **External Secrets Operator**/**OpenBao**; least-privilege service accounts for controllers; supply-chain hygiene via **CodeQL**, **OpenSSF Scorecard** and organization-wide **Trivy** CVE scanning of dependencies and container images.
|
||||
* *Loosening defaults:* adopters can relax tenant isolation (shared/flat networking), disable specific NetworkPolicies, or grant broader RBAC for single-tenant/lab use. `[maintainers: link docs on loosening tenant-isolation/network-policy defaults]`
|
||||
* **Security Hygiene.**
|
||||
* Practices ([SECURITY.md](https://github.com/cozystack/cozystack/blob/main/SECURITY.md)): GitHub review with required approvals; CI on every PR; **CodeQL** static analysis on PRs and weekly (blocks merge on new error-severity alerts); **OpenSSF Scorecard** weekly (published at scorecard.dev); OpenSSF Best Practices badge; organization-wide **Trivy** scanning of dependencies and container images on a 6-hour cycle for CRITICAL findings and weekly for the rest, with per-CVE triage tracked as issues (see Day 2 → Dependencies); **Renovate** for automated dependency updates; component versions pinned per release.
|
||||
* Practices: GitHub review with required approvals; CI on every PR. The branch protection on `main` currently requires two status checks, `pre-commit` and `E2E Tests`. **CodeQL** static analysis runs on every PR, on push to `main` and weekly; new error-severity alerts are expected to be resolved or explicitly dismissed before merge, but CodeQL is **not yet a required check** — promoting it to one is an open item, and [SECURITY.md](https://github.com/cozystack/cozystack/blob/main/SECURITY.md) states it as an intention rather than a fact. **zizmor** audits the GitHub Actions workflows themselves on PRs and fails the check on findings such as unpinned actions or over-broad `permissions`. **OpenSSF Scorecard** runs weekly and publishes to scorecard.dev; the OpenSSF Best Practices badge is maintained. Organization-wide **Trivy** scanning covers dependencies and container images on a 6-hour cycle for CRITICAL findings and weekly for the rest, with per-CVE triage tracked as issues (see Day 2 → Dependencies). **Renovate** automates dependency updates within the scope described in Day 2 → Dependencies. Component versions are pinned per release.
|
||||
* Unmaintained-feature risk: components are curated and version-pinned per release; the Helm-packaged, swappable building-block design makes replacing a risky/unmaintainable component tractable. `[maintainers: describe the formal process for retiring/replacing a risky component]`
|
||||
* **Cloud Native Threat Modeling.**
|
||||
* *Least privilege:* controllers run with scoped RBAC; elevated privileges are limited to and documented for infrastructure components that genuinely need them (KubeVirt/CDI for virtualization, Piraeus/LINSTOR for block devices, Cilium/Kube-OVN for CNI). `[maintainers: link a privileges/threat-model doc if published]`
|
||||
* *Least privilege:* controllers run with scoped RBAC; elevated privileges are limited to and documented for infrastructure components that genuinely need them (KubeVirt/CDI for virtualization, Piraeus/LINSTOR for block devices, Cilium/Kube-OVN for CNI). The published threat model is [`docs/security/threat-model.md`](https://github.com/cozystack/cozystack/blob/main/docs/security/threat-model.md).
|
||||
* *Certificate rotation:* automated via **cert-manager** (issuance/renewal/rotation) for platform TLS; Talos/Kubernetes-managed PKI for cluster components; tenant control-plane certs managed by **Kamaji**.
|
||||
* *Secure software supply chain:* **in place today** — CodeQL SAST (PRs + weekly, gating merges), OpenSSF Scorecard (weekly), continuous dependency and container-image CVE scanning with **Trivy** across the whole organization (see Day 2 → Dependencies → SCA), Renovate-managed dependency updates, component versions pinned per release, and private vulnerability reporting with defined CVSS response targets. **Not implemented today:** signed release artifacts (cosign) and SLSA provenance — neither is currently produced by any release workflow (`build-release`, `cut-prerelease`, `build-main`, `promote-rc`) and neither is yet tracked by an issue. SBOM generation is tracked as part of the CI image-build rework in [cozystack#2937](https://github.com/cozystack/cozystack/issues/2937), under the CI/build/release tracking issue [cozystack#3278](https://github.com/cozystack/cozystack/issues/3278).
|
||||
* *Secure software supply chain:* **in place today** — CodeQL SAST (PRs, push to `main`, weekly), zizmor workflow auditing (gating on PRs), OpenSSF Scorecard (weekly), continuous dependency and container-image CVE scanning with **Trivy** across the whole organization (see Day 2 → Dependencies → SCA), Renovate-managed dependency updates, component versions pinned per release, and private vulnerability reporting with defined CVSS response targets.
|
||||
* *Supply-chain gaps, stated precisely:* **artifact signing does not exist** — there is no cosign or sigstore anywhere in the build tooling, and no issue tracks adding it. **Build provenance is explicitly disabled**: [`hack/common-envs.mk`](https://github.com/cozystack/cozystack/blob/main/hack/common-envs.mk) sets `--provenance=false` in `BUILDX_ARGS`, so the attestation buildx would emit by default is switched off, and no SLSA provenance is published. **SBOM generation is implemented but off by default**: the same file plumbs `SBOM=1` through to `--sbom=true`, attaching a CycloneDX SBOM as a buildx attestation, and defaults it to `0` pending verification of registry referrers/attestation support; the remaining work is tracked in [cozystack#2937](https://github.com/cozystack/cozystack/issues/2937) under the CI/build/release tracking issue [cozystack#3278](https://github.com/cozystack/cozystack/issues/3278). Turning SBOMs on by default and re-enabling provenance are therefore configuration-and-verification work rather than greenfield work; signing is not.
|
||||
|
||||
---
|
||||
|
||||
@@ -86,7 +87,7 @@
|
||||
|
||||
* **Enable/disable in a live cluster.** Cozystack is the distribution rather than an add-on toggled inside a foreign cluster, so "enablement" = installing the operator bundle on the management cluster. Individual bundles/components and each tenant application are enabled/removed independently (create/delete the corresponding resource); removing a tenant application affects only that tenant, with no downtime to unrelated workloads. `[maintainers: confirm whether any core component change requires control-plane restart]`
|
||||
* **How enablement changes default cluster behavior.** Installing Cozystack sets the CNI (Cilium/Kube-OVN), default StorageClass (LINSTOR), ingress, cert-manager, and the aggregated API as cluster defaults for subsequently created workloads. Cozystack expects to own the cluster, so a clean install does not disturb pre-existing unrelated workloads.
|
||||
* **Testing enablement/disablement.** CI installs Cozystack end-to-end in ephemeral environments and provisions/destroys sample tenants and applications to validate create→ready→delete flows. Workflows: [`pull-requests.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/pull-requests.yaml) (per-PR checks), [`e2e-tag.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/e2e-tag.yaml) (tag/release e2e), [`nightly.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/nightly.yaml) (scheduled full run) and [`ui-test.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/ui-test.yaml) (dashboard). Test conventions are documented in [`docs/agents/e2e-testing.md`](https://github.com/cozystack/cozystack/blob/main/docs/agents/e2e-testing.md).
|
||||
* **Testing enablement/disablement.** CI installs Cozystack end-to-end in ephemeral environments and provisions/destroys sample tenants and applications to validate create→ready→delete flows. Workflows: [`pull-requests.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/pull-requests.yaml) (per-PR checks), [`e2e-tag.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/e2e-tag.yaml) (tag/release e2e), [`nightly.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/nightly.yaml) (scheduled full run) and [`ui-test.yaml`](https://github.com/cozystack/cozystack/blob/main/.github/workflows/ui-test.yaml) (dashboard). Test conventions are documented in [`docs/agents/e2e-testing.md`](https://github.com/cozystack/cozystack/blob/main/docs/agents/e2e-testing.md). **Current health, so that a reviewer following these links is not surprised:** the per-PR checks are the gating ones and are healthy — `pre-commit` and `E2E Tests` are the two required status checks on `main`. The scheduled `nightly.yaml` run is presently red and has been failing since 2026-08-02, and the tag-triggered `e2e-tag.yaml` also failed around the v1.6.1 release; the scheduled-run instability is tracked in [cozystack#3278](https://github.com/cozystack/cozystack/issues/3278). Enablement/disablement coverage therefore rests on the per-PR e2e job today, with the nightly full-matrix run being stabilised.
|
||||
* **Resource cleanup incl. CRDs.** Deleting an application resource triggers Flux/Helm to remove its HelmRelease and owned objects; finalizers ensure dependent resources (PVCs, VM disks, LB IPs) are released. `[maintainers: confirm CRD-cleanup behavior on full uninstall and any manual steps]`
|
||||
|
||||
### Rollout, Upgrade and Rollback Planning
|
||||
@@ -118,7 +119,7 @@
|
||||
### Observability Requirements
|
||||
|
||||
* **Signals produced** ([monitoring docs](https://cozystack.io/docs/v1.6/operations/services/monitoring/)): metrics via **VictoriaMetrics (VMCluster)** collected by **VMAgent** (Prometheus-compatible); logs via **VictoriaLogs (VLogs)** collected by **Fluent Bit** (DaemonSet); dashboards via **Grafana**; alerting via **Alerta**; plus **kube-state-metrics** and **node-exporter**. Kubernetes events and component logs in standard formats.
|
||||
* **Audit logging.** Kubernetes API audit logging can be enabled on management and tenant control planes (standard kube-apiserver audit policy). `[maintainers: confirm any default audit policy shipped]`
|
||||
* **Audit logging.** Kubernetes API audit logging can be enabled on management and tenant control planes through the standard kube-apiserver audit policy. **No default audit policy is shipped** by Cozystack — no audit-policy manifest exists in any package — so audit logging is opt-in and the policy is authored by the adopter. Enabling it by default, with a documented reference policy, is an open improvement rather than an existing feature.
|
||||
* **Dashboards.** Pre-built Grafana dashboards for cluster overview, node metrics, storage, KubeVirt/VMs and per-application health, plus user-created dashboards (Grafana Operator manages dashboards as CRDs).
|
||||
* **Cost/FinOps surfacing.** Per-tenant/per-application resource usage is observable via metrics and Kubernetes resource accounting (chargeback/showback), integrating with provider billing/portal. `[maintainers: link any FinOps/billing integration]`
|
||||
* **Health parameters.** Control-plane/API availability, Flux reconciliation status, Talos/node health, DRBD replication state, pod/VM readiness, ingress/LB health.
|
||||
@@ -129,9 +130,11 @@
|
||||
### Dependencies
|
||||
|
||||
* **Running services depended on.** As listed in Day 0 → in-cluster service dependencies (full platform stack).
|
||||
* **Dependency lifecycle policy.** Component versions are pinned and shipped per Cozystack release; upgrades are curated and tested together and bumped as a single coordinated release. Automated dependency updates are managed by **Renovate**, configured in [`.github/renovate.json`](https://github.com/cozystack/cozystack/blob/main/.github/renovate.json), which raises PRs for Go modules, container images, Helm charts and GitHub Actions so upstream bumps surface as reviewable changes rather than manual sweeps.
|
||||
* **Source Composition Analysis (SCA).** Three layers. (1) **Static analysis** — **CodeQL** on every PR and weekly, gating merges on new error-severity alerts. (2) **Supply-chain posture** — **OpenSSF Scorecard** weekly, published on scorecard.dev, plus the OpenSSF Best Practices badge. (3) **Dependency and container-image CVE scanning** — an organization-wide pipeline built on **[Trivy](https://trivy.dev/)** runs against every non-fork, non-archived repository in the `cozystack` organization. It discovers components automatically (Go modules from `go.mod`, base images from Dockerfile `FROM` directives, and container images referenced by the Helm charts under `packages/apps/*`, `packages/system/*` and `packages/core/*`), then scans both repository filesystems and the resolved container images against NVD, vendor advisories and the GitHub Advisory Database. A new application or system component is picked up on the next scan with no manual registration. CRITICAL findings are scanned and reported every 6 hours; HIGH/MEDIUM/LOW are collected into a weekly report. Every new CVE becomes a tracked issue with severity labels, affected components, fix version and a triage checklist, and maintainer triage decisions are persisted so a settled finding is not re-reported. The pipeline and its reports live in the `cozystack/security-scanner` repository, which is **private by design**: it holds pre-disclosure vulnerability detail and triage decisions for shipped artifacts, so publishing it would amount to publishing an exploitation roadmap for adopters running the affected releases. `[maintainers: decide what to expose publicly for TOC review — options are read access for the reviewers, or publishing the pipeline policy documents (SECURITY_PIPELINE_POLICY.md, SECURITY_TRIAGE_MATRIX.md, SECURITY_FINDING_STATUS_MODEL.md) and the monthly aggregate report while keeping per-CVE detail private]`
|
||||
* **Acting on SCA & timescale.** Two tracks with distinct SLAs. **Reported vulnerabilities** (Cozystack-specific code, packaging, defaults, integration logic) follow [SECURITY.md](https://github.com/cozystack/cozystack/blob/main/SECURITY.md): acknowledgement ≤3 business days, initial triage ≤7 business days, remediation targets Critical ≈14 days, High ≈30 days, Medium ≈90 days, Low next release, under a coordinated-disclosure window of up to 90 days. **Scanner findings in bundled upstream components** are triaged on the scanner pipeline's own schedule — Critical triaged within 1 business day with a 7-day fix target, High within 3 business days / 30 days, Medium within 10 business days / 90 days, Low within 30 days on a best-effort basis. Triage follows an explicit decision tree (is the CVE in a shipped artifact rather than dev/test tooling; is the vulnerable path reachable in Cozystack's usage; has the distribution already backported the fix; is an upstream fix available) and resolves to one of `confirmed`, `false-positive`, `accepted-risk`, `in-progress` or `fixed`. Confirmed findings ship as an ordinary component version bump in the next Cozystack release, or as a patch release on a supported line when severity warrants it, since component versions are pinned per release and an upgrade is a single coordinated bump.
|
||||
* **Dependency lifecycle policy.** Component versions are pinned and shipped per Cozystack release; upgrades are curated and tested together and bumped as a single coordinated release. **Renovate** ([`.github/renovate.json`](https://github.com/cozystack/cozystack/blob/main/.github/renovate.json)) automates part of this, and it is worth being exact about which part, because the automated share is smaller than the phrase "Renovate-managed" usually implies. Its `enabledManagers` are `gomod`, `dockerfile`, `github-actions` and `custom.regex`; the `helm-values` manager is **disabled repo-wide**, because many image references in the vendored charts are assembled at render time by the `cozy-lib.image` template helper rather than written literally in `values.yaml`, so a values-file manager cannot see them. Two bespoke regex managers cover specific pins that would otherwise age silently. Consequently: Go modules, Dockerfile base images, GitHub Actions and those regex-pinned refs get automated PRs, while **the curated component images that make up the shipped platform are bumped by maintainers as part of preparing a release**, not by a bot. That is a deliberate consequence of shipping a tested, coordinated version set, but it does mean the dependency class that dominates the product is on human cadence.
|
||||
* **Source Composition Analysis (SCA).** Four layers. (1) **Static analysis of first-party code** — **CodeQL** on every PR, on push to `main` and weekly, reporting only alerts new relative to `main`; expected to be resolved or dismissed before merge, though not yet a required check. (2) **Static analysis of the CI supply chain itself** — **zizmor** audits the GitHub Actions workflows on PRs and fails the check on unpinned actions, over-broad `permissions` and similar findings. (3) **Supply-chain posture** — **OpenSSF Scorecard** weekly, published on scorecard.dev, plus the OpenSSF Best Practices badge. (4) **Dependency and container-image CVE scanning** — an organization-wide pipeline built on **[Trivy](https://trivy.dev/)** running against every non-fork, non-archived repository in the `cozystack` organization.
|
||||
* **How the CVE-scanning pipeline works.** Discovery walks each repository for Go modules (`go.mod`, direct dependencies), base images from Dockerfile `FROM` directives, and container images referenced in `values.yaml` under `packages/apps/*`, `packages/system/*` and `packages/core/*`. Trivy then scans both the repository filesystem — which is where transitive Go dependencies and lock files are actually covered, since discovery itself reads only direct requirements — and every resolved container image, against NVD, vendor advisories and the GitHub Advisory Database. **A known limitation:** image references assembled at render time by the `cozy-lib.image` helper are not literal strings in `values.yaml` and are therefore invisible to values-file discovery, the same blind spot that led to disabling Renovate's `helm-values` manager. Those images are covered only insofar as they appear elsewhere; closing the gap requires resolving refs through the rendered chart rather than the values file. CRITICAL findings are scanned and reported every 6 hours; HIGH/MEDIUM/LOW are collected into a weekly report. Four filters run **before** an issue is created — findings with no upstream fix older than 365 days, dev and build-only dependencies (`golang:`/`node:`/`python:` images, `core/testing`, `hack/`, `e2e/`), CVEs already carrying a maintainer triage decision, and findings with no severity assigned in any database — so every new **actionable** CVE becomes a tracked issue with severity labels, affected components, fix version and a triage checklist, while roughly 20–30% of raw output is suppressed as noise. Triage decisions are persisted, so a settled finding is not re-reported.
|
||||
* **Public verifiability of the pipeline — an open problem, stated plainly.** The pipeline, its reports and its triage state live in `cozystack/security-scanner`, which returns 404 to anyone outside the organization. Only two parts of it genuinely require confidentiality: the per-CVE reports and the triage-state files, which describe unfixed exposure in shipped artifacts and would function as a target list for adopters running affected releases. The rest — the pipeline policy (`SECURITY_PIPELINE_POLICY.md`), the severity/SLA matrix (`SECURITY_TRIAGE_MATRIX.md`), the finding status model (`SECURITY_FINDING_STATUS_MODEL.md`), the scanning scripts, and the monthly aggregate summaries — contains no vulnerability detail and is what actually evidences the control. The project's intent is therefore to publish those and keep only per-CVE findings and triage state embargoed until fixed, so that this answer is verifiable without privileged access; the embargo scope is per-finding, not per-repository. `[maintainers: this publication needs to happen before submission, not be promised in it — it is a maintainer action, and until it lands a TOC reviewer cannot confirm any of the above]`
|
||||
* **Acting on SCA & timescale.** Two tracks with distinct **targets**. **Reported vulnerabilities** (Cozystack-specific code, packaging, defaults, integration logic) follow [SECURITY.md](https://github.com/cozystack/cozystack/blob/main/SECURITY.md): acknowledgement ≤3 business days, initial triage ≤7 business days, remediation targets Critical ≈14 days, High ≈30 days, Medium ≈90 days, Low next release, under a coordinated-disclosure window of up to 90 days. **Scanner findings in bundled upstream components** are a separate track with a tighter triage clock: Critical triaged within 1 business day against a 7-day fix target, High within 3 business days / 30 days, Medium within 10 business days / 90 days, Low within 30 days best-effort. Triage follows an explicit decision tree (is the CVE in a shipped artifact rather than dev/test tooling; is the vulnerable path reachable in Cozystack's usage; has the distribution already backported the fix; is an upstream fix available) and resolves to one of `confirmed`, `false-positive`, `accepted-risk`, `in-progress` or `fixed`. Confirmed findings ship as a pinned-component version bump in the next Cozystack release, or as a patch release on a supported line when severity warrants it. **These are documented targets, not measured attainment.** The scanner track is currently running a triage backlog against its stated clock, and the rotating role that owns meeting it is defined but unfilled. `[maintainers: supply current time-to-triage figures and open-backlog counts to the TOC through the private channel, together with the remediation plan — TAG Security asks for the distribution, and publishing raw open-CRITICAL counts in this repository would itself disclose unfixed exposure]`
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
@@ -140,7 +143,7 @@
|
||||
|
||||
### Compliance
|
||||
|
||||
* **Third-party attribution & license notices.** Apache-2.0 project bundling third-party components under their own licenses; notices retained per component. `[maintainers: confirm LICENSE + third-party NOTICE handling]`
|
||||
* **Third-party attribution & license notices.** The project is Apache-2.0 with a top-level [`LICENSE`](https://github.com/cozystack/cozystack/blob/main/LICENSE), and bundles third-party components under their own licenses, whose license files travel with the vendored component. **There is no top-level `NOTICE` file.** For a distribution that ships on the order of fifty upstream components, that is a real compliance gap rather than an oversight to paper over: adding a `NOTICE` that aggregates attribution for the bundled components, and a documented process for keeping it in step with the component set, is outstanding work.
|
||||
* **Alignment with CNCF attribution recommendations.**
|
||||
* *Notices for third-party code in source files:* retained in-file / in `LICENSE`/`NOTICE`. `[maintainers: confirm]`
|
||||
* *Notices for unmodified third-party components in the repo:* retained alongside the pinned component. `[maintainers: confirm]`
|
||||
|
||||
+15
-8
@@ -14,13 +14,15 @@ The Cozystack project maintains multiple release lines at once. Support is expre
|
||||
|
||||
| Version line | Status | Notes |
|
||||
| --- | --- | --- |
|
||||
| Latest stable minor (`vX.Y.x`) | Supported | Current stable release line. Security fixes land here first, and patch releases are cut from it. |
|
||||
| Previous stable minor (`vX.(Y-1).x`) | Supported | Receives security and important maintenance fixes, backported from the current line. |
|
||||
| Older `v1.x` minors | Limited support | Critical security and upgrade-blocking fixes may be backported at maintainer discretion. Adopters are expected to move to a supported line. |
|
||||
| `v0.x` (including `v0.41.x`) | Not supported | Pre-v1 lines from the v0 to v1 transition. Please upgrade to a supported release line before requesting a security fix. |
|
||||
| Latest stable minor | Supported | Current stable release line. Security fixes land here first, and patch releases are cut from it. |
|
||||
| Any earlier `1.x` minor that still has an active `release-1.Y` branch | Supported | The project maintains several `1.x` lines in parallel and backports security and important maintenance fixes to them, so more than one line receives patch releases at any given time. Which lines are currently active is visible from the `release-1.Y` branches and from the patch releases on the Releases page. |
|
||||
| `1.x` minors whose release branch is no longer receiving patches | Limited support | Critical security and upgrade-blocking fixes may be backported at maintainer discretion. Adopters are encouraged to move to an actively patched line. |
|
||||
| `0.x` | Limited support | Pre-v1 lines from the v0 to v1 transition. Critical security and upgrade-blocking fixes may be backported at maintainer discretion; please plan an upgrade to a `1.x` line. |
|
||||
| `alpha`, `beta`, `rc` releases | Not supported | Pre-release builds are for testing and evaluation only. |
|
||||
|
||||
Reporting a vulnerability against an unsupported line is still welcome: we will confirm whether the issue also affects a supported line and fix it there.
|
||||
This table describes the support the project actually provides today; it is not a contractual guarantee of a fixed backport window, and the set of actively patched lines changes as releases are cut.
|
||||
|
||||
Reporting a vulnerability against a line with limited support is still welcome. We will confirm whether the issue also affects an actively patched line and fix it there; whether the fix is additionally backported to the older line is a maintainer decision based on severity and upgrade impact.
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
@@ -98,12 +100,17 @@ Because Cozystack is an integration-heavy platform, some vulnerabilities may req
|
||||
|
||||
### Automated security analysis
|
||||
|
||||
Two scanners run continuously against this repository:
|
||||
Four automated controls run continuously against this repository and the artifacts built from it:
|
||||
|
||||
- **CodeQL** (static analysis). Runs on every pull request to `main`, on push to `main`, and on a weekly schedule. The Go database is built with CodeQL's `manual` build mode — each first-party module is compiled explicitly, so the analysis does not depend on the project `Makefile` (which fetches upstream tags) and stays reproducible. On a pull request CodeQL reports only alerts that are *new relative to `main`* and annotates them on the changed lines. New findings are expected to be resolved before merge — either by fixing the code, or, for a false positive or accepted risk, by dismissing the alert in the **Security → Code scanning** tab with a recorded reason (`False positive`, `Won't fix`, or `Used in tests`).
|
||||
- **OpenSSF Scorecard** (supply-chain posture). Runs weekly and on branch-protection changes, and publishes results to the public Scorecard API at <https://scorecard.dev/viewer/?uri=github.com/cozystack/cozystack>. Scorecard results are intentionally **not** uploaded to GitHub code scanning: it posts one alert per check, which would bury CodeQL's first-party findings. The scorecard.dev badge is the canonical view.
|
||||
|
||||
CodeQL is intended to run as a required pull-request check, so that a newly introduced alert at error severity blocks merge until it is fixed or dismissed.
|
||||
- **zizmor** (GitHub Actions static analysis). Audits the workflow definitions themselves on pull requests and fails the check on findings such as unpinned action references or over-broad `permissions`. As with Scorecard, the SARIF is intentionally not uploaded to code scanning — the public signal is the failing check.
|
||||
- **Trivy** (dependency and container-image CVE scanning). An organization-wide pipeline scans every non-fork, non-archived repository in the `cozystack` organization: Go modules, Dockerfile base images and the container images referenced by the packaged charts, against NVD, vendor advisories and the GitHub Advisory Database. CRITICAL findings are scanned every 6 hours; HIGH, MEDIUM and LOW are collected into a weekly report. Findings are filtered for noise (dev and build-only dependencies, unfixed-upstream findings older than a year, already-triaged CVEs) and every remaining new finding becomes a tracked issue with a severity label and a triage checklist. Triage targets are tighter than the reported-vulnerability targets above: CRITICAL within 1 business day against a 7-day fix target, HIGH within 3 business days / 30 days, MEDIUM within 10 business days / 90 days, LOW within 30 days best-effort. Confirmed findings ship as a pinned-component bump in the next release, or as a patch release on an actively patched line when severity warrants it. Per-CVE findings and triage state are kept private until fixed, because they describe unfixed exposure in released artifacts; the pipeline's policy and aggregate reporting are intended to be public.
|
||||
|
||||
Dependency updates are additionally automated by **Renovate** ([`.github/renovate.json`](.github/renovate.json)), which raises pull requests for Go modules, Dockerfile base images, GitHub Actions and a small number of regex-pinned references. The `helm-values` manager is disabled repo-wide, so the curated component images that make up the shipped platform are bumped by maintainers when preparing a release rather than by a bot.
|
||||
|
||||
CodeQL is intended to run as a required pull-request check, so that a newly introduced alert at error severity blocks merge until it is fixed or dismissed. It is **not** currently among the required status checks on `main` — those are `pre-commit` and `E2E Tests` — so today a new error-severity alert is expected to be resolved before merge by review convention rather than enforced by branch protection.
|
||||
|
||||
## Security Fixes and Announcements
|
||||
|
||||
@@ -117,7 +124,7 @@ Security fixes are published in normal release artifacts whenever possible. User
|
||||
|
||||
The following are generally out of scope for private security reporting unless there is a clear Cozystack-specific impact:
|
||||
|
||||
- vulnerabilities in unsupported or end-of-life Cozystack versions
|
||||
- vulnerabilities that reproduce only on an unsupported or end-of-life Cozystack version and not on any actively patched line — such reports are still accepted and triaged, but a fix will normally be delivered on an actively patched line rather than backported
|
||||
- issues that require access already equivalent to cluster-admin, node root, or direct infrastructure administrator privileges, unless they bypass an expected Cozystack security boundary
|
||||
- vulnerabilities that exist only in an upstream dependency and are not introduced or materially worsened by Cozystack packaging, configuration, or defaults
|
||||
- requests for security best-practice advice without a concrete vulnerability
|
||||
|
||||
@@ -142,8 +142,9 @@ Cozystack does not currently claim compliance with, or certification against, an
|
||||
- **Source control and review.** All changes land through GitHub pull requests. `.github/CODEOWNERS` requires maintainer review; the project deliberately requires a single approving review rather than two, to keep contribution velocity acceptable (branch protection requiring multiple reviews was considered and intentionally not adopted).
|
||||
- **Commit sign-off (DCO).** Contributor guidance requires `--signoff` on every commit (`docs/agents/contributing.md`, `.gemini/styleguide.md`), and DCO is **enforced by an automated DCO check on every pull request**. Remaining refinements are to surface the sign-off requirement in the top-level `CONTRIBUTING.md` and to add the DCO check to the branch-protection required-checks list so it is a hard merge gate as well as a reported check.
|
||||
- **Automated checks on pull requests.** A pre-commit workflow validates generated-code/schema freshness; unit and end-to-end tests run in CI.
|
||||
- **Static analysis (SAST).** CodeQL runs on pull requests, on push to `main`, and weekly (Go, manual build mode), intended as a required check that blocks merge on new error-severity alerts. Additional Go linters (`gosec`, `govulncheck`, `golangci-lint`) are not yet wired into CI and are a planned improvement.
|
||||
- **Dependency updates.** Renovate manages Go modules, Dockerfiles, and GitHub Actions, with OpenSSF OSV vulnerability alerts enabled and automerge disabled. There is no Dependabot configuration; Renovate is the dependency-update tool.
|
||||
- **Static analysis (SAST).** CodeQL runs on pull requests, on push to `main`, and weekly (Go, manual build mode), intended as a required check that blocks merge on new error-severity alerts. It is not yet in the required-checks list on `main` (currently `pre-commit` and `E2E Tests`), so the gate is review convention rather than branch protection. `zizmor` additionally audits the GitHub Actions workflows on pull requests and fails the check on unpinned actions and over-broad `permissions`. Additional Go linters (`gosec`, `govulncheck`, `golangci-lint`) are not yet wired into CI and are a planned improvement.
|
||||
- **Dependency and image CVE scanning (SCA).** An organization-wide pipeline built on Trivy scans every non-fork, non-archived repository in the `cozystack` organization — Go modules, Dockerfile base images, and container images referenced by the packaged charts — against NVD, vendor advisories and the GitHub Advisory Database. CRITICAL findings are scanned every 6 hours, the remaining severities weekly; findings are noise-filtered and tracked as issues under a triage matrix with per-severity targets (CRITICAL 1 business day to triage, 7-day fix target). Two limitations are worth stating: image references assembled at render time by the `cozy-lib.image` helper are invisible to values-file discovery, and per-CVE findings and triage state are currently held in a private repository, so the control is not yet externally verifiable. Publishing the pipeline policy, the triage matrix and the aggregate monthly reporting, while keeping per-finding detail embargoed until fixed, is outstanding work.
|
||||
- **Dependency updates.** Renovate manages Go modules, Dockerfiles, and GitHub Actions, plus a small set of regex-pinned references, with OpenSSF OSV vulnerability alerts enabled and automerge disabled. The `helm-values` manager is disabled repo-wide, so the curated component images that make up the shipped platform are bumped by maintainers when preparing a release rather than automatically. There is no Dependabot configuration; Renovate is the dependency-update tool.
|
||||
- **Supply-chain posture.** OpenSSF Scorecard runs weekly with published results. Most GitHub Actions are pinned by commit SHA; a small number of recently added workflows still use floating tags and are being brought into line. Renovate is configured to pin digests; applying digest pins across container base images is in progress.
|
||||
- **Signed / reproducible builds.** Honestly noted as gaps: release images are **not** signed (no cosign/sigstore), build provenance is currently disabled (`--provenance=false`), SBOM generation is plumbed but off by default, and reproducible builds are not yet established. These are recognized improvement areas for the incubation timeframe.
|
||||
|
||||
|
||||
Reference in new issue
Block a user