# janua — Ecosystem Context > [!IMPORTANT] > Janua owns ecosystem identity: users, tenants, OAuth/OIDC clients, sessions, token signing keys, MFA/passkeys, SAML/SCIM metadata, webhooks, and migration exports. Treat identity data and auth-provider operations as sensitive and side-effectful; keep examples placeholder-only. This is the identity-data side-effect doctrine for ecosystem context. > [!IMPORTANT] > MADFAM-ENCLII-FIRST-LEGACY-RAW v1: This document contains legacy raw infrastructure command examples. > Routine production operations must use Enclii web, API, or CLI. Treat raw > `kubectl`, `helm`, SSH, provider CLI/API, `docker exec`, and direct container > access as platform bootstrap or documented break-glass only, and record any > missing Enclii adapter gap. > **Self-hosted OIDC/OAuth2 provider — the identity backbone for every MADFAM service.** This file is self-contained: a Claude session on a fresh machine can operate this service by reading only this one document. No external links are load-bearing — the MADFAM ecosystem map and the full enclii CLI reference are embedded below. --- ## 1. What this repo is Janua is MADFAM's Auth0 replacement: OIDC/OAuth 2.0 with RS256 JWTs, multi-tenant orgs, GitHub OAuth, and a JWKS endpoint every other service verifies tokens against. It's hard-wired into Enclii (switchyard-api auth), and every ecosystem service that needs an authenticated caller validates against `auth.madfam.io/.well-known/jwks.json`. **Pillar**: Identity / Auth **Type**: service **Status**: production **Registry product**: Janua (`janua`, live, front door janua.dev). ### Deployed services | Service | Public domain | Container port | | ------------- | --------------- | -------------- | | `janua-api` | auth.madfam.io | 8000 | | `janua-admin` | admin.janua.dev | — | | `janua-app` | app.janua.dev | — | | `janua-docs` | docs.janua.dev | — | | `janua-web` | janua.dev | — | **Kubernetes namespace**: `janua` **Cluster**: bare-metal k3s (see topology section below). ### Upstream dependencies (this repo consumes) - postgres (users, orgs, sessions, tokens) - redis (session store) - cloudflare (tunnel + DNS + SSL) - enclii (deploy target) ### Downstream consumers (this repo is consumed by) - enclii (switchyard-api, dispatch) — OIDC SSO - dhanam, karafiel, forgesight, tezca, fortuna, digifab-quoting, selva-office, pravara-mes, yantra4d, avala, phynd-crm, routecraft, symbiosis-hcm — all verify tokens via JWKS ### Key environment variables - `JANUA_DATABASE_URL` — Postgres connection. - `JANUA_REDIS_URL` / `REDIS_URL` — session and rate-limit store. - `JANUA_JWT_PRIVATE_KEY` / `JANUA_JWT_PUBLIC_KEY` — RS256 signing material. - `GITHUB_OAUTH_CLIENT_ID` / `GITHUB_OAUTH_CLIENT_SECRET` — GitHub identity federation. --- ## MADFAM Ecosystem Map Everything below is embedded here so this document stands alone. The product tables are rendered from the public projection of the MADFAM product registry (`madfam-org/solarpunk-foundry` → `packages/core/src/products/projection.public.json`, generated from the registry in `madfam-org/internal-devops`). To change a row, change the registry and re-render — never hand-edit a rendered copy. Estate counts (services, ArgoCD applications, namespaces) are deliberately not typed here: they move weekly. The dated figures live in the private operations record, `madfam-org/internal-devops` (`infrastructure/topology.md`). ### Products in the registry 32 customer-facing products, grouped by the registry's category and listed in registry order. `—` means the registry records no public front door yet. #### Infrastructure | Product | Repo | Front door | Lifecycle | Role | | ---------------- | ------------------------- | ---------- | ---------- | --------------------------------------------------------------------------------------- | | **Enclii** | `madfam-org/enclii` | enclii.dev | live | PaaS control plane — every deploy goes through it | | **Janua** | `madfam-org/janua` | janua.dev | live | OIDC/OAuth 2.0 identity provider — RS256 JWKS at `auth.madfam.io/.well-known/jwks.json` | | **Selva** | `madfam-org/selva-office` | selva.town | live | LLM inference gateway (OpenAI-compatible `/v1`) + agent orchestration | | **Fragua** | `madfam-org/enclii` | — | incubating | — | | **Enclii Depot** | `madfam-org/enclii` | — | incubating | — | #### Intelligence | Product | Repo | Front door | Lifecycle | Role | | -------------- | ----------------------- | ------------------ | ---------- | ------------------------------------------------------------------------- | | **Forgesight** | `madfam-org/forgesight` | forgesight.app | live | Digital-fabrication industry intelligence (pricing/vendor feed to Cotiza) | | **Dhanam** | `madfam-org/dhanam` | dhan.am | live | Billing, entitlements and payment gateways (Stripe, Mercado Pago, SPEI) | | **Fortuna** | `madfam-org/fortuna` | fortuna.tube | live | Problem intelligence / zeitgeist analysis | | **Rondelio** | `madfam-org/rondelio` | rondel.io | live | Games | | **Factlas** | `madfam-org/factlas` | factl.as | live | Geospatial facts | | **Tlacuilo** | `madfam-org/tlacuilo` | tlacuilo.madfam.io | beta | Document intelligence (OCR) | | **LexiDrop** | `madfam-org/lexidrop` | ld.madfam.io | incubating | — | #### Standards | Product | Repo | Front door | Lifecycle | Role | | ------------- | ---------------------- | ------------------ | ---------- | ------------------------------------------------------------------------- | | **Karafiel** | `madfam-org/karafiel` | karafiel.mx | live | Operational compliance — CFDI, NOM-151, e.firma; owns legal-ops templates | | **Tezca** | `madfam-org/tezca` | tezca.mx | live | Mexican law oracle (informational only — feeds Karafiel) | | **Avala** | `madfam-org/avala` | avala.studio | live | Learning and competency verification | | **Meridian** | `madfam-org/meridian` | meridian.madfam.io | degraded | — | | **geom-core** | `madfam-org/geom-core` | — | incubating | — | #### Applications | Product | Repo | Front door | Lifecycle | Role | | ------------------- | ---------------------------- | ---------------- | ---------- | --------------------------------------------------------------------- | | **Yantra4D** | `madfam-org/yantra4d` | yantra4d.com | live | Phygital fabrication | | **Cotiza** | `madfam-org/digifab-quoting` | cotiza.studio | live | Quoting engine (fabrication + services) | | **Pravara MES** | `madfam-org/pravara-mes` | mes.madfam.io | live | Fabrication routing and dispatch (physical jobs) | | **Voxa** | `madfam-org/voxa` | voxa.madfam.io | live | Assistive communication | | **PhyndCRM** | `madfam-org/phynd-crm` | phynd.app | live | CRM — consent, campaigns, attribution | | **CEQ** | `madfam-org/ceq` | ceq.lol | degraded | Generative asset pipeline — ComfyUI wrapper behind `/v1/render` | | **Acervo** | `madfam-org/acervo` | acervo.madfam.io | live | Records engine | | **Kalya** | `madfam-org/kalya` | kalya.app | live | Booking and scheduling | | **Symbiosis HCM** | `madfam-org/symbiosis-hcm` | hcm.madfam.io | live | Human capital management — Mexican payroll | | **Nauta** | `madfam-org/nauta` | nauta.quest | live | Fractional CTO practice — staff cockpit and per-client ERP workspaces | | **Fashion Cabinet** | `madfam-org/fashion-cabinet` | fashioncabi.net | live | Parametric fashion | | **Periplo** | `madfam-org/periplo` | — | incubating | — | | **RouteCraft** | `madfam-org/routecraft` | routecraft.app | live | Trip planning | | **Telesia** | `madfam-org/telesia` | telesia.quest | incubating | Completion | | **Marca** | `madfam-org/marca` | madf.am | incubating | — | ### Retired products — never present as live | Product | Retired on | Successor | Redirect | | ------- | ---------- | --------- | -------- | | PENNY | 2026-07-25 | Selva | none | | Sim4D | 2026-08-30 | Yantra4D | none | | SPARK | 2026-04-08 | — | none | ### Cross-repo conventions - **Auth**: every authenticated service verifies Janua JWTs via JWKS at `https://auth.madfam.io/.well-known/jwks.json`. RS256 only — HS256 is banned on any path that verifies a Janua token (audit 2026-04-23 H3/H4); an app's own session cookie needs its own secret. - **Billing**: credit metering + entitlements flow through Dhanam. See `madfam-org/dhanam` for the meter/entitlement/invoice APIs. - **Inference**: every LLM call should route through Selva (`selva-office`) at `/v1` (OpenAI-compatible). Do not talk directly to OpenAI / Anthropic from service code. - **Agent SaaS tools**: end-user delegated tool calls (Slack, Gmail, etc.) route through Coupler (`madfam-org/coupler`, the Agent Tool Plane), not the Enclii Provider Hub. Operator infra actions stay on Enclii `providers.*` / `ops.*` (proxied as `madfam.ops.*` from Coupler for admin agents only). - **Third-party messages**: email/SMS/chat to people outside MADFAM go out through Angelia Courier (`madfam-org/angelia`). Carve-outs: Janua's customer-configured alert notifier and Selva agent tools. - **CORS**: explicit allowlist per service. Wildcards are banned (audit 2026-04-23 H2/H5/H6). - **Images**: `@sha256:`-pinned in every manifest; mutable tags such as `:latest` are a Kyverno policy violation. - **Onboarding**: `enclii onboard` (`POST /v1/admin/onboard` on switchyard-api) creates namespace, ArgoCD app, Cloudflare tunnel routes, Janua client, and NetworkPolicies in one shot. See `enclii/docs/guides/ONBOARDING_GUIDE.md`. ### Production topology Bare-metal k3s (v1.33+), 4 nodes, described by ROLE only. This file is generated and copied into public repos, so it never carries node hostnames, IP addresses or hardware SKUs (2026-07-16 exposure class 1). Node identity lives only in `madfam-org/internal-devops`. - control-plane node — control plane + primary workload - worker node — workloads + Longhorn second replica - two builder nodes (labelled `role=builder`, tainted `builder=true:NoSchedule`) — ARC runners only **Ingress**: Cloudflare Tunnel → cloudflared pods → K8s ClusterIP → container port. Zero exposed node ports. TLS terminated at Cloudflare edge. **Storage**: Longhorn CSI in 2-replica mode across the control-plane and worker nodes. Object storage: Cloudflare R2 (zero egress). **GitOps**: ArgoCD App-of-Apps with self-heal. Push to `main` → CI builds → GHCR → `kustomize edit set image` commits the digest → ArgoCD syncs → Switchyard tracks lifecycle events. **Operational access** (SSH, kubeconfigs, node identity, estate counts, cost ledger): private repo `madfam-org/internal-devops`. Not in any public repo. Policy: the repo-boundary contract, `internal-devops/docs/repo-boundary-contract.md`. --- ## Enclii CLI — DevOps Reference **Strong preference: use `enclii` over `kubectl`** for all operational tasks. The CLI routes through Switchyard API, which gives you audit logging, lifecycle event tracking, and service-scoped context. Escape to kubectl only for the gaps listed at the end of this section. ### Install GitHub Releases are the verified binary channel (Linux, macOS and Windows archives with checksums): `https://github.com/madfam-org/enclii/releases`. Homebrew, Scoop and `get.enclii.dev` are convenience targets, not yet monitored. ```bash # From source (any OS with Go) git clone https://github.com/madfam-org/enclii.git cd enclii && make build-cli && ./bin/enclii --version ``` ### Auth ```bash enclii login # browser SSO (Janua) enclii whoami # verify active session enclii logout # clear local creds ``` Global flags: `--api-endpoint` (or `ENCLII_API_ENDPOINT`, default `https://api.enclii.dev`) and `--api-token` (or `ENCLII_API_TOKEN`; legacy `ENCLII_TOKEN` is still read) for non-interactive use. Set `ENCLII_PROJECT=` (or pass `--project`) when a command has to resolve a service name. ### Day-to-day for janua-api The commands below default to `janua-api` — the primary service name for this repo as registered in Switchyard. For any other service in the ecosystem, swap the name. Environments are `dev`, `staging` and `prod`; most commands default to `dev`, so pass `--env prod` for production. ```bash # Status enclii ps --env prod # Logs enclii logs janua-api --env prod -f # live tail enclii logs janua-api --env prod --since 1h -n 200 # last hour # Deploy (reads service.yaml) enclii deploy --env staging --wait enclii deploy --env prod --canary 10% --change-ticket # Rollback enclii rollback janua-api --env prod # previous release enclii rollback janua-api v42 --env prod # Releases + deployment history enclii releases janua-api -n 20 enclii deployments list # Secrets (routed through Lockbox → Vault → ESO → K8s) enclii secrets list --env prod enclii secrets set MY_KEY=value --secret --env prod # Chat-safe operator intake (values never pass through agent chat) enclii secrets intake submit --reason "" --stdin enclii secrets intake status # Domains, tunnel routes, DNS enclii domains list --service janua-api enclii domains add my.example.com --service janua-api # auto-provisions tunnel route + DNS # Scheduled jobs, routing, serverless enclii jobs list --project enclii junctions list --project enclii functions list # Observability enclii observe health --service # Local dev environment enclii local up # spin up dependent services (postgres, redis, …) enclii local logs enclii local down ``` ### Full onboarding (only used when adding a brand-new service) ```bash # One-shot: namespace + ArgoCD app + tunnel routes + Janua client + netpol enclii onboard --repo madfam-org/ --db-name --secrets-file .env ``` ### Enclii-first production operations Enclii is the required control plane for routine production operations. Use the web UI, API, or CLI before reaching for raw infrastructure tools: - ArgoCD sync / diff / rollback — `enclii ops apps ...` - Pod logs, diagnosis, and safe restarts — `enclii ops pods ...` - Longhorn / PVC / PV inspection and repair planning — `enclii ops storage ...` - Kyverno violations and time-bound waivers — `enclii ops policy ...` - ExternalSecrets and Vault readiness — `enclii ops secrets ...` - ARC runner inspection and drain workflows — `enclii ops runners ...` - DNS, tunnels, SaaS hostnames, providers, and repo automation — `enclii providers ...` - Service lifecycle, domains, secrets, jobs, and observability — `enclii deploy`, `enclii rollback`, `enclii logs`, `enclii observe`, `enclii domains`, `enclii secrets`, `enclii jobs` ### Break-glass-only access Raw `kubectl`, `helm`, SSH, provider CLIs/APIs, `docker exec`, and direct container access are allowed only for platform bootstrap or documented break-glass emergencies when Enclii is unavailable or lacks an implemented adapter. Record the actor, reason, target service/environment, commands executed, result, and follow-up Enclii adapter gap or incident link. ### Cluster access kubeconfig + SSH keys live in `madfam-org/internal-devops` (private repo) for bootstrap and break-glass use only. Routine production operations must go through Enclii web, API, or CLI. ### Exit codes (scripting against the CLI) | Code | Meaning | | ---- | ---------------- | | 0 | success | | 10 | validation error | | 20 | build failed | | 30 | deploy failed | | 40 | timeout | | 50 | auth error | --- ## Document provenance Rendered by `madfam-org/enclii/docs/templates/ecosystem/generator.py` from this repo's metadata entry (plus any private overlay kept in this repo) and the public product-registry projection. First generated 2026-04-23 for the "each repo stands alone" docs sweep. Do not hand-edit this file: change the metadata, overlay or registry and re-render. `generator.py --check ` fails when this file differs from what the generator would write.