GitOps repository for personal infrastructure management
  • Nix 32.5%
  • Jinja 21.5%
  • Python 17.9%
  • Shell 11.8%
  • Go 8.1%
  • Other 8.2%
Find a file
Erich Blume 2d38418e6e C1: close forge package leak at the fly edge
forge.eblu.me's package registry (/api/packages/* and /api/v1/packages/*)
served anonymous reads to the world even for private-repo releases —
Forgejo's per-user visibility treats packages as world-readable when
the owner's Visibility is Public, and we keep eblume Public so the
profile page stays open. The sdist downloads include full source
trees of private repos; that's the leak.

The fix is to keep the user public but block /api/packages/* and
/api/v1/packages/* at the proxy edge. forge.ops.eblu.me (tailnet) is
untouched, so CI workflows + gilbert's uv + the nix-container-builder
still work — they just need to use the tailnet hostname.

Three consumers updated to forge.ops.eblu.me:
  - containers/shower/default.nix (the FOD pip --extra-index-url)
  - ansible/roles/cv/defaults/main.yml (cv_release_url for generic package)
  - chezmoi-tracked fish dotfiles (devpi.fish + conf.d/pypi.fish) —
    edited in chezmoi source, user will apply separately

The blumeops repo had no other forge-pypi consumers (audited: workers,
runner-job-image, ansible roles, container builds). Doc references in
changelog fragments + comments left as-is — they describe history.

The proper long-term fix is to move private packages to a Limited-
visibility Forgejo org instead of relying on a proxy-side block (see
queued Todoist for the migration plan). Edge block stays as
defense in depth.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 13:06:48 -07:00
.claude
.forgejo/workflows C1: migrate cv + docs from minikube to indri-native (#342) 2026-04-29 14:55:11 -07:00
.github
ansible C1: close forge package leak at the fly edge 2026-05-11 13:06:48 -07:00
argocd C1: pin shower image to v1.0.2-83b038e-nix 2026-05-11 12:21:13 -07:00
containers C1: close forge package leak at the fly edge 2026-05-11 13:06:48 -07:00
docs C1: fix expose-service-publicly tailscale key flow 2026-05-11 11:25:02 -07:00
fly C1: close forge package leak at the fly edge 2026-05-11 13:06:48 -07:00
mise-tasks C1: add shower.eblu.me to fly-setup cert list 2026-05-11 09:23:10 -07:00
nixos/ringtail Update ringtail flake inputs 2026-04-30 16:55:08 -07:00
pulumi C1: deploy adelaide-baby-shower-app to ringtail k3s 2026-05-11 08:14:12 -07:00
src/blumeops Refactor Dagger go_build() helper and standardize Alpine 3.23 2026-04-16 10:10:46 -07:00
utils/qart
.ansible-lint
.gitattributes
.gitignore Bump Dagger to 0.20.6 and migrate runner-job-image to Alpine container.py 2026-04-21 08:28:18 -07:00
.yamllint.yaml
AGENTS.md C0: docs — default argocd login to --sso; drop extraneous --grpc-web 2026-04-21 10:43:21 -07:00
Brewfile
CHANGELOG.md Update docs release to v1.16.0 2026-04-18 10:00:54 -07:00
CLAUDE.md C0: CLAUDE.md — import AGENTS.md instead of redirecting to it 2026-04-27 11:41:13 -07:00
compensating-controls.yaml C0: review CC init-container-isolation — defer retirement to post-ringtail 2026-05-04 18:31:13 -07:00
dagger.json Bump Dagger to 0.20.6 and migrate runner-job-image to Alpine container.py 2026-04-21 08:28:18 -07:00
LICENSE
mise.toml Bump Dagger to 0.20.6 and migrate runner-job-image to Alpine container.py 2026-04-21 08:28:18 -07:00
prek.toml C1: SHA-pin tooling dependencies (2026-04 cycle) (#344) 2026-04-30 16:51:43 -07:00
pyproject.toml
README.md C0: adopt AGENTS.md as canonical agent config 2026-04-18 20:15:30 -07:00
service-versions.yaml C1: bump shower to v1.0.2 (WhiteNoise upstreamed); cache static on fly 2026-05-11 12:06:28 -07:00
towncrier.toml
uv.lock

blumeops

aka "Blue Mops"

Tools and configuration for Erich Blume's personal infrastructure, orchestrated across a Tailscale tailnet.

This is a homelab, but it's also a testing ground for AI-assisted infrastructure development. Much of this codebase was initially co-authored with Claude Code, and the repo places heavy emphasis on documentation, process, and change classification to make that collaboration work well. I don't know entirely how I feel about LLMs in our current era (there are real concerns about how training data is sourced and energy subsidy) but it felt important to learn how to work with these tools.

The full documentation is published at docs.eblu.me and lives in the docs/ directory, structured around the Diataxis framework and designed to be compatible with Obsidian/Obsidian.nvim.

What runs here

Services are a mix of Kubernetes pods (managed by ArgoCD), macOS LaunchAgent services (managed by Ansible), and NixOS systemd services (managed by Nix flakes), all connected via Tailscale:

  • Indri (Mac Mini M1) - primary server. Most services run in Minikube via ArgoCD; Forgejo, Caddy, and others run natively as LaunchAgent services via Ansible.
  • Ringtail (NixOS desktop, RTX 4080) - GPU workloads (Frigate NVR, Authentik SSO) on k3s, plus NixOS systemd services.
  • Sifaka (Synology NAS) - backup target and bulk storage.

Notable services include Grafana/Prometheus/Loki observability, Immich photos, Jellyfin media, Forgejo git forge, a Zot container registry, and more. Public access is routed through a Fly.io proxy; everything else is tailnet-only.

Project structure

ansible/            Ansible playbooks and roles (indri, sifaka)
argocd/apps/        ArgoCD Application definitions
argocd/manifests/   Kubernetes manifests per service
containers/         Custom container builds (Dockerfile + Nix)
docs/               Diataxis documentation (published at docs.eblu.me)
fly/                Fly.io public proxy configuration
mise-tasks/         Operational scripts run via mise
nixos/              NixOS configuration for ringtail
pulumi/             Pulumi IaC (Tailscale ACLs, Gandi DNS)
.dagger/            Dagger CI pipelines
.forgejo/           Forgejo Actions CI/CD workflows

Getting started

You'll need Homebrew and mise:

brew bundle                    # install CLI tools (argocd, tea, flyctl, etc.)
mise install                   # install managed toolchains (ansible, pulumi, dagger, etc.)
prek install                    # set up git hooks

Git hooks (via prek) enforce secret scanning (TruffleHog), linting, formatting, and custom checks like doc link validation and the Mikado branch invariant. They run automatically on git commit.

Operational tasks are driven through mise. Run mise tasks to see what's available. Key examples:

mise run provision-indri       # deploy to indri via Ansible
mise run services-check        # verify service health
mise run container-list        # list tracked container images

AI-assisted development

This repo is designed to be worked on by both humans and AI agents. The AGENTS.md file provides shared instructions for agentic tools, and the docs/tutorials/ai-assistance-guide.md explains the full workflow.

Changes are classified before starting work:

  • C0 - quick fixes, committed directly to main
  • C1 - feature branch + PR, documentation written before code
  • C2 - multi-phase work using the Mikado method for dependency tracking

See the agent change process for details.

License

GPLv3