---
id: w4/m4/t002
title: "Argo Application for OpenFGA (pinned chart, values, cluster-internal)"
worker: worker4
status: done
estimate: 35m
depends_on: [w4/m4/t001]
---

## Objective

Deploy OpenFGA as a GitOps base component: multi-source Argo `Application` over the pinned upstream `openfga/openfga` Helm chart, values vendored in `base/values/`, Postgres datastore pointed at `openfga-db`, **no public ingress** — bex-api is the only intended caller, so both the API and playground stay cluster-internal.

## Context

- Pattern to copy: `deploy/gitops/base/kratos.yaml` / `hydra.yaml` — multi-source app (Helm repo chart + `$values` from git), sync-wave 3, ns `auth`, sync `retry` for the first-sync race against out-of-band secrets.
- Upstream chart: repo `https://openfga.github.io/helm-charts`, chart `openfga` — pin the exact current version (check the repo index at implementation time, like m1 pinned 0.62.1 for Ory).
- Datastore config: `datastore.engine: postgres`, DSN via env `OPENFGA_DATASTORE_URI` from an out-of-band Secret — extend `scripts/auth-secrets.sh` (composes DSNs from `<cluster>-app` credentials; add `openfga-db` → Secret `auth/openfga`). The chart supports `datastore.uriSecret`.
- The chart runs schema migrations via a hook/initContainer (`migrate.enabled`) — same automigration stance as Kratos/Hydra.
- AuthN for OpenFGA's own API: `authn.method: preshared`, key from the same out-of-band Secret (new `.env` key `OPENFGA_PRESHARED_KEY`, mirrored in `.env.example`/`.env.template`/`gh-secrets.sh` per the sync rule).

## Steps

1. Add `deploy/gitops/base/openfga.yaml` (multi-source Application, pinned version, retry) + `deploy/gitops/base/values/openfga.values.yaml`.
2. Extend `scripts/auth-secrets.sh` with the `auth/openfga` Secret (DSN + preshared key); add the `.env` key everywhere the sync rule demands.
3. Register in `base/kustomization.yaml`; local overlay values only if the base defaults don't fit CAPD (single replica, plain HTTP).
4. Mock cluster: apply secrets, install the chart the way the overlay renders it, pods Ready, `grpcurl`/HTTP health answering in-cluster.

## Files

- `deploy/gitops/base/openfga.yaml` (new)
- `deploy/gitops/base/values/openfga.values.yaml` (new)
- `deploy/gitops/base/kustomization.yaml`
- `scripts/auth-secrets.sh`, `.env.example`, `.env.template`, `scripts/gh-secrets.sh`

## Acceptance criteria

- [ ] `gitops-validate.sh` extended to render the openfga chart with the vendored values (it derives Ory charts from base Applications — follow that pattern) and passes.
- [ ] OpenFGA pods Ready on the mock cluster against `openfga-db`; API answers with the preshared key, 401 without.
- [ ] No Ingress anywhere for OpenFGA; no secret material in git.

## Out of scope

- The authorization model (t003); exposing the playground.
