This repository has been archived on 2026-07-10. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
olb042 c85556e327
Validate manifests / validate (push) Failing after 8s
Initial authentik gitops app
2026-04-20 01:03:25 +01:00

7.2 KiB

authentik

Kubernetes deployment source-of-truth repository for authentik.

This template is intended for applications deployed with ArgoCD through an ApplicationSet. It uses a base/ plus overlays/ layout, stores runtime secrets as SOPS-encrypted manifests, and includes a Gitea workflow that checks Kubernetes YAML syntax on every push and pull request. It also ships with a dormant bootstrap ApplicationSet that only becomes active after an explicit enable change and a promotion into main.

Layout

.
├── .gitea/
│   ├── template
│   └── workflows/validate.yaml
├── .github/
│   └── workflows/check-sops-sync.yml
├── .sops.yaml
├── bootstrap/
│   ├── applicationset.yaml
│   └── config.yaml
├── manifest/
│   ├── base/
│   │   ├── deployment.yaml
│   │   ├── kustomization.yaml
│   │   ├── namespace.yaml
│   │   └── service.yaml
│   ├── components/
│   │   └── example-component/
│   └── overlays/
│       └── production/
│           ├── ingressroute.yaml
│           ├── kustomization.yaml
│           ├── secret-generator.yaml
│           ├── secret.secret.yaml
│           └── storage/
│               ├── persistentvolumeclaim.yaml
│               └── persistentvolume-nfs.yaml
└── scripts/
    ├── ci/check-sops-sync
    ├── git-hooks/pre-commit
    ├── install-git-hooks
    └── lib/
        ├── sops-path-regexes
        └── sops-sync-lib

First edits

Update these files before the first deployment:

  1. manifest/base/deployment.yaml Set the container image, ports, probes, resource requests, and any required environment variables.
  2. manifest/overlays/production/ingressroute.yaml Set the real hostname, entry point names, and middleware references if used.
  3. manifest/overlays/production/storage/persistentvolumeclaim.yaml Set the requested size, access mode, and storage class for the environment.
  4. .sops.yaml Replace the sample age recipient with the public key that ArgoCD should use for decryption.
  5. manifest/overlays/production/secret.secret.yaml Re-encrypt the placeholder secret values with your own data.

Bootstrap activation model

This template is designed to start on an init branch. The intended flow is:

  1. Create the repository from this template with init as the initial branch.
  2. Tailor the manifests, secrets, storage, and ingress on init.
  3. Keep bootstrap/config.yaml set to enabled: false while the repository is being prepared.
  4. Create main by merging init only when the repository is ready to be part of the delivery pipeline.
  5. Deliberately change bootstrap/config.yaml to enabled: true on main to allow the workflow to apply the bootstrap ApplicationSet.

The workflow behavior is:

  • bootstrap/applicationset.yaml is ignored by validation while bootstrap is disabled
  • no cluster apply is attempted unless the workflow runs on main
  • cluster apply also requires the KUBECONFIG_B64 Gitea secret

Bootstrap files

  • bootstrap/config.yaml Repository-local activation switch. Default is disabled.
  • bootstrap/applicationset.yaml ArgoCD ApplicationSet manifest template for this repository.

If the repository is created by copying files with plain Git instead of Gitea's template expansion, you must replace the ${REPO_NAME...} placeholders in bootstrap/applicationset.yaml before enabling bootstrap.

Storage model

Storage is overlay-owned, so each environment can request different backing storage without sharing claims across environments.

  • manifest/overlays/production/storage/persistentvolumeclaim.yaml Default writable application storage. With the default longhorn storageClassName, Kubernetes dynamically provisions the backing PV when the claim is created.
  • manifest/overlays/production/storage/persistentvolume-nfs.yaml Optional static PV example for NFS-backed or pre-provisioned shared storage. This file is not referenced by default. Add it to the overlay kustomization only when you need a static PV.

The base deployment mounts the claim at /data.

If storage should be shared between multiple applications in different repositories, keep those applications in the same namespace and have a single repository own the PVC resource. The other repositories should reference the same claim name from their deployments instead of creating a duplicate PVC.

Secret workflow

  1. Generate an age key pair.
  2. Store the private key where ArgoCD / ksops can read it.
  3. Update .sops.yaml with the matching public recipient.
  4. Re-encrypt manifest/overlays/production/secret.secret.yaml.

Example:

age-keygen -o age-key.txt
sops --encrypt --in-place manifest/overlays/production/secret.secret.yaml

Repo-managed SOPS sync

This repo also supports sync-managed secrets using the naming convention:

foo.yaml -> foo.enc.yaml -> foo.enc.yaml.sync-hmac
  • foo.yaml Local plaintext source. Keep it gitignored and untracked.
  • foo.enc.yaml Tracked SOPS-encrypted file.
  • foo.enc.yaml.sync-hmac Tracked HMAC sidecar used to prove the encrypted file still matches the last synced plaintext content.

Requirements:

  • SOPS_SYNC_HMAC_KEY must be set locally for hooks and in CI
  • sops, openssl, and either yq or python3 with PyYAML must be available
  • CI also needs access to the repo's SOPS decryption mechanism, such as an age key

Generate a local HMAC key:

openssl rand -hex 32

Set it for the current shell session:

export SOPS_SYNC_HMAC_KEY='<paste-generated-key-here>'

Persist it in zsh:

echo "export SOPS_SYNC_HMAC_KEY='<paste-generated-key-here>'" >> ~/.zshrc
source ~/.zshrc

Persist it in bash:

echo "export SOPS_SYNC_HMAC_KEY='<paste-generated-key-here>'" >> ~/.bashrc
source ~/.bashrc

Verify it is set:

printenv SOPS_SYNC_HMAC_KEY

Install the local hook:

scripts/install-git-hooks

Local workflow:

  1. Keep your plaintext secret local-only, for example manifest/overlays/production/secret.yaml.
  2. Stage either the plaintext file or its .enc.yaml twin.
  3. On pre-commit, the hook encrypts the plaintext if needed, updates the .sync-hmac sidecar, and stages both tracked files.

CI behavior:

  • CI fails if a tracked .enc.yaml file is not valid SOPS content
  • CI fails if the .sync-hmac sidecar is missing
  • CI fails if decrypted plaintext no longer matches the tracked sidecar HMAC

Security tradeoffs:

  • The sidecar is an HMAC, not a plain checksum, so the plaintext fingerprint is keyed and not directly reusable without SOPS_SYNC_HMAC_KEY
  • Anyone who can decrypt the repo secret files and also access the HMAC key can recompute sidecars, so protect both inputs appropriately
  • Plaintext local files must remain gitignored and never be committed

ArgoCD ApplicationSet path

Point the generated ArgoCD Application at:

manifest/overlays/production

If your ApplicationSet uses repository scanning, this repository is designed to be the single source of truth for one application, with ArgoCD rendering the selected overlay.