> ## Documentation Index
> Fetch the complete documentation index at: https://docs.neobank.proofof.tech/llms.txt
> Use this file to discover all available pages before exploring further.

# Kubernetes deployment

> Configure the Helm chart for the production live adapter and its required services and secrets.

# Deploy the live adapter on Kubernetes

The Helm chart defaults to `config.perfloAdapter: live` and renders the five reviewed provider origins into the API, worker, and scheduler ConfigMaps. Production validation still enforces PostgreSQL, Redis, HTTPS Vault, Auth0, metrics authentication, HTTPS application origins, and disabled debug authentication.

## Configure public values

Set the application origins and network-policy namespaces:

```yaml theme={null}
config:
  appName: Example Neobank
  appNameAr: ""
  appMark: "N"
  perfloAdapter: live
  publicOrigin: https://neobank.example
  apiOrigin: https://neobank.example
  auth0Domain: auth.neobank.example
  auth0Audience: https://neobank.example
  auth0ClaimNamespace: https://neobank.example/claims
  problemTypeBase: https://neobank.example/problems
  vaultAddr: https://vault.vault.svc.cluster.local:8200
  vaultCaKey: ca.crt
  vaultCaPath: /etc/neobank/vault/ca.pem
  trustedProxyIps: 10.244.0.0/16 # replace with the ingress controller pod source CIDR
networkPolicy:
  ingressNamespace: ingress-nginx
  metricsNamespace: monitoring
  databaseNamespace: neobank-data
  sessionRedisNamespace: neobank-sessions
  taskRedisNamespace: neobank-tasks
  vaultNamespace: vault
existingSecrets:
  api: neobank-api-secrets-v1
  worker: neobank-worker-secrets-v1
  scheduler: neobank-scheduler-secrets-v1
  migration: neobank-migration-secrets-v1
  vaultCa: neobank-vault-ca-v1
ingress:
  webHost: neobank.example
  apiHost: api.neobank.example
```

Do not override the Perflo origins unless this repository has reviewed and pinned a contract change.
`config.publicOrigin`, `config.apiOrigin`, and `https://ingress.webHost` must be identical so the Auth0 callback and the SPA's same-origin `/v1` requests share the `__Host-` customer session cookie. `ingress.apiHost` remains a separate bearer-authenticated API host for agents and server integrations.
`config.trustedProxyIps` must be the narrow source address or CIDR used by the ingress
controller pods when connecting to the API. The chart rejects an empty value, while runtime
validation rejects wildcard and default-route trust. Keep `networkPolicy.ingressNamespace`
aligned with that ingress boundary. `networkPolicy.metricsNamespace` is the only non-ingress
namespace allowed to reach API port 8000; the metrics endpoint still requires its bearer token.

## Create workload secrets

Create the workload Secrets named by `existingSecrets.*` with these exact keys:

| Secret    | Required keys                                                                                                                                                                                                           |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| API       | `NEOBANK_DATABASE_URL`, `NEOBANK_REDIS_URL`, `NEOBANK_VAULT_TOKEN`, `NEOBANK_AUTH0_CLIENT_ID`, `NEOBANK_AUTH0_CLIENT_SECRET`, `NEOBANK_AUTH0_OPS_CLIENT_ID`, `NEOBANK_AUTH0_OPS_CLIENT_SECRET`, `NEOBANK_METRICS_TOKEN` |
| Worker    | `NEOBANK_DATABASE_URL`, `NEOBANK_TASK_QUEUE_URL`, `NEOBANK_VAULT_TOKEN`                                                                                                                                                 |
| Scheduler | `NEOBANK_TASK_QUEUE_URL`                                                                                                                                                                                                |
| Migration | `NEOBANK_DATABASE_URL`                                                                                                                                                                                                  |

The API session Redis and Celery task Redis must be separate instances or distinct Redis ACL
users that cannot access each other's keys. Database-number separation on one unrestricted
Redis identity is not an authorization boundary. Put the Vault CA bundle in the
`existingSecrets.vaultCa` Secret under `config.vaultCaKey`; the chart mounts it only into
the API and worker. The scheduler publishes tasks but receives no session, database, Vault,
Auth0, or metrics credential. Workers dispatch provider writes and perform reconciliation.

The chart checksums its ConfigMap into every consuming pod template, so identity and public
configuration changes trigger a rollout. Treat every external Secret name as versioned and
immutable. To rotate credentials or the Vault CA, create the next Secret version and update the
corresponding `existingSecrets.*` value; changing the referenced name triggers the workload
rollout. Do not replace data under an existing Secret name because Kubernetes does not restart
pods that consume it through `envFrom`.

The chart's default-deny policies assume in-cluster services on the standard ports in the
configured namespaces. Managed services outside the cluster need caller-supplied egress
NetworkPolicies restricted to their exact address ranges and ports; the chart deliberately
does not add broad external database, Redis, or Vault egress.

## Migrate the database

The migration job runs `alembic upgrade head` before the workloads and upgrades an existing database in place. The chart never deletes data, and every workload refuses to start against a stale schema revision.

## Validate the chart

Run:

```bash theme={null}
helm lint deploy/helm/neobank
helm template neobank deploy/helm/neobank
```

Then run the controlled live canary and complete security, load, backup, restore, deployment, CI, and independent review evidence before production traffic.
