s1d3sw1ped c38b2f9ece
CI / Go Tests (push) Successful in 13s
CI / Build (push) Successful in 11s
Format / gofmt (push) Successful in 7s
Release Artifacts / Validate release tag (push) Successful in 4s
Release Artifacts / Test release candidate (push) Successful in 12s
Release Artifacts / Build executable release artifacts (push) Successful in 14s
Release Artifacts / Build Docker image artifact (push) Successful in 29s
Release Artifacts / Publish release (push) Failing after 2s
Release Artifacts / Publish Docker image (push) Failing after 2s
Refactor release workflow to remove unnecessary registry login step and update fallback token handling
- Removed the login step to the Docker registry, simplifying the workflow.
- Updated fallback token retrieval to use secrets for enhanced security.
2026-06-01 03:13:35 -05:00
2026-06-01 01:29:47 -05:00
2026-06-01 01:29:47 -05:00
2026-06-01 01:29:47 -05:00
2026-06-01 01:29:47 -05:00
2026-05-31 20:17:49 -05:00

Scratchbox

Scratchbox is a minimal self-hosted scratch service written in Go. It is intentionally unauthenticated and optimized for temporary sharing of text or small files with an expiration time.

For multi-file sharing, bundle files into an archive (for example .zip or .tar.gz) before upload. Scratch content is gzip-compressed and AES-encrypted on disk transparently; API/UI reads return original uncompressed content.

Quick Start

  1. Generate defaults directly:
    • go run ./cmd/scratchbox generate-config > config.yaml
  2. Generate an encryption key file next to the config:
    • go run ./cmd/scratchbox generate-key > config.key
    • or: openssl rand -base64 32 > config.key
  3. Adjust settings for your environment.
  4. Start the server:
    • go run ./cmd/scratchbox server --config config.yaml
  5. Open:
    • http://127.0.0.1:8080/

Without --config, built-in defaults are used.

If you modify the web UI source (web/ui), rebuild frontend assets with:

  • make build

Docker

Build the container image:

  • make docker
  • Default image tag: scratchbox:dev

Optionally set a custom image name/tag:

  • make docker DOCKER_IMAGE=scratchbox:latest

Run with persistent data and config directories:

  • mkdir -p ./docker-data ./docker-config
  • docker run --rm -p 8080:8080 -v "$(pwd)/docker-data:/data" -v "$(pwd)/docker-config:/config" scratchbox:dev

Inside the container, the default command is:

  • scratchbox server --config /config/config.yaml

Create config files with the image (writes to mounted ./docker-config):

  • docker run --rm -v "$(pwd)/docker-config:/config" scratchbox:dev generate-config > ./docker-config/config.yaml
  • docker run --rm -v "$(pwd)/docker-config:/config" scratchbox:dev generate-key > ./docker-config/config.key

Release Artifacts

Tagged releases provide .tar.gz archives with prebuilt Linux binaries.

Accepted release tag formats:

  • 1.2.3 (stable release)
  • 1.2.3-alpha1, 1.2.3-beta1, 1.2.3-rc1 (prerelease)

Variant guide:

Variant Recommended for Notes
default Most Linux distributions (Ubuntu, Debian, Fedora, Arch, etc.) Smaller, dynamically linked Linux build
static Any Linux distro (including Alpine/musl) Statically linked for maximum Linux compatibility

To unpack an artifact:

  • tar -xzf scratchbox-<tag>-linux-amd64-default.tar.gz

To unpack into a specific directory:

  • mkdir -p ./scratchbox-release
  • tar -xzf scratchbox-<tag>-linux-amd64-default.tar.gz -C ./scratchbox-release

To run from an unpacked artifact:

  • ./scratchbox-<os>-<arch>-<variant> server --config config.yaml

If you do not have a config file yet, generate one first:

  • go run ./cmd/scratchbox generate-config > config.yaml
  • go run ./cmd/scratchbox generate-key > config.key

Configuration

All configuration is YAML.

server

  • listen_addr: address for the HTTP server (required).
    • Default: :8080
  • read_header_timeout: maximum time for reading request headers.
    • Must be > 0
    • Default: 5s
  • read_timeout: maximum time for reading the full request.
    • Must be > 0
    • Default: 30s
  • write_timeout: maximum time allowed for writing the response.
    • Must be > 0
    • Default: 30s
  • idle_timeout: maximum keep-alive idle time between requests.
    • Must be > 0
    • Default: 120s
  • max_header_bytes: max HTTP header size in bytes.
    • Must be > 0
    • Default: 1048576 (1 MiB)
  • access_log: structured request logs.
    • enabled: enable HTTP access logs
      • Default: true
    • file_path: optional log file path
      • When set, logs are tee'd to both stdout and the file
    • max_size: rotation threshold for file_path
      • Supported units: B, KB, MB, GB, KiB, MiB, GiB
      • Default: 100MiB
    • max_backups: number of rotated files to retain
      • Default: 5

limits

  • max_upload_size: max request body size for uploads.
    • Supported units: B, KB, MB, GB, KiB, MiB, GiB (case-insensitive)
    • If no unit is provided, value is interpreted as bytes
    • Examples: 5MB, 100MiB, 1GiB, 1048576
    • Default: 100MiB
  • default_ttl: expiration applied to new scratches.
    • Must be > 0 and <= 24h
    • Default: 15m
  • raw_cache_max_size: max total decompressed bytes cached in memory for /api/raw range requests.
    • Supported units: B, KB, MB, GB, KiB, MiB, GiB (case-insensitive)
    • Must be > 0
    • Default: 200MiB
  • raw_cache_max_entries: max number of decompressed /api/raw entries kept in memory.
    • Must be > 0
    • Used together with raw_cache_max_size as a secondary cap
    • Default: 32

storage

  • data_dir: directory for scratch files and metadata index.
    • Default: ./data
  • cleanup_interval: background interval for deleting expired content.
    • Must be at least 10s
    • Default: 1m
  • encryption_key_file: path to a file containing a base64-encoded 32-byte key used for at-rest encryption.
    • Relative paths are resolved from the config file directory
    • Default: config.key (expected alongside config.yaml)
    • Keep this key stable across restarts
    • Changing the key makes existing scratch files unreadable
    • generate-key emits a fresh random key each run

security

  • allowed_ips: optional list of IPs and CIDRs allowed to create scratches.
    • Applies to write route only: POST /api/scratch
    • Default includes 127.0.0.1 (localhost-only write access)
    • Add trusted IPs/CIDRs for LAN/proxy clients (for example 192.168.1.0/24)
    • Empty list means no allowlist restriction
  • trust_proxy_headers: if true, client IP extraction honors X-Forwarded-For then X-Real-IP.
    • Only used when source IP matches trusted_proxy_ips.
    • Keep false unless behind a trusted reverse proxy that sets these headers.
  • trusted_proxy_ips: list of reverse-proxy IPs/CIDRs permitted to supply forwarded headers.
    • Required when trust_proxy_headers: true
    • Examples: 127.0.0.1, 10.0.0.0/8
  • rate_limit_ui: per-IP token-bucket for UI routes (GET /, GET /u, GET /s/{id}).
    • enabled default: false
    • requests_per_minute must be > 0 (default 360)
    • burst must be > 0 (default 120)
  • rate_limit_api_read: per-IP token-bucket for API read routes (GET /api/config, GET /api/scratch/{id}, GET /api/raw/{id}).
    • enabled default: false
    • requests_per_minute must be > 0 (default 300)
    • burst must be > 0 (default 100)
  • rate_limit_api_write: per-IP token-bucket for API write route (POST /api/scratch).
    • enabled default: true
    • requests_per_minute must be > 0 (default 30)
    • burst must be > 0 (default 10)

Security Posture

This service is intentionally unauthenticated. Anyone with network access can read scratches, and (unless restricted) create scratches.

  • No authentication, user accounts, or moderation controls.
  • No malware scanning.
  • Abuse controls are limited to upload size limits, TTL expiration, optional IP allowlisting, and write-route rate limiting.
  • Treat this as a convenience utility, not a hardened internet-facing platform.

LAN Deployment Notes

For home/lab/LAN-only use:

  • Bind to a private address, for example 127.0.0.1:8080 (single host) or 192.168.x.x:8080.
  • Use allowed_ips to restrict write access to trusted subnets.
  • Keep max_upload_size and default_ttl small.
  • Keep trust_proxy_headers disabled unless using a trusted reverse proxy.

Public Deployment Notes

If exposed beyond a trusted LAN, place a reverse proxy in front (Nginx, Caddy, Traefik, etc.) and add external controls:

  • TLS termination and strict transport settings.
  • Additional request filtering/WAF controls.
  • Stronger rate limits at the edge.
  • Optional network-level restrictions to write route.
  • Monitoring and log retention suitable for abuse triage.

Recommended baseline: run behind a reverse proxy, keep low TTL and size limits, and use allowed_ips for write access whenever possible.

Storage Model

Scratchbox storage is designed for a single process instance per storage.data_dir.

  • Do not run multiple scratchbox processes against the same data directory.
  • Metadata/index writes are process-local and are not coordinated with cross-process locking.
  • Scratch payload files and metadata index are encrypted at rest.
  • Scratch IDs are derived from the SHA-256 of the stored blob (encrypted+gzip payload on disk).
S
Description
No description provided
Readme 1.7 GiB
1.0.4 Latest
2026-07-15 16:29:39 -05:00
Languages
Go 89.5%
Svelte 8.5%
Makefile 0.6%
HTML 0.4%
Dockerfile 0.4%
Other 0.6%