Security

The cache trust model

A remote cache is shared, writable infrastructure, so the interesting question is not how fast it is but who is allowed to write to it and what a bad write can do. Review how Cachely scopes access, handles writes for each protocol, and receives configured outputs without cloning your repository.

Cachely cache trust boundaryA build client sends a workspace-scoped Bearer token to the Cachely API. The API authenticates the token, checks its read or write scope, enforces protocol-specific write rules, and isolates the request to one workspace before reading or writing managed Cloudflare R2 storage. Untrusted pull-request and fork builds use read-only tokens, so they can read the cache but never write to it.Build clientCachely APIManaged storageBuild tool / CICloudflare R2authenticate tokenread / write scopeprotocol write rulesworkspace isolationscoped Bearer tokenencrypted at rest
One scoped token in, checked at the boundary, before any artifact is read or written. Untrusted builds get read-only tokens.

No repository access

Cachely receives the outputs and content hashes that your configured cache client sends. Signing in with GitHub uses a GitHub App that reads only your email address, with nothing to install and no repository permission to grant. You connect with a server URL and token, so the trust boundary is a scoped cache credential rather than access to your repo. If declared task outputs include source or source-derived files, those files are part of the artifact.

That means a compromise of Cachely exposes cached build artifacts, not repository access, git history, or CI credentials.

Every write is authenticated and scoped

  • Requests carry a Bearer token. Tokens are stored hashed (SHA-256) and shown in full only once, at creation.
  • An unknown or revoked token is rejected with a 401 before any storage is touched. Revoking a token cuts access instantly and does not affect any other token.
  • Each token is scoped to a single workspace. Issue one per CI pipeline, repo, or developer so you can rotate or revoke any of them in isolation.
  • Token scope is fixed at creation as read-only or read-write and enforced server-side. A leaked read token cannot be escalated to write.

What a pull-request or forked build can do

Untrusted builds - pull requests and forks - should read the cache to stay fast but must never write to it. That is the whole defense against cache poisoning, and Cachely enforces it at the API rather than trusting the client.

TokenRead cacheWrite cacheTypical use
Read-onlyYesNo - rejected with 403Pull-request and fork builds
Read-writeYesYesProtected branches and trusted CI

Artifact writes follow the protocol

Nx, Turborepo, Gradle, and Bazel CAS artifacts are write-once. Existing objects are not replaced. Nx returns 409 for a duplicate key; other clients may receive an idempotent success response. Bazel action-cache entries can be replaced by an authorized writer to allow stale results to be repaired.

Read-only tokens prevent untrusted builds from uploading artifacts, while write-once storage prevents replacement of existing Nx keys. Both controls matter when addressing CVE-2025-36852 (CREEP). Trusted writers and correct task inputs remain part of your security model. Read the Cache poisoning and CVE-2025-36852.

Workspaces are isolated

Every workspace has its own storage prefix, and artifacts are keyed under it. A token resolves to exactly one workspace, so one workspace can never read or write another workspace's cache - there is no shared namespace to collide in or enumerate across.

Storage, encryption, and retention

  • Managed artifacts live on Cloudflare R2. All traffic is served over HTTPS (encrypted in transit) and R2 encrypts objects at rest by default.
  • Cachely stores build outputs and their content hashes, plus cache event metadata - which task, which token, hit or miss - used for the ROI and insight reporting.
  • Automated analysis reads limited artifact structure, paths, metadata, and task-output prefixes to label customer-facing insights. Authorized maintainers may inspect the minimum necessary data for support, security, or debugging; customer-specific contents and insights are not published or used for model training.
  • Managed cache objects auto-expire after a retention window (currently 20 days from upload), so idle artifacts do not linger. Anything still in use is simply re-uploaded on the next run.
  • Build tools derive cache keys from task inputs. Correctly declared inputs and deterministic outputs are necessary for valid reuse; an omitted input can cause stale results even when the cache protocol is working correctly.

Cache availability and client fallback

A cache miss returns 404 so the client can execute the task locally. Network outages, authentication errors, retries, and timeouts can behave differently depending on your build tool and configuration. Test unavailable-cache and quota-limit behavior in your own pipeline before rollout. The troubleshooting guide covers common client symptoms, and the status page reports current service probes.

On certifications: Cachely does not yet hold a formal attestation such as SOC 2. We would rather be transparent about the trust model today than imply a certification we do not have. If a compliance requirement is blocking an evaluation, tell us what you need and we will be straight with you about where we are.

Security FAQ

Security questions, answered

Does Cachely need access to my source code?
Cachely does not need repository access and never clones your repo. Your configured cache client sends build task outputs and content hashes through the cache protocol. Signing in with GitHub uses a GitHub App that reads only your email address, with nothing to install and no repository permission to grant.
How are cache writes authenticated?
Every request carries a Bearer token. Tokens are stored hashed (SHA-256) and shown in full only once at creation. An unknown or revoked token is rejected with a 401 before any storage is touched, and each token is scoped to a single workspace.
What can a pull-request or forked build do?
Give PR and fork builds a read-only token. They can read from the cache to stay fast but cannot write to it, so an untrusted branch can never seed a poisoned artifact. Cachely enforces read-only at the API - a write with a read-only token is rejected with a 403.
Can a leaked read-only token be used to write?
No. A token is either read-only or read-write; the scope is fixed at creation and enforced server-side. A leaked read token cannot be escalated to write, and you can revoke any token instantly without affecting the others.
Are cache keys immutable after the first trusted write?
Nx, Turborepo, Gradle, and Bazel CAS artifacts are write-once. Nx returns 409 for duplicate keys; other clients may receive an idempotent success response. Bazel action-cache entries can be replaced by authorized writers. Give untrusted builds read-only tokens for every protocol.
Is one workspace isolated from another?
Yes. Every workspace has its own storage prefix and artifacts are keyed under it. A token resolves to exactly one workspace, so one workspace can never read or write another workspace's cache.
Where is my data stored, and is it encrypted?
Managed artifacts live on Cloudflare R2. All traffic is served over HTTPS (encrypted in transit) and R2 encrypts objects at rest by default. Cachely stores build outputs and content hashes, plus cache event metadata (which task, which token, hit or miss) used for ROI reporting.
How long are artifacts retained, and how do I delete them?
Managed cache objects auto-expire after a retention window (currently 20 days from upload). Revoke a token to cut off its access. Build tools derive keys from task inputs, so correctly declaring those inputs is necessary to avoid stale reuse.
What happens if the cache is unavailable or over quota?
Cache misses return 404 so clients can execute tasks locally. Reached limits stop uploads or return misses. Outages, authentication errors, retries, and timeouts depend on your build tool and configuration; test these conditions before rollout.

Set it up the safe way

Read-only tokens for pull requests, read-write for protected branches - the docs show the exact two-token setup for GitHub Actions and any other CI.