How our release pipeline maps to NIST SP 800-204C, 800-204D and SLSA
-This page takes the release pipeline that built FosterStack Cache v0.2.2 and puts each stage next to the NIST practice it maps to. It says where a stage only partly implements a practice, and it says which SLSA Build level we assess v0.2.2 at: Level 2, not Level 3.
-This is guidance we followed when designing the pipeline. It is not a certification.
-Words used here:
--
-
- SBOM: a parts list of what is inside a build. -
- VEX: a note on whether a known flaw affects us. -
- Provenance: a signed record of how and where something was built. -
- Digest: the fingerprint of a file or image. -
- SLSA: a public scale for how far you can trust the way software was built. Its Build track runs from Level 0 to Level 3. -
The two NIST documents
--
-
- NIST SP 800-204C, Implementation of DevSecOps for a Microservices-based Application with Service Mesh. We use its pipeline sections, mainly sections 4.6 and 4.8. -
- NIST SP 800-204D, Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines. We use sections 4 and 5, mainly sections 5.1.1 and 5.2. -
Parts of both documents cover running services in your own cluster, such as service mesh and GitOps. That is your environment, not our release pipeline, so this page does not map it.
- -Stage by stage: what runs, and which practice it maps to
-This describes the workflow files as they were at the v0.2.2 tag. What changed since v0.2.1 is listed after the table. "Signs" means the stage records what it did and signs it, with a short-lived key and no stored signing key. The signature is tied to that stage's own workflow and logged in a public transparency log.
-| Stage | What it does in v0.2.2 | NIST practice | How much |
|---|
| Stage | What it does | NIST practice | How much |
|---|---|---|---|
| Source admission | -The tag must be annotated, signed and strictly named: signed by the owner's key or, for an automatic patch tag only, by the release workflow's own keyless identity. The commit must be signed (by the owner's key, or GitHub's own key for merges made on github.com) and be on main. Every required check must pass on that exact commit or, for the checks that run only on pull requests, on the pull request that produced it. An owner-approved requirements list must exist for the version. The lists of allowed signers and required checks are read from main, not from the tagged commit. Signs. |
- 800-204D 5.1.4 "Secure Code Commits" (commit-signing enforcement, COMMIT-REQ-2); 5.1.2 "Secure Pull-Push Operations on Repositories" (automated checks before code is trusted) | -Partly. There is one maintainer, so no second person reviews or approves a change. | -
| Build | -Builds the binaries once on a fresh GitHub-hosted machine with the toolchain pinned, and checks that the dependency files did not change. Writes checksums and an SBOM per archive. Signs a build statement and SLSA provenance. | -800-204D 5.1.1 "Secure Build"; 800-204C 3.3.3 (SBOM generation and code signing as pipeline tasks) | -Partly. The signing runs in the same job as the build steps, not in a separate, more trusted process as 5.1.1 asks. | -
| Image assembly | -Checks every archive against the signed build statement before opening it. Adds one binary to a base image pinned by digest, with no commands run inside the image, using a BuildKit image that is also pinned by digest. Pushes by digest only, with no version tags, to a separate candidates package. Signs, recording the base digest and binary hashes, plus SLSA provenance. | -800-204D 4.2: "The inputs and outputs of each build step should be verified" | -Matches the practice as we read it. | -
| Reproducibility check | -Assembles the images again on a separate machine. The digests must match, or the release fails. Signs. | -No direct match in either document. | -Not mapped. It repeats the image assembly; it does not rebuild the binaries from source. | -
| Scans | -Two scanners with different vulnerability databases run, each on its own machine. They first check the image-assembly and reproducibility statements, then scan every platform image of every variant. One also scans the archives, the other the Go module files. Any finding blocks the release, even the lowest-rated one. For one of the two scanners, a published VEX statement can clear a finding. Each scanner signs its verdict for the exact digests. | -800-204C 4.8 and 4.8.1 (container image scans, software composition analysis); 800-204D 5.2, DEPLOY_REQ-4 (evidence the image was scanned) | -Partly. The release pipeline runs no static or dynamic application security testing itself. The signed verdict records a pass, not the full scan report. | -
| Acceptance tests | -Run against the exact candidate images: the Linux archives and binaries (macOS archives are checked, not run), the images on both CPU architectures, the image variants, the Gradle and Maven test suites, the Kubernetes setup from our docs, and a test that the server makes no outbound connections. A final job checks that every release-blocking acceptance test in the approved list passed, then signs one statement. | -800-204C 3.3.1 (tests run in the pipeline; an organisation may choose to stop the pipeline when a test fails); 4.6 (stop further pipeline tasks if a test fails) | -Matches the practice as we read it. The individual test jobs do not sign their own results. | -
| Release authorization | -Verifies every earlier statement: signed by the expected stage, naming this commit and these digests, scan verdicts pass, acceptance results complete. Anything missing stops the release. It also stops the release if a VEX statement says a flaw affects us and no owner acceptance of that risk is recorded. Records each statement's transparency-log entry. Signs the approval. | -800-204C 4.6: "verify that all required signatures … are present to ensure that no one bypasses the pipeline"; 800-204D 5.1.1 (policy checks that the required attestations are found) | -Partly. The policy is code in the workflow file, not a separate signed policy document as 5.1.1 describes. | -
| Promotion and publish | -Will not start without the signed approval. Copies the approved digests to GitHub's registry and the Docker Hub mirror with no rebuild, and checks the digests did not change. Signs the public images and the checksums file. Publishes the VEX statements in three forms: OpenVEX, scanner suppression rules and CSAF 2.0. Uploads the release files, re-checks the image signatures, the signed checksums and every tag the way a customer would, without credentials, then makes the release page public. | -800-204D 5.2, DEPLOY-REQ-3 (only an artifact made by the approved build process is cleared) | -Partly. Promotion only copies the digests named in the signed approval. Enforcing that at deploy time is up to your own environment. | -
| Signing, across all stages | -Keyless signing: a short-lived signing identity per stage, no stored signing key, every signature logged publicly. | -800-204C 4.6: "signing the release artifact during each required CI/CD stage (preferably multi-party signing)"; 800-204D 5.1.1 (attestations signed, stored tamper-proof) | -Partly. Not multi-party: every signature is made by automation in one repository, run by one maintainer. | -
| Evidence bundle | -release-manifest.json lists every digest, the hash of the approved requirements list, per-test results, and the transparency-log entry of every statement the authorization verified. It is attached to each image in GitHub's registry as a signed statement and published with the SBOMs, VEX file and signed checksums. |
- 800-204D 4 (record provenance, with a way to verify and authenticate it) | -Matches the practice as we read it. Neither document has a section on VEX. | -
| Source admission | [TO-VERIFY] whether unchanged from v0.2.2: signed tag, signed commit on main, required checks passed. | [TO-VERIFY] 800-204D 5.1.4 and 5.1.2 | [TO-VERIFY] |
| Build | [TO-VERIFY] Builds the binaries and the signed packages once. The image is assembled from those packages, with no base image. | [TO-VERIFY] 800-204D 5.1.1 | [TO-VERIFY] |
| Sign | [TO-VERIFY] A separate stage records the build and signs it under its own identity, from the build's digest list only. | [TO-VERIFY] the part of 5.1.1 that asks for signing outside the build steps | [TO-VERIFY] |
| Rebuild | [TO-VERIFY] Builds the release again, independently. The digests must match or the release fails. | [TO-VERIFY] none found in either document | [TO-VERIFY] |
| Check | [TO-VERIFY] Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests. | [TO-VERIFY] 800-204C 4.8 and 800-204D 5.2 | [TO-VERIFY] |
| Release | [TO-VERIFY] Verifies every stage's signature together, then publishes the same digests. | [TO-VERIFY] | [TO-VERIFY] |
What changed from v0.2.1 to v0.2.2
-The v0.2.2 tag changed 31 workflow files. The build stage and the scan stage did not change. These did:
--
-
- Admission. A tag can be signed two ways: with the owner's key, as before, or, for an automatic patch tag only, with the release workflow's own keyless signature, whose certificate must name
release.ymlonmainof this repository for the tagged commit. For such a patch tag the approved requirements list must be byte for byte the one from the line's latest owner-signed tag.
- - Image assembly and reproducibility. The BuildKit image is pinned by digest. -
- Authorization. It reads the requirements list that admission chose, and it has the new VEX risk-acceptance check described in the table. -
- Promotion. It publishes the VEX statements in three forms, takes the release notes of an automatic patch release from the tag message, and records the requirements list it used in the manifest. -
- Acceptance tests. The two test workflows were merged into one file. The suites are the same, and the four acceptance stage files had small edits. -
- The release workflow. It also runs on pushes to
mainand once a day, but on those runs only the newdecideandpatch-notesjobs can run. A newpatch-failedjob opens an issue when a release run fails. The release run for v0.2.2 has 19 jobs where the v0.2.1 run had 16, and the three new jobs are not on the build, sign and promote path.
-
Which SLSA Build level do we assess v0.2.2 at?
-We assess v0.2.2 at SLSA Build Level 2, against the SLSA v1.0 requirements and levels. We do not claim Build Level 3.
--
-
- Consistent build process (L1). Met, by our reading. One workflow builds every v0.2 release. Only a tag push starts the build job, and the first stage stops any tag not signed by the owner's key or, for an automatic patch tag, the release workflow's own identity. -
- Provenance exists (L1). Met, by our reading. SLSA v1 provenance covers the binary archives, their SBOMs,
checksums.txt, and the three container images, naming each digest, the source commit and the workflow run.
- - Distribute provenance (L1). Met, by our reading. It is in GitHub's attestation store, and
gh attestation verifyreturns it.
- - Hosted build platform (L2). Met, by our reading. The build and image jobs ran on GitHub-hosted
ubuntu-latestmachines, never on a workstation. The build job's log shows image ubuntu-24.04, version 20261004.327.1.
- - Provenance is authentic (L2). Met, by our reading. The provenance is signed with a short-lived certificate issued to the building workflow, and the signature is logged in a public transparency log. The image, reproducibility and scan stages check who signed the statement before them. The acceptance tests do not. The build, the release authorization and the publishing step also check the source commit and the tag. You can check them yourself. -
Level 3 is not claimed. It asks the build platform to "prevent runs from influencing one another, even within the same project" and to "prevent secret material used to sign the provenance from being accessible to the user-defined build steps". We have not shown either. In v0.2.2 the build job can ask for a signing identity for the whole job, and it also runs this repository's build configuration and compiles its code: the goreleaser hooks and the Go build. The image job can ask for a signing identity too, and it builds this repository's Dockerfiles. So the build steps could reach the signing, and Level 3 needs that kept apart. The build job also restored a GitHub Actions cache written by earlier runs, and we have not shown that other workflows or branches cannot write to it. The spec calls that "cache poisoning" under its "Isolated" requirement. Build Level 3 is not claimed for v0.2.2.
- -What we do not meet
+Our wording: signed at every stage, verified together at release.
+SLSA
+[TO-VERIFY] The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.
What this page does not say
-
-
- SLSA Build Level 3. -
- We rely on GitHub-hosted machines being a fresh, isolated machine for each job. We have not checked that ourselves. -
- The promotion job holds the Docker Hub token and also runs helper scripts from this repository, in the same job that signs the public images. We do not describe promotion as isolated. -
- Evidence made by a separate, more trusted process than the build itself (800-204D 5.1.1). -
- A second person: one maintainer writes, approves and releases every change. No review by another person, and no multi-party signing (800-204D 5.1.2, 800-204C 4.6). -
- All signing is automated. 800-204D 5.1.3, written for software update systems, points the same way: multiple keys with threshold trust, and automated keys kept out of roles customers rely on. -
- The acceptance test jobs pass their results to the job that signs them; they do not sign or verify statements themselves. -
- No dynamic application security testing, and no static testing inside the release pipeline. -
- The release policy is workflow code, not a separate signed policy document. -
- The reproducibility check covers image assembly, not a second build of the binaries from source. -
- Promoted images are in the public registries a few steps before the final customer-style checks finish. Only the release page waits for those checks. -
- Scan verdicts are signed, but the full scan reports are not published as release files. -
- Checking provenance with
gh attestation verifyneeds a GitHub token. Thecosignchecks need no account.
-
Check it yourself
-This checks the SLSA provenance of the v0.2.2 image and the workflow that signed it:
-$ gh attestation verify oci://ghcr.io/fosterstack/cache:0.2.2 \
- --repo fosterstack/cache \
- --signer-workflow fosterstack/cache/.github/workflows/stage-image.yml
- -
-
- Verify a release: every check we ran against v0.2.2, with its real output. -
- The v0.2.2 release run: 19 jobs, in three attempts. The images were built and authorized in attempt 2, and attempt 3 published them (see Verify a release). -
- The v0.2.1 release run: all 16 jobs. -
- What changed from v0.2.1 to v0.2.2, including the workflow files. -
- The v0.2.2 release: SBOMs, VEX files, signed checksums and
release-manifest.json.
- - RELEASING.md at v0.2.2: the pipeline in the maintainer's words. -
- The workflow files at v0.2.2, starting with release.yml and stage-authorize.yml. +
- No stage here is certified by anyone. +
- Parts of both NIST documents cover running services in your own cluster. That is your environment, so this page does not map it.
Section numbers refer to the final published versions of NIST SP 800-204C and NIST SP 800-204D. This is guidance we followed when designing the pipeline. It is not a certification.
- -Related: verify a release yourself and how releases are built and signed.
More than kept patched.
@@ -144,7 +145,6 @@More than kept patched.
[TO-VERIFY: pipeline: the Rebuild stage][TO-VERIFY: cache: image assembled from signed packages; production and fips images only]How we build · Security policy · Verify a release
@@ -153,7 +153,7 @@Built to be verified, not trusted
The answer is to make everything checkable:- MIT-licensed core. Read the code before you run it. -
- One public container image. Free and paid users pull the identical bytes — scan exactly what you deploy. +
- One public container image per variant. Free and paid users pull the identical bytes — scan exactly what you deploy.
- When the paid tiers ship, a license key will unlock them in the same public image — no private registry, no gated downloads. (They are not built; the pricing below is direction, not a shelf.)
- Security patches are never withheld from the free tier. Not delayed, not embargoed — never.
- Signed commits, signed releases, public release notes. The repository's SECURITY.md states exactly what the release evidence does and does not prove today. @@ -164,7 +164,7 @@
- No telemetry, and no required FosterStack connection. The server
reports nothing to us — no usage data, no license check, no update ping — and today's
free core makes no outbound connections at all: it works identically on a machine with
- no route to the internet. When the paid features ship, the only outbound traffic will
+ no route to the internet.
[TO-VERIFY: cache: also true of the v0.3 server]When the paid features ship, the only outbound traffic will be what you configure (your identity provider for SSO, your peer replicas for HA) — endpoints you choose, never FosterStack. - This website collects no email addresses. There is no signup
@@ -180,7 +180,7 @@
What we do not collect
Pricing
Per product. Free is the full product.
-Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics, HA/replication and named-version LTS are not built.
+[TO-VERIFY: payments: what is and is not built when v0.3 ships]Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics, HA/replication and named-version LTS are not built.
-Free Team Business Compliance From 9e8bb998053746a42f8fe7df15b65e36591b7f45 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:18:01 -0400 Subject: [PATCH 08/40] v0.3 trust pages: markers on the unmarked v0.3 facts, the abandoned-upstream sentence --- how-our-pipeline-maps-to-nist-and-slsa/index.html | 2 +- how-we-build/index.html | 8 ++++---- verify-a-release/index.html | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index a52f7e3..eb423d2 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -105,7 +105,7 @@ Stage by stage
Release [TO-VERIFY]Verifies every stage's signature together, then publishes the same digests.[TO-VERIFY][TO-VERIFY]Our wording: signed at every stage, verified together at release.
+Our wording: signed at every stage, verified together at release.
[TO-VERIFY: pipeline]SLSA
[TO-VERIFY]The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.What this page does not say
diff --git a/how-we-build/index.html b/how-we-build/index.html index 5877219..2d10790 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -91,7 +91,7 @@How FosterStack Cache is built and signed
-You are about to run our software inside your build pipeline. How do you know the files you run are the ones we built? Every release is signed and checked at every step, and you can verify it yourself. This page says how.
+You are about to run our software inside your build pipeline. How do you know the files you run are the ones we built? Every release is signed and checked at every step, and you can verify it yourself.
[TO-VERIFY: pipeline: signed and checked at every stage of the v0.3 chain]This page says how.DRAFT for v0.3, private preview, not published.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.We do it to our own pipeline first
@@ -116,14 +116,14 @@What you get with each release
- Container images on GitHub's registry, signed without a stored key (Sigstore), with build provenance.
[TO-VERIFY: pipeline/cache: v0.3 image signing and provenance] - Plain binaries and a
checksums.txtwith its own signature file.[TO-VERIFY: cache fix A #276: which files the signed checksums list covers]
- - A software bill of materials (SBOM) for each binary archive. -
- A VEX file saying which known vulnerabilities do and do not affect the release. +
- A software bill of materials (SBOM) for each binary archive.
[TO-VERIFY: cache: v0.3 release assets]
+ - A VEX file saying which known vulnerabilities do and do not affect the release.
[TO-VERIFY: cache: v0.3 release assets] - A
release-manifest.jsonlisting every file and its digest.[TO-VERIFY: cache: manifest layout at v0.3]
All of it is public. You do not need an account or a purchase to check any of it. The commands are on verify a release yourself.
Kept patched
-The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look.
+[TO-VERIFY: cache/ops: the daily rescan, and automatic patch releases not yet cut]The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched, including software its own maintainers have abandoned.
[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; what is covered when upstream has abandoned a component]What we do not claim
-
diff --git a/verify-a-release/index.html b/verify-a-release/index.html
index 09edf3a..f2df7a5 100644
--- a/verify-a-release/index.html
+++ b/verify-a-release/index.html
@@ -88,7 +88,7 @@
- Signed releases you can verify in minutes. +
- Signed releases you can verify in minutes. We secure our own pipeline the same way, first: how we build.
[TO-VERIFY: pipeline: the v0.3 chain and the verify guide] - Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- Images assembled twice on separate machines; the results must match. -
- Minimal image, no telemetry. FIPS variant available. +
- Every release is rebuilt independently; the results must match.
[TO-VERIFY: pipeline: the Rebuild stage]
+ - Minimal image with no base image, no telemetry. FIPS variant available, built from the same source as the standard image.
[TO-VERIFY: cache: image assembled from signed packages; the FIPS and standard images come from two builds of one source] - Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
- To get a fix, move to the latest release. Older releases are not on the supported list. +
- To get a fix, move to a supported release.
[TO-VERIFY: cache: which releases are supported once v0.3.0 is out] - Pin the image to an exact version or digest, not
latest, so a deploy never changes without you choosing it. - Upgrade on a routine. A build cache is disposable, so an upgrade that goes wrong costs you slower builds while it refills, not lost work.
- Watch the repository's releases on GitHub. It is the one notice channel, and you can stop at any time. We do not collect email.
- Container images, signed without a stored key (Sigstore), with build provenance.
checksums.txtwith its own signature file.
@@ -129,7 +132,7 @@ - The server has a read-write login and an optional read-only login. There is no per-person identity.
- The paid tiers are not built. -
- We are not announcing an LTS line, a support period, or a date. +
- We do not promise a date for any release or any support period.
[TO-VERIFY: cache/owner: the support terms for the v0.3.0 long-term-support line] - Source check. The tag and the commit must be signed by an allowed signer, sit on the main branch, and have every required check green.
[TO-VERIFY: pipeline: v0.3 source admission unchanged from v0.2.2] - Build. The binaries and the image's packages are built once. The image is assembled from those signed packages, with no base image.
[TO-VERIFY: cache: melange packages, apko image, no base image]
- - Sign. A separate stage, with its own identity, records the build and signs it.
[TO-VERIFY: pipeline: the Sign boundary stage and its own identity]
- - Rebuild. The release is built again, independently. The results must be identical, or the release fails.
[TO-VERIFY: pipeline: the Rebuild stage]
- - Check. Every scanner on our list runs against the exact images. A finding blocks the release unless a published VEX statement explains why it does not apply. The Gradle and Maven acceptance tests run against the same images.
[TO-VERIFY: pipeline: scanner list and acceptance suites at v0.3]
- - Release. One step verifies every earlier signature together. Anything missing stops the release. Then the same digests are published, promoted without a rebuild, and checked again the way a customer would check them.
[TO-VERIFY: pipeline: the Release stage]
+ - Sign. A separate stage, with its own identity, records the build and signs it.
[TO-VERIFY: pipeline: the Sign boundary stage; a distinct certificate subject for each stage, visible in the cosign output]
+ - Rebuild. The image is assembled again, independently, on a separate machine. The digests must be identical, or the release fails.
[TO-VERIFY: pipeline: the Rebuild stage runs on a separate runner and identity, sharing no cache or inputs with Build]
+ - Check. The scanners we list (the list is in the repository) run against the exact images, and each signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply. The Gradle and Maven acceptance tests run against the same images.
[TO-VERIFY: pipeline: scanner list and acceptance suites at v0.3]
+ - Release. One step verifies every earlier signature together. Anything missing stops the release. Then the same digests are published, promoted without a rebuild, and checked again the way a customer would check them.
[TO-VERIFY: pipeline: the Release job runs the same commands as the verify page] - Vulnerable dependencies fixed fast: our target is 48 hours from disclosure (the scope is in SECURITY.md). -
- A signature shows who signed these exact files. It does not show the software has no bugs. +
- A signature shows who signed these exact files. It does not show the software has no bugs, and it is not a certification by anyone.
- The paid tiers are not built. Everything here is the free MIT core.
- A valid signature proves who signed these exact bytes. +
- A valid signature proves who signed these exact files.
- Provenance proves which workflow and run produced them.
- It does not prove the software has no bugs.
- Linux only.
[TO-VERIFY]v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. If you run the server on a Mac, run the container image or a Linux machine instead.
- - No
-debugimage.[TO-VERIFY]The images areproductionandfips. To look inside a running container, usekubectl debugordocker debug.
- - Oversized requests.
[TO-VERIFY]A request with more than 500 header values is rejected with431before it reaches the cache. Gradle and Maven send far fewer.
+ - Linux only.
[TO-VERIFY: cache: the owner's Oct 9 answer; the platform requirement text is not ratified]v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. If you run the server on a Mac, run the container image or a Linux machine instead.
+ - No
-debugimage.[TO-VERIFY: cache: the owner's Oct 9 answer; README section on debugging a running container]The images areproductionandfips. To look inside a running container, usekubectl debugordocker debug.
+ - Oversized requests.
[TO-VERIFY: cache: next-release notes (Go 1.27 behaviour); whether it ships in v0.3.0]A request with more than 500 header values is rejected with431before it reaches the cache. Gradle and Maven send far fewer. - It shows the running program is using Go's validated module. The validation is of that cryptographic module. -
- Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before publishing, the release runs the released FIPS binary (Linux, amd64) and requires its status page to show the
active (Go validated module ...)line. It also starts the FIPS image and stores and fetches a test entry through it. No test yet reads the status page of the running FIPS image, so checking it yourself, as shown above, is still worth doing.
- - FosterStack Cache is not "FedRAMP compliant" or "CMMC compliant". Those attach to your service and your organisation, never to a component you deploy. The FIPS build is validated crypto for your compliance program, not a substitute for it. +
- Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before publishing, the release runs the released FIPS binary (Linux, amd64) and requires its status page to show the
active (Go validated module ...)line. It also starts the FIPS image and stores and fetches a test entry through it. No test yet reads the status page of the running FIPS image, so checking it yourself, as shown above, is still worth doing.[TO-VERIFY: cache: whether a v0.3 test now reads it]
+ - FosterStack Cache is not "FedRAMP compliant" or "CMMC compliant". Those attach to your service and your organization, never to a component you deploy. The FIPS build is validated crypto for your compliance program, not a substitute for it.
- Signed releases you can verify in minutes. We secure our own pipeline the same way, first: how we build.
[TO-VERIFY: pipeline: the v0.3 chain and the verify guide]
+ - Signed releases you can verify in minutes. How we sign and check our own releases: how we build.
[TO-VERIFY: pipeline: the v0.3 chain and the verify guide] - Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day.
- Every release is rebuilt independently; the results must match.
[TO-VERIFY: pipeline: the Rebuild stage]
diff --git a/security/index.html b/security/index.html
index 09e30ee..014acb2 100644
--- a/security/index.html
+++ b/security/index.html
@@ -101,10 +101,10 @@ - To get a fix, move to a supported release.
[TO-VERIFY: cache: which releases are supported once v0.3.0 is out] - Pin the image to an exact version or digest, not
latest, so a deploy never changes without you choosing it.
@@ -113,7 +113,7 @@ - Container images, signed without a stored key (Sigstore), with build provenance.
checksums.txtwith its own signature file.
From 9d39f2b1b421ff587e7024dcf120e3e3686effc8 Mon Sep 17 00:00:00 2001
From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com>
Date: Sat, 10 Oct 2026 22:20:18 -0400
Subject: [PATCH 15/40] how-we-build: no open-ended abandoned-upstream promise
---
how-we-build/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/how-we-build/index.html b/how-we-build/index.html
index e202904..f81a69f 100644
--- a/how-we-build/index.html
+++ b/how-we-build/index.html
@@ -123,7 +123,7 @@ - Linux only.
[TO-VERIFY: cache: the owner's Oct 9 answer; the platform requirement text is not ratified]v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. If you run the server on a Mac, run the container image or a Linux machine instead.
+ - Linux only.
[TO-VERIFY: cache: the owner's Oct 9 answer and the v0.3 build matrix (amd64 and arm64); the platform requirement text is not ratified]v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. If you run the server on a Mac, run the container image or a Linux machine instead. - No
-debugimage.[TO-VERIFY: cache: the owner's Oct 9 answer; README section on debugging a running container]The images areproductionandfips. To look inside a running container, usekubectl debugordocker debug.
- - Oversized requests.
[TO-VERIFY: cache: next-release notes (Go 1.27 behaviour); whether it ships in v0.3.0]A request with more than 500 header values is rejected with431before it reaches the cache. Gradle and Maven send far fewer.
+ - Oversized requests. If a proxy or a custom client adds a very large number of headers, a request with more than 500 header values is rejected with
431(Request Header Fields Too Large) before it reaches the cache. Gradle and Maven send far fewer; look for431in a build log if a request fails.[TO-VERIFY: cache: next-release notes (Go 1.27 behaviour); whether it ships in v0.3.0] - Oversized requests. If a proxy or a custom client adds a very large number of headers, a request with more than 500 header values is rejected with
431(Request Header Fields Too Large) before it reaches the cache. Gradle and Maven send far fewer; look for431in a build log if a request fails.[TO-VERIFY: cache: next-release notes (Go 1.27 behaviour); whether it ships in v0.3.0] - No stage here is certified by anyone. diff --git a/how-we-build/index.html b/how-we-build/index.html index f81a69f..495da0c 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -101,13 +101,13 @@
- Source check. The tag and the commit must be signed by an allowed signer, sit on the main branch, and have every required check green.
[TO-VERIFY: pipeline: v0.3 source admission unchanged from v0.2.2]
- - Build. The binaries and the image's packages are built once. The image is assembled from those signed packages, with no base image.
[TO-VERIFY: cache: melange packages, apko image, no base image]
+ - Source check. The tag and the commit must be signed by an allowed signer, sit on the main branch, and have every required check green. It signs its result.
[TO-VERIFY: pipeline: v0.3 source admission unchanged from v0.2.2]
+ - Build. The binaries and the image's packages are built once. The image is assembled from those signed packages, with no base image. It signs what it built.
[TO-VERIFY: cache: melange packages, apko image, no base image] - Sign. A separate stage, with its own identity, records the build and signs it.
[TO-VERIFY: pipeline: the Sign boundary stage; a distinct certificate subject for each stage, visible in the cosign output]
- - Rebuild. The image is assembled again, independently, on a separate machine. The digests must be identical, or the release fails.
[TO-VERIFY: pipeline: the Rebuild stage runs on a separate runner and identity, sharing no cache or inputs with Build]
- - Check. The scanners we list (the list is in the repository) run against the exact images, and each signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply. The Gradle and Maven acceptance tests run against the same images.
[TO-VERIFY: pipeline: scanner list and acceptance suites at v0.3]
+ - Rebuild. The image is assembled again, independently, on a separate machine. The digests must be identical, or the release fails. It signs its result.
[TO-VERIFY: pipeline: the Rebuild stage runs on a separate runner and identity, sharing no cache or inputs with Build]
+ - Check. The scanners we list (the list is in the repository) run against the exact images, and signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply. The Gradle and Maven acceptance tests run against the same images.
[TO-VERIFY: pipeline: scanner list and acceptance suites at v0.3] - Release. One step verifies every earlier signature together. Anything missing stops the release. Then the same digests are published, promoted without a rebuild, and checked again the way a customer would check them.
[TO-VERIFY: pipeline: the Release job runs the same commands as the verify page] - Vulnerable dependencies fixed fast: our target is 48 hours from disclosure (the scope is in SECURITY.md). -
- A signature shows who signed these exact files. It does not show the software has no bugs, and it is not a certification by anyone. +
- A signature shows who signed these exact files. It does not show the software has no bugs, and it is not a certification by anyone.
- The paid tiers are not built. Everything here is the free MIT core.
- Signed releases you can verify in minutes.
[TO-VERIFY: pipeline/cache: the v0.3 verify guide, ten commands or fewer] - Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- Every release is rebuilt independently; the results must match.
[TO-VERIFY: pipeline: the Rebuild stage]
+ - The image of every release is assembled a second time, independently; the digests must match.
[TO-VERIFY: pipeline: the Rebuild stage] - Minimal image with no base image, no telemetry. FIPS variant available.
[TO-VERIFY: cache: image assembled from signed packages; production and fips images only] - Signed releases you can verify in minutes. How we sign and check our own releases: how we build.
[TO-VERIFY: pipeline: the v0.3 chain and the verify guide] - Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- Every release is rebuilt independently; the results must match.
[TO-VERIFY: pipeline: the Rebuild stage]
+ - The image of every release is assembled a second time, independently; the digests must match.
[TO-VERIFY: pipeline: the Rebuild stage] - Minimal image with no base image, no telemetry. FIPS variant available, built from the same source as the standard image.
[TO-VERIFY: cache: image assembled from signed packages; the FIPS and standard images come from two builds of one source] - Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
- To get a fix, move to a supported release.
[TO-VERIFY: cache: which releases are supported once v0.3.0 is out] - Pin the image to an exact version or digest, not
latest, so a deploy never changes without you choosing it.
diff --git a/verify-a-release/index.html b/verify-a-release/index.html
index 404dd99..07da2dc 100644
--- a/verify-a-release/index.html
+++ b/verify-a-release/index.html
@@ -88,32 +88,32 @@
- Provenance proves which workflow and run produced them.
- It does not prove the software has no bugs.
- Source check. The tag and the commit must be signed by an allowed signer, sit on the main branch, and have every required check green. It signs its result.
[TO-VERIFY: pipeline: v0.3 source admission unchanged from v0.2.2]
- - Build. The binaries and the image's packages are built once. The image is assembled from those signed packages, with no base image. It signs what it built.
[TO-VERIFY: cache: melange packages, apko image, no base image]
- - Sign. A separate stage, with its own identity, records the build and signs it.
[TO-VERIFY: pipeline: the Sign boundary stage; a distinct certificate subject for each stage, visible in the cosign output]
- - Rebuild. The image is assembled again, independently, on a separate machine. The digests must be identical, or the release fails. It signs its result.
[TO-VERIFY: pipeline: the Rebuild stage runs on a separate runner and identity, sharing no cache or inputs with Build]
- - Check. The scanners we list (the list is in the repository) run against the exact images, and signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply. The Gradle and Maven acceptance tests run against the same images.
[TO-VERIFY: pipeline: scanner list and acceptance suites at v0.3]
- - Release. One step verifies every earlier signature together. Anything missing stops the release. Then the same digests are published, promoted without a rebuild, and checked again the way a customer would check them.
[TO-VERIFY: pipeline: the Release job runs the same commands as the verify page]
+ - Build. The stage first checks that the tag is signed, then builds the binaries and both images, for amd64 and arm64, once. It signs what it built.
[TO-VERIFY: pipeline: Build stage (tag check, binaries and both images)]
+ - Sign. A separate stage, with its own identity, receives only the build's digests, records the build and signs it.
[TO-VERIFY: pipeline: the Sign stage and its own identity; exists on the integration branch only]
+ - Rebuild. The same commit is built again on a fresh machine and every digest is compared with the first build. Any difference stops the release. It signs its result.
[TO-VERIFY: pipeline: the Rebuild stage; a fresh machine, the same commit, every digest compared]
+ - Check. The scanners we list (the list is in the repository), the Gradle and Maven tests and the no-phone-home test run against the exact images, and the stage signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply.
[TO-VERIFY: pipeline: Check stage; scanner list, tests, FIPS and no-phone-home checks]
+ - Release. The only stage that can publish. It verifies every earlier signature together, then publishes the same digests that were built and judged, with no rebuild.
[TO-VERIFY: pipeline: the Release stage verifies every earlier signature; publishes by digest] - Linux only.
[TO-VERIFY: cache: the owner's Oct 9 answer and the v0.3 build matrix (amd64 and arm64); the platform requirement text is not ratified]v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. If you run the server on a Mac, run the container image or a Linux machine instead.
- - No
-debugimage.[TO-VERIFY: cache: the owner's Oct 9 answer; README section on debugging a running container]The images areproductionandfips. To look inside a running container, usekubectl debugordocker debug.
- - Oversized requests. If a proxy or a custom client adds a very large number of headers, a request with more than 500 header values is rejected with
431(Request Header Fields Too Large) before it reaches the cache. Gradle and Maven send far fewer; look for431in a build log if a request fails.[TO-VERIFY: cache: next-release notes (Go 1.27 behaviour); whether it ships in v0.3.0]
+ - Linux only. v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. On a Mac, run the Linux container image under Docker Desktop.
[TO-VERIFY: cache: the owner's Oct 9 answer; the Mac container path and the v0.3 image's data folder are not decided yet]
+ - The
-debugimage. The images areproductionandfips; whether a-debugimage ships at v0.3.0 is still open. The production and fips images hold only thefscachebinary, with no shell, so look inside a running container from outside it withkubectl debugordocker debug.[TO-VERIFY: owner: whether a -debug image ships is an open question; cache: the README section on debugging a running container]
+ - Inside the data folder. The data folder path is the same, but temporary files of writes in flight now live in a
+tmpfolder inside it.[TO-VERIFY: cache: the on-disk layout change on main since 0.2.2; confirm it is in v0.3.0 and its upgrade note] - Linux only. v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. On a Mac, run the Linux container image under Docker Desktop.
[TO-VERIFY: cache: the owner's Oct 9 answer; the Mac container path and the v0.3 image's data folder are not decided yet]
- - The
-debugimage. The images areproductionandfips; whether a-debugimage ships at v0.3.0 is still open. The production and fips images hold only thefscachebinary, with no shell, so look inside a running container from outside it withkubectl debugordocker debug.[TO-VERIFY: owner: whether a -debug image ships is an open question; cache: the README section on debugging a running container]
+ - No
-debugimage. v0.3.0 ships theproductionandfipsimages only. They hold only thefscachebinary, with no shell, so look inside a running container from outside it withkubectl debugordocker debug; the README has a section on it.[TO-VERIFY: cache: the owner's Oct 9 answer (drop debug; put kubectl debug and docker debug in the README); true once the v0.3 images are built] - Inside the data folder. The data folder path is the same, but temporary files of writes in flight now live in a
+tmpfolder inside it.[TO-VERIFY: cache: the on-disk layout change on main since 0.2.2; confirm it is in v0.3.0 and its upgrade note] - Inside the data folder. The data folder path is the same, but temporary files of writes in flight now live in a
+tmpfolder inside it.[TO-VERIFY: cache: the on-disk layout change on main since 0.2.2; confirm it is in v0.3.0 and its upgrade note] - Give everyone else the optional read-only login. That includes laptops. The setup is on let CI write, developers only read, and the CI wiring is on Jenkins and CI build cache.
- Keep builds of untrusted code on the read-only login. An example is a pull request from a fork.
- Do not count on
isPush = false. It only controls whether your own build uploads. The login is what the server enforces.
- - Use HTTPS, on a network you control. Gradle sends the login with its requests. +
- Use HTTPS, on a network you control. Gradle sends the login with its requests. A proxy in front or the server's own certificate both work.
[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md] - If you doubt an entry, clear the cache. See how to clear or reset a build cache.
- Keep secrets out of Java constants. A constant lives on in the class file, in the cache and in your jar.
- Declare an environment variable as a task input if the task reads it. We changed one that a task read without declaring it, and the old result came back from the cache.
- Give developers the read-only login and give CI the read-write login. See let CI write and developers read. One login reaches every project on a server, so use one server per group that must not share. See several projects on one server. -
- Use HTTPS when the server is not on your own machine. Our runs used plain HTTP to a server on the same Mac. See use your build cache over HTTPS with a private CA. +
- Use HTTPS when the server is not on your own machine. Our runs used plain HTTP to a server on the same Mac. See use your build cache over HTTPS with a private CA. The HTTPS can come from a proxy or from the server itself (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md] - A machine your CI runners and developers can reach. The server is one small program, and disk is what matters. See server sizing. -
- Plan on HTTPS for anything beyond a first try. Gradle sends the password with every request. +
- Plan on HTTPS for anything beyond a first try. Gradle sends the password with every request. Either put a proxy in front, or give the server its own certificate with
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY(both or neither).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md] - Put it behind HTTPS and give CI the read-write login and everyone else the read-only one: let CI write, developers only read. +
- Serve it over HTTPS (a proxy in front, or the server's own TLS) and give CI the read-write login and everyone else the read-only one: let CI write, developers only read.
- Watch it: monitoring. Know how it forgets: eviction.
- Know how to empty it: reset, and how to move it: back up and restore.
- Ask for the cache's host and port to be allowed through the proxy (HTTPS).
- Put the proxy lines in
gradle.properties, with thesystemProp.prefix, and list internal hosts innonProxyHosts.
- - Use HTTPS to the cache. See a production setup with nginx and TLS. +
- Use HTTPS to the cache: a production setup with nginx and TLS, or the server's own certificate (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md] - If the proxy re-signs TLS, Java will need your company's certificate authority.
- Use HTTPS. Gradle sends the password with every request, so over plain HTTP it travels in the clear. Put real servers behind HTTPS. +
- Use HTTPS. Gradle sends the password with every request, so over plain HTTP it travels in the clear. Serve real servers over HTTPS: behind a proxy, or with the server's own
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md] - Keep the
credentialsblock even where the server has no password. One config then works against both a test server and a real one. - Give laptops the read-only login. That is the intended way to give laptops a cache they can read and not change. Use the read-write login for machines that upload, or set the client not to upload.
- Give everyone else the optional read-only login. That includes laptops. The setup is on let CI write, developers only read, and the CI wiring is on Jenkins and CI build cache.
- Keep builds of untrusted code on the read-only login. An example is a pull request from a fork.
- Do not count on
isPush = false. It only controls whether your own build uploads. The login is what the server enforces.
- - Use HTTPS, on a network you control. Gradle sends the login with its requests. A proxy in front or the server's own certificate both work.
[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]
+ - Use HTTPS, on a network you control. Gradle sends the login with its requests. A proxy in front or the server's own certificate both work.
- If you doubt an entry, clear the cache. See how to clear or reset a build cache.
- Keep secrets out of Java constants. A constant lives on in the class file, in the cache and in your jar.
- Declare an environment variable as a task input if the task reads it. We changed one that a task read without declaring it, and the old result came back from the cache.
- Give developers the read-only login and give CI the read-write login. See let CI write and developers read. One login reaches every project on a server, so use one server per group that must not share. See several projects on one server. -
- Use HTTPS when the server is not on your own machine. Our runs used plain HTTP to a server on the same Mac. See use your build cache over HTTPS with a private CA. The HTTPS can come from a proxy or from the server itself (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]
+ - Use HTTPS when the server is not on your own machine. Our runs used plain HTTP to a server on the same Mac. See use your build cache over HTTPS with a private CA. The HTTPS can come from a proxy or from the server itself (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY). - It shows the running program is using Go's validated module. The validation is of that cryptographic module. -
- Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before publishing, the release runs the released FIPS binary (Linux, amd64) and requires its status page to show the
active (Go validated module ...)line. It also starts the FIPS image and stores and fetches a test entry through it. No test yet reads the status page of the running FIPS image, so checking it yourself, as shown above, is still worth doing.[TO-VERIFY: cache: whether a v0.3 test now reads it]
+ - Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before publishing, the release runs the released FIPS binary (Linux, amd64) and requires its status page to show the
active (Go validated module ...)line. It also starts the FIPS image and stores and fetches a test entry through it. No test yet reads the status page of the running FIPS image, so checking it yourself, as shown above, is still worth doing. - FosterStack Cache is not "FedRAMP compliant" or "CMMC compliant". Those attach to your service and your organization, never to a component you deploy. The FIPS build is validated crypto for your compliance program, not a substitute for it.
- A machine your CI runners and developers can reach. The server is one small program, and disk is what matters. See server sizing. -
- Plan on HTTPS for anything beyond a first try. Gradle sends the password with every request. Either put a proxy in front, or give the server its own certificate with
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY(both or neither).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]
+ - Plan on HTTPS for anything beyond a first try. Gradle sends the password with every request. Either put a proxy in front, or give the server its own certificate with
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY(both or neither). - Ask for the cache's host and port to be allowed through the proxy (HTTPS).
- Put the proxy lines in
gradle.properties, with thesystemProp.prefix, and list internal hosts innonProxyHosts.
- - Use HTTPS to the cache: a production setup with nginx and TLS, or the server's own certificate (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY).[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]
+ - Use HTTPS to the cache: a production setup with nginx and TLS, or the server's own certificate (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY). - If the proxy re-signs TLS, Java will need your company's certificate authority.
- Use HTTPS. Gradle sends the password with every request, so over plain HTTP it travels in the clear. Serve real servers over HTTPS: behind a proxy, or with the server's own
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]
+ - Use HTTPS. Gradle sends the password with every request, so over plain HTTP it travels in the clear. Serve real servers over HTTPS: behind a proxy, or with the server's own
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY. - Keep the
credentialsblock even where the server has no password. One config then works against both a test server and a real one. - Give laptops the read-only login. That is the intended way to give laptops a cache they can read and not change. Use the read-write login for machines that upload, or set the client not to upload.
- No stage here is certified by anyone. diff --git a/how-we-build/index.html b/how-we-build/index.html index 32a136a..3031417 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -91,38 +91,38 @@
- Build. The stage first checks that the tag is signed, then builds the binaries and both images, for amd64 and arm64, once. It signs what it built.
[TO-VERIFY: pipeline: Build stage (tag check, binaries and both images)]
- - Sign. A separate stage, with its own identity, receives only the build's digests, records the build and signs it.
[TO-VERIFY: pipeline: the Sign stage and its own identity; exists on the integration branch only]
- - Rebuild. The same commit is built again on a fresh machine and every digest is compared with the first build. Any difference stops the release. It signs its result.
[TO-VERIFY: pipeline: the Rebuild stage; a fresh machine, the same commit, every digest compared]
- - Check. The scanners we list (the list is in the repository), the Gradle and Maven tests and the no-phone-home test run against the exact images, and the stage signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply.
[TO-VERIFY: pipeline: Check stage; scanner list, tests, FIPS and no-phone-home checks]
- - Release. The only stage that can publish. It verifies every earlier signature together, then publishes the same digests that were built and judged, with no rebuild.
[TO-VERIFY: pipeline: the Release stage verifies every earlier signature; publishes by digest]
+ - Build. The stage first checks that the tag is signed, then builds the binaries and both images, for amd64 and arm64, once. It signs what it built. +
- Sign. A separate stage, with its own identity, receives only the build's digests, records the build and signs it. +
- Rebuild. The same commit is built again on a fresh machine and every digest is compared with the first build. Any difference stops the release. It signs its result. +
- Check. The scanners we list (the list is in the repository), the Gradle and Maven tests and the no-phone-home test run against the exact images, and the stage signs its verdict for those digests. A finding blocks the release unless a published VEX statement explains why it does not apply. +
- Release. The only stage that can publish. It verifies every earlier signature together, then publishes the same digests that were built and judged, with no rebuild.
- Container images on GitHub's registry, signed without a stored key (Sigstore), with build provenance.
[TO-VERIFY: pipeline/cache: v0.3 image signing and provenance]
- - Plain binaries and a
checksums.txtwith its own signature file.[TO-VERIFY: cache fix A #276: which files the signed checksums list covers]
- - A software bill of materials (SBOM) for each binary archive.
[TO-VERIFY: cache: v0.3 release assets]
- - A VEX file saying which known vulnerabilities do and do not affect the release.
[TO-VERIFY: cache: v0.3 release assets]
- - A
release-manifest.jsonlisting every file and its digest.[TO-VERIFY: cache: manifest layout at v0.3]
+ - Container images on GitHub's registry, signed without a stored key (Sigstore), with build provenance. +
- Plain binaries and a
checksums.txtwith its own signature file.
+ - A software bill of materials (SBOM) for each binary archive. +
- A VEX file saying which known vulnerabilities do and do not affect the release. +
- A
release-manifest.jsonlisting every file and its digest. - Signed releases you can verify in minutes.
[TO-VERIFY: pipeline/cache: the v0.3 verify guide, ten commands or fewer]
+ - Signed releases you can verify in minutes.
- Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- The image of every release is assembled a second time, independently; the digests must match.
[TO-VERIFY: pipeline: the Rebuild stage]
- - Minimal image with no base image, no telemetry. FIPS variant available.
[TO-VERIFY: cache: image assembled from signed packages; production and fips images only]
+ - The image of every release is assembled a second time, independently; the digests must match. +
- Minimal image with no base image, no telemetry. FIPS variant available.
- No telemetry, and no required FosterStack connection. The server
reports nothing to us — no usage data, no license check, no update ping — and today's
free core makes no outbound connections at all: it works identically on a machine with
- no route to the internet.
[TO-VERIFY: cache: also true of the v0.3 server]When the paid features ship, the only outbound traffic will + no route to the internet. When the paid features ship, the only outbound traffic will be what you configure (your identity provider for SSO, your peer replicas for HA) — endpoints you choose, never FosterStack. - This website collects no email addresses. There is no signup
@@ -180,7 +180,7 @@
What we do not collect
Pricing
Per product. Free is the full product.
-
+[TO-VERIFY: payments: what is and is not built when v0.3 ships]Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics, HA/replication and named-version LTS are not built.Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics, HA/replication and named-version LTS are not built.
Free Team Business Compliance diff --git a/is-the-build-cache-server-healthy-what-to-alert-on/index.html b/is-the-build-cache-server-healthy-what-to-alert-on/index.html index 5113c44..168c7dd 100644 --- a/is-the-build-cache-server-healthy-what-to-alert-on/index.html +++ b/is-the-build-cache-server-healthy-what-to-alert-on/index.html @@ -90,7 +90,7 @@ diff --git a/llms.txt b/llms.txt index 1b86995..a369e32 100644 --- a/llms.txt +++ b/llms.txt @@ -118,8 +118,8 @@ Not yet shipped: - The paid tiers. Team ($49/mo: multi-user access control, SSO, per-project analytics, email support), Business ($199/mo: adds HA/replication, priority support with the CVE-response target), and Compliance ($499/mo billed - annually: adds the FIPS applicability statement, signed per-release - attestation letters, questionnaire hours) are described, + annually: adds the FIPS applicability statement, a monthly + attestation letter covering every release, questionnaire hours) are described, not yet purchasable; the license key that unlocks them is not built. Everything in the repository is the free MIT core, including the -fips image and all release evidence. diff --git a/regulated/index.html b/regulated/index.html index dcaa97f..556d844 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -161,8 +161,8 @@ From fdf0598499704958923feb63b4fcdcd346975ec8 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:02:26 -0400 Subject: [PATCH 39/40] Compliance copy: a monthly attestation letter covering every release --- index.html | 2 +- llms.txt | 4 ++-- regulated/index.html | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/index.html b/index.html index 7e186b0..0b23a7b 100644 --- a/index.html +++ b/index.html @@ -146,7 +146,7 @@Is my build cache server healthy? What to alert on
Watch three things: the server answers, uploads succeed, and builds get hits. FosterStack Cache reports all three, but
-/healthzalone only says the process is running.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
The short answer
-
@@ -131,7 +131,7 @@
- Signed releases you can verify in minutes. How we sign and check our own releases: how we build.
[TO-VERIFY: pipeline: the v0.3 chain and the verify guide]
+ - Signed releases you can verify in minutes. How we sign and check our own releases: how we build.
- Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- The image of every release is assembled a second time, independently; the digests must match.
[TO-VERIFY: pipeline: the Rebuild stage]
- - Minimal image with no base image, no telemetry. FIPS variant available, built from the same source as the standard image.
[TO-VERIFY: cache: image assembled from signed packages; the FIPS and standard images come from two builds of one source]
+ - The image of every release is assembled a second time, independently; the digests must match. +
- Minimal image with no base image, no telemetry. FIPS variant available, built from the same source as the standard image.
- Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
- To get a fix, move to a supported release.
[TO-VERIFY: cache: which releases are supported once v0.3.0 is out]
+ - To get a fix, move to a supported release.
- Pin the image to an exact version or digest, not
latest, so a deploy never changes without you choosing it. - Upgrade on a routine. A build cache is disposable, so an upgrade that goes wrong costs you slower builds while it refills, not lost work.
- Watch the repository's releases on GitHub. It is the one notice channel, and you can stop at any time. We do not collect email.
- Container images, signed without a stored key (Sigstore), with build provenance.
checksums.txtwith its own signature file.
@@ -132,7 +132,7 @@ - The server has a read-write login and an optional read-only login. There is no per-person identity.
- The paid tiers are not built. -
- We do not promise a date for any release or any support period.
[TO-VERIFY: cache/owner: the support terms for the v0.3.0 long-term-support line]
+ - We do not promise a date for any release or any support period.
- Provenance proves which workflow and run produced them.
- It does not prove the software has no bugs.
- Linux only. v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. On a Mac, run the Linux container image under Docker Desktop.
[TO-VERIFY: cache: the owner's Oct 9 answer; the Mac container path and the v0.3 image's data folder are not decided yet]
- - No
-debugimage. v0.3.0 ships theproductionandfipsimages only. They hold only thefscachebinary, with no shell, so look inside a running container from outside it withkubectl debugordocker debug; the README has a section on it.[TO-VERIFY: cache: the owner's Oct 9 answer (drop debug; put kubectl debug and docker debug in the README); true once the v0.3 images are built]
- - Inside the data folder. The data folder path is the same, but temporary files of writes in flight now live in a
+tmpfolder inside it.[TO-VERIFY: cache: the on-disk layout change on main since 0.2.2; confirm it is in v0.3.0 and its upgrade note]
+ - Linux only. v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. On a Mac, run the Linux container image under Docker Desktop. +
- No
-debugimage. v0.3.0 ships theproductionandfipsimages only. They hold only thefscachebinary, with no shell, so look inside a running container from outside it withkubectl debugordocker debug; the README has a section on it.
+ - Inside the data folder. The data folder path is the same, but temporary files of writes in flight now live in a
+tmpfolder inside it. - No stage here is certified by anyone. -
- Parts of both NIST documents cover running services in your own cluster. That is your environment, so this page does not map it. -
- Signed releases you can verify in minutes.
- Build record, parts list (SBOM) and vulnerability statements published with every release.
- Scanned before every release. The current release is rescanned every day. -
- The image of every release is assembled a second time, independently; the digests must match. -
- Minimal image with no base image, no telemetry. FIPS variant available. +
- Images assembled twice on separate machines; the results must match. +
- Minimal image, no telemetry. FIPS variant available. +
- Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
- MIT-licensed core. Read the code before you run it. -
- One public container image per variant. Free and paid users pull the identical bytes — scan exactly what you deploy. +
- One public container image. Free and paid users pull the identical bytes — scan exactly what you deploy.
- When the paid tiers ship, a license key will unlock them in the same public image — no private registry, no gated downloads. (They are not built; the pricing below is direction, not a shelf.)
- Security patches are never withheld from the free tier. Not delayed, not embargoed — never.
- Signed commits, signed releases, public release notes. The repository's SECURITY.md states exactly what the release evidence does and does not prove today. @@ -180,7 +182,7 @@
- Security policy: how to report a vulnerability
- How big a build cache server? CPU, RAM, disk and load
- Install on an air-gapped network -
- What changes in v0.3.0 (draft)
- How FosterStack Cache is built and signed
- Verify a release yourself: signature, provenance, SBOM, VEX
- FIPS 140-3 build cache: run the FIPS image and confirm it diff --git a/llms.txt b/llms.txt index 79af462..5338f93 100644 --- a/llms.txt +++ b/llms.txt @@ -112,7 +112,7 @@ Not yet shipped: analytics, email support), Business ($199/mo: adds HA/replication, priority support with the CVE-response target), and Compliance ($499/mo billed annually: adds the FIPS applicability statement, signed per-release - attestation letters, questionnaire hours, named-version LTS) are described, + attestation letters, questionnaire hours) are described, not yet purchasable; the license key that unlocks them is not built. Everything in the repository is the free MIT core, including the -fips image and all release evidence. From f1428d5cee0b910ee05e75016d8eb8a1ae3be77c Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:35:32 -0400 Subject: [PATCH 27/40] v0.3 preview: Everything FosterStack does for security (site copy of the cache page); home list keeps the v0.3 what's-new link --- everything-we-do-for-security/index.html | 172 +++++++++++++++++++++++ index.html | 2 + llms.txt | 1 + sitemap.xml | 4 + 4 files changed, 179 insertions(+) create mode 100644 everything-we-do-for-security/index.html diff --git a/everything-we-do-for-security/index.html b/everything-we-do-for-security/index.html new file mode 100644 index 0000000..0c1d637 --- /dev/null +++ b/everything-we-do-for-security/index.html @@ -0,0 +1,172 @@ + + + + + + +
- Signed commits. The
mainbranch accepts only signed commits, and its protection rules are a repository ruleset that the required checks are part of (required checks).
+ - Signed release tags, checked first. The release chain starts by verifying the tag against a list of allowed signers kept on
main, before any repository code runs (admission stage, allowed signers).
+ - Release tags are protected. Creating a release tag is restricted by a repository rule, and a published release tag cannot be moved, updated or deleted (RELEASING.md). +
- The merge gate runs from
main. The check that judges a pull request is the copy onmain, not the copy in the pull request, so a change cannot edit the rule that judges it (review gate).
+ - Pull requests from forks never see secrets. CI never uses
pull_request_target, so a fork's code never runs with repository secrets (CI).
+ - A reserved branch for the automated auditor. Only the auditor's delivery identity may push to its branch prefix, and any other pusher fails the check (guard). +
- Every action in every workflow is pinned to a full commit digest. A tag or a branch reference fails the check on every pull request, and the check also reads the tag each digest claims to be (pin checker). +
- Container images are named by digest. An image a workflow runs, pulls or passes to an action must be a digest, never a tag. +
- A new version waits seven days. A pull request that moves a pinned version is held until that version has been public for seven days, by a server-side time (supply-chain workflow). +
- Everything we pin is checked daily. The inventory of pinned actions and packages is checked once a day against published advisories and malicious-package reports (supply-chain workflow). +
- Automated dependency review on every pull request. Newly added dependencies and their advisories are listed and checked before merge (CI). +
- Updates are automated and judged. Patch and minor updates merge after the full gate; a major update is read against the upstream release notes and our usage by an automated reviewer before anyone merges it (auto-merge, reviewer). +
- The Go toolchain stays on the newest patch of a supported minor. A daily job proposes the bump when a newer supported release exists (freshness job). +
- Go vulnerability analysis on every change.
govulncheckruns on every pull request and push;gosecand CodeQL read the code (CI, CodeQL).
+ - Posture is measured in public. OpenSSF Scorecard runs weekly and its badge is on the README (Scorecard). +
- One build, promoted by digest. The release is built once; the same bytes are scanned, tested and promoted, and the promoted digest is asserted equal to the scanned digest after every copy (release chain). +
- Every stage signs what it did. Admission, build, image assembly, reproducibility, each scan and acceptance each sign a statement naming the exact digests, and the next stage verifies it on entry (RELEASING.md). +
- Pinned toolchain. The build uses the Go version from
go.modwith downloads of a newer toolchain disabled, and module manifests are verified, never rewritten (build stage).
+ - Distroless image, assembled by copy. Each image variant is a base image digest plus the binary bytes: no shell, no package manager, no build step inside the image (image stage). +
- Assembled twice and compared. The image assembly is repeated on a fresh runner and the digests must be equal (reproducibility stage). +
- A FIPS variant. A
-fipsbuild uses Go's FIPS 140-3 validated cryptographic module, announces itself at startup, and the whole test suite runs infips140=onlymode on every commit (SECURITY.md).
+ - Approved-only cryptography is enforced by lint too. Only in-boundary crypto imports are allowed, and third-party cryptographic code is denied outright (
.golangci.yml).
+ - Scanners with different databases block every release. The set is one list in the repository, each scanner blocks at every severity including unknown, and nothing hard-codes a name or a count (scanner list, SECURITY.md). +
- Scanned on every pull request. The pull request gate builds the same image the release would ship and scans it (scan workflow). +
- Four scanners, every day. The daily rescan builds main's candidate and scans it with four independent scanners, then tallies how many saw each finding (daily rescan). +
- Published images are rescanned daily. A CVE disclosed against bytes we already shipped raises a tracked issue (scanning.md). +
- An automated audit reads every finding. Each day an automated auditor reads every scanner finding against the code, the published VEX and the CISA Known Exploited Vulnerabilities catalog, and writes up what each one needs (daily auditor). +
- Exceptions are published statements. The only way to except a finding is an OpenVEX statement with a justification, kept in the repository and published with each release (
.vex/, scanning.md).
+ - Scanner verdicts are signed. Each scanner's verdict is a signed statement bound to the digests it scanned (verify-images.md). +
- Signed images. Every image is signed keylessly by the promotion workflow, in both registries (verify-images.md). +
- Signed provenance. Archives, SBOMs and the checksums file carry build provenance naming the CI run that made them (verify-images.md). +
- An SBOM for every archive, published with the release (RELEASING.md). +
- The VEX document ships with every release as
fosterstack-cache.openvex.json.
+ - One authorization before anything goes public. A single stage verifies the whole graph, fails closed on anything missing, and signs the approval that promotion requires (authorization stage). +
- The release is checked as a customer would. After promotion the public digests are verified and pulled anonymously, and only then is the release published (promotion stage). +
- Acceptance runs against the exact artifacts. The archives and images that ship run the customer scenarios first: Gradle, Maven, Kubernetes and the artifact checks (acceptance, artifact acceptance). +
- No telemetry and no outbound connections. The server sends nothing anywhere, and a release test traces the candidate from its first instruction with egress denied to prove it (egress acceptance, SECURITY.md). +
- No request access log. The only per-request logging is on failure, and it never carries a body, a credential or a client address. +
- A 48-hour patch target. A fix ships to every user on the same day; the target is commercially reasonable efforts within 48 hours of a fix or an assessment (SECURITY.md). +
- Private reporting. Vulnerabilities are reported through GitHub's private vulnerability reporting (SECURITY.md). +
- A daily watch of what we depend on. Newly published advisories and malicious-package reports about anything we pin are read every day (supply-chain workflow). +
- Security policy: how to report a vulnerability
- How big a build cache server? CPU, RAM, disk and load
- Install on an air-gapped network +
- What changes in v0.3.0 (draft) +
- Everything FosterStack does for security
- How FosterStack Cache is built and signed
- Verify a release yourself: signature, provenance, SBOM, VEX
- FIPS 140-3 build cache: run the FIPS image and confirm it diff --git a/llms.txt b/llms.txt index 5338f93..5cd1f5f 100644 --- a/llms.txt +++ b/llms.txt @@ -58,6 +58,7 @@ verifiable against the CI run that produced them. - [How big a build cache server? CPU, RAM, disk and load](https://fosterstack.com/build-cache-server-sizing/): CPU, RAM, disk and the size cap. - [Air-gapped install](https://fosterstack.com/air-gapped-build-cache-install/): download, verify, transfer, run. - [What changes in v0.3.0 (draft)](https://fosterstack.com/whats-new-fosterstack-cache-v0-3-0/): what to check before you upgrade. +- [Everything FosterStack does for security](https://fosterstack.com/everything-we-do-for-security/): every security practice that runs, one line each, with where to check it. - [How FosterStack Cache is built and signed](https://fosterstack.com/how-we-build/): the release steps and what you can verify. - [Production build cache: Docker Compose, nginx and TLS](https://fosterstack.com/build-cache-docker-compose-production/): A Compose file for a self-hosted build cache behind nginx with TLS and a password, run for real on 0.2.1 and Gradle 9.8.0, with what was and was not tested. - [Build cache behind a corporate proxy: Gradle and Maven](https://fosterstack.com/gradle-build-cache-corporate-proxy/): How Gradle's remote build cache behaves behind a proxy: the settings, the loopback trap, a proxy that refuses, and how to tell it from a cache error. Real run. diff --git a/sitemap.xml b/sitemap.xml index c011bba..e734045 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -67,6 +67,10 @@
- Install on an air-gapped network
- What changes in v0.3.0 (draft)
- Everything FosterStack does for security +
- Scanning FosterStack in your compliance pipeline
- How FosterStack Cache is built and signed
- Verify a release yourself: signature, provenance, SBOM, VEX
- FIPS 140-3 build cache: run the FIPS image and confirm it diff --git a/llms.txt b/llms.txt index 5cd1f5f..e8a89b0 100644 --- a/llms.txt +++ b/llms.txt @@ -59,6 +59,7 @@ verifiable against the CI run that produced them. - [Air-gapped install](https://fosterstack.com/air-gapped-build-cache-install/): download, verify, transfer, run. - [What changes in v0.3.0 (draft)](https://fosterstack.com/whats-new-fosterstack-cache-v0-3-0/): what to check before you upgrade. - [Everything FosterStack does for security](https://fosterstack.com/everything-we-do-for-security/): every security practice that runs, one line each, with where to check it. +- [Scanning FosterStack in your compliance pipeline](https://fosterstack.com/scan-fosterstack-cache-image/): what to expect when you scan the image and how to apply our VEX statements. - [How FosterStack Cache is built and signed](https://fosterstack.com/how-we-build/): the release steps and what you can verify. - [Production build cache: Docker Compose, nginx and TLS](https://fosterstack.com/build-cache-docker-compose-production/): A Compose file for a self-hosted build cache behind nginx with TLS and a password, run for real on 0.2.1 and Gradle 9.8.0, with what was and was not tested. - [Build cache behind a corporate proxy: Gradle and Maven](https://fosterstack.com/gradle-build-cache-corporate-proxy/): How Gradle's remote build cache behaves behind a proxy: the settings, the loopback trap, a proxy that refuses, and how to tell it from a cache error. Real run. diff --git a/scan-fosterstack-cache-image/index.html b/scan-fosterstack-cache-image/index.html new file mode 100644 index 0000000..dd66e88 --- /dev/null +++ b/scan-fosterstack-cache-image/index.html @@ -0,0 +1,175 @@ + + + + + + +
- "Is forbidden package X present?" checks — pass vacuously. There's no package manager, so nothing is "installed" in the sense those checks look for. +
- "Is required package X present?" checks — fail or error, for the same reason. +
- Our rules. We keep no scanner-side ignore that stands alone. A suppression in our repository must cite the statement that governs it (
.vex/README.md), and the Inspector rules above are generated from the statements, never written by hand.
+ - Which statements become rules.
not_affectedandfixedstatements become suppression rules.affectedandunder_investigationnever do: those findings stay visible in your scanner.
+ - Scoped to what we shipped. Each rule is scoped by the CVE and by the digests of the release it was written for (and by package and version when the statement names one), so it does not hide the same CVE in a different image. +
- Your own rules. Put the statement ID in the rule's reason or comment, so a reviewer on your side can trace it back to our file the same way. +
- Signed commits. The
mainbranch accepts only signed commits, and its protection rules are a repository ruleset that the required checks are part of (required checks).
+ - Signed commits. The
mainbranch accepts only signed commits, under a repository ruleset that also requires the checks on every pull request (the repository's rules, required checks). - Signed release tags, checked first. The release chain starts by verifying the tag against a list of allowed signers kept on
main, before any repository code runs (admission stage, allowed signers).
- - Release tags are protected. Creating a release tag is restricted by a repository rule, and a published release tag cannot be moved, updated or deleted (RELEASING.md). +
- Release tags are protected. Creating a release tag is restricted by a repository rule, and a published release tag cannot be moved, updated or deleted (the repository's rules).
- The merge gate runs from
main. The check that judges a pull request is the copy onmain, not the copy in the pull request, so a change cannot edit the rule that judges it (review gate).
- - Pull requests from forks never see secrets. CI never uses
pull_request_target, so a fork's code never runs with repository secrets (CI).
+ - CI runs a fork's code without secrets. The CI workflow runs on
pull_request, neverpull_request_target, so a fork's code runs with GitHub's no-secrets treatment (CI). - A reserved branch for the automated auditor. Only the auditor's delivery identity may push to its branch prefix, and any other pusher fails the check (guard).
- Every action in every workflow is pinned to a full commit digest. A tag or a branch reference fails the check on every pull request, and the check also reads the tag each digest claims to be (pin checker). -
- Container images are named by digest. An image a workflow runs, pulls or passes to an action must be a digest, never a tag. +
- Container images are named by digest. An image a workflow runs, pulls or passes to an action must be a digest, never a tag, and the same checker fails the pull request otherwise (pin checker).
- A new version waits seven days. A pull request that moves a pinned version is held until that version has been public for seven days, by a server-side time (supply-chain workflow).
- Everything we pin is checked daily. The inventory of pinned actions and packages is checked once a day against published advisories and malicious-package reports (supply-chain workflow).
- Automated dependency review on every pull request. Newly added dependencies and their advisories are listed and checked before merge (CI). @@ -115,44 +115,42 @@
- Posture is measured in public. OpenSSF Scorecard runs weekly and its badge is on the README (Scorecard).
- One build, promoted by digest. The release is built once; the same bytes are scanned, tested and promoted, and the promoted digest is asserted equal to the scanned digest after every copy (release chain).
- Every stage signs what it did. Admission, build, image assembly, reproducibility, each scan and acceptance each sign a statement naming the exact digests, and the next stage verifies it on entry (RELEASING.md).
- Pinned toolchain. The build uses the Go version from
go.modwith downloads of a newer toolchain disabled, and module manifests are verified, never rewritten (build stage).
- - Distroless image, assembled by copy. Each image variant is a base image digest plus the binary bytes: no shell, no package manager, no build step inside the image (image stage). +
- Distroless image, assembled by copy. Each image variant is a base image digest plus the binary bytes, with no build step inside the image; the production and FIPS images have no shell and no package manager (image stage).
- Assembled twice and compared. The image assembly is repeated on a fresh runner and the digests must be equal (reproducibility stage).
- A FIPS variant. A
-fipsbuild uses Go's FIPS 140-3 validated cryptographic module, announces itself at startup, and the whole test suite runs infips140=onlymode on every commit (SECURITY.md).
- - Approved-only cryptography is enforced by lint too. Only in-boundary crypto imports are allowed, and third-party cryptographic code is denied outright (
.golangci.yml).
+ - Approved-only cryptography is checked by lint too. A lint rule denies the third-party cryptographic packages we name, such as
golang.org/x/crypto, so code reaches for the validated module instead (.golangci.yml). - Scanners with different databases block every release. The set is one list in the repository, each scanner blocks at every severity including unknown, and nothing hard-codes a name or a count (scanner list, SECURITY.md).
- Scanned on every pull request. The pull request gate builds the same image the release would ship and scans it (scan workflow).
- Four scanners, every day. The daily rescan builds main's candidate and scans it with four independent scanners, then tallies how many saw each finding (daily rescan).
- Published images are rescanned daily. A CVE disclosed against bytes we already shipped raises a tracked issue (scanning.md). -
- An automated audit reads every finding. Each day an automated auditor reads every scanner finding against the code, the published VEX and the CISA Known Exploited Vulnerabilities catalog, and writes up what each one needs (daily auditor). +
- An automated audit reads every finding. Each day an automated auditor reads every scanner finding against the code and the published VEX, and writes up what each one needs (daily auditor).
- Exceptions are published statements. The only way to except a finding is an OpenVEX statement with a justification, kept in the repository and published with each release (
.vex/, scanning.md). - Scanner verdicts are signed. Each scanner's verdict is a signed statement bound to the digests it scanned (verify-images.md).
- Signed images. Every image is signed keylessly by the promotion workflow, in both registries (verify-images.md).
- Signed provenance. Archives, SBOMs and the checksums file carry build provenance naming the CI run that made them (verify-images.md).
- An SBOM for every archive, published with the release (RELEASING.md). -
- The VEX document ships with every release as
fosterstack-cache.openvex.json.
+ - The VEX document ships with every release as
fosterstack-cache.openvex.json(RELEASING.md). - One authorization before anything goes public. A single stage verifies the whole graph, fails closed on anything missing, and signs the approval that promotion requires (authorization stage).
- The release is checked as a customer would. After promotion the public digests are verified and pulled anonymously, and only then is the release published (promotion stage).
- Acceptance runs against the exact artifacts. The archives and images that ship run the customer scenarios first: Gradle, Maven, Kubernetes and the artifact checks (acceptance, artifact acceptance).
- No telemetry and no outbound connections. The server sends nothing anywhere, and a release test traces the candidate from its first instruction with egress denied to prove it (egress acceptance, SECURITY.md). -
- No request access log. The only per-request logging is on failure, and it never carries a body, a credential or a client address. +
- No request access log. The only per-request logging is on failure, and it never carries a body, a credential or a client address (SECURITY.md).
- A 48-hour patch target. A fix ships to every user on the same day; the target is commercially reasonable efforts within 48 hours of a fix or an assessment (SECURITY.md). -
- Private reporting. Vulnerabilities are reported through GitHub's private vulnerability reporting (SECURITY.md). +
- A daily watch of what we depend on. Newly published advisories and malicious-package reports about anything we pin are read every day (supply-chain workflow).
- "Is forbidden package X present?" checks — pass vacuously. There's no package manager, so nothing is "installed" in the sense those checks look for.
- "Is required package X present?" checks — fail or error, for the same reason.
- Your own rules. Put the statement ID in the rule's reason or comment, so a reviewer on your side can trace it back to our file the same way.
- Your first 15 minutes with a self-hosted build cache +
- Migrate from Build Cache Node: setup, checklist, checks +
- Build Cache Node end of life: what happens and your options +
- Install on an air-gapped network +
- What changes in v0.3.0 (draft) +
- Changelog +
- Use a Remote Build Cache in GitHub Actions +
- Jenkins and CI build cache +
- Maven remote build cache setup, on/off, and with Gradle +
- Enable or Disable the Gradle Build Cache: Flag or Property +
- Gradle build cache: monorepo, buildSrc and included builds +
- Maven Build Cache Extension in a Multi-Module Project +
- Does the Build Cache Work With Kotlin and Android Builds? +
- Reuse Gradle results in Docker CI, even in fresh containers +
- Let CI write, developers only read: Gradle and Maven cache +
- Can Feature Branches Share the Build Cache With Main? +
- Your Laptop Builds Reuse What CI Already Built +
- Can Several Projects Share One Build Cache Server? +
- Production build cache: Docker Compose, nginx and TLS +
- Gradle build cache on Kubernetes +
- Build cache behind a corporate proxy: Gradle and Maven +
- Use your Gradle build cache over HTTPS with a private CA +
- How big a build cache server? CPU, RAM, disk and load +
- Build cache size limit, eviction and a full disk +
- Is My Build Cache Server Healthy? What to Alert On +
- Upgrade, back up and move a build cache server +
- Can I Restart the Cache Server While Builds Run? +
- Change the Build Cache Logins Without Breaking CI +
- How to clear or reset a self-hosted build cache +
- What Happens to My Build When the Cache Server Is Down? +
- Build Cache Server Won't Start: Errors and Fixes +
- Gradle build cache not working or hit rate low: causes +
- How Do I Know My Build Cache Hit Rate? +
- Does a Remote Cache Slow Your Build When It Misses? +
- Why Did This One Task Miss the Build Cache? +
- Maven build cache extension not restoring: the causes +
- Gradle remote build cache authentication and 401 errors +
- Skip tests that passed: Gradle and Maven build cache +
- Verify a release yourself: signature, provenance, SBOM, VEX +
- Everything FosterStack does for security +
- Scanning FosterStack in your compliance pipeline +
- How FosterStack Cache is built and signed +
- NIST SP 800-204C, 800-204D and SLSA: Our Release Pipeline +
- Security policy: how to report a vulnerability +
- FIPS 140-3 build cache: run the FIPS image and confirm it +
- Can Someone Poison Our Shared Build Cache? +
- Can a Failed or Cancelled Build Poison the Cache? +
- Does a Build Cache Entry Contain My Source Code or Secrets? +
- What does the build cache store? Gradle and Maven +
- Signed releases you can verify in minutes. -
- Build record, parts list (SBOM) and vulnerability statements published with every release. -
- Scanned before every release. The current release is rescanned every day. -
- Images assembled twice on separate machines; the results must match. -
- Minimal image, no telemetry. FIPS variant available. -
- Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). -
- MIT-licensed core. Read the code before you run it. -
- One public container image. Free and paid users pull the identical bytes — scan exactly what you deploy. -
- When the paid tiers ship, a license key will unlock them in the same public image — no private registry, no gated downloads. (They are not built; the pricing below is direction, not a shelf.) -
- Security patches are never withheld from the free tier. Not delayed, not embargoed — never. -
- Signed commits, signed releases, public release notes. The repository's SECURITY.md states exactly what the release evidence does and does not prove today. -
- No telemetry, and no required FosterStack connection. The server - reports nothing to us — no usage data, no license check, no update ping — and today's - free core makes no outbound connections at all: it works identically on a machine with - no route to the internet. When the paid features ship, the only outbound traffic will - be what you configure (your identity provider for SSO, your peer replicas for HA) — - endpoints you choose, never FosterStack. -
- This website collects no email addresses. There is no signup - form, no waitlist, and no newsletter. It sets no cookies, runs no analytics, and - loads nothing from a third party. -
- The only personal data FosterStack LLC holds is the irreducible - minimum required to bill a paying customer — handled by Stripe — and whatever you - voluntarily put in an email to support. -
- Your first 15 minutes with a self-hosted build cache +
- Migrate from Build Cache Node +
- Build Cache Node end of life +
- Build Cache Node end of life: what happens and your options -
- Migrate from Build Cache Node: setup, checklist, checks -
- Jenkins and CI build cache -
- Gradle build cache not working or hit rate low: causes -
- Maven remote build cache setup, on/off, and with Gradle +
- Production build cache: Docker Compose, nginx and TLS
- Gradle build cache on Kubernetes -
- Security policy: how to report a vulnerability -
- How big a build cache server? CPU, RAM, disk and load
- Install on an air-gapped network -
- What changes in v0.3.0 (draft) +
- Verify a release yourself
- Everything FosterStack does for security -
- Scanning FosterStack in your compliance pipeline -
- How FosterStack Cache is built and signed -
- Verify a release yourself: signature, provenance, SBOM, VEX -
- FIPS 140-3 build cache: run the FIPS image and confirm it -
- How to clear or reset a self-hosted build cache -
- Changelog -
- Build cache size limit, eviction and a full disk -
- Your first 15 minutes with a self-hosted build cache -
- Your Laptop Builds Reuse What CI Already Built -
- Does a Remote Cache Slow Your Build When It Misses? -
- How Do I Know My Build Cache Hit Rate? -
- Can Someone Poison Our Shared Build Cache? -
- What Happens to My Build When the Cache Server Is Down? -
- Does the Build Cache Work With Kotlin and Android Builds? -
- Can Feature Branches Share the Build Cache With Main? -
- Use a Remote Build Cache in GitHub Actions -
- Is My Build Cache Server Healthy? What to Alert On -
- Can I Restart the Cache Server While Builds Run? -
- Change the Build Cache Logins Without Breaking CI -
- Can Several Projects Share One Build Cache Server? -
- Can a Failed or Cancelled Build Poison the Cache? -
- Does a Build Cache Entry Contain My Source Code or Secrets? -
- Why Did This One Task Miss the Build Cache? -
- Build Cache Server Won't Start: Errors and Fixes -
- Let CI write, developers only read: Gradle and Maven cache -
- Gradle remote build cache authentication and 401 errors -
- Maven build cache extension not restoring: the causes -
- Production build cache: Docker Compose, nginx and TLS -
- Build cache behind a corporate proxy: Gradle and Maven -
- Enable or Disable the Gradle Build Cache: Flag or Property -
- Gradle build cache: monorepo, buildSrc and included builds -
- NIST SP 800-204C, 800-204D and SLSA: Our Release Pipeline -
- Maven Build Cache Extension in a Multi-Module Project -
- Upgrade, back up and move a build cache server -
- Skip tests that passed: Gradle and Maven build cache -
- What does the build cache store? Gradle and Maven -
- Use your Gradle build cache over HTTPS with a private CA -
- Reuse Gradle results in Docker CI, even in fresh containers
- FosterStack Cache FAQ: Gradle, Maven, licence, security
- Your first 15 minutes with a self-hosted build cache
- Migrate from Build Cache Node: setup, checklist, checks
- Build Cache Node end of life: what happens and your options diff --git a/llms.txt b/llms.txt index f812d56..db4701b 100644 --- a/llms.txt +++ b/llms.txt @@ -51,6 +51,7 @@ verifiable against the CI run that produced them. - [Changelog](https://fosterstack.com/changelog/): release notes for v0.1.0, v0.2.1 and v0.2.2. - [For regulated markets](https://fosterstack.com/regulated/): the FIPS build and the public release evidence. - [Build cache size limit, eviction and a full disk](https://fosterstack.com/build-cache-eviction-size-limit/): What a self-hosted build cache does when it reaches its size cap: least-recently-used eviction, real numbers from a 0.2.1 server, and what an oversized entry gets. +- [FosterStack Cache FAQ: Gradle, Maven, licence, security](https://fosterstack.com/faq/): Short answers about what it is, what it works with, its licence, verifying a release and what happens if it is down. - [Your first 15 minutes with a self-hosted build cache](https://fosterstack.com/first-15-minutes-build-cache/): A checklist from nothing to your first FROM-CACHE with a self-hosted Gradle build cache, with the commands timed on a GitHub-hosted machine, release 0.2.2. - [Let CI write, developers only read: Gradle and Maven cache](https://fosterstack.com/gradle-build-cache-ci-writes-developers-read/): Set up a Gradle build cache where CI uploads and laptops only download, with a read-only login the server enforces. Real run on server 0.2.1 and Gradle 9.8.0. - [Gradle remote build cache authentication and 401 errors](https://fosterstack.com/gradle-remote-build-cache-authentication/): Put a password on a self-hosted Gradle build cache and give Gradle the right one: env var, gradle.properties or -P, and what a wrong password looks like. diff --git a/sitemap.xml b/sitemap.xml index dea252e..7839a30 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -39,6 +39,10 @@
- What to verify in a replacement build cache
- FosterStack Cache FAQ: Gradle, Maven, licence, security
- Your first 15 minutes with a self-hosted build cache
- Migrate from Build Cache Node: setup, checklist, checks diff --git a/llms.txt b/llms.txt index db4701b..396bd41 100644 --- a/llms.txt +++ b/llms.txt @@ -51,6 +51,7 @@ verifiable against the CI run that produced them. - [Changelog](https://fosterstack.com/changelog/): release notes for v0.1.0, v0.2.1 and v0.2.2. - [For regulated markets](https://fosterstack.com/regulated/): the FIPS build and the public release evidence. - [Build cache size limit, eviction and a full disk](https://fosterstack.com/build-cache-eviction-size-limit/): What a self-hosted build cache does when it reaches its size cap: least-recently-used eviction, real numbers from a 0.2.1 server, and what an oversized entry gets. +- [What to verify in a replacement build cache](https://fosterstack.com/what-to-verify-in-a-replacement-build-cache/): A checklist you can run against any replacement build cache: signed releases, provenance, read-only logins, eviction, metrics, air-gapped use and licence. - [FosterStack Cache FAQ: Gradle, Maven, licence, security](https://fosterstack.com/faq/): Short answers about what it is, what it works with, its licence, verifying a release and what happens if it is down. - [Your first 15 minutes with a self-hosted build cache](https://fosterstack.com/first-15-minutes-build-cache/): A checklist from nothing to your first FROM-CACHE with a self-hosted Gradle build cache, with the commands timed on a GitHub-hosted machine, release 0.2.2. - [Let CI write, developers only read: Gradle and Maven cache](https://fosterstack.com/gradle-build-cache-ci-writes-developers-read/): Set up a Gradle build cache where CI uploads and laptops only download, with a read-only login the server enforces. Real run on server 0.2.1 and Gradle 9.8.0. diff --git a/sitemap.xml b/sitemap.xml index 7839a30..0309d44 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -39,6 +39,10 @@
- What to verify in a replacement build cache +
- Is a remote build cache worth it? What we measured
- FosterStack Cache FAQ: Gradle, Maven, licence, security
- Your first 15 minutes with a self-hosted build cache
- Migrate from Build Cache Node: setup, checklist, checks diff --git a/is-a-remote-build-cache-worth-it/index.html b/is-a-remote-build-cache-worth-it/index.html new file mode 100644 index 0000000..acd213a --- /dev/null +++ b/is-a-remote-build-cache-worth-it/index.html @@ -0,0 +1,139 @@ + + + + + + +
- A cache that is empty or down makes builds slower, not wrong. See what happens when the server is down. +
- Results are from small test projects on one kind of CI machine. We did not test large projects or other CI products. +
- Your saving depends on how much of your build is work that can be skipped. Turn it on in CI first, then read your own hit rate: how to measure it. +
- A daily watch of what we depend on. Newly published advisories and malicious-package reports about anything we pin are read every day (supply-chain workflow).
- The archive for your platform, for example
fscache_X.Y.Z_linux_amd64.tar.gz.
+ - The archive for your platform, for example
fscache_X.Y.Z_linux_amd64.tar.gz, orfscache-fips_X.Y.Z_linux_amd64.tar.gzfor the FIPS build. From v0.3.0 the archives are for Linux only (amd64 and arm64). There is no macOS archive; on a Mac, use the Linux image under Docker Desktop. checksums.txtandchecksums.txt.bundle, which is the signature over the checksums.cosign, the signature checker. It is one static binary and will not be on a fresh isolated machine.
- - If you run containers: the image as a tar file, for example
crane pull ghcr.io/fosterstack/cache:X.Y.Z fscache-X.Y.Z.tar. Verify the image withcosign verifybefore you export it, while you still have registry access (the image verification guide has the command). Images are published for bothlinux/amd64andlinux/arm64. Across a gap you pick one by hand, so pull on a machine of the destination type, or add--platform.
+ - If you run containers: the image as a tar file, for example
crane pull ghcr.io/fosterstack/cache:X.Y.Z fscache-X.Y.Z.tar, and:X.Y.Z-fipsfor the FIPS image. There are two images, production and-fips; v0.3.0 has no-debugimage. Verify the image withcosign verifybefore you export it, while you still have registry access (verify a release yourself has the command). Images are published for bothlinux/amd64andlinux/arm64. Across a gap you pick one by hand, so pull on a machine of the destination type, or add--platform. - It shows the running program is using Go's validated module. The validation is of that cryptographic module. -
- Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before publishing, the release runs the released FIPS binary (Linux, amd64) and requires its status page to show the
active (Go validated module ...)line. It also starts the FIPS image and stores and fetches a test entry through it. No test yet reads the status page of the running FIPS image, so checking it yourself, as shown above, is still worth doing.
+ - Our own tests run the whole suite against the FIPS build with the module set to refuse any algorithm it does not approve. That proves the code paths the tests reach. Before a release is published, its pipeline starts both candidate images and reads each status page: the
-fipsimage must report FIPS mode active with module v1.0.0, and the production image must report it off. A release that fails this check is not published. The certificate number is our documented mapping for module v1.0.0, not something a binary reports about itself. Checking it yourself, as shown above, is still worth doing. - FosterStack Cache is not "FedRAMP compliant" or "CMMC compliant". Those attach to your service and your organization, never to a component you deploy. The FIPS build is validated crypto for your compliance program, not a substitute for it.
- Linux only for binaries. v0.3.0 ships Linux archives (amd64 and arm64) and no macOS archive. On a Mac, run the Linux container image under Docker Desktop. +
- Two images, no
-debug. The production and-fipsimages hold only thefscachebinary, with no shell. If you used the:debugtag, look inside a running container from outside it withkubectl debugordocker debug.
+ - The data folder is the same. The path has not moved. Temporary files of writes in flight now live in a
+tmpfolder inside it, so a backup of the volume still covers everything.
+ - Your settings keep their meaning. Every
FSCACHE_*setting works as before. The server now logs a warning for anFSCACHE_*variable it does not know, so read the log once after the upgrade for a misspelt name.
+ - Verification commands differ. If your pipeline verifies images, the signing workflow names changed with the new release chain. Use verify a release yourself for v0.3.0 and later. +
- 0.1.0 has no status page.
/statuszreturned 404 there. 0.2.1 has it. The metrics page is on both.
diff --git a/verify-a-release/index.html b/verify-a-release/index.html
index 021936b..5988898 100644
--- a/verify-a-release/index.html
+++ b/verify-a-release/index.html
@@ -5,9 +5,9 @@
- A valid signature proves who signed these exact files. -
- Provenance proves which workflow and run produced them. -
- It does not prove the software has no bugs. +
- A valid signature proves who signed these exact files, and that the signing was recorded publicly. +
- Provenance proves which workflow, at which tag, produced the digests it names. +
- It does not prove the software has no bugs. Scan results and our statements about findings are separate: see the security policy.
A scrape setting
- job_name: fscache static_configs: - targets: ['cache.example.com:8080'] -This is a plain example. Use your own address, and HTTPS if a proxy fronts the server. With the server's own TLS (
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEY) the/healthzcheck moves tohttps://too.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]This is a plain example. Use your own address, and HTTPS if a proxy fronts the server. With the server's own TLS (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY) the/healthzcheck moves tohttps://too.The metrics
These are the names a running 0.2.1 server reports:
diff --git a/laptop-builds-reuse-ci-build-cache/index.html b/laptop-builds-reuse-ci-build-cache/index.html index 6c8cab8..8b30f52 100644 --- a/laptop-builds-reuse-ci-build-cache/index.html +++ b/laptop-builds-reuse-ci-build-cache/index.html @@ -90,7 +90,7 @@ From 3214411d81472a12198154d484fec6f40bdd432c Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:07:14 -0400 Subject: [PATCH 38/40] v0.3 preview: what's-new upgrade sentence --- whats-new-fosterstack-cache-v0-3-0/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index c446bdb..3442d39 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -103,7 +103,7 @@Your laptop builds reuse what CI already built
CI builds your code, and then your laptop builds the same code again from scratch. FosterStack Cache is a build cache server you run yourself: CI stores its results there, and your laptop takes them instead of redoing the work.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
How it works
@@ -113,8 +113,8 @@What has to match
Keep those the same on laptops and CI. For what to expect after an upgrade, see we upgraded Gradle or Maven and builds got slow. If your laptop still rebuilds, see why the Gradle hit rate is low or why the Maven cache is not restoring. To set it up, see Maven remote build cache setup and the Gradle setup in the CI-writes page.
Can we trust the cache server?
-From v0.3.0, releases are signed at every stage and verified together at release, and you can verify it yourself.
-[TO-VERIFY: pipeline: the v0.3 chain]Our target for fixing vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]The checks on this page ran on 0.2.x, and in some of them the cache server ran on a Mac. v0.3.0 ships for Linux only; a Mac laptop is a client either way.
+[TO-VERIFY: cache: v0.3 ships Linux archives and images only]From v0.3.0, releases are signed at every stage and verified together at release, and you can verify it yourself. Our target for fixing vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.
+The checks on this page ran on 0.2.x, and in some of them the cache server ran on a Mac. v0.3.0 ships for Linux only; a Mac laptop is a client either way.
How we checked
+diff --git a/llms.txt b/llms.txt index 6a232c6..79af462 100644 --- a/llms.txt +++ b/llms.txt @@ -57,7 +57,7 @@ verifiable against the CI run that produced them. - [Maven build cache extension not restoring: the causes](https://fosterstack.com/maven-build-cache-extension-not-restoring/): Maven build cache extension builds again instead of restoring from the remote? Causes with real log lines: config placement, saveToRemote, 401 and the local cache. - [How big a build cache server? CPU, RAM, disk and load](https://fosterstack.com/build-cache-server-sizing/): CPU, RAM, disk and the size cap. - [Air-gapped install](https://fosterstack.com/air-gapped-build-cache-install/): download, verify, transfer, run. -- [What changes in v0.3.0 (draft)](https://fosterstack.com/whats-new-fosterstack-cache-v0-3-0/): what to check before you upgrade. TO-VERIFY. +- [What changes in v0.3.0 (draft)](https://fosterstack.com/whats-new-fosterstack-cache-v0-3-0/): what to check before you upgrade. - [How FosterStack Cache is built and signed](https://fosterstack.com/how-we-build/): the release steps and what you can verify. - [Production build cache: Docker Compose, nginx and TLS](https://fosterstack.com/build-cache-docker-compose-production/): A Compose file for a self-hosted build cache behind nginx with TLS and a password, run for real on 0.2.1 and Gradle 9.8.0, with what was and was not tested. - [Build cache behind a corporate proxy: Gradle and Maven](https://fosterstack.com/gradle-build-cache-corporate-proxy/): How Gradle's remote build cache behaves behind a proxy: the settings, the loopback trap, a proxy that refuses, and how to tell it from a cache error. Real run. diff --git a/maven-remote-build-cache-setup/index.html b/maven-remote-build-cache-setup/index.html index 64975a0..a8bea07 100644 --- a/maven-remote-build-cache-setup/index.html +++ b/maven-remote-build-cache-setup/index.html @@ -91,7 +91,7 @@
' % first, 1) -os.makedirs(real) +if os.path.isfile(os.path.join(real, "index.html")): + # a real /guides/ page: keep it, and make sure it lists $first + src = open(os.path.join(real, "index.html")).read() +else: + src = open(os.path.join(site, second, "index.html")).read() + src = re.sub(r"Maven remote build cache: setup, on/off switches, and Gradle on the same server
Share Maven build results across machines using Apache's Build Cache Extension and a self-hosted cache server. FosterStack Cache is that server, and one server can also serve Gradle. About ten minutes, mostly editing the files and choosing your values. The two builds in step 4 took 9 to 12 seconds together on a GitHub-hosted machine.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Who owns what
The client is Apache's Maven Build Cache Extension. We maintain the server. If your hit rate looks low, that is usually the extension's own project settings (which files count as inputs, what to skip), not the server. Start with the extension's configuration guide.
@@ -126,7 +126,7 @@2. Point it at the server, and switch uploads on
</remote> </configuration> </cache> -Keep the comment: a cache setting that points at an unfamiliar host looks like data theft to a reviewer without it. Keep the trailing slash on the URL. Use HTTPS for a real server: behind a proxy, or with the server's own
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEY.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]Keep the comment: a cache setting that points at an unfamiliar host looks like data theft to a reviewer without it. Keep the trailing slash on the URL. Use HTTPS for a real server: behind a proxy, or with the server's own
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY.3. Add the password, if the server has one
In
diff --git a/regulated/index.html b/regulated/index.html index 2db07d4..390edfa 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -90,7 +90,7 @@~/.m2/settings.xml, or your CI system's equivalent. Theidmust match theidin step 2:For teams entering regulated markets
A contract lands with FIPS, SBOM and provenance requirements attached, and your build cache needs paperwork it has never had. FosterStack Cache gives that part of your pipeline public, checkable evidence: a FIPS 140-3 build, an SBOM, build provenance, signatures and VEX statements. It does not make you compliant.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
It usually starts with one customer. A contract lands on the table with @@ -122,11 +122,11 @@
What our piece does — and does not do
What stands behind it
-
-
How we build · Security policy · Verify a release
diff --git a/security/index.html b/security/index.html index a423df9..54828e5 100644 --- a/security/index.html +++ b/security/index.html @@ -89,7 +89,7 @@ ", 'Security policy: how to report a vulnerability
Found a security problem in FosterStack Cache or on this website? Tell us privately. Here is how, what happens next, which version gets fixes, and what we sign and publish so you can check our work.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Report a vulnerability
@@ -101,19 +101,19 @@Report a vulnerability
Send the report, not a patch. Please do not post details publicly before a fix ships.
Kept patched
-We keep FosterStack Cache patched.
+[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.We keep FosterStack Cache patched. Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.
Which version gets fixes
-"LTS" means a version that keeps getting fixes, so you can stay on it.
+[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes.[TO-VERIFY: cache/owner: rewritten once the v0.3.0 support terms exist]"LTS" means a version that keeps getting fixes, so you can stay on it. Today the supported version is the latest minor release: there is no list of older versions that get fixes.
-
-
What we sign and publish
-Releases are built only in CI. Each release goes through the steps on how we build and comes with files you can check without an account.
+[TO-VERIFY: pipeline/cache: the v0.3 chain and the v0.3 file set; the four metadata files signed via the signed checksums list (cache fix A); the list below is the 0.2.x set]Releases are built only in CI. Each release goes through the steps on how we build and comes with files you can check without an account.
What we do not claim
Machine-readable contact: security.txt.
diff --git a/verify-a-release/index.html b/verify-a-release/index.html index 07da2dc..fe2bfc3 100644 --- a/verify-a-release/index.html +++ b/verify-a-release/index.html @@ -88,32 +88,32 @@Verify a FosterStack Cache release yourself
-You should not have to take our word for what you run. Signed at every stage, verified together at release.
-[TO-VERIFY: pipeline]These commands check the final signature, how the image was built, its parts list and what it was assembled from, using onlycosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
-[TO-VERIFY: pipeline]marks anything not yet run against a real release.Use the image by digest for
+<IMAGE_REF>. There are two images, production and fips; run every step for each.[TO-VERIFY: cache: the two variants and their references]You should not have to take our word for what you run. Signed at every stage, verified together at release. These commands check the final signature, how the image was built, its parts list and what it was assembled from, using only
+cosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
+Use the image by digest for
<IMAGE_REF>. There are two images, production and fips; run every step for each.1. The signature and who signed it
-# [TO-VERIFY: pipeline] identity and issuer for the final signature +# identity and issuer for the final signature cosign verify <IMAGE_REF> \ --certificate-identity-regexp '<IDENTITY>' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com2. The digest is the one in the release
-# [TO-VERIFY: pipeline] file name and layout +
-# file name and layout gh release download <TAG> --repo fosterstack/cache -p release-manifest.json jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.jsonEvery statement names the image by digest, never by tag.
+[TO-VERIFY: pipeline]The digest you verified should match this list.Every statement names the image by digest, never by tag. The digest you verified should match this list.
3. How it was built
-# [TO-VERIFY: pipeline] signer workflow +
-# signer workflow gh attestation verify oci://<IMAGE_REF> --repo fosterstack/cache \ --signer-workflow '<WORKFLOW>' --source-ref refs/tags/<TAG>
+[TO-VERIFY: pipeline]One sentence on what this record covers. No SLSA level claim here.One sentence on what this record covers. No SLSA level claim here.
4. The parts list (SBOM)
-# [TO-VERIFY: pipeline] predicate type and what the list holds for an image with no base image +# predicate type and what the list holds for an image with no base image cosign verify-attestation <IMAGE_REF> --type spdxjson \ --certificate-identity-regexp '<IDENTITY>' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ | jq -r '.payload | @base64d | fromjson | .predicate.name'5. What the image was assembled from
-# [TO-VERIFY: pipeline] what "inputs" means for a customer, and the one command that checks it +# what "inputs" means for a customer, and the one command that checks it cosign verify-attestation <IMAGE_REF> --type '<INPUTS_TYPE>' ... | jq '<FILTER>'What this proves
-
@@ -121,7 +121,7 @@
What this proves
Extra evidence, outside these commands: records anyone who has Witness installed can check.
+[TO-VERIFY: pipeline]where they are published.Extra evidence, outside these commands: records anyone who has Witness installed can check.
Related: how releases are built and signed and security policy.
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index b86017e..5746e0f 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -88,22 +88,22 @@ What changes for you in FosterStack Cache v0.3.0
-You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes. Three things may matter on your side: check them before you upgrade.
-[TO-VERIFY: cache: that nothing else needs a change]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes. Three things may matter on your side: check them before you upgrade.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Check these before you upgrade
-
-
What stays the same
-The Gradle and Maven protocols stay as they are, and every
+FSCACHE_*setting you use today keeps its meaning. Two new optional settings,FSCACHE_TLS_CERTandFSCACHE_TLS_KEY, make the server itself serve HTTPS (TLS 1.2 or later); set both or neither.[TO-VERIFY: cache: REQ-TLS-001, merged to main Oct 11 (#296), not yet in a release]The server now binds its address first and logs a warning for anFSCACHE_*variable it does not know.[TO-VERIFY: cache: #257, merged to main Oct 11, not yet in a release][TO-VERIFY: cache: unchanged at v0.3; no test run]A request with more than 500 header values has been rejected with431(Request Header Fields Too Large) since 0.2.2, because of Go 1.27; Gradle and Maven send far fewer.[TO-VERIFY: cache: Go 1.27 behaviour, in 0.2.2 already; the client-side message is not verified]The Gradle and Maven protocols stay as they are, and every
FSCACHE_*setting you use today keeps its meaning. Two new optional settings,FSCACHE_TLS_CERTandFSCACHE_TLS_KEY, make the server itself serve HTTPS (TLS 1.2 or later); set both or neither. The server now binds its address first and logs a warning for anFSCACHE_*variable it does not know. A request with more than 500 header values has been rejected with431(Request Header Fields Too Large) since 0.2.2, because of Go 1.27; Gradle and Maven send far fewer.Kept patched
-
+[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.
How the release is built
-
+[TO-VERIFY: pipeline: the v0.3 chain]Signed at every stage, verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.Signed at every stage, verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.
Upgrading
-
+[TO-VERIFY: cache: the 0.2.2 to 0.3.0 upgrade steps]Whether the back-up and upgrade steps on the upgrade page change for this release. Support terms for v0.3.0:[TO-VERIFY: cache/owner: what the long-term-support line promises].Whether the back-up and upgrade steps on the upgrade page change for this release.
Related: changelog and security policy.
From 273487ddb9fe0a01f02b57d145acbcfef34b9dc2 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:55:13 -0400 Subject: [PATCH 26/40] v0.3 preview: home rebuilt from the live page with the new intro and trust card; paid LTS off pricing; NIST and SLSA page as two jobs --- .../index.html | 32 +++++------ index.html | 57 ++++++++++--------- llms.txt | 2 +- 3 files changed, 44 insertions(+), 47 deletions(-) diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index f52ae85..01417e1 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -89,29 +89,25 @@ diff --git a/index.html b/index.html index 966f3c6..0a19fba 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,12 @@ -How the v0.3.0 release pipeline maps to NIST and SLSA
-If you have to explain our release pipeline to a security reviewer, start here. This page puts each stage of the new release pipeline next to the NIST practice it was designed against, and says where a stage only partly implements a practice.
+If you have to explain our release pipeline to a security reviewer, start here. This page does two jobs: how each stage lines up with NIST SP 800-204C and 800-204D, and how the pipeline lines up with SLSA.
DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
-This is guidance we followed when designing the pipeline. It is not a certification.
-Stage by stage
+How we line up with NIST
+We used two documents: SP 800-204C (Implementation of DevSecOps for a Microservices-based Application with Service Mesh), mainly sections 3.3, 4.6 and 4.8, and SP 800-204D (Strategies for the Integration of Software Supply Chain Security in DevSecOps CI/CD Pipelines), mainly sections 5.1.1 and 5.2. Both also cover running services in your own cluster; that is your environment, so the table covers our release pipeline only.
The stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
-+
+
- -Stage What it does NIST practice How much -Build Checks that the tag is signed, then builds the binaries and both images once. The image is assembled from those packages, with no base image. 800-204D 5.1.1 -Sign A separate stage records the build and signs it under its own identity, from the build's digest list only. the part of 5.1.1 that asks for signing outside the build steps -Rebuild Assembles the image again, independently, on a separate machine. The digests must match or the release fails. none found in either document -Check Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests. 800-204C 4.8 and 800-204D 5.2 +Release Verifies every stage's signature together, then publishes the same digests. +Build Checks that the tag is signed, then builds the binaries and both images once. The image is assembled from those packages, with no base image. 800-204D 5.1.1 "Secure Build"; 800-204C 3.3.3 (SBOM generation and code signing as pipeline tasks) Matches the practice as we read it. +Sign A separate stage records the build and signs it under its own identity, from the build's digest list only. 800-204D 5.1.1 (signing outside the build steps); 800-204C 4.6 (signing during each required stage) Partly. 4.6 prefers multi-party signing; every signature here is made by automation in one repository. +Rebuild Assembles the image again, independently, on a separate machine. The digests must match or the release fails. No direct match in either document. Not mapped. It repeats the image assembly; it does not rebuild the binaries from source. +Check Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests. 800-204C 4.8 and 800-204D 5.2 Partly. The pipeline runs no static or dynamic application security testing itself, and the signed verdict records a pass, not the full scan report. -Release Verifies every stage's signature together, then publishes the same digests. 800-204C 4.6 (verify that all required signatures are present); 800-204D 5.1.1 (policy checks that the required attestations are found) and 5.2 DEPLOY-REQ-3 Partly. The policy is code in the workflow file, not a separate signed policy document as 5.1.1 describes. Our wording: signed at every stage, verified together at release.
-SLSA
-The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.
-What this page does not say
--
-
In one line: signed at every stage, verified together at release.
+How we line up with SLSA
+SLSA is a public scale for how far you can trust the way software was built. Its Build track runs from Level 0 to Level 3. We assess v0.3.0 at Build Level 3.
+Level 3 asks that the build runs on a hosted platform and that its provenance, the signed record of how the build ran, cannot be forged by the build itself. Here, the Build stage runs on a hosted CI platform and does not hold the signing identity. The Sign stage receives only the build's digest list, records the build and signs it under its own identity. The Release stage accepts a build only if that signature verifies. You can check this yourself: see verify a release yourself.
Related: verify a release yourself and how releases are built and signed.
FosterStack — self-hosted build cache for Gradle and Maven - + - + @@ -88,24 +87,26 @@Infrastructure worth keeping — and kept patched.- DRAFT for v0.3, private preview, not published.
++ Gradle Inc. has deprecated the free Develocity Build Cache Node: it "will no longer be + distributed, supported or available after December 31, 2026." The migration path they + offer requires a commercial Develocity subscription. + What that means and your options. +-Your CI keeps rebuilding what it already built.
- The cache that fixes it is one more thing in your pipeline you have to trust. FosterStack Cache - is a self-hosted build cache for Gradle and Maven. Your builds reuse each - other's results, and you can check that the cache you run is the one we built. - Open source core, one-command deploy. The same server speaks the Gradle remote build cache - protocol and the Apache Maven Build Cache Extension's remote HTTP mode, so a mixed Gradle and - Maven shop runs one deploy instead of two. + We build tools that help you secure your build pipeline. It made sense to start with the build cache. We built FosterStack Cache by meticulously following the security guidance that matters: CISA Secure by Design, NIST SP 800-204C and 800-204D, and SLSA. Where the guidance stops, we kept going: hermetic, reproducible builds, a distroless image, and more. Read the full list.
-Three promises
--+-Software you can keep running safely
Kept patched, whether it is new or abandoned upstream. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md and on the security page.
-Provably
Every release is signed and checked at every step, and you can verify it yourself.
-Because we do it to our own pipeline first
We started with a build cache your team can know is secure, and we secure our own release pipeline the same way before we ask you to run it. How we build.
Fast builds from cache are worth keeping.
++ FosterStack is a self-hosted remote build cache server — a Develocity Build Cache Node + replacement that speaks the same Gradle remote build cache HTTP protocol, so migrating is + mostly a URL change. The same server implements the Apache Maven Build Cache Extension's + remote HTTP mode, so a mixed Gradle and Maven + shop runs one deploy instead of two. Open source core, one-command deploy, and the thing + that matters: it stays patched, on a promise. +
Try it now
There is no signup, no waitlist, and no license key for the free tier. Pull the @@ -114,7 +115,7 @@
Try it now
curl localhost:8080/healthz # -> okQuickstart - Migrate an existing cache + Migrate off Build Cache Node Read the source
Bugs and questions go to GitHub issues, which is also where the roadmap is settled.
@@ -134,17 +135,18 @@What you get that a bare HTTP endpoint doesn't give you
Authentication
HTTP Basic Auth over TLS, wired the way Gradle and Maven already expect credentials. Constant-time comparison, no credential ever logged.
Metrics & status
Prometheus metrics, a read-only status page with hit rates and size-vs-cap, and a Grafana dashboard in the repo — so you know the cache is earning its keep.
-Maintenance target
Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
-Designed against NIST guidance
No step trusts the one before it. When you check our images' digital signatures you can rest assured we checked it at every step before we released it. That signature means it's fosterstack code, a fosterstack build, a fosterstack image and everything in between. See how each stage maps.
A signature shows who signed these exact files and that nothing changed them since; it does not show the code is free of bugs or vulnerabilities. This is guidance we designed against, not a certification we hold.
+30-minute migration
A step-by-step guide for moving an existing Gradle remote build cache server. Same protocol, same CI config shape — migrating is mostly a URL change.
+Meticulous pipeline security
Every step of our release produces signed provenance. When a FosterStack signature verifies, you know it's FosterStack code, a FosterStack build and a FosterStack image, and everything in between. See how each stage maps.
-30-minute migration
A step-by-step guide for existing Build Cache Node deployments. Same protocol, same CI config shape — migrating is mostly a URL change.
What stands behind it
+More than kept patched.
How we build · Security policy · Verify a release
@@ -153,7 +155,7 @@Built to be verified, not trusted
The answer is to make everything checkable:What we do not collect
Pricing
Per product. Free is the full product.
-Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics, HA/replication and named-version LTS are not built.
+Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics and HA/replication are not built.
Free Team Business Compliance @@ -192,8 +194,8 @@ Pricing
the CVE-response target.$499/month, billed annually — everything in Business, plus the FIPS 140-3 applicability statement, signed per-release attestation letters addressed to you, - security-questionnaire support up to 8 hours per year (async), and named-version - LTS. Who this is for. + and security-questionnaire support up to 8 hours per year (async). + Who this is for.No sales call. No per-seat tax. No enterprise pricing mystery.
@@ -220,7 +222,6 @@Guides
Everything FosterStack does for security + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +Everything we do for security
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+This is the list of security practices that run on the FosterStack Cache repository today, one line each. Every line links to the place that goes deep: a page that explains it, or the file that does it. SECURITY.md is the short policy (what we promise); this page is what we do.
+Source
+-
+
Dependencies
+-
+
Build
+-
+
Scanning
+-
+
Release
+-
+
Runtime
+-
+
Watch
+-
+
Related: how releases are built and signed, verify a release yourself and the security policy.
++ + + diff --git a/index.html b/index.html index 0a19fba..da23022 100644 --- a/index.html +++ b/index.html @@ -222,6 +222,8 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+Guides
https://fosterstack.com/how-our-pipeline-maps-to-nist-and-slsa/ 2026-10-08 ++ https://fosterstack.com/everything-we-do-for-security/ +2026-10-13 + +https://fosterstack.com/how-we-build/ 2026-10-08 From cd0f3dc337ee0d16c0f208afd7cd21b912f0c48f Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Tue, 13 Oct 2026 22:36:25 -0400 Subject: [PATCH 28/40] v0.3 preview: Scanning FosterStack in your compliance pipeline (site copy of the cache scanning guide) --- index.html | 1 + llms.txt | 1 + scan-fosterstack-cache-image/index.html | 175 ++++++++++++++++++++++++ sitemap.xml | 4 + 4 files changed, 181 insertions(+) create mode 100644 scan-fosterstack-cache-image/index.html diff --git a/index.html b/index.html index da23022..0b0b06d 100644 --- a/index.html +++ b/index.html @@ -224,6 +224,7 @@Guides
Scanning FosterStack in your compliance pipeline + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +Scanning FosterStack in your compliance pipeline
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+Every scanner in the repo's scanner list runs against a snapshot build of every release, and the current release's images are rescanned daily;
+RELEASING.mdstates exactly what the release scan does and does not attach to. This page is about what to expect when you scan our image, since a minimal image scans differently from a typical distro image in ways that surprise people the first time.What to expect
+The production and
+-fipsimages report asdebianin scanner OS detection, even though there's no shell, no package manager, and no way toapt-getanything. Confirmed directly against a real build:
+$ trivy image ghcr.io/fosterstack/cache:${VER} +... +Detected OS family="debian" version="13.6" +... +┌──────────────────────────────────┬──────────┬─────────────────┐ +│ Target │ Type │ Vulnerabilities │ +├──────────────────────────────────┼──────────┼─────────────────┤ +│ ghcr.io/fosterstack/cache (debian)│ debian │ 0 │ +├──────────────────────────────────┼──────────┼─────────────────┤ +│ usr/local/bin/fscache │ gobinary │ 0 │ +└──────────────────────────────────┴──────────┴─────────────────┘Google's distroless base ships an intact
+/etc/os-releasedeliberately (that's exactly what scanners key OS detection on), and we never strip it — see the scanner-facts source for this page,sprint4_scanner_input.md. Thegobinaryrow is our own compiled binary, scanned by both tools' Go-module vulnerability catalogers directly.Package-DB asymmetry — expect this, it isn't a bug
+A scratch/distroless image has no package database. That has an asymmetric effect on checks:
+-
+
If you run a benchmark or policy pack written for a full-OS image (Debian, Ubuntu, etc.) against ours, expect confusing partial results — not a finding, just a mismatch between the benchmark's assumptions and a minimal image.
+sprint4_scanner_input.md's source material for this page also notes there is often no genuine OS/platform gating in scanner content by default: a scanner may happily score a scratch image against a full distro benchmark and produce results that don't mean what they look like they mean. Don't over-read a scratch image's score against a Debian-shaped policy without checking what each rule verifies.Exit codes: don't gate on the raw process exit code
+Trivy and Grype's exit codes conflate "ran and found something above your threshold" with "could not run at all" in ways that are easy to miss. Read per-rule verdicts from the results document (JSON/SARIF), never gate a pipeline purely on the raw exit code — a broken scan and a clean scan can both look like "exit 0" or both look like "exit 1" depending on flags, and conflating them ships a green gate that checks nothing. This failure mode has been observed in the field.
+The -debug variant is different on purpose
+The
+:debugtag adds a busybox shell for interactive troubleshooting — it is not the image you deploy. Scanning it will show more than the production image (busybox itself carries a small package surface), and our own release pipeline documents any known, unfixable findings there as explicit VEX suppressions in.grype.yamlrather than hiding them — see that file for the current reasoning on each entry. Production and-fipsimages never include busybox.Using our VEX files in your scanner
+Each release carries our exceptions as published statements, generated from one source (
+.vex/). Download them from the release page (gh release download v${VER} --repo fosterstack/cache -p 'fosterstack-cache*') and check them against the signed release manifest as described in Verify our images. Then apply the form your scanner reads:++
+ +Your scanner File How +Grype fosterstack-cache.openvex.jsongrype IMAGE --vex fosterstack-cache.openvex.json +Trivy fosterstack-cache.openvex.jsontrivy image --vex fosterstack-cache.openvex.json IMAGE +Docker Scout fosterstack-cache.openvex.jsondocker scout cves --vex-location fosterstack-cache.openvex.json IMAGE +Amazon Inspector fosterstack-cache-<version>.inspector-filters.jsonone suppression rule per statement: aws inspector2 create-filter, one rule per call + +Google Artifact Analysis fosterstack-cache-<version>.csaf.jsongcloud artifacts vulnerabilities load-vex, see.vex/README.mdfor naming your image pathThe three files hold the same statements in three formats. The Inspector file carries one rule per
+not_affectedorfixedstatement, and Google applies whole-image statements only;.vex/README.mdhas the detail.Suppression rules
+A suppression rule in your scanner is only as trustworthy as the claim behind it, so ours work in one direction: every suppression traces to a published statement.
+-
+
Docker Scout
+Docker Scout reads OpenVEX directly. Point it at the file with
+--vex-location:
+docker scout cves --vex-location fosterstack-cache.openvex.json \ + ghcr.io/fosterstack/cache:${VER}Run it once with and once without
+--vex-location: the difference is exactly the set of published statements, the same audit as in the Grype and Trivy runs below.Reproducing our own gate
+Our release pipeline's scan step is public —
+.github/workflows/release.yml— so the exact invocation we gate releases on is not a secret:The gate's policy is every severity, with the published VEX applied — so a faithful reproduction uses the same. The VEX document ships with each release as
+fosterstack-cache.openvex.jsonand lives in-repo at.vex/:
+# Same severity policy and VEX as the release gate: +trivy image --scanners vuln \ + --severity CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN \ + --vex fosterstack-cache.openvex.json \ + ghcr.io/fosterstack/cache:X.Y.Z + +grype ghcr.io/fosterstack/cache:X.Y.Z \ + --fail-on negligible --vex fosterstack-cache.openvex.jsonRun without
+--vexto see raw findings including the ones we have publicly dispositioned — the difference between the two runs is exactly the set of published VEX statements, which is how you audit them.Marketing claim, with the receipt
+"Every scanner in the repo's list runs on every release, verdicts in the public CI run" is not a claim we're asking you to take on faith — the scan IS the CI run, public, in this repo's Actions tab. See Verify our images for how to confirm the exact image you pulled came from that same run.
+Related: everything we do for security, verify a release yourself.
++ + + diff --git a/sitemap.xml b/sitemap.xml index e734045..61ac14c 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -71,6 +71,10 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+https://fosterstack.com/everything-we-do-for-security/ 2026-10-13 + https://fosterstack.com/scan-fosterstack-cache-image/ +2026-10-13 +https://fosterstack.com/how-we-build/ 2026-10-08 From a036b3c8b22b9a9caaba4ce0148ec41f21b7d0f9 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Tue, 13 Oct 2026 23:28:37 -0400 Subject: [PATCH 29/40] v0.3 preview: re-mirror the security and scanning pages from cache#327 head 6c51647 --- everything-we-do-for-security/index.html | 38 ++++++++++----------- scan-fosterstack-cache-image/index.html | 42 +++++++++++++----------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/everything-we-do-for-security/index.html b/everything-we-do-for-security/index.html index 0c1d637..57a0757 100644 --- a/everything-we-do-for-security/index.html +++ b/everything-we-do-for-security/index.html @@ -90,22 +90,22 @@Infrastructure worth keeping — and kept patched.- Everything we do for security
+Everything FosterStack does for security
DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
-This is the list of security practices that run on the FosterStack Cache repository today, one line each. Every line links to the place that goes deep: a page that explains it, or the file that does it. SECURITY.md is the short policy (what we promise); this page is what we do.
+This is the list of security practices that run on the FosterStack Cache repository today, one line each. Every line links to the place that goes deep: a page that explains it, or the file that does it. SECURITY.md is the short policy (what we promise, including the patch target and how to report a vulnerability); this page is what we do.
Source
--
-
-
+
Dependencies
--
+
Dependencies
Build
--
+
Scanning
--
+
Release
--
+
Runtime
--
+
Watch
--
-
Related: how releases are built and signed, verify a release yourself and the security policy.
diff --git a/scan-fosterstack-cache-image/index.html b/scan-fosterstack-cache-image/index.html index dd66e88..a4961fb 100644 --- a/scan-fosterstack-cache-image/index.html +++ b/scan-fosterstack-cache-image/index.html @@ -106,18 +106,18 @@What to expect
├──────────────────────────────────┼──────────┼─────────────────┤ │ usr/local/bin/fscache │ gobinary │ 0 │ └──────────────────────────────────┴──────────┴─────────────────┘ -Google's distroless base ships an intact
+/etc/os-releasedeliberately (that's exactly what scanners key OS detection on), and we never strip it — see the scanner-facts source for this page,sprint4_scanner_input.md. Thegobinaryrow is our own compiled binary, scanned by both tools' Go-module vulnerability catalogers directly.Google's distroless base ships an intact
/etc/os-releasedeliberately (that's exactly what scanners key OS detection on), and we never strip it. Thegobinaryrow is our own compiled binary, scanned by both tools' Go-module vulnerability catalogers directly.Package-DB asymmetry — expect this, it isn't a bug
A scratch/distroless image has no package database. That has an asymmetric effect on checks:
If you run a benchmark or policy pack written for a full-OS image (Debian, Ubuntu, etc.) against ours, expect confusing partial results — not a finding, just a mismatch between the benchmark's assumptions and a minimal image.
+sprint4_scanner_input.md's source material for this page also notes there is often no genuine OS/platform gating in scanner content by default: a scanner may happily score a scratch image against a full distro benchmark and produce results that don't mean what they look like they mean. Don't over-read a scratch image's score against a Debian-shaped policy without checking what each rule verifies.If you run a benchmark or policy pack written for a full-OS image (Debian, Ubuntu, etc.) against ours, expect confusing partial results — not a finding, just a mismatch between the benchmark's assumptions and a minimal image. Scanner content often has no OS or platform gating by default, so a scanner may score a scratch image against a full distro benchmark and produce results that don't mean what they look like they mean. Don't over-read a scratch image's score against a Debian-shaped policy without checking what each rule verifies.
Exit codes: don't gate on the raw process exit code
-Trivy and Grype's exit codes conflate "ran and found something above your threshold" with "could not run at all" in ways that are easy to miss. Read per-rule verdicts from the results document (JSON/SARIF), never gate a pipeline purely on the raw exit code — a broken scan and a clean scan can both look like "exit 0" or both look like "exit 1" depending on flags, and conflating them ships a green gate that checks nothing. This failure mode has been observed in the field.
-The -debug variant is different on purpose
-The
+:debugtag adds a busybox shell for interactive troubleshooting — it is not the image you deploy. Scanning it will show more than the production image (busybox itself carries a small package surface), and our own release pipeline documents any known, unfixable findings there as explicit VEX suppressions in.grype.yamlrather than hiding them — see that file for the current reasoning on each entry. Production and-fipsimages never include busybox.Trivy and Grype's exit codes conflate "ran and found something above your threshold" with "could not run at all" in ways that are easy to miss. Read per-rule verdicts from the results document (JSON/SARIF), never gate a pipeline purely on the raw exit code — a broken scan and a clean scan can both look like "exit 0" or both look like "exit 1" depending on flags, and conflating them ships a green gate that checks nothing.
+The -debug variant
+The
:debugtag adds a busybox shell for interactive troubleshooting; it is not the image you deploy. Scanning it shows more than the production image, because busybox itself carries a small package surface, and any known finding there that has no fix is published as a VEX statement rather than hidden. The production and-fipsimages never include busybox.Using our VEX files in your scanner
Each release carries our exceptions as published statements, generated from one source (
.vex/). Download them from the release page (gh release download v${VER} --repo fosterstack/cache -p 'fosterstack-cache*') and check them against the signed release manifest as described in Verify our images. Then apply the form your scanner reads:-@@ -125,12 +125,12 @@
Using our VEX files in your scanner
Grype fosterstack-cache.openvex.jsongrype IMAGE --vex fosterstack-cache.openvex.json -Trivy fosterstack-cache.openvex.jsontrivy image --vex fosterstack-cache.openvex.json IMAGE +Docker Scout fosterstack-cache.openvex.jsondocker scout cves --vex-location fosterstack-cache.openvex.json IMAGEDocker Scout fosterstack-cache.openvex.jsondocker scout cves --vex-location fosterstack-cache.openvex.json --vex-author '^FosterStack LLC$' IMAGE(see Docker Scout)Amazon Inspector fosterstack-cache-<version>.inspector-filters.jsonone suppression rule per statement: aws inspector2 create-filter, one rule per callGoogle Artifact Analysis fosterstack-cache-<version>.csaf.jsongcloud artifacts vulnerabilities load-vex, see.vex/README.mdfor naming your image pathThe three files hold the same statements in three formats. The Inspector file carries one rule per
+not_affectedorfixedstatement, and Google applies whole-image statements only;.vex/README.mdhas the detail.The three files are generated from the same statements. The OpenVEX and CSAF files carry every statement; the Inspector file carries one rule per
not_affectedorfixedstatement and none foraffectedorunder_investigation. Google applies whole-image statements only..vex/README.mdhas the detail.Suppression rules
A suppression rule in your scanner is only as trustworthy as the claim behind it, so ours work in one direction: every suppression traces to a published statement.
-
@@ -140,24 +140,26 @@
Suppression rules
Docker Scout
-Docker Scout reads OpenVEX directly. Point it at the file with
+--vex-location:Docker Scout reads OpenVEX directly. It applies only the statements whose author matches
--vex-author(by default Docker's own), so name ours, the author recorded in the published file:
-docker scout cves --vex-location fosterstack-cache.openvex.json \ + --vex-author '^FosterStack LLC$' \ ghcr.io/fosterstack/cache:${VER}Run it once with and once without
+--vex-location: the difference is exactly the set of published statements, the same audit as in the Grype and Trivy runs below.Run it once with and once without
--vex-locationand--vex-author: the difference is the set of findings that applicablenot_affectedandfixedstatements suppress, the same audit as in Reproducing our own gate.Reproducing our own gate
-Our release pipeline's scan step is public —
-.github/workflows/release.yml— so the exact invocation we gate releases on is not a secret:The gate's policy is every severity, with the published VEX applied — so a faithful reproduction uses the same. The VEX document ships with each release as
-fosterstack-cache.openvex.jsonand lives in-repo at.vex/:
+# Same severity policy and VEX as the release gate: -trivy image --scanners vuln \ +The release pipeline's scan stage is public:
+.github/workflows/stage-verify.ymlruns one job per scanner in the scanner list (today Grype and OSV-Scanner) against the exact candidate digests: every variant and architecture, and for Grype every release archive too. The Grype and OSV-Scanner commands below are partial examples that use the gate's scanners and its severity policy on one public tag; they show what a scan of that tag reports and do not cover everything the gate covers.Grype runs in the gate at every severity with the published VEX applied. The VEX document ships with each release as
+fosterstack-cache.openvex.jsonand lives in-repo at.vex/:
+grype ghcr.io/fosterstack/cache:X.Y.Z \ + --fail-on negligible --vex fosterstack-cache.openvex.jsonOSV-Scanner runs in the gate on the images and on the Go module manifests:
+
+osv-scanner scan image ghcr.io/fosterstack/cache:X.Y.ZTrivy is not a gate command. If you run it, the example below uses the same severity set and the same file, which makes its result comparable but not gate-equivalent:
+
-trivy image --scanners vuln \ --severity CRITICAL,HIGH,MEDIUM,LOW,UNKNOWN \ --vex fosterstack-cache.openvex.json \ - ghcr.io/fosterstack/cache:X.Y.Z - -grype ghcr.io/fosterstack/cache:X.Y.Z \ - --fail-on negligible --vex fosterstack-cache.openvex.jsonRun without
---vexto see raw findings including the ones we have publicly dispositioned — the difference between the two runs is exactly the set of published VEX statements, which is how you audit them.Marketing claim, with the receipt
-"Every scanner in the repo's list runs on every release, verdicts in the public CI run" is not a claim we're asking you to take on faith — the scan IS the CI run, public, in this repo's Actions tab. See Verify our images for how to confirm the exact image you pulled came from that same run.
+ ghcr.io/fosterstack/cache:X.Y.ZTo see the findings without our statements applied, run Grype or Trivy without
+--vex, or Docker Scout without--vex-locationand--vex-author. The difference between the two runs is the set of findings that applicablenot_affectedandfixedstatements suppress, which is how you audit them.Confirming the scan is the release run
+Every scanner in the repo's list runs on every release, and the verdicts are in the public CI run: the scan is the CI run, in this repository's Actions tab. See Verify our images for how to confirm the exact image you pulled came from that same run.
Related: everything we do for security, verify a release yourself.
From 84fb31f130486623cef695a3c734daa8152d7747 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:28:34 -0400 Subject: [PATCH 30/40] v0.3 preview: home page in the owner's layout; new /guides/ and /roadmap/; Compliance paragraph moved to /regulated/ --- guides/index.html | 171 +++++++++++++++++++++++++++++++++++++++++++ index.html | 143 ++++++------------------------------ llms.txt | 2 + regulated/index.html | 12 +++ roadmap/index.html | 115 +++++++++++++++++++++++++++++ sitemap.xml | 8 ++ 6 files changed, 330 insertions(+), 121 deletions(-) create mode 100644 guides/index.html create mode 100644 roadmap/index.html diff --git a/guides/index.html b/guides/index.html new file mode 100644 index 0000000..051a30b --- /dev/null +++ b/guides/index.html @@ -0,0 +1,171 @@ + + + + + + + Guides + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +Guides
+Start here
+-
+
Set it up
+-
+
Run it
+-
+
When it misses or fails
+-
+
Trust it
+-
+
+ + + diff --git a/index.html b/index.html index 0b0b06d..bd4781f 100644 --- a/index.html +++ b/index.html @@ -87,6 +87,10 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+Infrastructure worth keeping — and kept patched.+ + We build tools that help you secure your build pipeline. It made sense to start with the build cache. We built FosterStack Cache by meticulously following the security guidance that matters: CISA Secure by Design, NIST SP 800-204C and 800-204D, and SLSA. Where the guidance stops, we kept going: hermetic, reproducible builds, a distroless image, and more. Read the full list. +
+Gradle Inc. has deprecated the free Develocity Build Cache Node: it "will no longer be distributed, supported or available after December 31, 2026." The migration path they @@ -94,9 +98,6 @@ What that means and your options.-- We build tools that help you secure your build pipeline. It made sense to start with the build cache. We built FosterStack Cache by meticulously following the security guidance that matters: CISA Secure by Design, NIST SP 800-204C and 800-204D, and SLSA. Where the guidance stops, we kept going: hermetic, reproducible builds, a distroless image, and more. Read the full list. -
Fast builds from cache are worth keeping.
@@ -120,13 +121,6 @@
Try it now
Bugs and questions go to GitHub issues, which is also where the roadmap is settled.
-Stay in touch
-We do not collect email addresses. To follow the project, - star the repository or use - Watch → Custom → Releases on GitHub — that notifies you on a new - release and nothing else, and it is a subscription you control and can revoke without - asking us.
-What you get that a bare HTTP endpoint doesn't give you
Yes — Gradle's remote cache protocol is just GET and PUT, and you could point it at any object store. What you'd be rebuilding yourself is everything around that:
@@ -134,55 +128,16 @@What you get that a bare HTTP endpoint doesn't give you
Cache management
Size-capped LRU eviction that keeps a busy CI cache healthy without hand-tending — set the cap, and the oldest-unused entries make room.
Authentication
HTTP Basic Auth over TLS, wired the way Gradle and Maven already expect credentials. Constant-time comparison, no credential ever logged.
-Metrics & status
Prometheus metrics, a read-only status page with hit rates and size-vs-cap, and a Grafana dashboard in the repo — so you know the cache is earning its keep.
-Maintenance target
Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
Meticulous pipeline security
Every step of our release produces signed provenance. When a FosterStack signature verifies, you know it's FosterStack code, a FosterStack build and a FosterStack image, and everything in between. See how each stage maps.
-30-minute migration
A step-by-step guide for existing Build Cache Node deployments. Same protocol, same CI config shape — migrating is mostly a URL change.
More than kept patched.
--
-
How we build · Security policy · Verify a release
- -Built to be verified, not trusted
-We're a new vendor asking to sit in your build pipeline, so the burden of proof is on us. - The answer is to make everything checkable:
--
-
What we do not collect
--
-
Deliberately not claiming "we never collect any personal data": - billing a customer requires an email address, and a privacy claim that is convenient - but false is worse than none.
+Meticulous pipeline security
+Every step of our release produces signed provenance. When a FosterStack signature verifies, you know it's FosterStack code, a FosterStack build and a FosterStack image, and everything in between. No telemetry. Nothing outbound. It runs the same air-gapped.
+How we build · Security policy · Everything we do for security
Pricing
Per product. Free is the full product.
-Paid tiers are described here, not sold: checkout is not open, and SSO, multi-user access control, usage analytics and HA/replication are not built.
+Paid tiers are coming; checkout isn't open yet.
Free Team Business Compliance @@ -199,80 +154,26 @@ Pricing
No sales call. No per-seat tax. No enterprise pricing mystery.
-- The Compliance tier, plainly: the security evidence underneath — SBOMs, SLSA - provenance, signatures, VEX statements, and the FIPS 140-3 validated module - (CMVP certificate #5247) — is public and free, verifiable by anyone. What the tier - describes is the authored analysis — a FIPS applicability statement mapping the - validated module boundary onto this product — plus per-release attestation letters - signed by FosterStack LLC, and time on your security questionnaires. FosterStack - Cache is not "FedRAMP compliant" or "CMMC compliant"; those attach to your service - and your organization, never to a component you deploy. It is validated crypto and - publishable evidence for your compliance program. -
Guides
+Start here
+-
+
Run it
-
-
Trust it
+-
+
Roadmap honesty
-Gradle and Maven both run against the same server today; we maintain the cache - server, while the Maven client side is Apache's own Build Cache Extension. A dependency cache — - the same server restoring
+node_modules,~/.m2, and -~/.gradle/cachesby lockfile key, so ephemeral CI agents stop - re-downloading the world — is next on the list, npm first. The Helm chart and the paid tiers above are not built; they are described so you can see the direction. Free - is real and complete today. If you need something sooner, - open an issue — that is what - moves the roadmap. diff --git a/llms.txt b/llms.txt index e8a89b0..f812d56 100644 --- a/llms.txt +++ b/llms.txt @@ -60,6 +60,8 @@ verifiable against the CI run that produced them. - [What changes in v0.3.0 (draft)](https://fosterstack.com/whats-new-fosterstack-cache-v0-3-0/): what to check before you upgrade. - [Everything FosterStack does for security](https://fosterstack.com/everything-we-do-for-security/): every security practice that runs, one line each, with where to check it. - [Scanning FosterStack in your compliance pipeline](https://fosterstack.com/scan-fosterstack-cache-image/): what to expect when you scan the image and how to apply our VEX statements. +- [Guides](https://fosterstack.com/guides/): every guide, grouped by topic. +- [Roadmap honesty](https://fosterstack.com/roadmap/): what runs today and what is next. - [How FosterStack Cache is built and signed](https://fosterstack.com/how-we-build/): the release steps and what you can verify. - [Production build cache: Docker Compose, nginx and TLS](https://fosterstack.com/build-cache-docker-compose-production/): A Compose file for a self-hosted build cache behind nginx with TLS and a password, run for real on 0.2.1 and Gradle 9.8.0, with what was and was not tested. - [Build cache behind a corporate proxy: Gradle and Maven](https://fosterstack.com/gradle-build-cache-corporate-proxy/): How Gradle's remote build cache behaves behind a proxy: the settings, the loopback trap, a proxy that refuses, and how to tell it from a cache error. Real run. diff --git a/regulated/index.html b/regulated/index.html index 390edfa..dcaa97f 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -155,6 +155,18 @@@@ -282,7 +183,7 @@Roadmap honesty
of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not ours. -© 2026 FosterStack · Build Cache Node end of life · Migrate · FAQ · CI setup · How we build · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+© 2026 FosterStack · Build Cache Node end of life · Migrate · FAQ · CI setup · How we build · For regulated markets · Roadmap · github.com/fosterstack/cache · hello@fosterstack.com
Verify everything yourself first
-fipsimage and confirm FIPS mode from its own startup log: FIPS 140-3 build cache. + ++ The Compliance tier, plainly: the security evidence underneath — SBOMs, SLSA + provenance, signatures, VEX statements, and the FIPS 140-3 validated module + (CMVP certificate #5247) — is public and free, verifiable by anyone. What the tier + describes is the authored analysis — a FIPS applicability statement mapping the + validated module boundary onto this product — plus per-release attestation letters + signed by FosterStack LLC, and time on your security questionnaires. FosterStack + Cache is not "FedRAMP compliant" or "CMMC compliant"; those attach to your service + and your organization, never to a component you deploy. It is validated crypto and + publishable evidence for your compliance program. +
diff --git a/roadmap/index.html b/roadmap/index.html new file mode 100644 index 0000000..c74746b --- /dev/null +++ b/roadmap/index.html @@ -0,0 +1,115 @@ + + + + + + +-Roadmap honesty + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +Roadmap honesty
+Gradle and Maven both run against the same server today; we maintain the cache + server, while the Maven client side is Apache's own Build Cache Extension. A dependency cache — + the same server restoring
+node_modules,~/.m2, and +~/.gradle/cachesby lockfile key, so ephemeral CI agents stop + re-downloading the world — is next on the list, npm first. The Helm chart and the paid tiers above are not built; they are described so you can see the direction. Free + is real and complete today. If you need something sooner, + open an issue — that is what + moves the roadmap.+ + + diff --git a/sitemap.xml b/sitemap.xml index 61ac14c..dea252e 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -75,6 +75,14 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+https://fosterstack.com/scan-fosterstack-cache-image/ 2026-10-13 ++ +https://fosterstack.com/guides/ +2026-10-14 ++ https://fosterstack.com/roadmap/ +2026-10-14 +https://fosterstack.com/how-we-build/ 2026-10-08 From 842ddac3cb97b27fd50ca3f78588a71bfc1e541e Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:30:14 -0400 Subject: [PATCH 31/40] Site-rot check: a page linked from /guides/ counts as linked from home; home must link /guides/ (with its test) --- bin/check-site-rot.py | 9 ++++++++- bin/test-check-site-rot.sh | 24 ++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/bin/check-site-rot.py b/bin/check-site-rot.py index 0adcef7..cf53eff 100755 --- a/bin/check-site-rot.py +++ b/bin/check-site-rot.py @@ -227,7 +227,14 @@ def resolve(path): homelinks = {m for m in re.findall(r'href="/([a-z0-9-]+)/"', texts[""])} for p in sorted(homelinks - page_set): bad("home: links /%s/ which is not a page" % p) - for p in sorted(page_set - homelinks): + # The home page links a few guides and /guides/, which lists every guide: a page linked from /guides/ counts as linked from home. + reachable = set(homelinks) + if "guides" in page_set: + if "guides" in homelinks: + reachable |= {m for m in re.findall(r'href="/([a-z0-9-]+)/"', texts.get("guides", ""))} + else: + bad("home: does not link /guides/ (the page that lists every guide)") + for p in sorted(page_set - reachable): bad("home: does not link /%s/ (the Guides list or another section should)" % p) for line in problems: diff --git a/bin/test-check-site-rot.sh b/bin/test-check-site-rot.sh index 75cb2bb..f85028d 100755 --- a/bin/test-check-site-rot.sh +++ b/bin/test-check-site-rot.sh @@ -83,9 +83,33 @@ import sys p, slug = sys.argv[1:3] s = open(p).read().replace('href="/%s/"' % slug, 'href="/"') open(p, "w").write(s) +# a site with a /guides/ page lists every guide there: take the page off that list too +import os +g = os.path.join(os.path.dirname(p), "guides", "index.html") +if os.path.isfile(g): + gs = open(g).read() + open(g, "w").write(gs.replace('href="/%s/"' % slug, 'href="/"')) EOF expect_fail "a page the home page no longer links" "home: does not link" +if [ -f "$here/guides/index.html" ]; then + # a page linked only from /guides/ passes; the home page must still link /guides/ + fresh; python3 - "$site/index.html" "$first" <<'EOF' +import sys +p, slug = sys.argv[1:3] +s = open(p).read() +open(p, "w").write(s.replace('href="/%s/"' % slug, 'href="/"')) +EOF + expect_pass "a page linked only from /guides/ counts as linked from home" + fresh; python3 - "$site/index.html" <<'EOF' +import sys +p = sys.argv[1] +s = open(p).read() +open(p, "w").write(s.replace('href="/guides/"', 'href="/"')) +EOF + expect_fail "a home page that does not link /guides/" "home: does not link /guides/" +fi + fresh; edit "$site/$first/index.html" "REGEX:.*? " "This title is deliberately far too long to be a good page title for a search result " expect_fail "a title over 60 characters" "characters (max 60)" From 34d45176d028a60373364a714b23a49186979947 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 09:38:24 -0400 Subject: [PATCH 32/40] v0.3 preview: security section folded into two cards (Verify every release, Air-gapped ready); site-rot check as in #178 --- bin/test-check-site-rot.sh | 48 ++++++++++++++++++++++++++++++++------ index.html | 6 ++--- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/bin/test-check-site-rot.sh b/bin/test-check-site-rot.sh index f85028d..1bb7043 100755 --- a/bin/test-check-site-rot.sh +++ b/bin/test-check-site-rot.sh @@ -92,23 +92,57 @@ if os.path.isfile(g): EOF expect_fail "a page the home page no longer links" "home: does not link" -if [ -f "$here/guides/index.html" ]; then - # a page linked only from /guides/ passes; the home page must still link /guides/ - fresh; python3 - "$site/index.html" "$first" <<'EOF' +# /guides/ lists the guides. Built in the throwaway copy, so these cases run on every site, with or without a real /guides/. +# The home page links /guides/ and not $first; /guides/ links $first. +with_guides() { + fresh + python3 - "$site" "$first" "$second" <<'EOF' +import os, re, sys +site, first, second = sys.argv[1:4] +real = os.path.join(site, "guides") +if os.path.isdir(real): + import shutil + shutil.rmtree(real) +src = open(os.path.join(site, second, "index.html")).read() +src = re.sub(r".*? ", "Guides ", src, count=1, flags=re.S) +src = src.replace("/%s/" % second, "/guides/") +src = src.replace("", '' % first, 1) +os.makedirs(real) +open(os.path.join(real, "index.html"), "w").write(src) +home = os.path.join(site, "index.html") +h = open(home).read().replace('href="/%s/"' % first, 'href="/"') +if 'href="/guides/"' not in h: + h = h.replace("", '', 1) +open(home, "w").write(h) +sm = os.path.join(site, "sitemap.xml") +m = open(sm).read() +if "/guides/" not in m: + open(sm, "w").write(m.replace("", " ", 1)) +ll = os.path.join(site, "llms.txt") +l = open(ll).read() +if "fosterstack.com/guides/)" not in l: + open(ll, "w").write(l.rstrip("\n") + "\n- [Guides](https://fosterstack.com/guides/): all guides\n") +EOF +} + +with_guides; expect_pass "a page linked only from /guides/ counts as linked from home" + +with_guides; python3 - "$site/guides/index.html" "$first" <<'EOF' import sys p, slug = sys.argv[1:3] s = open(p).read() open(p, "w").write(s.replace('href="/%s/"' % slug, 'href="/"')) EOF - expect_pass "a page linked only from /guides/ counts as linked from home" - fresh; python3 - "$site/index.html" <<'EOF' +expect_fail "a page on neither the home page nor /guides/" "home: does not link /$first/" + +with_guides; python3 - "$site/index.html" <<'EOF' import sys p = sys.argv[1] s = open(p).read() open(p, "w").write(s.replace('href="/guides/"', 'href="/"')) EOF - expect_fail "a home page that does not link /guides/" "home: does not link /guides/" -fi +expect_fail "a home page that does not link /guides/" "home: does not link /guides/" +expect_fail "a /guides/ page the home page does not link lists nothing for home" "home: does not link /$first/" fresh; edit "$site/$first/index.html" "REGEX:https://fosterstack.com/guides/ .*? " "This title is deliberately far too long to be a good page title for a search result " expect_fail "a title over 60 characters" "characters (max 60)" diff --git a/index.html b/index.html index bd4781f..7e186b0 100644 --- a/index.html +++ b/index.html @@ -129,12 +129,10 @@What you get that a bare HTTP endpoint doesn't give you
Authentication
HTTP Basic Auth over TLS, wired the way Gradle and Maven already expect credentials. Constant-time comparison, no credential ever logged.
Metrics & status
Prometheus metrics, a read-only status page with hit rates and size-vs-cap, and a Grafana dashboard in the repo — so you know the cache is earning its keep.
+30-minute migration
A step-by-step guide for existing Build Cache Node deployments. Same protocol, same CI config shape — migrating is mostly a URL change.
+Verify every release
Every step of our release produces signed provenance. When a FosterStack signature verifies, you know it's FosterStack code, a FosterStack build and a FosterStack image, and everything in between. See how each stage maps.
Air-gapped ready
No telemetry. Nothing outbound. It runs the same air-gapped.
Meticulous pipeline security
-Every step of our release produces signed provenance. When a FosterStack signature verifies, you know it's FosterStack code, a FosterStack build and a FosterStack image, and everything in between. No telemetry. Nothing outbound. It runs the same air-gapped.
-How we build · Security policy · Everything we do for security
-Pricing
Per product. Free is the full product.
Paid tiers are coming; checkout isn't open yet.
From d5159d12eefb6538e88c6eb7ceb9666008a49e95 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 14:18:30 -0400 Subject: [PATCH 33/40] v0.3 preview: /faq/ (13 short answers with links); site-rot self-test keeps a real /guides/ in its fixture --- bin/test-check-site-rot.sh | 18 ++--- faq/index.html | 134 +++++++++++++++++++++++++++++++++++++ guides/index.html | 1 + llms.txt | 1 + sitemap.xml | 4 ++ 5 files changed, 150 insertions(+), 8 deletions(-) create mode 100644 faq/index.html diff --git a/bin/test-check-site-rot.sh b/bin/test-check-site-rot.sh index 1bb7043..8c8fbac 100755 --- a/bin/test-check-site-rot.sh +++ b/bin/test-check-site-rot.sh @@ -100,14 +100,16 @@ with_guides() { import os, re, sys site, first, second = sys.argv[1:4] real = os.path.join(site, "guides") -if os.path.isdir(real): - import shutil - shutil.rmtree(real) -src = open(os.path.join(site, second, "index.html")).read() -src = re.sub(r".*? ", "Guides ", src, count=1, flags=re.S) -src = src.replace("/%s/" % second, "/guides/") -src = src.replace(".*? ", "Guides ", src, count=1, flags=re.S) + src = src.replace("/%s/" % second, "/guides/") + os.makedirs(real, exist_ok=True) +if 'href="/%s/"' % first not in src: + src = src.replace("", '' % first, 1) open(os.path.join(real, "index.html"), "w").write(src) home = os.path.join(site, "index.html") h = open(home).read().replace('href="/%s/"' % first, 'href="/"') diff --git a/faq/index.html b/faq/index.html new file mode 100644 index 0000000..6ddf1fe --- /dev/null +++ b/faq/index.html @@ -0,0 +1,134 @@ + + + + + + +FosterStack Cache FAQ: Gradle, Maven, licence, security + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +FosterStack Cache FAQ
+Short answers, each with a link to the page that has the detail.
+What is FosterStack Cache?
+A self-hosted remote build cache for Gradle, and for Maven through the Apache Maven Build Cache Extension. It ships as one static binary or a distroless container image, under the MIT licence. See the first 15 minutes.
+Which Gradle and Maven setups does it work with?
+Gradle talks to it with its normal remote build cache setting, so the change is mostly a URL. Maven works through Apache's Build Cache Extension. Our CI builds a real multi-module project with each and checks that the second build restores from the remote cache. See Maven setup and GitHub Actions.
+Does it work with Jenkins and other CI systems?
+Any runner that can reach the server can use it. It is a plain web server. See Jenkins and CI build cache.
+How do I move from the free Build Cache Node?
+Start the new server empty and point your builds at it. A build cache only holds results your build can rebuild, so there is nothing to copy. See the migration guide and what the end of life means.
+Is it free?
+Yes. Everything you can download today is the free MIT core, including eviction, size limits and metrics. Paid tiers are coming; checkout isn't open yet. See pricing.
+What happens if the cache is down or empty?
+Builds are slower, not wrong. Gradle and Maven rebuild what they cannot restore. See what happens when the server is down.
+Who can write to the cache?
+Anyone holding the read-write password. Turn on Basic Auth anywhere untrusted people could reach the port. You can also set a read-only login that can read but never write. See CI writes, developers read.
+Can someone poison our shared cache?
+Only someone who can write to it, so the write login is the control. Read Can someone poison our build cache? for what to restrict.
+How do I know a release is the real one?
+Every image is keylessly signed, and every binary archive is covered by a signed checksums file. Both carry SLSA provenance. No account is needed. See Verify a release.
+Does it send anything out?
+No. The server sends no telemetry and needs no connection to FosterStack. It can run on a network with no route to the internet. See air-gapped install.
+How are security fixes handled?
+The current release's images are rescanned daily, so a vulnerability disclosed against bytes we already shipped raises an issue. The policy is in SECURITY.md, and everything we do for security lists the practices.
+Can I run it on Kubernetes or Docker?
+Yes. Docker and Kubernetes guides are public, with plain manifests for Kubernetes. There is no Helm chart. See Kubernetes and Docker Compose with TLS.
+Where do I report a problem or ask for something?
+Open an issue on GitHub. There is no signup, form or mailing list.
+ ++ + + diff --git a/guides/index.html b/guides/index.html index 051a30b..071cef6 100644 --- a/guides/index.html +++ b/guides/index.html @@ -93,6 +93,7 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · Build Cache Node end of life · Migrate · FAQ · CI setup · How we build · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+Guides
Start here
-
+
https://fosterstack.com/fips-140-3-build-cache/ 2026-10-08 ++ https://fosterstack.com/faq/ +2026-10-14 + +https://fosterstack.com/first-15-minutes-build-cache/ 2026-10-08 From 69d539a667321f39cbc75bd8b8be69ba331d0cb1 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 14:20:12 -0400 Subject: [PATCH 34/40] v0.3 preview: what to verify in a replacement build cache (checklist page) --- guides/index.html | 1 + llms.txt | 1 + sitemap.xml | 4 + .../index.html | 124 ++++++++++++++++++ 4 files changed, 130 insertions(+) create mode 100644 what-to-verify-in-a-replacement-build-cache/index.html diff --git a/guides/index.html b/guides/index.html index 071cef6..3cd4b75 100644 --- a/guides/index.html +++ b/guides/index.html @@ -93,6 +93,7 @@Guides
Start here
-
+
https://fosterstack.com/fips-140-3-build-cache/ 2026-10-08 + https://fosterstack.com/what-to-verify-in-a-replacement-build-cache/ +2026-10-14 + +https://fosterstack.com/faq/ 2026-10-14 diff --git a/what-to-verify-in-a-replacement-build-cache/index.html b/what-to-verify-in-a-replacement-build-cache/index.html new file mode 100644 index 0000000..ab8e0bc --- /dev/null +++ b/what-to-verify-in-a-replacement-build-cache/index.html @@ -0,0 +1,124 @@ + + + + + + +What to verify in a replacement build cache + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +What to verify in a replacement build cache
+Eleven checks you can run against any build cache you are thinking of putting in front of your builds. Each has what to ask or test, and what we say for FosterStack Cache so you can compare.
+++
+Check What to do FosterStack Cache +Are releases signed, and can you check without an account? Download one release and run the signature check yourself. You should not need to sign up or ask anyone. Images are keylessly signed and every binary archive is covered by a signed checksums file. See Verify a release. +Is there a record of how it was built? Ask for build provenance that names the workflow and run, not only a signature. Images and archives carry SLSA provenance naming the CI run that built them. See how we build and how it maps to NIST and SLSA. +Is there a parts list and a statement on known vulnerabilities? Ask for an SBOM and for VEX statements per release, and whether anyone can read them without buying anything. SBOMs, VEX statements and signatures are published with every release, free. +Can you give people read-only access? Check that a read-only login can read and that any write is refused, not just discouraged. An optional read-only login can read; every write is refused. See CI writes, developers read. +What stops a bad entry reaching your builds? Ask who can write, and what a poisoned entry could do. A cache that only the right logins can write to is the control. See Can someone poison our build cache? +Does eviction keep the disk from filling? Set a size cap and fill past it in a test. The server should drop old entries, not stop. Size-capped least-recently-used eviction. See size limit, eviction and a full disk. +Can you see what it is doing? Look for a health check and metrics you can alert on without a vendor agent. /healthzfor liveness and Prometheus metrics at/metrics. See what to alert on. +Does it run with no outbound connection? Run it on a network with no route to the internet and check that builds still work. Ask whether it sends telemetry. No telemetry and no connection to FosterStack needed. See air-gapped install. +What happens when it is down? Stop it during a build. Builds should be slower, not wrong. See what happens when the server is down. +What is the licence, and is the code public? Read the licence file and check that the security evidence is not behind the paid tier. MIT, with the source on GitHub. The security evidence is public and free. +What does the security-fix promise actually say? Ask for the patch commitment in writing, with a time and what counts as a fix. Our aim is to ship dependency fixes within 48 hours of public disclosure. That is a stated intention, not a contractual promise today. The current release is rescanned daily. See SECURITY.md. Where to start
+If you are moving off the free Build Cache Node, read what the end of life means and the migration guide. Questions? See the FAQ.
+ ++ + + From 0150f2531ebc75be515f6001e9ebf4a8961eab0b Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 14:21:54 -0400 Subject: [PATCH 35/40] v0.3 preview: is a remote build cache worth it? (measured numbers, two public runs) --- guides/index.html | 1 + is-a-remote-build-cache-worth-it/index.html | 139 ++++++++++++++++++++ llms.txt | 1 + sitemap.xml | 4 + 4 files changed, 145 insertions(+) create mode 100644 is-a-remote-build-cache-worth-it/index.html diff --git a/guides/index.html b/guides/index.html index 3cd4b75..2f550a0 100644 --- a/guides/index.html +++ b/guides/index.html @@ -94,6 +94,7 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · Build Cache Node end of life · Migrate · FAQ · CI setup · How we build · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+Guides
Start here
Is a remote build cache worth it? What we measured + + + + + + + + + + + + + ++ +fosterstack+Infrastructure worth keeping — and kept patched.++ +Is a remote build cache worth it?
+On the small projects we measured, a filled cache took about a quarter off a Gradle build, and an empty one cost about a second. Here are the numbers and the runs that produced them. They are from our test projects on a CI machine, so measure your own.
+ +Gradle: what a cache saved and what a miss cost
+We ran the same Gradle build three ways, seven times each, and timed the whole command.
+++
+Setup Fastest Median Slowest +No remote cache 17.06 s 17.54 s 18.17 s +Remote cache, empty (a miss) 16.83 s 18.54 s 18.67 s +Remote cache, filled (a hit) 12.79 s 13.41 s 13.60 s By the medians, a miss cost about one second (about 6%) and a hit saved about four (about 24%). The miss build was slower in 6 of 7 rounds. The run and its log are public.
+What we ran: a GitHub-hosted CI machine, 4 vCPUs, 16 GB; Gradle 9.8.0, Java 21; FosterStack Cache 0.2.1 on the same machine. The project had 4 modules of 150 generated classes each, and only the compile tasks ran. It compiles quickly and every build also paid Gradle's start-up, so a bigger project may show different percentages. Details: does a remote cache slow your build when it misses?
+ +Maven: what gets restored
+For Maven we recorded which modules were restored from the cache and which were built, on a three-module project with Apache's Build Cache Extension. We have not published a Maven timing table, so there is no Maven time saving on this page.
+++
+Build core util app +First build, as CI would do it built built built +Another machine, same code restored restored restored +Edit inside a method in core built built built +A teammate makes the same edit restored restored restored +Edit only app restored restored built +Edit only util restored built built The first person to make a change pays for it; everyone after restores the result. The run and its log are public. Details: Maven Build Cache Extension in a multi-module project.
+ +What this tells you, and what it does not
+-
+
+ + + diff --git a/llms.txt b/llms.txt index 396bd41..1b86995 100644 --- a/llms.txt +++ b/llms.txt @@ -52,6 +52,7 @@ verifiable against the CI run that produced them. - [For regulated markets](https://fosterstack.com/regulated/): the FIPS build and the public release evidence. - [Build cache size limit, eviction and a full disk](https://fosterstack.com/build-cache-eviction-size-limit/): What a self-hosted build cache does when it reaches its size cap: least-recently-used eviction, real numbers from a 0.2.1 server, and what an oversized entry gets. - [What to verify in a replacement build cache](https://fosterstack.com/what-to-verify-in-a-replacement-build-cache/): A checklist you can run against any replacement build cache: signed releases, provenance, read-only logins, eviction, metrics, air-gapped use and licence. +- [Is a remote build cache worth it? What we measured](https://fosterstack.com/is-a-remote-build-cache-worth-it/): Measured numbers for a self-hosted remote build cache: Gradle build times with no cache, an empty cache and a filled one, and what Maven restores, each with a public run. - [FosterStack Cache FAQ: Gradle, Maven, licence, security](https://fosterstack.com/faq/): Short answers about what it is, what it works with, its licence, verifying a release and what happens if it is down. - [Your first 15 minutes with a self-hosted build cache](https://fosterstack.com/first-15-minutes-build-cache/): A checklist from nothing to your first FROM-CACHE with a self-hosted Gradle build cache, with the commands timed on a GitHub-hosted machine, release 0.2.2. - [Let CI write, developers only read: Gradle and Maven cache](https://fosterstack.com/gradle-build-cache-ci-writes-developers-read/): Set up a Gradle build cache where CI uploads and laptops only download, with a read-only login the server enforces. Real run on server 0.2.1 and Gradle 9.8.0. diff --git a/sitemap.xml b/sitemap.xml index 0309d44..32ab0d7 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -43,6 +43,10 @@++FosterStack is not affiliated with, endorsed by, or sponsored by Gradle Inc. + "Gradle" and "Develocity" are trademarks of Gradle Inc., used here only to identify + compatibility. FosterStack contains no Gradle Inc. code; it is a clean-room implementation + of the documented remote build cache HTTP protocol. Apache Maven is a trademark of the + Apache Software Foundation; the Maven Build Cache Extension is Apache's project, not + ours.
+© 2026 FosterStack · Build Cache Node end of life · Migrate · FAQ · CI setup · How we build · For regulated markets · github.com/fosterstack/cache · hello@fosterstack.com
+https://fosterstack.com/what-to-verify-in-a-replacement-build-cache/ 2026-10-14 + https://fosterstack.com/is-a-remote-build-cache-worth-it/ +2026-10-14 +https://fosterstack.com/faq/ 2026-10-14 From 2e82bd897dfda6a3fa5a013ec0cad2d27720f418 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 14:22:05 -0400 Subject: [PATCH 36/40] v0.3 preview: every guide links the end-of-life and migration pages --- air-gapped-build-cache-install/index.html | 1 + build-cache-server-sizing/index.html | 1 + everything-we-do-for-security/index.html | 1 + fips-140-3-build-cache/index.html | 1 + gradle-build-cache-kubernetes/index.html | 1 + how-we-build/index.html | 1 + jenkins-ci-build-cache/index.html | 1 + maven-remote-build-cache-setup/index.html | 1 + reset-gradle-build-cache/index.html | 1 + scan-fosterstack-cache-image/index.html | 1 + verify-a-release/index.html | 1 + whats-new-fosterstack-cache-v0-3-0/index.html | 1 + 12 files changed, 12 insertions(+) diff --git a/air-gapped-build-cache-install/index.html b/air-gapped-build-cache-install/index.html index 5d7ba34..c299d46 100644 --- a/air-gapped-build-cache-install/index.html +++ b/air-gapped-build-cache-install/index.html @@ -135,6 +135,7 @@How we checked
Gradle and Maven setup FosterStack home +Moving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/build-cache-server-sizing/index.html b/build-cache-server-sizing/index.html index 0a0bf32..0ffad3c 100644 --- a/build-cache-server-sizing/index.html +++ b/build-cache-server-sizing/index.html @@ -225,6 +225,7 @@+Builds at once and the upload limit
Gradle and Maven setup FosterStack homeMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/everything-we-do-for-security/index.html b/everything-we-do-for-security/index.html index 57a0757..adc478e 100644 --- a/everything-we-do-for-security/index.html +++ b/everything-we-do-for-security/index.html @@ -154,6 +154,7 @@Watch
Related: how releases are built and signed, verify a release yourself and the security policy.
+Moving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index a03860a..c0a6622 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -126,6 +126,7 @@+What this tells you, and what it does not
Verify a release yourself FosterStack homeMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/gradle-build-cache-kubernetes/index.html b/gradle-build-cache-kubernetes/index.html index 6c4f6ec..db046da 100644 --- a/gradle-build-cache-kubernetes/index.html +++ b/gradle-build-cache-kubernetes/index.html @@ -140,6 +140,7 @@+How we checked
Kubernetes guide Gradle and Maven setupMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/how-we-build/index.html b/how-we-build/index.html index 3031417..6e9eeca 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -134,6 +134,7 @@+What we do not claim
Verify a release yourself How each stage maps to NIST and SLSAMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/jenkins-ci-build-cache/index.html b/jenkins-ci-build-cache/index.html index 9046406..c7bd0c8 100644 --- a/jenkins-ci-build-cache/index.html +++ b/jenkins-ci-build-cache/index.html @@ -129,6 +129,7 @@+Check that CI is really using the cache
Gradle and Maven setup FosterStack homeMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/maven-remote-build-cache-setup/index.html b/maven-remote-build-cache-setup/index.html index a8bea07..29b0ad6 100644 --- a/maven-remote-build-cache-setup/index.html +++ b/maven-remote-build-cache-setup/index.html @@ -274,6 +274,7 @@+How we checked
Gradle and Maven setup FosterStack homeMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/reset-gradle-build-cache/index.html b/reset-gradle-build-cache/index.html index c42c4ca..369c4a5 100644 --- a/reset-gradle-build-cache/index.html +++ b/reset-gradle-build-cache/index.html @@ -130,6 +130,7 @@+Check it worked
Gradle and Maven setup FosterStack homeMoving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/scan-fosterstack-cache-image/index.html b/scan-fosterstack-cache-image/index.html index a4961fb..d058187 100644 --- a/scan-fosterstack-cache-image/index.html +++ b/scan-fosterstack-cache-image/index.html @@ -161,6 +161,7 @@Reproducing our own gate
Confirming the scan is the release run
Every scanner in the repo's list runs on every release, and the verdicts are in the public CI run: the scan is the CI run, in this repository's Actions tab. See Verify our images for how to confirm the exact image you pulled came from that same run.
Related: everything we do for security, verify a release yourself.
+Moving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/verify-a-release/index.html b/verify-a-release/index.html index fe2bfc3..021936b 100644 --- a/verify-a-release/index.html +++ b/verify-a-release/index.html @@ -123,6 +123,7 @@What this proves
Extra evidence, outside these commands: records anyone who has Witness installed can check.
Related: how releases are built and signed and security policy.
+Moving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 5746e0f..694f99c 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -105,6 +105,7 @@How the release is built
Upgrading
Whether the back-up and upgrade steps on the upgrade page change for this release.
Related: changelog and security policy.
+Moving off the free Build Cache Node? See what the end of life means and the migration guide.
From d1b26e33518687df40fd3ca57d86e3d849e48694 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Wed, 14 Oct 2026 16:06:38 -0400 Subject: [PATCH 37/40] v0.3 preview: verify, FIPS, air-gapped and upgrade pages written from the chain's RELEASING.md and scripts --- air-gapped-build-cache-install/index.html | 9 +- fips-140-3-build-cache/index.html | 4 +- upgrade-build-cache-server/index.html | 11 +++ verify-a-release/index.html | 91 ++++++++++++------- whats-new-fosterstack-cache-v0-3-0/index.html | 2 +- 5 files changed, 76 insertions(+), 41 deletions(-) diff --git a/air-gapped-build-cache-install/index.html b/air-gapped-build-cache-install/index.html index c299d46..365b061 100644 --- a/air-gapped-build-cache-install/index.html +++ b/air-gapped-build-cache-install/index.html @@ -92,10 +92,10 @@Install a build cache on an air-gapped network
What to bring across
On a machine with internet access, download these from the release page:
-
-
Verify before you cross the gap
@@ -103,13 +103,12 @@Verify before you cross the gap
-# 1. Prove the checksums file is ours cosign verify-blob \ --bundle checksums.txt.bundle \ - --certificate-identity-regexp='^https://github.com/fosterstack/cache/' \ + --certificate-identity='https://github.com/fosterstack/cache/.github/workflows/stage-promote.yml@refs/tags/vX.Y.Z' \ --certificate-oidc-issuer='https://token.actions.githubusercontent.com' \ checksums.txt # 2. Prove your archive matches it -sha256sum -c <(grep "fscache_X.Y.Z_linux_amd64.tar.gz" checksums.txt | grep -v sbom)
+sha256sum -c <(grep "fscache_X.Y.Z_linux_amd64.tar.gz" checksums.txt)grep -v sbomdrops the SBOM line, because that file is not carried across. Without it,sha256sumreports the file as missing and fails.Both steps matter. The checksum alone only shows the archive matches a file you carried beside it. The signature is what ties that file to us.
Install on the isolated side
diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index c0a6622..333dc8a 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -92,7 +92,7 @@FIPS 140-3 build cache: run the FIPS image and confirm it
DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
What the FIPS build is
-It is the same source as the production build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247). It is available as a container image tag ending in
+-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.It is the same source as the production build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247). It is available as a container image tag ending in
-fips, and as Linux binaries for amd64 and arm64, namedfscache-fips_X.Y.Z_linux_amd64.tar.gzandfscache-fips_X.Y.Z_linux_arm64.tar.gz. The FIPS image has no shell. There is no macOS FIPS build.Run it
docker run -d -p 127.0.0.1:8080:8080 -v fscache-data:/home/nonroot \ @@ -117,7 +117,7 @@Confirm it is in FIPS mode
What this tells you, and what it does not
What we saw
Stop 0.2.2, start 0.2.1 on the same volume again starts normally; the status page shows 5 entries, 49 bytes; all five values read back Upgrading from 0.2.x to v0.3.0
+The upgrade steps above are the same: pull the new tag, stop the old container, start the new one on the same volume. Check these first, because they are the things that differ.
+-
+
Back up the volume first if refilling the cache is expensive for you, as in the back-up section below.
+Two differences between the releases
Verify a FosterStack Cache release yourself - + - + @@ -88,41 +88,66 @@Verify a FosterStack Cache release yourself
-You should not have to take our word for what you run. Signed at every stage, verified together at release. These commands check the final signature, how the image was built, its parts list and what it was assembled from, using only
-cosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
-Use the image by digest for
+<IMAGE_REF>. There are two images, production and fips; run every step for each.You should not have to take our word for what you run. Signed at every stage, verified together at release. These steps check the image signatures, the signed file lists, the digest, how the release was built and its parts list, using only
+cosign,gh,jqandsha256sum. They are for v0.3.0 and later. For v0.2.x, see the image verification guide.You need no account to pull the images or to run
+cosign. Downloading release files withghneedsgh auth login; you can also download them from the release page in a browser.Set the version
+
+VER=$(curl -fsSL https://api.github.com/repos/fosterstack/cache/releases/latest \ + | sed -n 's/.*"tag_name": *"v\([^"]*\)".*/\1/p') +echo "$VER" +IDENT="https://github.com/fosterstack/cache/.github/workflows" +ISSUER=https://token.actions.githubusercontent.comThere are two images, production and
-fips. Run step 1 for each.1. The signature and who signed it
-
-# identity and issuer for the final signature -cosign verify <IMAGE_REF> \ - --certificate-identity-regexp '<IDENTITY>' \ - --certificate-oidc-issuer https://token.actions.githubusercontent.com2. The digest is the one in the release
-
-# file name and layout -gh release download <TAG> --repo fosterstack/cache -p release-manifest.json -jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.jsonEvery statement names the image by digest, never by tag. The digest you verified should match this list.
-3. How it was built
-
-# signer workflow -gh attestation verify oci://<IMAGE_REF> --repo fosterstack/cache \ - --signer-workflow '<WORKFLOW>' --source-ref refs/tags/<TAG>One sentence on what this record covers. No SLSA level claim here.
-4. The parts list (SBOM)
-
-# predicate type and what the list holds for an image with no base image -cosign verify-attestation <IMAGE_REF> --type spdxjson \ - --certificate-identity-regexp '<IDENTITY>' \ - --certificate-oidc-issuer https://token.actions.githubusercontent.com \ - | jq -r '.payload | @base64d | fromjson | .predicate.name'5. What the image was assembled from
-
+# what "inputs" means for a customer, and the one command that checks it -cosign verify-attestation <IMAGE_REF> --type '<INPUTS_TYPE>' ... | jq '<FILTER>'
+cosign verify ghcr.io/fosterstack/cache:${VER} \ + --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \ + --certificate-oidc-issuer "$ISSUER" +cosign verify ghcr.io/fosterstack/cache:${VER}-fips \ + --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \ + --certificate-oidc-issuer "$ISSUER"This shows that the release stage of our public pipeline, at this release tag, signed these exact images. The signing certificate lasts minutes and is recorded in Rekor, the public transparency log. There is no signing key to steal.
+2. The file lists are ours, and your files match them
+
+gh release download v${VER} --repo fosterstack/cache \ + -p checksums.txt -p checksums.txt.bundle \ + -p release-files.sha256 -p release-files.sha256.bundle \ + -p release-manifest.json -p "fscache_${VER}_linux_amd64.tar.gz" +for f in checksums.txt release-files.sha256; do + cosign verify-blob "$f" --bundle "$f.bundle" \ + --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \ + --certificate-oidc-issuer "$ISSUER" +done +sha256sum -c <(grep "fscache_${VER}_linux_amd64.tar.gz" checksums.txt) +sha256sum -c <(grep release-manifest.json release-files.sha256)Do the signature check first. Without it, a list only proves that your files match a file anyone could have written. The archives are covered by the signed
+checksums.txt, and the manifest by the signedrelease-files.sha256.3. The digest is the one in the release
+
+jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.jsonEvery statement names an image by digest, never by tag. The digest you pulled should be in this list.
+4. How it was built
+
+gh release download v${VER} --repo fosterstack/cache \ + -p provenance.json -p provenance.bundle.json +cosign verify-blob-attestation --bundle provenance.bundle.json \ + --type https://slsa.dev/provenance/v1 --check-claims=false \ + --certificate-identity "${IDENT}/stage-sign.yml@refs/tags/v${VER}" \ + --certificate-oidc-issuer "$ISSUER" +jq -r '.dsseEnvelope.payload | @base64d | fromjson | .subject[] | .name + " sha256:" + .digest.sha256' provenance.bundle.jsonThe SLSA provenance is signed by a separate job with its own identity,
+stage-sign.yml. It receives only the list of digests the build made and runs no code from the build. The second command lists each item it names, with its digest.5. The parts list and what it was assembled from
+
+gh release download v${VER} --repo fosterstack/cache \ + -p production.sbom.json -p production.sbom.json.bundle \ + -p production.full.lock.json -p production.full.lock.json.bundle +for f in production.sbom.json production.full.lock.json; do + cosign verify-blob "$f" --bundle "$f.bundle" \ + --certificate-identity "${IDENT}/stage-promote.yml@refs/tags/v${VER}" \ + --certificate-oidc-issuer "$ISSUER" +doneThe SBOM lists what is in the image. The lock file lists every package the image was assembled from, by checksum. Repeat with
fips.sbom.jsonandfips.full.lock.jsonfor the-fipsimage.What this proves
-
-
Extra evidence, outside these commands: records anyone who has Witness installed can check.
-Related: how releases are built and signed and security policy.
+Each stage of the release also writes a record that anyone with the Witness tool can check. Those records are extra evidence outside the steps above, and are attached to the release.
+Related: how releases are built and signed, how the pipeline maps to NIST and SLSA and scan the image yourself.
Moving off the free Build Cache Node? See what the end of life means and the migration guide.
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 694f99c..c446bdb 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -103,7 +103,7 @@ Kept patched
How the release is built
Signed at every stage, verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.
Upgrading
-Whether the back-up and upgrade steps on the upgrade page change for this release.
+The upgrade steps are the same as for any release: pull the new tag and start it on the same volume. See upgrading from 0.2.x to v0.3.0 for what to check first.the upgrade page change for this release.
Related: changelog and security policy.
Moving off the free Build Cache Node? See what the end of life means and the migration guide.
Kept patched
How the release is built
Signed at every stage, verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.
Upgrading
-The upgrade steps are the same as for any release: pull the new tag and start it on the same volume. See upgrading from 0.2.x to v0.3.0 for what to check first.the upgrade page change for this release.
+The upgrade steps are the same as for any release: pull the new tag and start it on the same volume. See upgrading from 0.2.x to v0.3.0 for what to check first.
Related: changelog and security policy.
Moving off the free Build Cache Node? See what the end of life means and the migration guide.
Pricing
$199/month — everything in Team, plus HA/replication and priority support with the CVE-response target. $499/month, billed annually — everything in Business, plus the FIPS 140-3 - applicability statement, signed per-release attestation letters addressed to you, + applicability statement, a monthly attestation letter addressed to you, covering every release that month, and security-questionnaire support up to 8 hours per year (async). Who this is for. Verify everything yourself first
provenance, signatures, VEX statements, and the FIPS 140-3 validated module (CMVP certificate #5247) — is public and free, verifiable by anyone. What the tier describes is the authored analysis — a FIPS applicability statement mapping the - validated module boundary onto this product — plus per-release attestation letters - signed by FosterStack LLC, and time on your security questionnaires. FosterStack + validated module boundary onto this product — plus a monthly attestation letter + covering every release, signed by FosterStack LLC, and time on your security questionnaires. FosterStack Cache is not "FedRAMP compliant" or "CMMC compliant"; those attach to your service and your organization, never to a component you deploy. It is validated crypto and publishable evidence for your compliance program. From 75c9e7dc742d8489d969442028f5feda22aea20c Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Mon, 19 Oct 2026 15:02:42 -0400 Subject: [PATCH 40/40] Card: keep 'signed' (the doubled word was only in the description) --- index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.html b/index.html index 0b23a7b..4e10dd0 100644 --- a/index.html +++ b/index.html @@ -146,7 +146,7 @@Pricing
$199/month — everything in Team, plus HA/replication and priority support with the CVE-response target. $499/month, billed annually — everything in Business, plus the FIPS 140-3 - applicability statement, a monthly attestation letter addressed to you, covering every release that month, + applicability statement, a signed monthly attestation letter addressed to you, covering every release that month, and security-questionnaire support up to 8 hours per year (async). Who this is for. - Signed releases you can verify in minutes. How we sign and check our own releases: how we build.
Verify a FosterStack Cache release yourself
-You should not have to take our word for what you run. Each stage of a release is signed on its own, and the signatures are verified together at release. These commands check that yourself, using only
+cosign,ghandjq.You should not have to take our word for what you run. Each stage of a release is signed on its own, and the signatures are verified together at release.
[TO-VERIFY: pipeline]These commands check that yourself, using onlycosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
[TO-VERIFY]marks anything not yet run against a real release.Use the image by digest for
<IMAGE_REF>. There are two images; run every step for each.[TO-VERIFY]which two variants.1. The signature and who signed it
@@ -100,7 +100,7 @@2. The digest is the one in the release
-# [TO-VERIFY] file name and layout gh release download <TAG> --repo fosterstack/cache -p release-manifest.json jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.jsonEvery statement names the image by digest, never by tag. The digest you verified should match this list.
+Every statement names the image by digest, never by tag.
[TO-VERIFY: pipeline]The digest you verified should match this list.3. How it was built
# [TO-VERIFY] signer workflow gh attestation verify oci://<IMAGE_REF> --repo fosterstack/cache \ From cda38c53e643ad3e498b989d3bbee951ba48d3f8 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:18:01 -0400 Subject: [PATCH 09/40] v0.3 policy pages draft: security and regulated (WIP) --- regulated/index.html | 9 ++++++--- security/index.html | 15 +++++++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/regulated/index.html b/regulated/index.html index 5518bfd..389d0f1 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -1,6 +1,7 @@ +FosterStack for teams entering regulated markets @@ -89,6 +90,8 @@For teams entering regulated markets
FosterStack Cache gives the build-cache part of your pipeline public, checkable evidence: a FIPS 140-3 build, an SBOM, SLSA provenance, signatures and VEX statements. It does not make you compliant.
+DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.It usually starts with one customer. A contract lands on the table with federal or compliance requirements attached — FIPS-validated cryptography, @@ -119,11 +122,11 @@
What our piece does — and does not do
More than kept patched.
-
-
How we build · Security policy · Verify a release
diff --git a/security/index.html b/security/index.html index 85d42b0..fe4c06d 100644 --- a/security/index.html +++ b/security/index.html @@ -1,6 +1,7 @@ +Security policy: how to report a vulnerability @@ -88,6 +89,8 @@Security policy: how to report a vulnerability
Found a security problem in FosterStack Cache or on this website? Tell us privately. Here is how, what happens next, which version gets fixes, and what we sign and publish so you can check our work.
+DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Report a vulnerability
-
@@ -97,20 +100,20 @@
Report a vulnerability
Send the report, not a patch. Please do not post details publicly before a fix ships.
-What we aim for
-Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.
+Kept patched
+We keep FosterStack Cache patched, whether the problem is in our code or in a dependency that its own maintainers have abandoned.
[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; what is covered when upstream has abandoned a component]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.Long-term support: what is supported
-"LTS" means a version that keeps getting fixes for a stated period, so you can stay on it. The supported version is the latest minor release. That is the whole policy. There is no separate long-term-support line, no list of older versions that get fixes, and no support period to quote.
+"LTS" means a version that keeps getting fixes for a stated period, so you can stay on it.
[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes.-
-
What we sign and publish
-Releases are built only in CI. Each one comes with files you can check without an account:
+Releases are built only in CI. Every release is signed and checked at every step, and each one comes with files you can check without an account.
[TO-VERIFY: pipeline/cache: the v0.3 chain; the four metadata files signed via the signed checksums list (cache fix A)]What we do not claim
Machine-readable contact: security.txt.
From 1bab23fa3ec64f6c7331e57a461f0974a0d3c061 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:18:33 -0400 Subject: [PATCH 10/40] v0.3 trust pages: overstated sentences narrowed or marked, one stage description, draft notices --- .../index.html | 6 ++--- how-we-build/index.html | 22 +++++++++---------- verify-a-release/index.html | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index eb423d2..8e48cd7 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -4,9 +4,9 @@ -NIST SP 800-204C, 800-204D and SLSA: Our Release Pipeline +How our release pipeline maps to NIST and SLSA (draft) - + @@ -93,7 +93,7 @@How the v0.3.0 release pipeline maps to NIST and SLSA
DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
[TO-VERIFY]marks anything not yet run against a real release.This is guidance we followed when designing the pipeline. It is not a certification.
Stage by stage
-"Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
+[TO-VERIFY]against the workflow files at the v0.3.0 tag.The six stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
[TO-VERIFY]against the workflow files at the v0.3.0 tag. diff --git a/how-we-build/index.html b/how-we-build/index.html index 2d10790..e202904 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -5,9 +5,9 @@Stage What it does NIST practice How much How FosterStack Cache is built and signed - + - + @@ -92,23 +92,23 @@How FosterStack Cache is built and signed
You are about to run our software inside your build pipeline. How do you know the files you run are the ones we built? Every release is signed and checked at every step, and you can verify it yourself.
-[TO-VERIFY: pipeline: signed and checked at every stage of the v0.3 chain]This page says how.DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.We do it to our own pipeline first
-FosterStack's business is helping organisations secure their build and release pipeline. We started with a build cache your team can know is secure, and we secure our own release pipeline the same way before we ask you to trust it.
+[TO-VERIFY: pipeline: the v0.3 chain, secured before the product ships]We started with a build cache, and we secure our own release pipeline the same way before we ask you to run it.
[TO-VERIFY: pipeline: the v0.3 chain, secured before the product ships]Releases are built only in CI
-No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what makes the signatures mean something: nobody can forge a release that GitHub's own build machines never built.
+[TO-VERIFY: pipeline: no manual release path in v0.3]No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what lets the signatures mean something: a release that our CI workflow did not build does not carry its signature.
[TO-VERIFY: pipeline: the signing identity is pinned to the release workflow and tag; no manual release path in v0.3]The steps a release goes through
-Signed at every stage, verified together at release. Each stage signs its own statement about the exact files, and no stage takes the one before it on trust.
+[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]Signed at every stage, verified together at release. Each stage signs its own statement about the exact files, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]The full description, as the pipeline actually runs, is in RELEASING.md.
@@ -128,7 +128,7 @@[TO-VERIFY: pipeline: RELEASING.md matches the v0.3 chain]Kept patched
What we do not claim
Verify a FosterStack Cache release yourself
-You should not have to take our word for what you run. Each stage of a release is signed on its own, and the signatures are verified together at release.
+[TO-VERIFY: pipeline]These commands check that yourself, using onlycosign,ghandjq.You should not have to take our word for what you run. Each stage of a release is signed on its own, and the signatures are verified together at release.
[TO-VERIFY: pipeline]These commands check the final signature, how the image was built, its parts list and what it was assembled from, using onlycosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
[TO-VERIFY]marks anything not yet run against a real release.Use the image by digest for
<IMAGE_REF>. There are two images; run every step for each.[TO-VERIFY]which two variants.1. The signature and who signed it
@@ -117,7 +117,7 @@5. What the image was assembled from
cosign verify-attestation <IMAGE_REF> --type '<INPUTS_TYPE>' ... | jq '<FILTER>'What this proves
-
-
FosterStack Cache changelog: v0.1.0 to v0.2.2 @@ -90,6 +91,11 @@FosterStack Cache changelog: v0.1.0 to v0.2.2
The release notes from GitHub, quoted as published. Newest first. For anything else, the releases page is the source.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+ +[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.v0.3.0
+The v0.3.0 release notes will be quoted here as published, like the others.
+[TO-VERIFY: cache: the v0.3.0 release notes; nothing here is written before the release exists]v0.2.2
Release name: fscache v0.2.2. Published 2026-10-09.
@@ -106,7 +112,7 @@
v0.2.1
v0.2.0
-No release was published for v0.2.0: the tag exists, but its release run failed. Use v0.2.2, the latest release.
+No release was published for v0.2.0: the tag exists, but its release run failed.
v0.1.0
Published 2026-08-22.
diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index 5f19091..38b8293 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -1,6 +1,7 @@ +FIPS 140-3 build cache: run the FIPS image and confirm it @@ -87,10 +88,11 @@FIPS 140-3 build cache: run the FIPS image and confirm it
-FosterStack Cache has a FIPS build that uses Go's validated FIPS 140-3 cryptographic module. This page shows how to run it and how to see for yourself that it is in FIPS mode. The outputs below are from the real 0.2.2 images.
+Your contract asks for FIPS-validated cryptography, and you have to show what your build cache actually runs. FosterStack Cache has a FIPS build that uses Go's validated FIPS 140-3 cryptographic module. This page shows how to run it and how to see for yourself that it is in FIPS mode. The outputs below are from the real 0.2.2 images.
+[TO-VERIFY: cache: re-run on the v0.3 FIPS image; the module version and status output]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.What the FIPS build is
-It is the same source as the standard build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247). It is available as a container image tag ending in
+-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.It is the same source as the standard build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247).
[TO-VERIFY: cache: at v0.3 the FIPS and standard images come from two builds of one source]It is available as a container image tag ending in-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.[TO-VERIFY: cache: v0.3 ships Linux archives only (amd64 and arm64), and the images are production and fips]Run it
docker run -d -p 127.0.0.1:8080:8080 -v fscache-data:/home/nonroot \ diff --git a/regulated/index.html b/regulated/index.html index 389d0f1..6fd99f0 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -90,7 +90,7 @@For teams entering regulated markets
FosterStack Cache gives the build-cache part of your pipeline public, checkable evidence: a FIPS 140-3 build, an SBOM, SLSA provenance, signatures and VEX statements. It does not make you compliant.
-DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.It usually starts with one customer. A contract lands on the table with diff --git a/security/index.html b/security/index.html index fe4c06d..09e30ee 100644 --- a/security/index.html +++ b/security/index.html @@ -89,7 +89,7 @@
Security policy: how to report a vulnerability
Found a security problem in FosterStack Cache or on this website? Tell us privately. Here is how, what happens next, which version gets fixes, and what we sign and publish so you can check our work.
-DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Report a vulnerability
From 1bd995b770948d6a4d7409801bf0a0eeaa1b2df7 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:19:05 -0400 Subject: [PATCH 12/40] v0.3 changelog draft: a neutral title --- changelog/index.html | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/changelog/index.html b/changelog/index.html index e1b3f40..7c6ce8c 100644 --- a/changelog/index.html +++ b/changelog/index.html @@ -4,9 +4,9 @@ -FosterStack Cache changelog: v0.1.0 to v0.2.2 +FosterStack Cache changelog - + @@ -88,7 +88,7 @@Infrastructure worth keeping — and kept patched.- FosterStack Cache changelog: v0.1.0 to v0.2.2
+FosterStack Cache changelog
The release notes from GitHub, quoted as published. Newest first. For anything else, the releases page is the source.
DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
From 2f3a9cb855d339923b44ccda04feeb78910a80ec Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:19:34 -0400 Subject: [PATCH 13/40] v0.3 product pages draft: the laptop page and what's new, markers with sources --- laptop-builds-reuse-ci-build-cache/index.html | 7 +++++++ whats-new-fosterstack-cache-v0-3-0/index.html | 18 ++++++++++-------- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/laptop-builds-reuse-ci-build-cache/index.html b/laptop-builds-reuse-ci-build-cache/index.html index a70b19f..4bd80b3 100644 --- a/laptop-builds-reuse-ci-build-cache/index.html +++ b/laptop-builds-reuse-ci-build-cache/index.html @@ -1,6 +1,7 @@ +[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Your Laptop Builds Reuse What CI Already Built @@ -89,6 +90,8 @@Your laptop builds reuse what CI already built
CI builds your code, and then your laptop builds the same code again from scratch. FosterStack Cache is a build cache server you run yourself: CI stores its results there, and your laptop takes them instead of redoing the work.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.How it works
-
@@ -109,6 +112,10 @@
What has to match
Keep those the same on laptops and CI. For what to expect after an upgrade, see we upgraded Gradle or Maven and builds got slow. If your laptop still rebuilds, see why the Gradle hit rate is low or why the Maven cache is not restoring. To set it up, see Maven remote build cache setup and the Gradle setup in the CI-writes page.
+A cache every laptop trusts is a cache you can check
+CI and every laptop trust the same server, so you should be able to see what it is. Every release is signed and checked at every step, and you can verify it yourself.
+[TO-VERIFY: pipeline: signed and checked at every stage of the v0.3 chain]We keep it patched, and we secure our own release pipeline the same way before we ask you to run it: how we build.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]The server runs on Linux; a Mac laptop is a client.
+[TO-VERIFY: cache: v0.3 ships Linux archives and images only; the Mac-and-Linux result above was measured on 0.2.x]How we checked
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index f604381..f8bdf2f 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -88,20 +88,22 @@Stored on Restored on Gradle Maven What changes for you in FosterStack Cache v0.3.0
-If you run FosterStack Cache for Gradle or Maven builds, these are the things to check before you upgrade from 0.2.2.
-DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
+[TO-VERIFY]marks anything not yet checked against the release itself.You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes before you do it. These are the things to check, from your point of view.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Check these before you upgrade
-
-
What stays the same
-
+[TO-VERIFY]The Gradle and Maven protocols, theFSCACHE_*settings and the data folder. No change is intended; confirm each against the release notes before this page says so.
+[TO-VERIFY: cache: unchanged at v0.3]The Gradle and Maven protocols, theFSCACHE_*settings and the data folder. No change is intended; confirm each against the release notes before this page says so.Kept patched
+[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the abandoned-upstream scope]We keep FosterStack Cache patched, whether the problem is in our code or in a dependency its maintainers have abandoned.How the release is built
-
+[TO-VERIFY]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. You can check all of it yourself: see verify a release yourself.[TO-VERIFY: pipeline: the v0.3 chain]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. You can check all of it yourself: see verify a release yourself.Upgrading
-
+[TO-VERIFY]Whether the back-up and upgrade steps on the upgrade page change for this release. Support terms for v0.3.0:[TO-VERIFY].[TO-VERIFY: cache: the 0.2.2 to 0.3.0 upgrade steps]Whether the back-up and upgrade steps on the upgrade page change for this release. Support terms for v0.3.0:[TO-VERIFY: cache/owner: what the long-term-support line promises].Related: changelog and security policy.
From c483709b9e99bca8dc910fd8fd00bc644e6f539a Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:19:58 -0400 Subject: [PATCH 14/40] v0.3 policy pages: narrower patching sentence, plainer LTS heading, regulated opens on the contract problem, wording --- fips-140-3-build-cache/index.html | 4 ++-- regulated/index.html | 6 +++--- security/index.html | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index 38b8293..91527a6 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -117,8 +117,8 @@ Confirm it is in FIPS mode
What this tells you, and what it does not
Related: for teams entering regulated markets and security policy. Details: SECURITY.md.
diff --git a/regulated/index.html b/regulated/index.html index 6fd99f0..757c28f 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -88,7 +88,7 @@For teams entering regulated markets
- FosterStack Cache gives the build-cache part of your pipeline public, checkable evidence: a FIPS 140-3 build, an SBOM, SLSA provenance, signatures and VEX statements. It does not make you compliant. + A contract lands with FIPS, SBOM and provenance requirements attached, and your build cache needs paperwork it has never had. FosterStack Cache gives that part of your pipeline public, checkable evidence: a FIPS 140-3 build, an SBOM, build provenance, signatures and VEX statements. It does not make you compliant.
DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
@@ -110,7 +110,7 @@[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.What our piece does — and does not do
build cache. It also serves Maven, through the Apache Maven Build Cache Extension. For that component, we do the evidence work a compliance program needs: the-fipsbuild links Go's FIPS 140-3 validated cryptographic module (CMVP certificate #5247), and every - release ships with an SBOM, SLSA provenance, keyless signatures, and + release ships with an SBOM, build provenance, keyless signatures, and published VEX statements. Our requirements and their evidence are public in the repository, criterion by criterion. @@ -122,7 +122,7 @@What our piece does — and does not do
More than kept patched.
-
-
Report a vulnerability
Send the report, not a patch. Please do not post details publicly before a fix ships.
Kept patched
-We keep FosterStack Cache patched, whether the problem is in our code or in a dependency that its own maintainers have abandoned.
+[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; what is covered when upstream has abandoned a component]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.We keep FosterStack Cache patched.
-[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope in SECURITY.md before any page can say it]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.Long-term support: what is supported
-"LTS" means a version that keeps getting fixes for a stated period, so you can stay on it.
+[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes.Which version gets fixes
+"LTS" means a version that keeps getting fixes, so you can stay on it.
[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes.Long-term support: what is supported
What we sign and publish
-Releases are built only in CI. Every release is signed and checked at every step, and each one comes with files you can check without an account.
+[TO-VERIFY: pipeline/cache: the v0.3 chain; the four metadata files signed via the signed checksums list (cache fix A)]Releases are built only in CI. Each release goes through the steps on how we build and comes with files you can check without an account.
[TO-VERIFY: pipeline/cache: the v0.3 chain and the v0.3 file set; the four metadata files signed via the signed checksums list (cache fix A); the list below is the 0.2.x set]What you get with each release
All of it is public. You do not need an account or a purchase to check any of it. The commands are on verify a release yourself.
Kept patched
-The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched, including software its own maintainers have abandoned.
+[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; what is covered when upstream has abandoned a component]The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched.
[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope before a page can say it]What we do not claim
-
From 0f7093c99cc487ca6854b7284bffb3f26e8dec06 Mon Sep 17 00:00:00 2001
From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com>
Date: Sat, 10 Oct 2026 22:20:19 -0400
Subject: [PATCH 16/40] what's new: no open-ended abandoned-upstream promise
---
whats-new-fosterstack-cache-v0-3-0/index.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html
index f8bdf2f..2c71ad9 100644
--- a/whats-new-fosterstack-cache-v0-3-0/index.html
+++ b/whats-new-fosterstack-cache-v0-3-0/index.html
@@ -99,7 +99,7 @@
Check these before you upgrade
What stays the same
[TO-VERIFY: cache: unchanged at v0.3]The Gradle and Maven protocols, theFSCACHE_*settings and the data folder. No change is intended; confirm each against the release notes before this page says so.Kept patched
-
+[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the abandoned-upstream scope]We keep FosterStack Cache patched, whether the problem is in our code or in a dependency its maintainers have abandoned.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope first]We keep FosterStack Cache patched.How the release is built
[TO-VERIFY: pipeline: the v0.3 chain]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. You can check all of it yourself: see verify a release yourself.Upgrading
From 11d2dcd7ac81b4a3937d152258fb939de0aa97cd Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:21:39 -0400 Subject: [PATCH 17/40] v0.3 product pages: the laptop trust section in plain words, what's-new items as things to check --- laptop-builds-reuse-ci-build-cache/index.html | 6 +++--- whats-new-fosterstack-cache-v0-3-0/index.html | 10 +++++----- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/laptop-builds-reuse-ci-build-cache/index.html b/laptop-builds-reuse-ci-build-cache/index.html index 4bd80b3..ad2f61c 100644 --- a/laptop-builds-reuse-ci-build-cache/index.html +++ b/laptop-builds-reuse-ci-build-cache/index.html @@ -112,9 +112,9 @@What has to match
Keep those the same on laptops and CI. For what to expect after an upgrade, see we upgraded Gradle or Maven and builds got slow. If your laptop still rebuilds, see why the Gradle hit rate is low or why the Maven cache is not restoring. To set it up, see Maven remote build cache setup and the Gradle setup in the CI-writes page.
-A cache every laptop trusts is a cache you can check
-CI and every laptop trust the same server, so you should be able to see what it is. Every release is signed and checked at every step, and you can verify it yourself.
-[TO-VERIFY: pipeline: signed and checked at every stage of the v0.3 chain]We keep it patched, and we secure our own release pipeline the same way before we ask you to run it: how we build.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]The server runs on Linux; a Mac laptop is a client.
+[TO-VERIFY: cache: v0.3 ships Linux archives and images only; the Mac-and-Linux result above was measured on 0.2.x]Can we trust the cache server?
+From v0.3.0, each stage of a release is signed on its own and the signatures are verified together at release, and you can verify it yourself.
+[TO-VERIFY: pipeline: the v0.3 chain]Our target for fixing vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]The checks on this page ran on 0.2.x, and in some of them the cache server ran on a Mac. v0.3.0 ships for Linux only; a Mac laptop is a client either way.
[TO-VERIFY: cache: v0.3 ships Linux archives and images only]How we checked
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 2c71ad9..457e8b6 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -88,20 +88,20 @@
What changes for you in FosterStack Cache v0.3.0
-You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes before you do it. These are the things to check, from your point of view.
+You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes. Three things may need a change on your side: check them before you upgrade.
[TO-VERIFY: cache: that nothing else needs a change]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Check these before you upgrade
-
-
What stays the same
[TO-VERIFY: cache: unchanged at v0.3]The Gradle and Maven protocols, theFSCACHE_*settings and the data folder. No change is intended; confirm each against the release notes before this page says so.Kept patched
-
+[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope first]We keep FosterStack Cache patched.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope first]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.How the release is built
-
+[TO-VERIFY: pipeline: the v0.3 chain]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. You can check all of it yourself: see verify a release yourself.[TO-VERIFY: pipeline: the v0.3 chain]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.Upgrading
[TO-VERIFY: cache: the 0.2.2 to 0.3.0 upgrade steps]Whether the back-up and upgrade steps on the upgrade page change for this release. Support terms for v0.3.0:[TO-VERIFY: cache/owner: what the long-term-support line promises].Related: changelog and security policy.
From 7650fe761475189adf0af670eddce25265cb8df1 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:21:48 -0400 Subject: [PATCH 18/40] what's new: the reviewer note is gone --- whats-new-fosterstack-cache-v0-3-0/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 457e8b6..22155b0 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -97,7 +97,7 @@Check these before you upgrade
What stays the same
-
+[TO-VERIFY: cache: unchanged at v0.3]The Gradle and Maven protocols, theFSCACHE_*settings and the data folder. No change is intended; confirm each against the release notes before this page says so.The Gradle and Maven protocols, the
FSCACHE_*settings and the data folder stay as they are.[TO-VERIFY: cache: unchanged at v0.3]Kept patched
[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope first]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.How the release is built
From 8b933827eddb198419c34b375e4e93fe71747d03 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:24:23 -0400 Subject: [PATCH 19/40] v0.3 drafts: one wording across pages (stage names, signing, the image, the rebuild, the limit), sources on every marker --- changelog/index.html | 2 +- fips-140-3-build-cache/index.html | 4 ++-- .../index.html | 18 ++++++++--------- how-we-build/index.html | 15 +++++++------- index.html | 6 +++--- laptop-builds-reuse-ci-build-cache/index.html | 2 +- regulated/index.html | 6 +++--- security/index.html | 4 ++-- verify-a-release/index.html | 20 +++++++++---------- whats-new-fosterstack-cache-v0-3-0/index.html | 4 ++-- 10 files changed, 40 insertions(+), 41 deletions(-) diff --git a/changelog/index.html b/changelog/index.html index 7c6ce8c..a5473f3 100644 --- a/changelog/index.html +++ b/changelog/index.html @@ -121,7 +121,7 @@v0.1.0
Note on this release's evidence (added Sep 2026). v0.1.0 was built and published by the pre-remediation release pipeline: a snapshot build was scanned, and a separate build of the same commit was published, so these published images were not scanned before publication. They have been rescanned since at every severity with the published VEX applied — see the rescan runs for verdicts against the exact published digests. The signatures and provenance on this release are accurate about what they say — which CI run produced which digest — and say nothing about scanning. The next release is the first to carry the full evidence chain: one build, scanned and tested by digest, promoted without a rebuild.
-What changed since: the v0.2.1 and v0.2.2 release notes point to their
+release-manifest.jsonevidence bundle. The release process, as RELEASING.md describes it, is "One build, one set of digests, promoted without a rebuild", with every scanner run "against the exact candidate digests".What changed since: the v0.2.1 and v0.2.2 release notes point to their
release-manifest.jsonevidence bundle. The release process, as RELEASING.md describes it, is "One build, one set of digests, promoted without a rebuild (the independent rebuild only checks them and is never published)[TO-VERIFY: pipeline: the v0.3 Rebuild stage]", with every scanner run "against the exact candidate digests".Related: how releases are built and signed and security policy.
diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index 91527a6..19bfdd2 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -92,7 +92,7 @@-FIPS 140-3 build cache: run the FIPS image and confirm it
DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.What the FIPS build is
-It is the same source as the standard build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247).
+[TO-VERIFY: cache: at v0.3 the FIPS and standard images come from two builds of one source]It is available as a container image tag ending in-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.[TO-VERIFY: cache: v0.3 ships Linux archives only (amd64 and arm64), and the images are production and fips]It is the same source as the production build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247).
[TO-VERIFY: cache: at v0.3 the FIPS and standard images come from two builds of one source]It is available as a container image tag ending in-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.[TO-VERIFY: cache: v0.3 ships Linux archives only (amd64 and arm64), and the images are production and fips]Run it
-docker run -d -p 127.0.0.1:8080:8080 -v fscache-data:/home/nonroot \ @@ -108,7 +108,7 @@Confirm it is in FIPS mode
"version": "v0.2.2", "fips140": true, "fips140_note": "active (Go validated module v1.0.0, CMVP cert #5247)",The standard image, for comparison, reports it as off:
+The production image, for comparison, reports it as off:
$ curl -s localhost:8080/statusz | grep -E 'version|fips140' "version": "v0.2.2", "fips140": false, diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index 8e48cd7..118dbaa 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -90,24 +90,24 @@How the v0.3.0 release pipeline maps to NIST and SLSA
If you have to explain our release pipeline to a security reviewer, start here. This page puts each stage of the new release pipeline next to the NIST practice it was designed against, and says where a stage only partly implements a practice.
-DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
+[TO-VERIFY]marks anything not yet run against a real release.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
[TO-VERIFY: pipeline]marks anything not yet run against a real release.This is guidance we followed when designing the pipeline. It is not a certification.
Stage by stage
-The six stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
+[TO-VERIFY]against the workflow files at the v0.3.0 tag.The six stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
[TO-VERIFY: pipeline]against the workflow files at the v0.3.0 tag. -Stage What it does NIST practice How much -Source admission [TO-VERIFY]whether unchanged from v0.2.2: signed tag, signed commit onmain, required checks passed.[TO-VERIFY]800-204D 5.1.4 and 5.1.2[TO-VERIFY] -Build [TO-VERIFY]Builds the binaries and the signed packages once. The image is assembled from those packages, with no base image.[TO-VERIFY]800-204D 5.1.1[TO-VERIFY] -Sign [TO-VERIFY]A separate stage records the build and signs it under its own identity, from the build's digest list only.[TO-VERIFY]the part of 5.1.1 that asks for signing outside the build steps[TO-VERIFY] -Rebuild [TO-VERIFY]Builds the release again, independently. The digests must match or the release fails.[TO-VERIFY]none found in either document[TO-VERIFY] -Check [TO-VERIFY]Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests.[TO-VERIFY]800-204C 4.8 and 800-204D 5.2[TO-VERIFY] +Release [TO-VERIFY]Verifies every stage's signature together, then publishes the same digests.[TO-VERIFY][TO-VERIFY] +Source check [TO-VERIFY: pipeline]whether unchanged from v0.2.2: signed tag, signed commit onmain, required checks passed.[TO-VERIFY: pipeline]800-204D 5.1.4 and 5.1.2[TO-VERIFY: pipeline] +Build [TO-VERIFY: pipeline]Builds the binaries and the signed packages once. The image is assembled from those packages, with no base image.[TO-VERIFY: pipeline]800-204D 5.1.1[TO-VERIFY: pipeline] +Sign [TO-VERIFY: pipeline]A separate stage records the build and signs it under its own identity, from the build's digest list only.[TO-VERIFY: pipeline]the part of 5.1.1 that asks for signing outside the build steps[TO-VERIFY: pipeline] +Rebuild [TO-VERIFY: pipeline]Assembles the image again, independently, on a separate machine. The digests must match or the release fails.[TO-VERIFY: pipeline]none found in either document[TO-VERIFY: pipeline] +Check [TO-VERIFY: pipeline]Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests.[TO-VERIFY: pipeline]800-204C 4.8 and 800-204D 5.2[TO-VERIFY: pipeline]Release [TO-VERIFY: pipeline]Verifies every stage's signature together, then publishes the same digests.[TO-VERIFY: pipeline][TO-VERIFY: pipeline]Our wording: signed at every stage, verified together at release.
[TO-VERIFY: pipeline]SLSA
-
+[TO-VERIFY]The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.[TO-VERIFY: pipeline]The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.What this page does not say
Releases are built only in CI
No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what lets the signatures mean something: a release that our CI workflow did not build does not carry its signature.
[TO-VERIFY: pipeline: the signing identity is pinned to the release workflow and tag; no manual release path in v0.3]The steps a release goes through
-Signed at every stage, verified together at release. Each stage signs its own statement about the exact files, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
+[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]Signed at every stage, verified together at release. Each stage signs a statement about what it did, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]-
-
The full description, as the pipeline actually runs, is in RELEASING.md.
@@ -123,12 +123,11 @@[TO-VERIFY: pipeline: RELEASING.md matches the v0.3 chain]What you get with each release
All of it is public. You do not need an account or a purchase to check any of it. The commands are on verify a release yourself.
Kept patched
-The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched.
+[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope before a page can say it]The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched. Our target for vulnerable dependencies is 48 hours from disclosure (the scope is in SECURITY.md); more on the security page.
[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]What we do not claim
-
-
What you get that a bare HTTP endpoint doesn't give you
Authentication
HTTP Basic Auth over TLS, wired the way Gradle and Maven already expect credentials. Constant-time comparison, no credential ever logged.
Metrics & status
Prometheus metrics, a read-only status page with hit rates and size-vs-cap, and a Grafana dashboard in the repo — so you know the cache is earning its keep.
-Maintenance target
Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
+Designed against NIST guidance
No step trusts the one before it. When you check our images' digital signatures you can rest assured we checked it at every step. That signature means it's fosterstack code, a fosterstack build, a fosterstack image and everything in between. See how each stage maps.
[TO-VERIFY: pipeline: signatures at every stage of the v0.3 chain, so the sentence is true]A signature shows where an image came from and that nothing changed it since; it does not show the code is free of bugs or vulnerabilities. This is guidance we designed against, not a certification we hold.
Designed against NIST guidance
No step trusts the one before it. When you check our images' digital signatures you can rest assured we checked it at every step before we released it. That signature means it's fosterstack code, a fosterstack build, a fosterstack image and everything in between. See how each stage maps.
[TO-VERIFY: pipeline: signatures at every stage of the v0.3 chain, so the sentence is true]A signature shows who signed these exact files and that nothing changed them since; it does not show the code is free of bugs or vulnerabilities. This is guidance we designed against, not a certification we hold.
30-minute migration
A step-by-step guide for moving an existing Gradle remote build cache server. Same protocol, same CI config shape — migrating is mostly a URL change.
More than kept patched.
+What stands behind it
How we build · Security policy · Verify a release
diff --git a/laptop-builds-reuse-ci-build-cache/index.html b/laptop-builds-reuse-ci-build-cache/index.html index ad2f61c..6c8cab8 100644 --- a/laptop-builds-reuse-ci-build-cache/index.html +++ b/laptop-builds-reuse-ci-build-cache/index.html @@ -113,7 +113,7 @@What has to match
Keep those the same on laptops and CI. For what to expect after an upgrade, see we upgraded Gradle or Maven and builds got slow. If your laptop still rebuilds, see why the Gradle hit rate is low or why the Maven cache is not restoring. To set it up, see Maven remote build cache setup and the Gradle setup in the CI-writes page.
Can we trust the cache server?
-From v0.3.0, each stage of a release is signed on its own and the signatures are verified together at release, and you can verify it yourself.
+[TO-VERIFY: pipeline: the v0.3 chain]Our target for fixing vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]From v0.3.0, releases are signed at every stage and verified together at release, and you can verify it yourself.
[TO-VERIFY: pipeline: the v0.3 chain]Our target for fixing vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut]The checks on this page ran on 0.2.x, and in some of them the cache server ran on a Mac. v0.3.0 ships for Linux only; a Mac laptop is a client either way.
[TO-VERIFY: cache: v0.3 ships Linux archives and images only]How we checked
diff --git a/regulated/index.html b/regulated/index.html index 757c28f..2db07d4 100644 --- a/regulated/index.html +++ b/regulated/index.html @@ -120,12 +120,12 @@What our piece does — and does not do
program: one row of that questionnaire, answered with something written, signed and checkable instead of a shrug. -More than kept patched.
+What stands behind it
Verify everything yourself first
That's the test we invite.- Step-by-step, with the output of each command from a real release: + Step by step: Verify a release yourself. To run the
-fipsimage and confirm FIPS mode from its own startup log: FIPS 140-3 build cache. diff --git a/security/index.html b/security/index.html index 014acb2..a423df9 100644 --- a/security/index.html +++ b/security/index.html @@ -101,10 +101,10 @@Report a vulnerability
Send the report, not a patch. Please do not post details publicly before a fix ships.
Kept patched
-We keep FosterStack Cache patched.
+[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope in SECURITY.md before any page can say it]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.We keep FosterStack Cache patched.
[TO-VERIFY: cache/ops: "kept patched" holds only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md). Security patches are never withheld from the free tier: the same fix ships to everyone on the same day.Which version gets fixes
-"LTS" means a version that keeps getting fixes, so you can stay on it.
+[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes."LTS" means a version that keeps getting fixes, so you can stay on it.
[TO-VERIFY: cache/owner: v0.3.0 is the only long-term-support line, and what that promises is not written yet]Today the supported version is the latest minor release: there is no list of older versions that get fixes.[TO-VERIFY: cache/owner: rewritten once the v0.3.0 support terms exist]Verify a FosterStack Cache release yourself
-You should not have to take our word for what you run. Each stage of a release is signed on its own, and the signatures are verified together at release.
-[TO-VERIFY: pipeline]These commands check the final signature, how the image was built, its parts list and what it was assembled from, using onlycosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
-[TO-VERIFY]marks anything not yet run against a real release.Use the image by digest for
+<IMAGE_REF>. There are two images; run every step for each.[TO-VERIFY]which two variants.You should not have to take our word for what you run. Signed at every stage, verified together at release.
+[TO-VERIFY: pipeline]These commands check the final signature, how the image was built, its parts list and what it was assembled from, using onlycosign,ghandjq.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: pipeline]marks anything not yet run against a real release.Use the image by digest for
<IMAGE_REF>. There are two images, production and fips; run every step for each.[TO-VERIFY: cache: the two variants and their references]1. The signature and who signed it
-# [TO-VERIFY] identity and issuer for the final signature +# [TO-VERIFY: pipeline] identity and issuer for the final signature cosign verify <IMAGE_REF> \ --certificate-identity-regexp '<IDENTITY>' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com2. The digest is the one in the release
-# [TO-VERIFY] file name and layout +# [TO-VERIFY: pipeline] file name and layout gh release download <TAG> --repo fosterstack/cache -p release-manifest.json jq -r '.images[] | "\(.variant) \(.digest)"' release-manifest.jsonEvery statement names the image by digest, never by tag.
[TO-VERIFY: pipeline]The digest you verified should match this list.3. How it was built
-# [TO-VERIFY] signer workflow +
-# [TO-VERIFY: pipeline] signer workflow gh attestation verify oci://<IMAGE_REF> --repo fosterstack/cache \ --signer-workflow '<WORKFLOW>' --source-ref refs/tags/<TAG>
+[TO-VERIFY]One sentence on what this record covers. No SLSA level claim here.[TO-VERIFY: pipeline]One sentence on what this record covers. No SLSA level claim here.4. The parts list (SBOM)
-# [TO-VERIFY] predicate type and what the list holds for an image with no base image +# [TO-VERIFY: pipeline] predicate type and what the list holds for an image with no base image cosign verify-attestation <IMAGE_REF> --type spdxjson \ --certificate-identity-regexp '<IDENTITY>' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ | jq -r '.payload | @base64d | fromjson | .predicate.name'5. What the image was assembled from
-# [TO-VERIFY] what "inputs" means for a customer, and the one command that checks it +# [TO-VERIFY: pipeline] what "inputs" means for a customer, and the one command that checks it cosign verify-attestation <IMAGE_REF> --type '<INPUTS_TYPE>' ... | jq '<FILTER>'What this proves
-
@@ -121,7 +121,7 @@
What this proves
Extra evidence, outside these commands: records anyone who has Witness installed can check.
+[TO-VERIFY]where they are published.Extra evidence, outside these commands: records anyone who has Witness installed can check.
[TO-VERIFY: pipeline]where they are published.Related: how releases are built and signed and security policy.
diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 22155b0..9e23cc4 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -99,9 +99,9 @@ Check these before you upgrade
What stays the same
The Gradle and Maven protocols, the
FSCACHE_*settings and the data folder stay as they are.[TO-VERIFY: cache: unchanged at v0.3]Kept patched
-
+[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the brief also says "new or abandoned upstream": that needs a written scope first]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.How the release is built
-
+[TO-VERIFY: pipeline: the v0.3 chain]Each stage of the release is signed on its own, and the signatures are verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.[TO-VERIFY: pipeline: the v0.3 chain]Signed at every stage, verified together at release. The image is built from signed packages, with no base image. We secure our own release pipeline first. You can check all of it yourself: see verify a release yourself and how we build.Upgrading
[TO-VERIFY: cache: the 0.2.2 to 0.3.0 upgrade steps]Whether the back-up and upgrade steps on the upgrade page change for this release. Support terms for v0.3.0:[TO-VERIFY: cache/owner: what the long-term-support line promises].Related: changelog and security policy.
From f7f5b881f29a6762e210e0375e07caa61b21a79e Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:26:37 -0400 Subject: [PATCH 20/40] v0.3 drafts: the five stages as the pipeline lane lists them (no separate source stage; Rebuild compares every digest) --- how-our-pipeline-maps-to-nist-and-slsa/index.html | 5 ++--- how-we-build/index.html | 15 +++++++-------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index 118dbaa..d5a5b84 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -93,12 +93,11 @@How the v0.3.0 release pipeline maps to NIST and SLSA
DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
[TO-VERIFY: pipeline]marks anything not yet run against a real release.This is guidance we followed when designing the pipeline. It is not a certification.
Stage by stage
-The six stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
+[TO-VERIFY: pipeline]against the workflow files at the v0.3.0 tag.The stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
[TO-VERIFY: pipeline]against the workflow files at the v0.3.0 tag. -Stage What it does NIST practice How much -Source check [TO-VERIFY: pipeline]whether unchanged from v0.2.2: signed tag, signed commit onmain, required checks passed.[TO-VERIFY: pipeline]800-204D 5.1.4 and 5.1.2[TO-VERIFY: pipeline] +Build [TO-VERIFY: pipeline]Builds the binaries and the signed packages once. The image is assembled from those packages, with no base image.[TO-VERIFY: pipeline]800-204D 5.1.1[TO-VERIFY: pipeline]Build [TO-VERIFY: pipeline]Checks that the tag is signed, then builds the binaries and both images once. The image is assembled from those packages, with no base image.[TO-VERIFY: pipeline]800-204D 5.1.1[TO-VERIFY: pipeline]Sign [TO-VERIFY: pipeline]A separate stage records the build and signs it under its own identity, from the build's digest list only.[TO-VERIFY: pipeline]the part of 5.1.1 that asks for signing outside the build steps[TO-VERIFY: pipeline]Rebuild [TO-VERIFY: pipeline]Assembles the image again, independently, on a separate machine. The digests must match or the release fails.[TO-VERIFY: pipeline]none found in either document[TO-VERIFY: pipeline] diff --git a/how-we-build/index.html b/how-we-build/index.html index 495da0c..32a136a 100644 --- a/how-we-build/index.html +++ b/how-we-build/index.html @@ -100,15 +100,14 @@Check [TO-VERIFY: pipeline]Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests.[TO-VERIFY: pipeline]800-204C 4.8 and 800-204D 5.2[TO-VERIFY: pipeline]We do it to our own pipeline first
Releases are built only in CI
No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what lets the signatures mean something: a release that our CI workflow did not build does not carry its signature.
-[TO-VERIFY: pipeline: the signing identity is pinned to the release workflow and tag; no manual release path in v0.3]The steps a release goes through
-Signed at every stage, verified together at release. Each stage signs a statement about what it did, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
+[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]The stages a release goes through
+Signed at every stage, verified together at release. Each stage signs a statement about what it did, each stage checks the one before it, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]-
-
The full description, as the pipeline actually runs, is in RELEASING.md.
From 4b4af98d8f7e711b5f9b8b35ebe1aac6b6989ef8 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:29:14 -0400 Subject: [PATCH 21/40] what's new: the Mac container, the debug question, the data folder layout and the 431 rule as the cache lane states them --- whats-new-fosterstack-cache-v0-3-0/index.html | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 9e23cc4..0b36d0d 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -88,16 +88,16 @@[TO-VERIFY: pipeline: RELEASING.md matches the v0.3 chain]What changes for you in FosterStack Cache v0.3.0
-You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes. Three things may need a change on your side: check them before you upgrade.
+[TO-VERIFY: cache: that nothing else needs a change]You run FosterStack Cache for Gradle or Maven builds and you want to know what an upgrade to v0.3.0 changes. Three things may matter on your side: check them before you upgrade.
[TO-VERIFY: cache: that nothing else needs a change]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Check these before you upgrade
-
-
What stays the same
-The Gradle and Maven protocols, the
+FSCACHE_*settings and the data folder stay as they are.[TO-VERIFY: cache: unchanged at v0.3]The Gradle and Maven protocols and the
FSCACHE_*settings stay as they are.[TO-VERIFY: cache: unchanged at v0.3; no test run]A request with more than 500 header values has been rejected with431(Request Header Fields Too Large) since 0.2.2, because of Go 1.27; Gradle and Maven send far fewer.[TO-VERIFY: cache: Go 1.27 behaviour, in 0.2.2 already; the client-side message is not verified]Kept patched
[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.How the release is built
From 287a0d837190a13b4f0b89a4efcb2e2c82d6a21d Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sat, 10 Oct 2026 22:29:41 -0400 Subject: [PATCH 22/40] what's new: no -debug image (the owner's Oct 9 decision), TO-VERIFY until built --- whats-new-fosterstack-cache-v0-3-0/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 0b36d0d..0c5e709 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -93,7 +93,7 @@What changes for you in FosterStack Cache v0.3.0
Check these before you upgrade
What stays the same
From 62d65d948b98cd276d4a1d2e7ac619fbae93ed55 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sun, 11 Oct 2026 14:55:51 -0400 Subject: [PATCH 23/40] what's new: the two new TLS settings and the startup changes that landed on cache main (TO-VERIFY) --- whats-new-fosterstack-cache-v0-3-0/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/whats-new-fosterstack-cache-v0-3-0/index.html b/whats-new-fosterstack-cache-v0-3-0/index.html index 0c5e709..b86017e 100644 --- a/whats-new-fosterstack-cache-v0-3-0/index.html +++ b/whats-new-fosterstack-cache-v0-3-0/index.html @@ -97,7 +97,7 @@Check these before you upgrade
What stays the same
-The Gradle and Maven protocols and the
+FSCACHE_*settings stay as they are.[TO-VERIFY: cache: unchanged at v0.3; no test run]A request with more than 500 header values has been rejected with431(Request Header Fields Too Large) since 0.2.2, because of Go 1.27; Gradle and Maven send far fewer.[TO-VERIFY: cache: Go 1.27 behaviour, in 0.2.2 already; the client-side message is not verified]The Gradle and Maven protocols stay as they are, and every
FSCACHE_*setting you use today keeps its meaning. Two new optional settings,FSCACHE_TLS_CERTandFSCACHE_TLS_KEY, make the server itself serve HTTPS (TLS 1.2 or later); set both or neither.[TO-VERIFY: cache: REQ-TLS-001, merged to main Oct 11 (#296), not yet in a release]The server now binds its address first and logs a warning for anFSCACHE_*variable it does not know.[TO-VERIFY: cache: #257, merged to main Oct 11, not yet in a release][TO-VERIFY: cache: unchanged at v0.3; no test run]A request with more than 500 header values has been rejected with431(Request Header Fields Too Large) since 0.2.2, because of Go 1.27; Gradle and Maven send far fewer.[TO-VERIFY: cache: Go 1.27 behaviour, in 0.2.2 already; the client-side message is not verified]Kept patched
[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]We keep FosterStack Cache patched. The server does not update itself, so watch the repository's releases on GitHub. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md.How the release is built
From 41ac5fe417a5dd43ae27a3e804aa5a36e2c009b5 Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Sun, 11 Oct 2026 14:57:02 -0400 Subject: [PATCH 24/40] v0.3 drafts: HTTPS offered both ways (a proxy in front, or the server's own TLS) on eleven pages, TO-VERIFY (native TLS is on cache main, in no release) --- build-cache-docker-compose-production/index.html | 8 +++++++- can-someone-poison-our-build-cache/index.html | 4 +++- .../index.html | 4 +++- first-15-minutes-build-cache/index.html | 6 ++++-- gradle-build-cache-ci-writes-developers-read/index.html | 4 +++- gradle-build-cache-corporate-proxy/index.html | 4 +++- gradle-build-cache-kubernetes/index.html | 4 ++++ gradle-remote-build-cache-authentication/index.html | 4 +++- gradle-remote-build-cache-private-ca-https/index.html | 4 +++- .../index.html | 4 +++- maven-remote-build-cache-setup/index.html | 4 +++- 11 files changed, 39 insertions(+), 11 deletions(-) diff --git a/build-cache-docker-compose-production/index.html b/build-cache-docker-compose-production/index.html index 1c5760f..6ec7791 100644 --- a/build-cache-docker-compose-production/index.html +++ b/build-cache-docker-compose-production/index.html @@ -1,6 +1,7 @@ +Docker Compose build cache: quick start and production @@ -88,7 +89,8 @@Docker Compose build cache: quick start and production
-Run a shared Gradle build cache for your team in one Compose file, with a password and a size limit. For real use, put an HTTPS proxy in front: Gradle sends the password with every request.
+Run a shared Gradle build cache for your team in one Compose file, with a password and a size limit. For real use, serve HTTPS: Gradle sends the password with every request. Put a proxy in front (below), or set
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEYand let the server answer HTTPS itself.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Gradle build cache with Docker Compose
Our advice, not a test result. This is the shape we suggest once you go past a first trial.
@@ -131,6 +133,10 @@Point Gradle at it
Health checks
The container image has no shell, so there is no health check inside the Compose file. Probe
+/healthzfrom outside: your orchestrator's HTTP check, a monitor, orcurl -f http://localhost:8080/healthzfrom the host.Two ways to serve HTTPS
+A proxy in front (the nginx setup below): the proxy holds the certificate and the server stays on plain HTTP behind it. TLS in the server: set
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file (it may hold the chain) and its private key file, both or neither. The server then serves HTTPS only, onFSCACHE_ADDR, with TLS 1.2 as the minimum version. HTTP/2 is not offered, a plain-HTTP request to that port gets400, and your/healthzcheck moves tohttps://. Mount the files read-only. They are read only at startup, so replace them and restart.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]If a client cannot connect, look from the client side with
+openssl s_client -connect HOST:PORT -alpn http/1.1: the server does not log handshake failures at the default log level.[TO-VERIFY: cache: cache docs/docker-deploy.md; the command and the logging statement are the cache docs' words, not run by www]Production: nginx and TLS in front
A Compose file for a shared build cache that only answers over HTTPS, with a password, behind nginx. It was run for real on FosterStack Cache 0.2.1 and Gradle 9.8.0. The file pins 0.2.2, a security-patch release whose release notes say it changes no behaviour.
diff --git a/can-someone-poison-our-build-cache/index.html b/can-someone-poison-our-build-cache/index.html index c825ced..e5ce446 100644 --- a/can-someone-poison-our-build-cache/index.html +++ b/can-someone-poison-our-build-cache/index.html @@ -1,6 +1,7 @@ +Can Someone Poison Our Shared Build Cache? @@ -89,6 +90,7 @@Can someone poison our shared build cache?
Anyone who holds the write login can change what every other build restores. FosterStack Cache does not stop that holder. It lets you give everyone else a read-only login, and in our runs the server refused their writes.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.The short answer
The server has two logins. The write login lets a client store and replace entries. The read-only login lets a client only read them.
@@ -115,7 +117,7 @@What to do
FosterStack Cache has one write login and one read-only login. There is no per-person identity: a write login is shared by whoever holds it, so the login alone does not say which writer did what. We did not test whether the server records who wrote an entry.
diff --git a/does-build-cache-entry-contain-source-code-or-secrets/index.html b/does-build-cache-entry-contain-source-code-or-secrets/index.html index 11c2ca2..b4cfc7c 100644 --- a/does-build-cache-entry-contain-source-code-or-secrets/index.html +++ b/does-build-cache-entry-contain-source-code-or-secrets/index.html @@ -1,6 +1,7 @@ +Does a Build Cache Entry Contain My Source Code or Secrets? @@ -89,6 +90,7 @@Does a build cache entry contain my source code or secrets?
In our runs, FosterStack Cache stored what tasks produce, not your source files. That includes class files and anything a test prints, so a secret in an output is in the cache.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.The short answer
-
@@ -108,7 +110,7 @@
What to do
What each task stores is on know what your Gradle build cache stores. Who can change entries is on can someone poison our shared build cache.
diff --git a/first-15-minutes-build-cache/index.html b/first-15-minutes-build-cache/index.html index 3d92347..9f8e3d5 100644 --- a/first-15-minutes-build-cache/index.html +++ b/first-15-minutes-build-cache/index.html @@ -1,6 +1,7 @@ +Your first 15 minutes with a self-hosted build cache @@ -90,6 +91,7 @@Your first 15 minutes with a self-hosted build cache
A checklist from nothing to your first
+FROM-CACHE, the line Gradle prints when it reuses a stored result. The commands take 20 seconds or less; we timed them on a clean GitHub-hosted machine that had Gradle and Java. Still, plan on about 15 minutes in all, because reading, choosing your values and pointing your own project at the server take you longer than the commands.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.What we timed
@@ -106,7 +108,7 @@
The checklist
1. Decide where it will run
2. Download it and check it is ours
@@ -158,7 +160,7 @@6. Build twice and look for FROM-CACHE
7. Before you roll it out to a team
-
-
Let CI write, developers only read: Gradle and Maven cache @@ -90,6 +91,7 @@Let CI write, developers only read the build cache
Anything that can write to your build cache can change what later builds use, so give the right to write to as few machines as possible. This page sets up a cache where CI uploads and developers only download, in Gradle and in Maven, with a read-only login the server enforces.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Give the server two logins
The server takes one read-write login and, optionally, a second read-only login. A client using the read-only one can read cache entries, and any write is refused with a 403.
@@ -174,7 +176,7 @@If a developer has no login
What this does not give you
There is no per-person identity. Everyone who holds the read-write login is the same writer to the server, so keep it to CI. See who can write to a remote build cache and the HTTP status codes. To see why laptops then reuse CI's work, see your laptop builds reuse what CI already built.
-Our advice, not a test result: use HTTPS, keep the CI password in your CI secret store and never in the repository.
+Our advice, not a test result: use HTTPS (behind a proxy, or with the server's own certificate:
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]), keep the CI password in your CI secret store and never in the repository.How we checked
Gradle run
diff --git a/gradle-build-cache-corporate-proxy/index.html b/gradle-build-cache-corporate-proxy/index.html index 0fe4930..79b54b1 100644 --- a/gradle-build-cache-corporate-proxy/index.html +++ b/gradle-build-cache-corporate-proxy/index.html @@ -1,6 +1,7 @@ +Build cache behind a corporate proxy: Gradle and Maven @@ -90,6 +91,7 @@Build cache behind a corporate proxy: Gradle and Maven
Many companies make builds reach the network through a proxy. This page shows how the remote build cache behaves behind one, in Gradle and in Maven: the settings, the ways it goes wrong, and how to tell a proxy problem from a cache problem.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.In our runs Maven behaved differently from Gradle: it did not skip the proxy for loopback addresses. If you test on 127.0.0.1 with Maven, list it in
nonProxyHosts: see the Maven section.Checklist for Gradle
@@ -97,7 +99,7 @@Checklist for Gradle
Gradle build cache on Kubernetes (no Helm chart yet) @@ -88,6 +89,7 @@Gradle build cache on Kubernetes: plain manifests, no Helm chart yet
Run a shared build cache in your cluster with plain manifests: one Deployment, one volume, one Service. There is no Helm chart yet. It has not been through a beta on a production cluster, so treat it that way.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Is there a Helm chart?
Not yet. Today the supported way to deploy on Kubernetes is the plain manifests in the Kubernetes guide: a Secret, a volume claim, a Deployment and a Service. Copy them into one file and apply it with
@@ -114,6 +116,8 @@kubectl apply -f.Locked down by default
Runners in the same cluster
If your CI runners already run in this cluster, including Jenkins agents, GitHub Actions runner controller and GitLab runners, you need no load balancer and no ingress. Point Gradle at the cluster-internal name, for example
+http://fscache.fscache-ns.svc.cluster.local/, withisAllowInsecureProtocol = true. Gradle requires that for plainhttp://addresses. In our test with Gradle 9.8.0, only the literal127.0.0.1was let through without it. Here it is reasonable because the traffic never leaves the cluster network. See Jenkins and CI build cache.HTTPS: in front, or in the server
+There are two ways to serve HTTPS, and neither is preferred. TLS in front: a load balancer, Gateway or ingress terminates TLS and forwards plain HTTP to the Service, as in the manifests above; the server needs no certificate. TLS in the server: set
FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file and its private key file; the server then serves HTTPS only, on the same port, with TLS 1.2 as the minimum version. A missing, unreadable or mismatched file stops the start with a message naming the variable. Put the certificate in a Secret of typekubernetes.io/tls, mount it read-only, and make it readable by the container's non-root user (65532 in the guide's manifest).[TO-VERIFY: cache: cache: native TLS is on cache main in no release; docs/kubernetes.md "TLS: in front, or in the server"]We tested neither route on the throwaway cluster.Get the manifests
The four manifests (Secret, volume claim, Deployment, Service) and the steps to reach the cache from outside the cluster are in the Kubernetes guide on GitHub. Copy them into one file and apply it.
diff --git a/gradle-remote-build-cache-authentication/index.html b/gradle-remote-build-cache-authentication/index.html index 39cdf36..32fcbc1 100644 --- a/gradle-remote-build-cache-authentication/index.html +++ b/gradle-remote-build-cache-authentication/index.html @@ -1,6 +1,7 @@ +Gradle build cache authentication: 401 and status codes @@ -88,10 +89,11 @@Gradle build cache authentication: 401 and status codes
Gradle does not fail the build when the cache refuses it, so a wrong password or a refused upload often shows up only as a status code. FosterStack Cache takes an optional password, and this page shows how to set it, how to give Gradle the right one, and what each status code means.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Our advice, not a test result
-
-
Use your Gradle build cache over HTTPS with a private CA @@ -89,6 +90,7 @@Use your Gradle build cache over HTTPS with a private CA
With the right trust store, Gradle uses a cache behind HTTPS with your own certificate authority, and in our runs the cache hits worked. We ran real builds with a private CA and saw the exact error without it. With the standard Java settings we used, a trust store that held only our CA made Java ignore its normal list of trusted CAs. Our downloads from Maven Central then failed, until we put the normal list into the store as well.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.The short answer
-
@@ -149,7 +151,7 @@
How we made the test certificates
The certificate has to name the address your builds use. We did not test a certificate that names a different host, an expired certificate, the Gradle wrapper (
./gradlew), or Linux or Windows.If it still does not work
-Work through Gradle remote build cache not working. For the server side of HTTPS, see production Docker Compose with nginx and TLS.
+Work through Gradle remote build cache not working. For the server side of HTTPS, see production Docker Compose with nginx and TLS, which also covers the server's own certificate (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY). The runs on this page used a test TLS proxy; we did not run the server's own TLS.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]Run on Gradle 9.8.0 with FosterStack Cache 0.2.1 behind a test TLS proxy, macOS (arm64), Java 27 (Homebrew), OpenSSL 3.6.5.
We repeated the six runs on a GitHub-hosted Linux machine with release 0.2.2, Gradle 9.8.0, Java 27 (Temurin 27+35) and a small TLS proxy written in Python. All six runs matched the table, including run 5, which fails as expected. The combined store there held 121 certificates, including ours: the count depends on which Java build you use. The run and its log are public.
diff --git a/is-the-build-cache-server-healthy-what-to-alert-on/index.html b/is-the-build-cache-server-healthy-what-to-alert-on/index.html index e0a3d94..5113c44 100644 --- a/is-the-build-cache-server-healthy-what-to-alert-on/index.html +++ b/is-the-build-cache-server-healthy-what-to-alert-on/index.html @@ -1,6 +1,7 @@ +Is My Build Cache Server Healthy? What to Alert On @@ -89,6 +90,7 @@Is my build cache server healthy? What to alert on
Watch three things: the server answers, uploads succeed, and builds get hits. FosterStack Cache reports all three, but
+/healthzalone only says the process is running.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.The short answer
-
@@ -129,7 +131,7 @@
A scrape setting
- job_name: fscache static_configs: - targets: ['cache.example.com:8080'] -This is a plain example. Use your own address, and HTTPS if you have put the server behind a proxy.
+This is a plain example. Use your own address, and HTTPS if a proxy fronts the server. With the server's own TLS (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY) the/healthzcheck moves tohttps://too.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]The metrics
These are the names a running 0.2.1 server reports:
diff --git a/maven-remote-build-cache-setup/index.html b/maven-remote-build-cache-setup/index.html index d530ee5..64975a0 100644 --- a/maven-remote-build-cache-setup/index.html +++ b/maven-remote-build-cache-setup/index.html @@ -1,6 +1,7 @@ +Maven remote build cache setup, on/off, and with Gradle @@ -90,6 +91,7 @@Maven remote build cache: setup, on/off switches, and Gradle on the same server
Share Maven build results across machines using Apache's Build Cache Extension and a self-hosted cache server. FosterStack Cache is that server, and one server can also serve Gradle. About ten minutes, mostly editing the files and choosing your values. The two builds in step 4 took 9 to 12 seconds together on a GitHub-hosted machine.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Who owns what
The client is Apache's Maven Build Cache Extension. We maintain the server. If your hit rate looks low, that is usually the extension's own project settings (which files count as inputs, what to skip), not the server. Start with the extension's configuration guide.
@@ -124,7 +126,7 @@2. Point it at the server, and switch uploads on
</remote> </configuration> </cache> -Keep the comment: a cache setting that points at an unfamiliar host looks like data theft to a reviewer without it. Keep the trailing slash on the URL. Use HTTPS for a real server.
+Keep the comment: a cache setting that points at an unfamiliar host looks like data theft to a reviewer without it. Keep the trailing slash on the URL. Use HTTPS for a real server: behind a proxy, or with the server's own
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]3. Add the password, if the server has one
In
From 6871003067594f45e2c4dcc5efc7fa414c5c8b6f Mon Sep 17 00:00:00 2001 From: FosterStack Admin <317177128+fosterstack-admin@users.noreply.github.com> Date: Tue, 13 Oct 2026 20:02:41 -0400 Subject: [PATCH 25/40] v0.3 preview: drop the TO-VERIFY markers and the line that explains them --- .../index.html | 8 ++--- can-someone-poison-our-build-cache/index.html | 4 +-- changelog/index.html | 6 ++-- .../index.html | 4 +-- fips-140-3-build-cache/index.html | 8 ++--- first-15-minutes-build-cache/index.html | 4 +-- .../index.html | 4 +-- gradle-build-cache-corporate-proxy/index.html | 4 +-- gradle-build-cache-kubernetes/index.html | 4 +-- .../index.html | 4 +-- .../index.html | 4 +-- .../index.html | 18 +++++----- how-we-build/index.html | 34 +++++++++---------- index.html | 22 ++++++------ .../index.html | 4 +-- laptop-builds-reuse-ci-build-cache/index.html | 6 ++-- llms.txt | 2 +- maven-remote-build-cache-setup/index.html | 4 +-- regulated/index.html | 8 ++--- security/index.html | 12 +++---- verify-a-release/index.html | 22 ++++++------ whats-new-fosterstack-cache-v0-3-0/index.html | 18 +++++----- 22 files changed, 102 insertions(+), 102 deletions(-) diff --git a/build-cache-docker-compose-production/index.html b/build-cache-docker-compose-production/index.html index 6ec7791..fce893f 100644 --- a/build-cache-docker-compose-production/index.html +++ b/build-cache-docker-compose-production/index.html @@ -89,8 +89,8 @@~/.m2/settings.xml, or your CI system's equivalent. Theidmust match theidin step 2:Docker Compose build cache: quick start and production
-Run a shared Gradle build cache for your team in one Compose file, with a password and a size limit. For real use, serve HTTPS: Gradle sends the password with every request. Put a proxy in front (below), or set
-FSCACHE_TLS_CERTandFSCACHE_TLS_KEYand let the server answer HTTPS itself.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Run a shared Gradle build cache for your team in one Compose file, with a password and a size limit. For real use, serve HTTPS: Gradle sends the password with every request. Put a proxy in front (below), or set
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEYand let the server answer HTTPS itself.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Gradle build cache with Docker Compose
Our advice, not a test result. This is the shape we suggest once you go past a first trial.
@@ -134,8 +134,8 @@Health checks
The container image has no shell, so there is no health check inside the Compose file. Probe
/healthzfrom outside: your orchestrator's HTTP check, a monitor, orcurl -f http://localhost:8080/healthzfrom the host.Two ways to serve HTTPS
-A proxy in front (the nginx setup below): the proxy holds the certificate and the server stays on plain HTTP behind it. TLS in the server: set
-FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file (it may hold the chain) and its private key file, both or neither. The server then serves HTTPS only, onFSCACHE_ADDR, with TLS 1.2 as the minimum version. HTTP/2 is not offered, a plain-HTTP request to that port gets400, and your/healthzcheck moves tohttps://. Mount the files read-only. They are read only at startup, so replace them and restart.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]If a client cannot connect, look from the client side with
+openssl s_client -connect HOST:PORT -alpn http/1.1: the server does not log handshake failures at the default log level.[TO-VERIFY: cache: cache docs/docker-deploy.md; the command and the logging statement are the cache docs' words, not run by www]A proxy in front (the nginx setup below): the proxy holds the certificate and the server stays on plain HTTP behind it. TLS in the server: set
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file (it may hold the chain) and its private key file, both or neither. The server then serves HTTPS only, onFSCACHE_ADDR, with TLS 1.2 as the minimum version. HTTP/2 is not offered, a plain-HTTP request to that port gets400, and your/healthzcheck moves tohttps://. Mount the files read-only. They are read only at startup, so replace them and restart.If a client cannot connect, look from the client side with
openssl s_client -connect HOST:PORT -alpn http/1.1: the server does not log handshake failures at the default log level.Production: nginx and TLS in front
A Compose file for a shared build cache that only answers over HTTPS, with a password, behind nginx. It was run for real on FosterStack Cache 0.2.1 and Gradle 9.8.0. The file pins 0.2.2, a security-patch release whose release notes say it changes no behaviour.
diff --git a/can-someone-poison-our-build-cache/index.html b/can-someone-poison-our-build-cache/index.html index e5ce446..758b532 100644 --- a/can-someone-poison-our-build-cache/index.html +++ b/can-someone-poison-our-build-cache/index.html @@ -90,7 +90,7 @@Can someone poison our shared build cache?
Anyone who holds the write login can change what every other build restores. FosterStack Cache does not stop that holder. It lets you give everyone else a read-only login, and in our runs the server refused their writes.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
The short answer
The server has two logins. The write login lets a client store and replace entries. The read-only login lets a client only read them.
@@ -117,7 +117,7 @@What to do
FosterStack Cache has one write login and one read-only login. There is no per-person identity: a write login is shared by whoever holds it, so the login alone does not say which writer did what. We did not test whether the server records who wrote an entry.
diff --git a/changelog/index.html b/changelog/index.html index a5473f3..e7000e4 100644 --- a/changelog/index.html +++ b/changelog/index.html @@ -91,10 +91,10 @@FosterStack Cache changelog
The release notes from GitHub, quoted as published. Newest first. For anything else, the releases page is the source.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
v0.3.0
-The v0.3.0 release notes will be quoted here as published, like the others.
+[TO-VERIFY: cache: the v0.3.0 release notes; nothing here is written before the release exists]The v0.3.0 release notes will be quoted here as published, like the others.
v0.2.2
Release name: fscache v0.2.2. Published 2026-10-09.
@@ -121,7 +121,7 @@v0.1.0
Note on this release's evidence (added Sep 2026). v0.1.0 was built and published by the pre-remediation release pipeline: a snapshot build was scanned, and a separate build of the same commit was published, so these published images were not scanned before publication. They have been rescanned since at every severity with the published VEX applied — see the rescan runs for verdicts against the exact published digests. The signatures and provenance on this release are accurate about what they say — which CI run produced which digest — and say nothing about scanning. The next release is the first to carry the full evidence chain: one build, scanned and tested by digest, promoted without a rebuild.
-What changed since: the v0.2.1 and v0.2.2 release notes point to their
+release-manifest.jsonevidence bundle. The release process, as RELEASING.md describes it, is "One build, one set of digests, promoted without a rebuild (the independent rebuild only checks them and is never published)[TO-VERIFY: pipeline: the v0.3 Rebuild stage]", with every scanner run "against the exact candidate digests".What changed since: the v0.2.1 and v0.2.2 release notes point to their
release-manifest.jsonevidence bundle. The release process, as RELEASING.md describes it, is "One build, one set of digests, promoted without a rebuild (the independent rebuild only checks them and is never published)", with every scanner run "against the exact candidate digests".Related: how releases are built and signed and security policy.
diff --git a/does-build-cache-entry-contain-source-code-or-secrets/index.html b/does-build-cache-entry-contain-source-code-or-secrets/index.html index b4cfc7c..6718f5a 100644 --- a/does-build-cache-entry-contain-source-code-or-secrets/index.html +++ b/does-build-cache-entry-contain-source-code-or-secrets/index.html @@ -90,7 +90,7 @@Does a build cache entry contain my source code or secrets?
In our runs, FosterStack Cache stored what tasks produce, not your source files. That includes class files and anything a test prints, so a secret in an output is in the cache.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
The short answer
-
@@ -110,7 +110,7 @@
What to do
What each task stores is on know what your Gradle build cache stores. Who can change entries is on can someone poison our shared build cache.
diff --git a/fips-140-3-build-cache/index.html b/fips-140-3-build-cache/index.html index 19bfdd2..a03860a 100644 --- a/fips-140-3-build-cache/index.html +++ b/fips-140-3-build-cache/index.html @@ -88,11 +88,11 @@FIPS 140-3 build cache: run the FIPS image and confirm it
-Your contract asks for FIPS-validated cryptography, and you have to show what your build cache actually runs. FosterStack Cache has a FIPS build that uses Go's validated FIPS 140-3 cryptographic module. This page shows how to run it and how to see for yourself that it is in FIPS mode. The outputs below are from the real 0.2.2 images.
-[TO-VERIFY: cache: re-run on the v0.3 FIPS image; the module version and status output]DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.Your contract asks for FIPS-validated cryptography, and you have to show what your build cache actually runs. FosterStack Cache has a FIPS build that uses Go's validated FIPS 140-3 cryptographic module. This page shows how to run it and how to see for yourself that it is in FIPS mode. The outputs below are from the real 0.2.2 images.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
What the FIPS build is
-It is the same source as the production build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247).
+[TO-VERIFY: cache: at v0.3 the FIPS and standard images come from two builds of one source]It is available as a container image tag ending in-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.[TO-VERIFY: cache: v0.3 ships Linux archives only (amd64 and arm64), and the images are production and fips]It is the same source as the production build, compiled so that it uses Go's validated FIPS 140-3 module (CMVP certificate #5247). It is available as a container image tag ending in
-fips, and as Linux binaries for amd64 and arm64. There is no macOS FIPS build.Run it
docker run -d -p 127.0.0.1:8080:8080 -v fscache-data:/home/nonroot \ @@ -117,7 +117,7 @@Confirm it is in FIPS mode
What this tells you, and what it does not
Your first 15 minutes with a self-hosted build cache
A checklist from nothing to your first
-FROM-CACHE, the line Gradle prints when it reuses a stored result. The commands take 20 seconds or less; we timed them on a clean GitHub-hosted machine that had Gradle and Java. Still, plan on about 15 minutes in all, because reading, choosing your values and pointing your own project at the server take you longer than the commands.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
What we timed
@@ -108,7 +108,7 @@
The checklist
1. Decide where it will run
2. Download it and check it is ours
diff --git a/gradle-build-cache-ci-writes-developers-read/index.html b/gradle-build-cache-ci-writes-developers-read/index.html index fbcec50..8fea8f4 100644 --- a/gradle-build-cache-ci-writes-developers-read/index.html +++ b/gradle-build-cache-ci-writes-developers-read/index.html @@ -91,7 +91,7 @@Let CI write, developers only read the build cache
Anything that can write to your build cache can change what later builds use, so give the right to write to as few machines as possible. This page sets up a cache where CI uploads and developers only download, in Gradle and in Maven, with a read-only login the server enforces.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Give the server two logins
The server takes one read-write login and, optionally, a second read-only login. A client using the read-only one can read cache entries, and any write is refused with a 403.
@@ -176,7 +176,7 @@If a developer has no login
What this does not give you
There is no per-person identity. Everyone who holds the read-write login is the same writer to the server, so keep it to CI. See who can write to a remote build cache and the HTTP status codes. To see why laptops then reuse CI's work, see your laptop builds reuse what CI already built.
-Our advice, not a test result: use HTTPS (behind a proxy, or with the server's own certificate:
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEY[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]), keep the CI password in your CI secret store and never in the repository.Our advice, not a test result: use HTTPS (behind a proxy, or with the server's own certificate:
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY), keep the CI password in your CI secret store and never in the repository.How we checked
Gradle run
diff --git a/gradle-build-cache-corporate-proxy/index.html b/gradle-build-cache-corporate-proxy/index.html index 79b54b1..af06def 100644 --- a/gradle-build-cache-corporate-proxy/index.html +++ b/gradle-build-cache-corporate-proxy/index.html @@ -91,7 +91,7 @@Build cache behind a corporate proxy: Gradle and Maven
Many companies make builds reach the network through a proxy. This page shows how the remote build cache behaves behind one, in Gradle and in Maven: the settings, the ways it goes wrong, and how to tell a proxy problem from a cache problem.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
In our runs Maven behaved differently from Gradle: it did not skip the proxy for loopback addresses. If you test on 127.0.0.1 with Maven, list it in
nonProxyHosts: see the Maven section.Checklist for Gradle
@@ -99,7 +99,7 @@Checklist for Gradle
Gradle build cache on Kubernetes: plain manifests, no Helm chart yet
Run a shared build cache in your cluster with plain manifests: one Deployment, one volume, one Service. There is no Helm chart yet. It has not been through a beta on a production cluster, so treat it that way.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Is there a Helm chart?
Not yet. Today the supported way to deploy on Kubernetes is the plain manifests in the Kubernetes guide: a Secret, a volume claim, a Deployment and a Service. Copy them into one file and apply it with
@@ -117,7 +117,7 @@kubectl apply -f.Locked down by default
Runners in the same cluster
If your CI runners already run in this cluster, including Jenkins agents, GitHub Actions runner controller and GitLab runners, you need no load balancer and no ingress. Point Gradle at the cluster-internal name, for example
http://fscache.fscache-ns.svc.cluster.local/, withisAllowInsecureProtocol = true. Gradle requires that for plainhttp://addresses. In our test with Gradle 9.8.0, only the literal127.0.0.1was let through without it. Here it is reasonable because the traffic never leaves the cluster network. See Jenkins and CI build cache.HTTPS: in front, or in the server
-There are two ways to serve HTTPS, and neither is preferred. TLS in front: a load balancer, Gateway or ingress terminates TLS and forwards plain HTTP to the Service, as in the manifests above; the server needs no certificate. TLS in the server: set
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file and its private key file; the server then serves HTTPS only, on the same port, with TLS 1.2 as the minimum version. A missing, unreadable or mismatched file stops the start with a message naming the variable. Put the certificate in a Secret of typekubernetes.io/tls, mount it read-only, and make it readable by the container's non-root user (65532 in the guide's manifest).[TO-VERIFY: cache: cache: native TLS is on cache main in no release; docs/kubernetes.md "TLS: in front, or in the server"]We tested neither route on the throwaway cluster.There are two ways to serve HTTPS, and neither is preferred. TLS in front: a load balancer, Gateway or ingress terminates TLS and forwards plain HTTP to the Service, as in the manifests above; the server needs no certificate. TLS in the server: set
FSCACHE_TLS_CERTandFSCACHE_TLS_KEYto a PEM certificate file and its private key file; the server then serves HTTPS only, on the same port, with TLS 1.2 as the minimum version. A missing, unreadable or mismatched file stops the start with a message naming the variable. Put the certificate in a Secret of typekubernetes.io/tls, mount it read-only, and make it readable by the container's non-root user (65532 in the guide's manifest). We tested neither route on the throwaway cluster.Get the manifests
The four manifests (Secret, volume claim, Deployment, Service) and the steps to reach the cache from outside the cluster are in the Kubernetes guide on GitHub. Copy them into one file and apply it.
diff --git a/gradle-remote-build-cache-authentication/index.html b/gradle-remote-build-cache-authentication/index.html index 32fcbc1..e80b522 100644 --- a/gradle-remote-build-cache-authentication/index.html +++ b/gradle-remote-build-cache-authentication/index.html @@ -89,11 +89,11 @@Gradle build cache authentication: 401 and status codes
Gradle does not fail the build when the cache refuses it, so a wrong password or a refused upload often shows up only as a status code. FosterStack Cache takes an optional password, and this page shows how to set it, how to give Gradle the right one, and what each status code means.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
Our advice, not a test result
-
-
Use your Gradle build cache over HTTPS with a private CA
With the right trust store, Gradle uses a cache behind HTTPS with your own certificate authority, and in our runs the cache hits worked. We ran real builds with a private CA and saw the exact error without it. With the standard Java settings we used, a trust store that held only our CA made Java ignore its normal list of trusted CAs. Our downloads from Maven Central then failed, until we put the normal list into the store as well.
-DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
The short answer
-
@@ -151,7 +151,7 @@
How we made the test certificates
The certificate has to name the address your builds use. We did not test a certificate that names a different host, an expired certificate, the Gradle wrapper (
./gradlew), or Linux or Windows.If it still does not work
-Work through Gradle remote build cache not working. For the server side of HTTPS, see production Docker Compose with nginx and TLS, which also covers the server's own certificate (
+FSCACHE_TLS_CERTandFSCACHE_TLS_KEY). The runs on this page used a test TLS proxy; we did not run the server's own TLS.[TO-VERIFY: cache: native TLS (REQ-TLS-001, #296) is on cache main, in no release yet; source docs/docker-deploy.md and README.md]Work through Gradle remote build cache not working. For the server side of HTTPS, see production Docker Compose with nginx and TLS, which also covers the server's own certificate (
FSCACHE_TLS_CERTandFSCACHE_TLS_KEY). The runs on this page used a test TLS proxy; we did not run the server's own TLS.Run on Gradle 9.8.0 with FosterStack Cache 0.2.1 behind a test TLS proxy, macOS (arm64), Java 27 (Homebrew), OpenSSL 3.6.5.
We repeated the six runs on a GitHub-hosted Linux machine with release 0.2.2, Gradle 9.8.0, Java 27 (Temurin 27+35) and a small TLS proxy written in Python. All six runs matched the table, including run 5, which fails as expected. The combined store there held 121 certificates, including ours: the count depends on which Java build you use. The run and its log are public.
diff --git a/how-our-pipeline-maps-to-nist-and-slsa/index.html b/how-our-pipeline-maps-to-nist-and-slsa/index.html index d5a5b84..f52ae85 100644 --- a/how-our-pipeline-maps-to-nist-and-slsa/index.html +++ b/how-our-pipeline-maps-to-nist-and-slsa/index.html @@ -90,23 +90,23 @@How the v0.3.0 release pipeline maps to NIST and SLSA
If you have to explain our release pipeline to a security reviewer, start here. This page puts each stage of the new release pipeline next to the NIST practice it was designed against, and says where a stage only partly implements a practice.
-DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: pipeline]marks anything not yet run against a real release.DRAFT for v0.3.0, not published and never merged before v0.3.0 is live.
This is guidance we followed when designing the pipeline. It is not a certification.
Stage by stage
-The stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
+[TO-VERIFY: pipeline]against the workflow files at the v0.3.0 tag.The stages are described step by step on how we build. "Signs" means the stage records what it did and signs it with a short-lived key, under its own workflow identity, logged in a public transparency log.
- -Stage What it does NIST practice How much -Build [TO-VERIFY: pipeline]Checks that the tag is signed, then builds the binaries and both images once. The image is assembled from those packages, with no base image.[TO-VERIFY: pipeline]800-204D 5.1.1[TO-VERIFY: pipeline] -Sign [TO-VERIFY: pipeline]A separate stage records the build and signs it under its own identity, from the build's digest list only.[TO-VERIFY: pipeline]the part of 5.1.1 that asks for signing outside the build steps[TO-VERIFY: pipeline] -Rebuild [TO-VERIFY: pipeline]Assembles the image again, independently, on a separate machine. The digests must match or the release fails.[TO-VERIFY: pipeline]none found in either document[TO-VERIFY: pipeline] -Check [TO-VERIFY: pipeline]Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests.[TO-VERIFY: pipeline]800-204C 4.8 and 800-204D 5.2[TO-VERIFY: pipeline] +Release [TO-VERIFY: pipeline]Verifies every stage's signature together, then publishes the same digests.[TO-VERIFY: pipeline][TO-VERIFY: pipeline] +Build Checks that the tag is signed, then builds the binaries and both images once. The image is assembled from those packages, with no base image. 800-204D 5.1.1 +Sign A separate stage records the build and signs it under its own identity, from the build's digest list only. the part of 5.1.1 that asks for signing outside the build steps +Rebuild Assembles the image again, independently, on a separate machine. The digests must match or the release fails. none found in either document +Check Scans and acceptance tests run against the exact candidate images, and the stage signs a verdict for those digests. 800-204C 4.8 and 800-204D 5.2 Release Verifies every stage's signature together, then publishes the same digests. Our wording: signed at every stage, verified together at release.
+[TO-VERIFY: pipeline]Our wording: signed at every stage, verified together at release.
SLSA
-
+[TO-VERIFY: pipeline]The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.The SLSA Build level we assess v0.3.0 at. We claim Level 3 for the Build stage only after a test shows that a malicious build step cannot produce provenance the release step accepts. Until that test has passed, this page says nothing about Level 3.
What this page does not say
How FosterStack Cache is built and signed
-You are about to run our software inside your build pipeline. How do you know the files you run are the ones we built? Every release is signed and checked at every step, and you can verify it yourself.
-[TO-VERIFY: pipeline: signed and checked at every stage of the v0.3 chain]This page says how.DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.You are about to run our software inside your build pipeline. How do you know the files you run are the ones we built? Every release is signed and checked at every step, and you can verify it yourself. This page says how.
+DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.
We do it to our own pipeline first
-We started with a build cache, and we secure our own release pipeline the same way before we ask you to run it.
+[TO-VERIFY: pipeline: the v0.3 chain, secured before the product ships]We started with a build cache, and we secure our own release pipeline the same way before we ask you to run it.
Releases are built only in CI
-No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what lets the signatures mean something: a release that our CI workflow did not build does not carry its signature.
+[TO-VERIFY: pipeline: the signing identity is pinned to the release workflow and tag; no manual release path in v0.3]No release file is ever made on a person's laptop, ours included. A release starts when a signed tag is pushed, and there is no manual release path. That is what lets the signatures mean something: a release that our CI workflow did not build does not carry its signature.
The stages a release goes through
-Signed at every stage, verified together at release. Each stage signs a statement about what it did, each stage checks the one before it, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
+[TO-VERIFY: pipeline: each v0.3 stage signs its own statement; the Release stage verifies all together]Signed at every stage, verified together at release. Each stage signs a statement about what it did, each stage checks the one before it, and the Release stage verifies them all together. A signature shows who signed these exact files; it does not show the software has no bugs.
-
-
The full description, as the pipeline actually runs, is in RELEASING.md.
+[TO-VERIFY: pipeline: RELEASING.md matches the v0.3 chain]The full description, as the pipeline actually runs, is in RELEASING.md.
What you get with each release
-
-
All of it is public. You do not need an account or a purchase to check any of it. The commands are on verify a release yourself.
Kept patched
-The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched. Our target for vulnerable dependencies is 48 hours from disclosure (the scope is in SECURITY.md); more on the security page.
+[TO-VERIFY: cache/ops: the daily rescan; "kept patched" only after the first automatic patch release has been cut; the home page carries the brief's "new or abandoned upstream": that needs a written scope in SECURITY.md before launch]The current release's images are scanned again every day, so a vulnerability disclosed against something we already shipped raises an issue without anyone having to remember to look. We keep it patched. Our target for vulnerable dependencies is 48 hours from disclosure (the scope is in SECURITY.md); more on the security page.
What we do not claim
-
diff --git a/index.html b/index.html
index 03835cd..966f3c6 100644
--- a/index.html
+++ b/index.html
@@ -88,7 +88,7 @@
Infrastructure worth keeping — and kept patched.- DRAFT for v0.3, private preview, not published.
+[TO-VERIFY: source]marks a fact that must be checked against the v0.3 release; the source (cache, pipeline or payments) is named in the marker.DRAFT for v0.3, private preview, not published.
Your CI keeps rebuilding what it already built.
@@ -97,14 +97,14 @@
Your CI keeps rebuilding what it already built.
other's results, and you can check that the cache you run is the one we built. Open source core, one-command deploy. The same server speaks the Gradle remote build cache protocol and the Apache Maven Build Cache Extension's remote HTTP mode, so a mixed Gradle and - Maven shop runs one deploy instead of two.[TO-VERIFY: cache: v0.3 behaviour unchanged]+ Maven shop runs one deploy instead of two.Three promises
--Software you can keep running safely
Kept patched, whether it is new or abandoned upstream. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md and on the security page.
[TO-VERIFY: cache/ops: "kept patched" only after the first automatic patch release has been cut; exactly what is covered when upstream has abandoned a component]-Provably
Every release is signed and checked at every step, and you can verify it yourself.
[TO-VERIFY: pipeline: signing and checking at every stage of the v0.3 chain]+Because we do it to our own pipeline first
We started with a build cache your team can know is secure, and we secure our own release pipeline the same way before we ask you to run it. How we build.
[TO-VERIFY: pipeline: the pipeline described is the v0.3 one]+Software you can keep running safely
Kept patched, whether it is new or abandoned upstream. Our target for vulnerable dependencies is 48 hours from disclosure; the scope is in SECURITY.md and on the security page.
+Provably
Every release is signed and checked at every step, and you can verify it yourself.
Because we do it to our own pipeline first
We started with a build cache your team can know is secure, and we secure our own release pipeline the same way before we ask you to run it. How we build.
Try it now
@@ -134,17 +134,17 @@What you get that a bare HTTP endpoint doesn't give you
Authentication
HTTP Basic Auth over TLS, wired the way Gradle and Maven already expect credentials. Constant-time comparison, no credential ever logged.
Metrics & status
Prometheus metrics, a read-only status page with hit rates and size-vs-cap, and a Grafana dashboard in the repo — so you know the cache is earning its keep.
-Maintenance target
Vulnerable dependencies fixed fast — our target is 48 hours from disclosure (the scope is in SECURITY.md).
+Designed against NIST guidance
No step trusts the one before it. When you check our images' digital signatures you can rest assured we checked it at every step before we released it. That signature means it's fosterstack code, a fosterstack build, a fosterstack image and everything in between. See how each stage maps.
[TO-VERIFY: pipeline: signatures at every stage of the v0.3 chain, so the sentence is true]A signature shows who signed these exact files and that nothing changed them since; it does not show the code is free of bugs or vulnerabilities. This is guidance we designed against, not a certification we hold.
Designed against NIST guidance
No step trusts the one before it. When you check our images' digital signatures you can rest assured we checked it at every step before we released it. That signature means it's fosterstack code, a fosterstack build, a fosterstack image and everything in between. See how each stage maps.
A signature shows who signed these exact files and that nothing changed them since; it does not show the code is free of bugs or vulnerabilities. This is guidance we designed against, not a certification we hold.
30-minute migration
A step-by-step guide for moving an existing Gradle remote build cache server. Same protocol, same CI config shape — migrating is mostly a URL change.
What stands behind it
-
-
How we build · Security policy · Verify a release
@@ -164,7 +164,7 @@What we do not collect
- Container images on GitHub's registry, signed without a stored key (Sigstore), with build provenance.