- TypeScript 98.2%
- Just 1.8%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
Component-based (namespace/db/redis/migrate/app), tiered (light/production/ production-ha), BYO-everything adoption seams, generated CI (GitHub/GitLab/ Forgejo), and 11 lifecycle Ops (seed/backup/restore/rotate/watch/reconcile/ upgrade/teardown/local k3d up-down). Built with chant and its Kubernetes lexicon, in the style of INTENTIUS/loomster. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> |
||
| .chant/rules | ||
| .forgejo/workflows | ||
| .github/workflows | ||
| .gitlab | ||
| docs | ||
| ops | ||
| skills/infisical-chant | ||
| src | ||
| .gitignore | ||
| .gitlab-ci.yml | ||
| chant.config.ts | ||
| justfile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
infisical-chant
A deployment of Infisical (self-hosted) you drive
from the repo, for any Kubernetes cluster — a local k3d cluster, EKS,
GKE, AKS, k3s, OpenShift, whatever kubectl can reach. Five components,
three tiers (light / production / production-ha), generated CI, and a
naming scheme that lets many Infisical instances coexist in one namespace or
across many clusters without collision. Built with
chant and its Kubernetes lexicon, in the style
of loomster — chant's own AWS/CDK
reference deployment — though you run infisical-chant by its verbs, not by
knowing chant.
Drive it with your agent
Clone it and your agent already knows how to operate it:
git clone <this-repo>
cd infisical-chant && npm install
The checkout ships skills/infisical-chant/SKILL.md, the capability map an
agent reads on its own — every lifecycle verb, the golden paths, and the
guardrails that keep a deploy from locking itself out. chant also serves an
MCP server (chant serve mcp, stdio) for inspecting and building the graph.
From the checkout, ask your agent to "stand up Infisical locally" and it
knows what to run.
Docs: Tiers & targets · Naming & cross-stack wiring · Adoption (BYO) · Run it locally · Seeding · Backup & restore
Where it runs
- Locally, on a real k3d Kubernetes cluster in Docker, no cloud account
—
just local-up(seedocs/local.md). Unlike an AWS-emulator-based local loop, this is an actual (if small) Kubernetes cluster running the exact manifests a real deploy uses. - Anywhere else
kubectlcan reach — this project makes no cloud-specific assumptions in its core composites; cloud-managed pieces (ingress, storage class) are opt-in adoption seams, not defaults (seedocs/adoption.md).
Run it locally
just local-up # a real k3d cluster + the full stack, needs Docker + k3d
just local-down # tear it down
See docs/local.md for the full walkthrough, including seeding the first
admin org and reaching the app through a port-forward.
Develop
package.json consumes published @intentius/chant and its lexicons from
npm. No sibling checkout, no codegen step.
just install # npm install
just build # typecheck
just lint # chant lint . — core k8s-lexicon rules + .chant/rules/ project-local rules
just test # vitest run
just check # all of the above
Components
Five stacks, deployed in dependency order:
| Component | Depends on | What it is |
|---|---|---|
infisical-namespace |
— | Namespace + ResourceQuota + LimitRange + default-deny NetworkPolicy |
infisical-db |
infisical-namespace |
Postgres (single-replica StatefulSet, or reference-existing a managed database) |
infisical-redis |
infisical-namespace |
Redis (single-replica StatefulSet, or reference-existing a managed cache) |
infisical-migrate |
infisical-db |
One-shot Job — runs Infisical's database migrations |
infisical-app |
infisical-db, infisical-redis, infisical-migrate |
Infisical's own container (backend API + built frontend), Service, optional Ingress |
Every physical name and label comes from the shared naming helper
(src/lib/naming.ts); nothing is a literal (.chant/rules/no-hardcoded-name.ts,
INF001). Cross-component wiring is a deterministically-derived Secret name,
not a live cross-stack lookup — see docs/naming.md for why that's the
right call on Kubernetes (where loomster, an AWS/CloudFormation project,
needs stackOutput(...)).
Deploy
Each component synthesizes to a plain Kubernetes manifest
(chant build src/<component> --lexicon k8s); applying it is kubectl apply, since the k8s lexicon is a synthesis compiler, not a deploy
orchestrator (see the chant-k8s skill). The generated CI component
pipeline (.github/workflows/components.yml /
.gitlab/components.yml / .forgejo/workflows/components.yml, regenerated
via chant build --components --generate <target>) wires exactly that:
build → lint → synth → kubectl apply, one job per component, needs:
mirroring dependsOn. deploy.yml gates it — inert until:
- Repo variable
DEPLOY=true. - A CI environment named
productionholding the kubeconfig the job uses.
Lifecycle Ops
Beyond one-shot component deploys, ops/ holds the durable, gated concerns
for a running Infisical deployment, as chant Ops
on Temporal where they need an approval gate, or on
the local executor where they don't.
| Op | What it does | Gated? |
|---|---|---|
infisical-watch |
Drift detection — kubectl diff against fresh synth. Every tier. |
No |
infisical-reconcile |
On drift, opens a cloud-to-code PR (owned-only, never mutates the cluster). production/production-ha. |
No |
infisical-upgrade-light |
Re-run migrations, roll infisical-app to a new image tag. |
No — local executor |
infisical-upgrade-production |
Same, gated behind an approval phase. | Yes |
infisical-rotate-auth-secret |
Rotate the JWT signing secret + restart the app. Never touches ENCRYPTION_KEY (see the skill's Guardrails). |
Yes |
infisical-backup |
pg_dump via kubectl exec. Additive. |
No — local executor |
infisical-restore-drill |
Restore the latest backup to a throwaway namespace, assert it's healthy, delete it. | No — local executor |
infisical-restore |
Restore a named backup and cut infisical-app over to it. |
Yes — cutover is destructive |
infisical-seed |
Bootstrap the first admin org via Infisical's own API. | No — local executor |
infisical-teardown |
Gated, owned-only, marker-scoped namespace delete. No foreign deletes. | Yes |
infisical-local-up / infisical-local-down |
k3d cluster lifecycle for local dev. | No — local executor |
chant build ops # compile to dist/ops/<name>/
chant run infisical-upgrade-light # local executor, no Temporal needed
chant run infisical-upgrade-production --temporal # pauses at "Approve"
chant run signal infisical-upgrade-production approve-infisical-upgrade-production
npm run watch # one-shot infisical-watch
npm run reconcile # one-shot infisical-reconcile
Generated CI
chant build --components --generate gitlab synthesizes the component
pipeline from the same component graph chant graph --components reads.
One stage per parallel-safe wave, one job per component, needs: mirroring
dependsOn. It's written to .gitlab/components.yml; the root
.gitlab-ci.yml includes it and adds a gated deploy job and the
scheduled lifecycle jobs.
npm run generate:gitlab # writes .gitlab/components.yml
just gitlab-validate # regenerate + diff against the committed copy (fails on drift)
Same for GitHub Actions (npm run generate:github, just github-validate) and Forgejo Actions (npm run generate:forgejo, just forgejo-validate).
Adoption (bring your own infrastructure)
Every referenceable seam — database, cache, app secrets, ingress — exposes
provision | reference-existing, set from INFISICAL_* env vars, with no
forking of a composite. src/examples/byo/ wires every seam to
reference-existing at once. Full matrix: docs/adoption.md.
What this starter is (and isn't)
This is a starter kit: real, typed, lint-clean, unit-tested chant source
that synthesizes to valid Kubernetes manifests and generates real CI
pipelines — not a hand-wavy sketch. It has not been applied to a live
cluster as part of building it (this environment has no Docker/kubectl
available to prove that final mile) — just local-up's k3d loop is the
intended way to close that gap yourself, and is the first thing to run
after cloning. Treat chant build/chant lint/vitest passing as "this
compiles and is internally consistent," and a real kubectl apply as the
step that proves it deploys.