Architecture¶
Server Structure¶
All Go code lives in server/:
server/
├── main.go # Entry point, config, routing, lazy GCS client
├── auth.go # Login page, cookie validation, auth middleware
├── proxy.go # GCS proxy, path rewriting, repo discovery
├── cache.go # In-memory LRU/TTL cache
├── go.mod
├── go.sum
└── Dockerfile
The server is a single main package with no internal sub-packages. This keeps the codebase simple for a focused tool.
Key Interfaces¶
BucketReader¶
type BucketReader interface {
ReadObject(ctx context.Context, key string) ([]byte, string, error)
ListPrefixes(ctx context.Context, prefix, delimiter string) ([]string, error)
ReadObjectIfExists(ctx context.Context, key string) ([]byte, bool, error)
}
All GCS operations go through this interface. The production implementation (LazyBucket) wraps *storage.BucketHandle. Tests use a mock.
Authentication Flow¶
authMiddlewarechecks for_sessioncookie on every request- Cookie format:
<expiry_unix>.<hmac_sha256_hex> - HMAC is computed over the expiry timestamp string
- Validation: verify HMAC signature, then check
expiry > now - Invalid or missing →
302redirect to/_login?next={path} - Password comparison uses
subtle.ConstantTimeCompare
Cache Design¶
- LRU eviction using
container/listfrom stdlib - TTL-based expiration checked lazily on
Get() - Thread-safe via
sync.Mutex - Configurable max total size and max per-object size
- No background goroutines — expiration is lazy
Lazy GCS Client¶
The GCS client is initialized on first request, not at startup. This allows:
- Server to start and serve
/_healthwithout GCP credentials - Health checks to work in CI and local dev
- Faster cold starts on Cloud Run
Error Handling¶
| GCS Error | HTTP Status |
|---|---|
| Object not found | 404 Not Found |
| Permission denied / other | 502 Bad Gateway |
| Client not initialized | 503 Service Unavailable |
GCS error details are logged but not exposed to clients.
Dependencies¶
cloud.google.com/go/storage— GCS clientcloud.google.com/go/secretmanager— Secret Manager (conditional)net/http— HTTP server (no framework)log/slog— Structured loggingcontainer/list— LRU linked list