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. Here is exactly how Cachely scopes access, keeps artifacts immutable, and avoids repository access.

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 artifact immutability, 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 storageNx / Turborepo CLICloudflare R2authenticate tokenread / write scopeimmutability (409)workspace 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. There is no GitHub App 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

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.
  • 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.
  • 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 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. There is no GitHub App to install or 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?
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.