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. Here is exactly how Cachely scopes access, keeps artifacts immutable, and stays out of your source code.
Your code stays where it is
Cachely caches the outputs of build tasks and their content hashes - never your source. There is no GitHub App to install and no repository permission to grant. You connect by setting two environment variables (a server URL and a token), so the trust boundary is a single scoped credential, not access to your repo.
That means a compromise of Cachely exposes cached build artifacts, not your codebase, your git history, or your CI secrets.
Every write is authenticated and scoped
- Requests carry a
Bearertoken. Tokens are stored hashed (SHA-256) and shown in full only once, at creation. - An unknown or revoked token is rejected with a
401before 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.
| Token | Read cache | Write cache | Typical use |
|---|---|---|---|
| Read-only | Yes | No - rejected with 403 | Pull-request and fork builds |
| Read-write | Yes | Yes | Protected branches and trusted CI |
Artifacts are immutable
Managed artifacts are content-addressed and immutable. Once a cache key exists it cannot be overwritten - the API returns 409 on a re-write of an existing key. A known-good build can never be silently replaced by a later one claiming the same hash.
Immutability plus read-only tokens for untrusted builds is precisely what closes the CVE-2025-36852 (CREEP) cache-poisoning attack. We wrote up how that attack works and why these two controls stop it: 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.
- 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.
- Cache keys are content-hashed, so changing a task's inputs produces a new key. Stale results are never served, and there is no manual purge to get wrong.
The cache never breaks a build
Caching is an optimization, never a dependency in the critical path. A miss, an outage, or an over-quota workspace returns a 404, and your build tool simply runs the task locally and re-uploads when it can. There is no failure mode in which Cachely being unavailable stops your build from completing.
On certifications: Cachely is in beta and 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 questions, answered
- Does Cachely need access to my source code?
- No. Cachely never clones, scans, or stores your source. It stores build task outputs and their content hashes only. There is no GitHub App to install and no repository permission to grant - you connect by setting two environment variables (a server URL and a token).
- 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?
- Yes. Managed artifacts are content-addressed and immutable - once a key exists it cannot be overwritten (the API returns 409). A known-good build can never be silently replaced, which is the core defense against the CVE-2025-36852 (CREEP) cache-poisoning attack.
- 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), so idle artifacts do not linger. Revoke a token to cut access immediately. Because keys are content-hashed, changing a task's inputs produces a new key and stale results are never served.
- What happens if the cache is unavailable or over quota?
- The cache never blocks a build. A miss, an outage, or an over-quota workspace simply returns a 404, and your build tool rebuilds the task locally and re-uploads when it can. Caching is an optimization, never a dependency in the critical path.
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.