cachew

module
v0.7.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2026 License: Apache-2.0

README

Cachew

Cachew (pronounced "cashew") is a tiered, protocol-aware, caching HTTP proxy for software engineering infrastructure. It understands higher-level protocols (Git, Docker, Go modules, etc.) and makes smarter caching decisions than a naive HTTP proxy.

Strategies

Git

Caches Git repositories with two complementary techniques:

  1. Snapshots — periodic .tar.zst archives that restore 4–5x faster than git clone.
  2. Pack caching — passthrough caching of packs from git-upload-pack for incremental pulls.

Redirect Git traffic through cachew:

[url "https://cachew.example.com/git/github.com/"]
  insteadOf = https://github.com/

Restore a repository from a snapshot (with automatic delta bundle to reach HEAD):

cachew git restore https://github.com/org/repo ./repo
git {
  snapshot-interval = "1h"
  repack-interval   = "1h"
}
GitHub Releases

Caches public and private GitHub release assets. Private orgs use a token or GitHub App for authentication.

URL pattern: /github-releases/{owner}/{repo}/{tag}/{asset}

github-releases {
  token        = "${GITHUB_TOKEN}"
  private-orgs = ["myorg"]
}
Go Modules

Go module proxy (GOPROXY-compatible). Private modules are fetched via git clone.

URL pattern: /gomod/...

export GOPROXY=http://cachew.example.com/gomod,direct
gomod {
  proxy         = "https://proxy.golang.org"
  private-paths = ["github.com/myorg/*"]
}
Hermit

Caches Hermit package downloads. GitHub release URLs are automatically routed through the github-releases strategy.

URL pattern: /hermit/{host}/{path...}

hermit {}
Artifactory

Caches artifacts from JFrog Artifactory with host-based or path-based routing.

artifactory "example.jfrog.io" {
  target = "https://example.jfrog.io"
}
Host

Generic reverse-proxy caching for arbitrary HTTP hosts, with optional custom headers.

host "https://ghcr.io" {
  headers = {
    "Authorization": "Bearer QQ=="
  }
}

host "https://w3.org" {}

Optional fallback blocks select trusted mirrors in declaration order. Cachew tries the next mirror only after a 429, a 5xx response, or a transport error. It never retries a 404 against a mirror: the primary is authoritative and mirrors can lag. Cancellation stops retries. Failures after response streaming starts cannot retry.

host "https://packages.example.com" {
  fallback "https://mirror.example.com/archive" {
    path-prefix = "/releases"
  }
}

This maps /releases/pkg.tar.gz to https://mirror.example.com/archive/pkg.tar.gz. path-prefix defaults to / and matches complete path segments. Unmatched paths do not use that fallback. Query strings are preserved.

Fallbacks receive the same request headers and are trusted like the primary for shared cache content. Configure only mirrors that serve byte-identical content. Successful responses use the primary URL's cache key, regardless of which upstream served them. Non-200 and incomplete responses are not cached.

HTTP Proxy

Caching proxy for clients that use absolute-form HTTP requests (e.g. Android sdkmanager --proxy_host).

proxy {}

Cache Backends

Multiple backends can be configured simultaneously — they are automatically combined into a tiered cache. Cache blocks are ordered from lowest/nearest to highest/authoritative. Reads check each tier in order and backfill lower tiers on a hit. Writes go to all tiers in parallel. Replica invalidations evict only non-authoritative tiers; the final cache block is authoritative. Tiered caches use the metadata backend to track authoritative ETags and invalidate stale lower-tier copies before falling through to the authoritative tier.

Memory

In-memory LRU cache.

memory {
  limit-mb = 1024   # default
  max-ttl  = "1h"   # default
}
Disk

On-disk LRU cache with TTL-based eviction.

disk {
  limit-mb = 250000
  max-ttl  = "8h"
}
S3

S3-compatible object storage (AWS S3, MinIO, etc.).

s3 {
  bucket   = "my-cache-bucket"
  endpoint = "s3.amazonaws.com"
  region   = "us-east-1"
}

Request Coalescing

Concurrent requests for the same uncached object share one upstream fetch, and every client streams the response while it downloads. The fetch continues and fills the cache even if every client disconnects.

Error responses are shared only when HTTP caching rules allow reuse, and for at most error-window.

spool {
  dir          = "${CACHEW_STATE}/spools"  # Response files for backends that cannot be read while writing
  fill-timeout = "30m"                     # 0 disables the limit
  error-window = "5s"                      # 0 shares errors only with requests already waiting
}

Authorization (OPA)

Cachew uses Open Policy Agent for request authorization. The default policy allows all requests from localhost and restricts remote access to non-admin paths (/api/*, /admin/*).

Policies must be in package cachew.authz and define an allow rule. If allow is true the request proceeds; otherwise it is rejected with 403.

opa {
  policy = <<EOF
    package cachew.authz
    default allow := false
    allow if input.headers["authorization"]
  EOF
}

Or reference an external file with optional data:

opa {
  policy-file = "./policy.rego"
  data-file   = "./opa-data.json"
}

Input fields: input.method, input.path (string array), input.headers, input.remote_addr (includes port — use startswith to match by IP).

Testing policies

The test field holds a Rego test module that is run against the policy when cachewd starts. Any rule prefixed with test_ is executed; if a test fails, cachewd exits.

opa {
  policy = <<EOF
    package cachew.authz
    default allow := false
    allow if input.method == "POST"
  EOF
  test = <<EOF
    package cachew.authz_test
    import data.cachew.authz

    test_post_allowed if authz.allow with input as {"method": "POST"}
    test_get_denied if not authz.allow with input as {"method": "GET"}
  EOF
}

GitHub App Authentication

For private Git repositories and GitHub release assets, configure a GitHub App:

github-app {
  app-id           = "12345"
  private-key-path = "./github-app.pem"
  installations    = { "myorg": "67890" }
}

Installations can also be discovered dynamically via the GitHub API.

CLI

Server (cachewd)
cachewd --config cachew.hcl
cachewd --schema  # print config schema
Client (cachew)
# Object operations
cachew get <namespace> <key> [-o file]
cachew put <namespace> <key> [file] [--ttl 1h]
cachew stat <namespace> <key>
cachew delete <namespace> <key>
cachew namespaces

# Directory snapshots
cachew save <namespace> <directory> [paths...] (--key <key> | -H <glob>) [--ttl 1h] [--exclude pattern]
cachew restore <namespace> <directory> (--key <key> | -H <glob>)  # exit 0 hit, 2 miss, 1 error

# Git
cachew git restore <repo-url> <directory> [--no-bundle]

Global flags: --url (CACHEW_URL), --authorization (CACHEW_AUTHORIZATION), --platform (prefix keys with os-arch), --daily/--hourly (prefix keys with date).

Observability

log {
  level = "info"  # debug, info, warn, error
}

metrics {
  service-name = "cachew"
}

Admin endpoints: /_liveness, /_readiness, PUT /admin/log/level, /admin/pprof/.

GitHub App installations are checked at startup and every minute via /rate_limit. The poller includes dynamically discovered installations and the configured fallback organization.

Metric Type Labels
github.ratelimit_remaining Gauge app, installation_id, owner, resource
github.ratelimit_limit Gauge app, installation_id, owner, resource
github.ratelimit_used Gauge app, installation_id, owner, resource
github.api_calls Counter owner, operation

app is the configured App ID. owner identifies the installation actually used, including fallback credentials. Installation discovery uses owner=unknown because it authenticates as the App before resolving an installation. API calls for release metadata/assets, installation discovery, token creation and quota polling are counted. Responses with less than 10% of their API quota remaining produce a warning. Static release tokens receive API call counts and warnings, but are not polled for quota gauges.

Quota gauges describe the installation's shared API budget; do not sum them across replicas. They do not track Git transport or LFS limits. Polling does not consume the primary API budget, but can count toward GitHub's secondary limits.

Full Configuration Example

state = "./state"
bind  = "0.0.0.0:8080"
url   = "http://cachew.example.com:8080/"

log {
  level = "info"
}

opa {
  policy = <<EOF
    package cachew.authz
    default allow := false
    allow if startswith(input.remote_addr, "127.0.0.1:")
  EOF
}

metrics {}

github-app {
  app-id           = "12345"
  private-key-path = "./github-app.pem"
}

git-clone {}

git {
  snapshot-interval = "1h"
  repack-interval   = "1h"
}

github-releases {
  token        = "${GITHUB_TOKEN}"
  private-orgs = ["myorg"]
}

gomod {
  proxy         = "https://proxy.golang.org"
  private-paths = ["github.com/myorg/*"]
}

hermit {}

host "https://ghcr.io" {
  headers = {
    "Authorization": "Bearer ${GHCR_TOKEN}"
  }
}

disk {
  limit-mb = 250000
  max-ttl  = "8h"
}

proxy {}

Directories

Path Synopsis
Package client provides a standalone HTTP client for the Cachew cache server.
Package client provides a standalone HTTP client for the Cachew cache server.
cmd
cachew command
cachewd command
internal
cache
Package cache provides a framework for implementing and registering different cache backends.
Package cache provides a framework for implementing and registering different cache backends.
config
Package config loads HCL configuration and uses that to construct the cache backend, and proxy strategies.
Package config loads HCL configuration and uses that to construct the cache backend, and proxy strategies.
featureflags
Package featureflags provides typed feature flags backed by environment variables.
Package featureflags provides typed feature flags backed by environment variables.
gitclone
Package gitclone provides reusable git clone management with lifecycle control, concurrency management, and large repository optimizations.
Package gitclone provides reusable git clone management with lifecycle control, concurrency management, and large repository optimizations.
githubapp
Package githubapp provides GitHub App authentication and token management.
Package githubapp provides GitHub App authentication and token management.
httputil
Package httputil contains utilities for HTTP clients and servers.
Package httputil contains utilities for HTTP clients and servers.
jobscheduler
Package jobscheduler provides a means to schedule work across multiple queues while limiting overall work.
Package jobscheduler provides a means to schedule work across multiple queues while limiting overall work.
logging
Package logging provides logging configuration and utility functions.
Package logging provides logging configuration and utility functions.
metadatadb
Package metadatadb provides a metadata store for coordinating state across cachew replicas.
Package metadatadb provides a metadata store for coordinating state across cachew replicas.
metadatadb/s3
Package s3 implements the S3 metadata backend as an append-only journal of immutable op segments plus a compacted rollup snapshot, replayed in a canonical order all replicas agree on.
Package s3 implements the S3 metadata backend as an append-only journal of immutable op segments plus a compacted rollup snapshot, replayed in a canonical order all replicas agree on.
opa
Package opa provides OPA-based HTTP request authorization middleware.
Package opa provides OPA-based HTTP request authorization middleware.
reaper
Package reaper provides a background zombie process reaper.
Package reaper provides a background zombie process reaper.
s3client
Package s3client provides shared S3 connection configuration and minio client construction.
Package s3client provides shared S3 connection configuration and minio client construction.
s3client/s3clienttest
Package s3clienttest provides a reusable MinIO test server via Docker.
Package s3clienttest provides a reusable MinIO test server via Docker.
snapshot
Package snapshot provides streaming directory archival and restoration using tar and zstd.
Package snapshot provides streaming directory archival and restoration using tar and zstd.
spool
Package spool shares one in-flight HTTP response between concurrent requests, which stream it while it is still being produced.
Package spool shares one in-flight HTTP response between concurrent requests, which stream it while it is still being produced.
strategy
Package strategy provides a framework for implementing and registering different caching strategies.
Package strategy provides a framework for implementing and registering different caching strategies.
strategy/git
Package git implements a protocol-aware Git caching proxy strategy.
Package git implements a protocol-aware Git caching proxy strategy.
tracing
Package tracing wires up the OpenTelemetry tracer provider so callers can use the standard otel.Tracer(...) API to create spans.
Package tracing wires up the OpenTelemetry tracer provider so callers can use the standard otel.Tracer(...) API to create spans.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL