---
id: w1/m2/t007
title: GitOps-deploy the control plane + end-to-end acceptance
worker: worker1
status: done
estimate: 30m
depends_on: [w1/m2/t002, w1/m2/t005, w1/m2/t006]
---

## Objective

Ship the service via GitOps and prove the whole chain works.

## Context

- Mirror `deploy/gitops/base/bex.yaml` (in-repo path, SSH deploy key) for the control-plane Deployment; register in `base/kustomization.yaml`.

## Steps

1. Add an Argo Application for the control-plane service.
2. Run the acceptance flow end-to-end.

## Files

- `deploy/gitops/base/` (control-plane Argo app + kustomization entry)

## Acceptance criteria

- [x] Create a tenant + app via the API → an `App` CR appears → the operator deploys it → `status.url` flows back. _Met 2026-07-09:_ ran live as `scripts/auth-tenant-e2e.sh` (w1/m9/t004) — signup → tenant mint → app create via the internal API → projector-created App CRs → workspace-scoped key sees only its own service (cross-tenant 403, unauth 401); prod `BEX_CP_DB_URI` on in `lego/operator/config/api/deployment.yaml` since w1/m9. The "flows back onto the row" leg was superseded by the committed design: bex-api reads observed phase/url from the CR (`internal/store/reconciler.go`), never copying status into Postgres.

## Out of scope

- Auth/billing/UI polish.
