𝔩𝔢𝔩𝕠𝔭𝔢𝔷
Theme
Connect With Me on LinkedIn Buy Me a Coffee

Homelab

SOPS and Age GitOps Secrets

Setting Up SOPS and Age Encryption for GitOps Secrets Management

Overview

Git repository for all Infrastructure as Code - Talos configs, Kubernetes manifests, Helm values, and scripts. If something breaks, I can clone and rebuild.

Tip:Having trouble? See v0.4.0 for reference.

Before You Begin

Prerequisites

What We're Setting Up

  • Git repository with directory structure for Talos, Kubernetes, and Flux configs
  • Auto-push hook for multi-machine workflow
  • SOPS + age encryption with key stored in 1Password

Set Up Repository

Create Repository

mkdir ~/homelab && cd ~/homelab
git init

Directory Structure

mkdir -p talos
mkdir -p k8s/{core,apps}
mkdir -p flux/config
  • talos/ - Machine configs and encrypted secrets
  • k8s/core/ - Infrastructure (Tailscale, MetalLB, Ingress, Longhorn)
  • k8s/apps/ - Applications (Plex, Minecraft)
  • flux/config/ - Flux sync configuration

Hook Directory

I work from multiple machines, so I added a post-commit hook to auto-push:

mkdir .githooks

Post-Commit Script

.githooks/post-commit:

#!/bin/sh
current_branch=$(git rev-parse --abbrev-ref HEAD)
echo "Pushing to origin/$current_branch..."
git push origin "$current_branch" 2>&1 || echo "Push failed - pull first"

Enable Hook

chmod +x .githooks/post-commit
ln -sf ../../.githooks/post-commit .git/hooks/post-commit

Commit Hook

git add .githooks/
git commit -m "chore(git): init post-commit hook"

Ignore Patterns

.gitignore:

# macOS
.DS_Store

Commit Ignore Patterns

git add .gitignore
git commit -m "chore(git): ignore mac files"

Additional gitignore patterns are added as needed per component (see Talhelper Cluster Bootstrap for Talos-specific entries).

Project Overview

README.md:

# homelab

Talos Kubernetes cluster with GPU transcoding, Tailscale VPN, and GitOps via Flux.

Commit Project Overview

git add README.md
git commit -m "docs(readme): init with overview"

Push to GitHub

git remote add origin git@github.com:lelopez-io/homelab.git
git branch -M main
git push -u origin main

Configure SOPS Encryption

Encrypt sensitive configs with SOPS1 and age2 before committing. Age key stored in 1Password - never touches disk.

Install

brew install sops age 1password-cli

Generate Key

# Generate key to temp file
# Note the public key (age1...) - needed for .sops.yaml
age-keygen -o /tmp/age-key.txt

# Store in 1Password as document
op document create /tmp/age-key.txt --title "sops-key | homelab" --vault "Private"

# Delete local copy
rm /tmp/age-key.txt

The public key (starts with age1...) is needed for the next step.

Create Config

.sops.yaml:

creation_rules:
  - age: <your-age-public-key>

SOPS walks up the directory tree to find this file, so one config at the repo root covers secrets anywhere in the repo. The creation rule tells SOPS which key to use when encrypting - decryption works automatically since key info is embedded in encrypted files.

Commit Config

git add .sops.yaml
git commit -m "chore(sops): init encryption config"

Next Steps

With the repository configured and secrets encryption in place, you're ready to generate Talos configs and bootstrap the cluster.

See: Talhelper Cluster Bootstrap

Resources

Footnotes

  1. SOPS, "SOPS: Secrets OPerationS," github.com. Accessed: Dec. 16, 2025. [Online]. Available: https://github.com/getsops/sops

  2. FiloSottile, "age - A simple, modern and secure encryption tool," github.com. Accessed: Dec. 16, 2025. [Online]. Available: https://github.com/FiloSottile/age

Previous
Talos Linux USB Installation