Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
3aaab86
DRAFT-HOLD v0.3.0: verify-a-release (rule 78 shape) and the new-chain…
fosterstack-admin Oct 10, 2026
f61f2d5
Merge main into the v0.3.0 hold branch
fosterstack-admin Oct 10, 2026
0145e4f
DRAFT-HOLD v0.3.0: what changes for you (developer-first, every claim…
fosterstack-admin Oct 10, 2026
785b109
Merge main into the v0.3.0 hold branch
fosterstack-admin Oct 10, 2026
478562c
DRAFT-HOLD v0.3.0: a CISA Secure by Design section for the NIST/SLSA …
fosterstack-admin Oct 10, 2026
af7e7d3
DRAFT-HOLD: CISA section wording limited to the evidence
fosterstack-admin Oct 10, 2026
c80cc84
Start the v0.3 revamp branch from the held drafts (PR #165 content)
fosterstack-admin Oct 11, 2026
55c197c
v0.3 homepage draft: the buyer's problem first, the three promises, t…
fosterstack-admin Oct 11, 2026
d31eb1e
v0.3 trust pages draft: how-we-build, the reader's problem on the NIS…
fosterstack-admin Oct 11, 2026
bfd5e48
v0.3 home: shorter h1, promises linked to their proof, a limit senten…
fosterstack-admin Oct 11, 2026
9e8bb99
v0.3 trust pages: markers on the unmarked v0.3 facts, the abandoned-u…
fosterstack-admin Oct 11, 2026
cda38c5
v0.3 policy pages draft: security and regulated (WIP)
fosterstack-admin Oct 11, 2026
1bab23f
v0.3 trust pages: overstated sentences narrowed or marked, one stage …
fosterstack-admin Oct 11, 2026
b69ee03
v0.3 policy pages draft: security, regulated, fips, changelog
fosterstack-admin Oct 11, 2026
1bd995b
v0.3 changelog draft: a neutral title
fosterstack-admin Oct 11, 2026
2f3a9cb
v0.3 product pages draft: the laptop page and what's new, markers wit…
fosterstack-admin Oct 11, 2026
c483709
v0.3 policy pages: narrower patching sentence, plainer LTS heading, r…
fosterstack-admin Oct 11, 2026
9d39f2b
how-we-build: no open-ended abandoned-upstream promise
fosterstack-admin Oct 11, 2026
0f7093c
what's new: no open-ended abandoned-upstream promise
fosterstack-admin Oct 11, 2026
11d2dcd
v0.3 product pages: the laptop trust section in plain words, what's-n…
fosterstack-admin Oct 11, 2026
7650fe7
what's new: the reviewer note is gone
fosterstack-admin Oct 11, 2026
4ef4a11
Merge remote-tracking branch 'origin/www/v030-trust' into www/v030-re…
fosterstack-admin Oct 11, 2026
3bf42e8
Merge remote-tracking branch 'origin/www/v030-policy' into www/v030-r…
fosterstack-admin Oct 11, 2026
a2b175f
Merge remote-tracking branch 'origin/www/v030-product' into www/v030-…
fosterstack-admin Oct 11, 2026
8b93382
v0.3 drafts: one wording across pages (stage names, signing, the imag…
fosterstack-admin Oct 11, 2026
f7f5b88
v0.3 drafts: the five stages as the pipeline lane lists them (no sepa…
fosterstack-admin Oct 11, 2026
4b4af98
what's new: the Mac container, the debug question, the data folder la…
fosterstack-admin Oct 11, 2026
287a0d8
what's new: no -debug image (the owner's Oct 9 decision), TO-VERIFY u…
fosterstack-admin Oct 11, 2026
62d65d9
what's new: the two new TLS settings and the startup changes that lan…
fosterstack-admin Oct 11, 2026
41ac5fe
v0.3 drafts: HTTPS offered both ways (a proxy in front, or the server…
fosterstack-admin Oct 11, 2026
6871003
v0.3 preview: drop the TO-VERIFY markers and the line that explains them
fosterstack-admin Oct 14, 2026
273487d
v0.3 preview: home rebuilt from the live page with the new intro and …
fosterstack-admin Oct 14, 2026
f1428d5
v0.3 preview: Everything FosterStack does for security (site copy of …
fosterstack-admin Oct 14, 2026
cd0f3dc
v0.3 preview: Scanning FosterStack in your compliance pipeline (site …
fosterstack-admin Oct 14, 2026
a036b3c
v0.3 preview: re-mirror the security and scanning pages from cache#32…
fosterstack-admin Oct 14, 2026
84fb31f
v0.3 preview: home page in the owner's layout; new /guides/ and /road…
fosterstack-admin Oct 14, 2026
842ddac
Site-rot check: a page linked from /guides/ counts as linked from hom…
fosterstack-admin Oct 14, 2026
34d4517
v0.3 preview: security section folded into two cards (Verify every re…
fosterstack-admin Oct 14, 2026
d5159d1
v0.3 preview: /faq/ (13 short answers with links); site-rot self-test…
fosterstack-admin Oct 14, 2026
69d539a
v0.3 preview: what to verify in a replacement build cache (checklist …
fosterstack-admin Oct 14, 2026
0150f25
v0.3 preview: is a remote build cache worth it? (measured numbers, tw…
fosterstack-admin Oct 14, 2026
2e82bd8
v0.3 preview: every guide links the end-of-life and migration pages
fosterstack-admin Oct 14, 2026
d1b26e3
v0.3 preview: verify, FIPS, air-gapped and upgrade pages written from…
fosterstack-admin Oct 14, 2026
3214411
v0.3 preview: what's-new upgrade sentence
fosterstack-admin Oct 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions air-gapped-build-cache-install/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -92,24 +92,23 @@ <h1>Install a build cache on an air-gapped network</h1>
<h2>What to bring across</h2>
<p>On a machine with internet access, download these from the release page:</p>
<ul class="trust">
<li>The archive for your platform, for example <code>fscache_X.Y.Z_linux_amd64.tar.gz</code>.</li>
<li>The archive for your platform, for example <code>fscache_X.Y.Z_linux_amd64.tar.gz</code>, or <code>fscache-fips_X.Y.Z_linux_amd64.tar.gz</code> for 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.</li>
<li><code>checksums.txt</code> and <code>checksums.txt.bundle</code>, which is the signature over the checksums.</li>
<li><code>cosign</code>, the signature checker. It is one static binary and will not be on a fresh isolated machine.</li>
<li>If you run containers: the image as a tar file, for example <code>crane pull ghcr.io/fosterstack/cache:X.Y.Z fscache-X.Y.Z.tar</code>. Verify the image with <code>cosign verify</code> before you export it, while you still have registry access (the <a href="https://github.com/fosterstack/cache/blob/main/docs/verify-images.md">image verification guide</a> has the command). Images are published for both <code>linux/amd64</code> and <code>linux/arm64</code>. Across a gap you pick one by hand, so pull on a machine of the destination type, or add <code>--platform</code>.</li>
<li>If you run containers: the image as a tar file, for example <code>crane pull ghcr.io/fosterstack/cache:X.Y.Z fscache-X.Y.Z.tar</code>, and <code>:X.Y.Z-fips</code> for the FIPS image. There are two images, production and <code>-fips</code>; v0.3.0 has no <code>-debug</code> image. Verify the image with <code>cosign verify</code> before you export it, while you still have registry access (<a href="/verify-a-release/">verify a release yourself</a> has the command). Images are published for both <code>linux/amd64</code> and <code>linux/arm64</code>. Across a gap you pick one by hand, so pull on a machine of the destination type, or add <code>--platform</code>.</li>
</ul>

<h2>Verify before you cross the gap</h2>
<p>Do this on the connected side, where the signature check can reach its public log:</p>
<pre tabindex="0"><code># 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 &lt;(grep "fscache_X.Y.Z_linux_amd64.tar.gz" checksums.txt | grep -v sbom)</code></pre>
<p><code>grep -v sbom</code> drops the SBOM line, because that file is not carried across. Without it, <code>sha256sum</code> reports the file as missing and fails.</p>
sha256sum -c &lt;(grep "fscache_X.Y.Z_linux_amd64.tar.gz" checksums.txt)</code></pre>
<p>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.</p>

<h2>Install on the isolated side</h2>
Expand All @@ -135,6 +134,7 @@ <h2>How we checked</h2>
<a class="btn" href="/migrate-build-cache-node/">Gradle and Maven setup</a>
<a class="btn btn-secondary" href="/">FosterStack home</a>
</div>
<p class="muted-note">Moving off the free Build Cache Node? See <a href="/build-cache-node-end-of-life/">what the end of life means</a> and the <a href="/migrate-build-cache-node/">migration guide</a>.</p>
</main>
<footer>
<div>
Expand Down
9 changes: 8 additions & 1 deletion bin/check-site-rot.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
60 changes: 60 additions & 0 deletions bin/test-check-site-rot.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,69 @@ 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"

# /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.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"<title>.*?</title>", "<title>Guides</title>", 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("</main>", '<p><a href="/%s/">listed guide</a></p></main>' % 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="/"')
if 'href="/guides/"' not in h:
h = h.replace("</main>", '<p><a href="/guides/">All guides</a></p></main>', 1)
open(home, "w").write(h)
sm = os.path.join(site, "sitemap.xml")
m = open(sm).read()
if "/guides/</loc>" not in m:
open(sm, "w").write(m.replace("</urlset>", "<url><loc>https://fosterstack.com/guides/</loc></url></urlset>", 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_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/"
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:<title>.*?</title>" "<title>This title is deliberately far too long to be a good page title for a search result</title>"
expect_fail "a title over 60 characters" "characters (max 60)"

Expand Down
8 changes: 7 additions & 1 deletion build-cache-docker-compose-production/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!doctype html>
<html lang="en">
<head>
<meta name="robots" content="noindex, nofollow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Docker Compose build cache: quick start and production</title>
Expand Down Expand Up @@ -88,7 +89,8 @@
</header>
<main>
<h1>Docker Compose build cache: quick start and production</h1>
<p class="lede">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.</p>
<p class="lede">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 <code>FSCACHE_TLS_CERT</code> and <code>FSCACHE_TLS_KEY</code> and let the server answer HTTPS itself.</p>
<p class="muted-note"><strong>DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.</strong></p>

<h2 id="gradle-build-cache-docker-compose">Gradle build cache with Docker Compose</h2>
<p>Our advice, not a test result. This is the shape we suggest once you go past a first trial.</p>
Expand Down Expand Up @@ -131,6 +133,10 @@ <h2>Point Gradle at it</h2>
<h2>Health checks</h2>
<p>The container image has no shell, so there is no health check inside the Compose file. Probe <code>/healthz</code> from outside: your orchestrator's HTTP check, a monitor, or <code>curl -f http://localhost:8080/healthz</code> from the host.</p>

<h2>Two ways to serve HTTPS</h2>
<p><strong>A proxy in front</strong> (the nginx setup below): the proxy holds the certificate and the server stays on plain HTTP behind it. <strong>TLS in the server:</strong> set <code>FSCACHE_TLS_CERT</code> and <code>FSCACHE_TLS_KEY</code> to a PEM certificate file (it may hold the chain) and its private key file, both or neither. The server then serves HTTPS only, on <code>FSCACHE_ADDR</code>, with TLS 1.2 as the minimum version. HTTP/2 is not offered, a plain-HTTP request to that port gets <code>400</code>, and your <code>/healthz</code> check moves to <code>https://</code>. Mount the files read-only. They are read only at startup, so replace them and restart.</p>
<p>If a client cannot connect, look from the client side with <code>openssl s_client -connect HOST:PORT -alpn http/1.1</code>: the server does not log handshake failures at the default log level.</p>

<h2>Production: nginx and TLS in front</h2>
<p>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.</p>

Expand Down
1 change: 1 addition & 0 deletions build-cache-server-sizing/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ <h3>Builds at once and the upload limit</h3>
<a class="btn" href="/migrate-build-cache-node/">Gradle and Maven setup</a>
<a class="btn btn-secondary" href="/">FosterStack home</a>
</div>
<p class="muted-note">Moving off the free Build Cache Node? See <a href="/build-cache-node-end-of-life/">what the end of life means</a> and the <a href="/migrate-build-cache-node/">migration guide</a>.</p>
</main>
<footer>
<div>
Expand Down
4 changes: 3 additions & 1 deletion can-someone-poison-our-build-cache/index.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!doctype html>
<html lang="en">
<head>
<meta name="robots" content="noindex, nofollow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Can Someone Poison Our Shared Build Cache?</title>
Expand Down Expand Up @@ -89,6 +90,7 @@
<main>
<h1>Can someone poison our shared build cache?</h1>
<p class="lede">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.</p>
<p class="muted-note"><strong>DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.</strong></p>

<h2>The short answer</h2>
<p>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.</p>
Expand All @@ -115,7 +117,7 @@ <h2>What to do</h2>
<li><strong>Give everyone else the optional read-only login.</strong> That includes laptops. The setup is on <a href="/gradle-build-cache-ci-writes-developers-read/">let CI write, developers only read</a>, and the CI wiring is on <a href="/jenkins-ci-build-cache/">Jenkins and CI build cache</a>.</li>
<li><strong>Keep builds of untrusted code on the read-only login.</strong> An example is a pull request from a fork.</li>
<li><strong>Do not count on <code>isPush = false</code>.</strong> It only controls whether your own build uploads. The login is what the server enforces.</li>
<li><strong>Use HTTPS, on a network you control.</strong> Gradle sends the login with its requests.</li>
<li><strong>Use HTTPS, on a network you control.</strong> Gradle sends the login with its requests. A proxy in front or the server's own certificate both work.</li>
<li><strong>If you doubt an entry, clear the cache.</strong> See <a href="/reset-gradle-build-cache/">how to clear or reset a build cache</a>.</li>
</ul>
<p>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.</p>
Expand Down
16 changes: 11 additions & 5 deletions changelog/index.html
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta name="robots" content="noindex, nofollow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>FosterStack Cache changelog: v0.1.0 to v0.2.2</title>
<title>FosterStack Cache changelog</title>
<meta name="description" content="Release notes for FosterStack Cache v0.1.0, v0.2.1 and v0.2.2, quoted from GitHub as published, and a note that no release was published for v0.2.0.">
<meta property="og:title" content="FosterStack Cache changelog: v0.1.0 to v0.2.2">
<meta property="og:title" content="FosterStack Cache changelog">
<meta property="og:description" content="Release notes for FosterStack Cache v0.1.0, v0.2.1 and v0.2.2, quoted from GitHub as published, and a note that no release was published for v0.2.0.">
<meta property="og:url" content="https://fosterstack.com/changelog/">
<meta property="og:type" content="website">
Expand Down Expand Up @@ -87,9 +88,14 @@
<div class="tag">Infrastructure worth keeping — and kept patched.</div>
</header>
<main>
<h1>FosterStack Cache changelog: v0.1.0 to v0.2.2</h1>
<h1>FosterStack Cache changelog</h1>
<p class="lede">The release notes from GitHub, quoted as published. Newest first. For anything else, the <a href="https://github.com/fosterstack/cache/releases">releases page</a> is the source.</p>

<p class="muted-note"><strong>DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.</strong></p>

<h2>v0.3.0</h2>
<p>The v0.3.0 release notes will be quoted here as published, like the others.</p>

<h2>v0.2.2</h2>
<p class="muted-note">Release name: fscache v0.2.2. Published 2026-10-09.</p>
<blockquote>
Expand All @@ -106,7 +112,7 @@ <h2>v0.2.1</h2>
<p><a href="https://github.com/fosterstack/cache/releases/tag/v0.2.1">v0.2.1 on GitHub</a></p>

<h2>v0.2.0</h2>
<p>No release was published for v0.2.0: the tag exists, but its release run failed. Use v0.2.2, the latest release.</p>
<p>No release was published for v0.2.0: the tag exists, but its release run failed.</p>

<h2>v0.1.0</h2>
<p class="muted-note">Published 2026-08-22.</p>
Expand All @@ -115,7 +121,7 @@ <h2>v0.1.0</h2>
<p><strong>Note on this release's evidence (added Sep 2026).</strong> 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 <a href="https://github.com/fosterstack/cache/actions/workflows/rescan-v010.yml">rescan runs</a> 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.</p>
</blockquote>
<p><a href="https://github.com/fosterstack/cache/releases/tag/v0.1.0">v0.1.0 on GitHub</a></p>
<p><strong>What changed since:</strong> the v0.2.1 and v0.2.2 release notes point to their <code>release-manifest.json</code> evidence bundle. The release process, as <a href="https://github.com/fosterstack/cache/blob/main/RELEASING.md">RELEASING.md</a> describes it, is "One build, one set of digests, promoted without a rebuild", with every scanner run "against the exact candidate digests".</p>
<p><strong>What changed since:</strong> the v0.2.1 and v0.2.2 release notes point to their <code>release-manifest.json</code> evidence bundle. The release process, as <a href="https://github.com/fosterstack/cache/blob/main/RELEASING.md">RELEASING.md</a> 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".</p>

<p class="muted-note">Related: <a href="/how-we-build/">how releases are built and signed</a> and <a href="/security/">security policy</a>.</p>
<div class="cta-row">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<!doctype html>
<html lang="en">
<head>
<meta name="robots" content="noindex, nofollow">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Does a Build Cache Entry Contain My Source Code or Secrets?</title>
Expand Down Expand Up @@ -89,6 +90,7 @@
<main>
<h1>Does a build cache entry contain my source code or secrets?</h1>
<p class="lede">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.</p>
<p class="muted-note"><strong>DRAFT for v0.3, private preview, not published and never merged before v0.3.0 is live.</strong></p>

<h2>The short answer</h2>
<ul class="trust">
Expand All @@ -108,7 +110,7 @@ <h2>What to do</h2>
<li><strong>Keep secrets out of Java constants.</strong> A constant lives on in the class file, in the cache and in your jar.</li>
<li><strong>Declare an environment variable as a task input if the task reads it.</strong> We changed one that a task read without declaring it, and the old result came back from the cache.</li>
<li><strong>Give developers the read-only login and give CI the read-write login.</strong> See <a href="/gradle-build-cache-ci-writes-developers-read/">let CI write and developers read</a>. One login reaches every project on a server, so use one server per group that must not share. See <a href="/several-projects-share-one-build-cache-server/">several projects on one server</a>.</li>
<li><strong>Use HTTPS when the server is not on your own machine.</strong> Our runs used plain HTTP to a server on the same Mac. See <a href="/gradle-remote-build-cache-private-ca-https/">use your build cache over HTTPS with a private CA</a>.</li>
<li><strong>Use HTTPS when the server is not on your own machine.</strong> Our runs used plain HTTP to a server on the same Mac. See <a href="/gradle-remote-build-cache-private-ca-https/">use your build cache over HTTPS with a private CA</a>. The HTTPS can come from a proxy or from the server itself (<code>FSCACHE_TLS_CERT</code> and <code>FSCACHE_TLS_KEY</code>).</li>
</ul>
<p>What each task stores is on <a href="/what-gradle-stores-in-build-cache/">know what your Gradle build cache stores</a>. Who can change entries is on <a href="/can-someone-poison-our-build-cache/">can someone poison our shared build cache</a>.</p>

Expand Down
Loading
Loading