Skip to content

Commit f92ce54

Browse files
jamesarichclaude
andcommitted
ci: harden shared build cache (TLS-only, trusted-event pushes)
Addresses CodeRabbit review of the shared build-cache script: - Drop allowInsecureProtocol/allowUntrustedServer — the cache server presents a valid public TLS cert, so enforce HTTPS + certificate validation. - Write to the cache only on trusted events (push/merge_group/local) with credentials present, so pull_request runs stay pull-only and cannot poison the cache. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 06f6265 commit f92ce54

1 file changed

Lines changed: 13 additions & 7 deletions

File tree

packages/kmp/gradle/build-cache.settings.gradle

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@
33
*
44
* Credentials come from the GRADLE_CACHE_URL / GRADLE_CACHE_USERNAME /
55
* GRADLE_CACHE_PASSWORD environment variables (CI secrets), or a
6-
* local.properties / config.properties entry for local use. Push is enabled
7-
* only when credentials are present, so fork PRs (which have no secrets) are
8-
* pull-only and cannot poison the cache.
6+
* local.properties / config.properties entry for local use. Writes to the
7+
* cache happen only from trusted events (local dev, push, merge_group) with
8+
* credentials present, so pull-request runs (and credential-less fork PRs)
9+
* stay pull-only and cannot poison the cache.
910
*/
1011

1112
def getMeshProperty(String key) {
@@ -37,17 +38,22 @@ buildCache {
3738
def cacheUsername = getMeshProperty("GRADLE_CACHE_USERNAME")?.trim()
3839
def cachePassword = getMeshProperty("GRADLE_CACHE_PASSWORD")?.trim()
3940
if (cacheUrl) {
41+
// HTTPS + valid TLS enforced (no allowInsecureProtocol / no
42+
// allowUntrustedServer): the cache server must present a trusted
43+
// certificate over TLS.
4044
url = cacheUrl.endsWith("/") ? cacheUrl : "${cacheUrl}/"
4145
if (cacheUsername && cachePassword) {
4246
credentials {
4347
username = cacheUsername
4448
password = cachePassword
4549
}
4650
}
47-
allowInsecureProtocol = true
48-
allowUntrustedServer = true
49-
// Push only when credentials exist -> fork PRs are pull-only.
50-
push = (cacheUsername && cachePassword)
51+
// Write only from trusted events (local dev, push to a protected
52+
// branch, or the merge queue) with credentials — never from
53+
// pull_request runs, so unmerged code can't poison the cache.
54+
def eventName = System.getenv("GITHUB_EVENT_NAME")
55+
def trustedForPush = eventName == null || eventName == "push" || eventName == "merge_group"
56+
push = (cacheUsername && cachePassword && trustedForPush)
5157
enabled = true
5258
} else {
5359
enabled = false

0 commit comments

Comments
 (0)