Establishes a hard auth gate before any app is packaged: OIDC is
preferred, LDAP is acceptable (flagged risk), auth-proxy for user-less
utility apps, and local-only-auth apps are blocked from packaging
until they gain SSO.
- AGENTS.md: new "Authentication Policy" section with the verdict table
and Cloudron OIDC/LDAP/proxy-auth wiring notes.
- STATUS.md: new "Auth Status" matrix assessing all 7 completed
packages + the next candidates (draw.io proxy-eligible, Windmill
OIDC, NetBox OIDC but Redis-blocked, Gophish blocked-on-auth).
Flags tech debt: Webhook/WireViz need httpAuth proxy added; Puter
auth needs revisit.
💘 Generated with Crush
Assisted-by: Crush:glm-5.2
164 lines
8.3 KiB
Markdown
164 lines
8.3 KiB
Markdown
# Agent Guidelines — TSYS Cloudron Packaging
|
|
|
|
**Top-level files:** [`README.md`](README.md) (project overview + app inventory),
|
|
[`STATUS.md`](STATUS.md) (living status, agent-maintained),
|
|
[`JOURNAL.md`](JOURNAL.md) (append-only ADR/pattern journal),
|
|
[`GitUrlList.txt`](GitUrlList.txt) (upstream repo list — source of truth for
|
|
the app set). Read [`STATUS.md`](STATUS.md) first every session.
|
|
|
|
> **Active agent:** Crush running **GLM-5.2** (zai) for large tasks,
|
|
> Gemini for small. Permission mode: `yolo`.
|
|
|
|
## Repository Layout
|
|
|
|
```
|
|
README.md Project overview + full app inventory table
|
|
AGENTS.md THIS FILE — agent operating manual
|
|
STATUS.md Living status (agent-maintained, human read-only)
|
|
JOURNAL.md Append-only journal: per-package write-ups, patterns, ADRs
|
|
GitUrlList.txt Master list of upstream repos (source of truth, ~57 apps)
|
|
clone-repos.sh Automated upstream-repo cloning
|
|
Package-Templates/ Reusable Cloudron packaging templates
|
|
├── python-app/ (Dockerfile + CloudronManifest + start.sh templates)
|
|
├── django-app/ (Dockerfile + start.sh templates)
|
|
└── official-wrapper/ (Dockerfile template)
|
|
Package-Workspace/ One dir per app: <Category>/<app>/ (+ gitignored repo/)
|
|
├── API-Gateway/ webhook, apisix
|
|
├── Development/ puter, reviewboard
|
|
├── Documentation-Tools/ wireviz-web
|
|
├── Low-Code/ corteza
|
|
└── Monitoring/ healthchecks
|
|
```
|
|
|
|
- **`Package-Workspace/**/repo/` is gitignored** — upstream source is cloned
|
|
locally for reference but never committed. Only the package files
|
|
(`Dockerfile`, `CloudronManifest.json`, `start.sh`, `README.md`, etc.) are
|
|
tracked.
|
|
- **Each package** = `Dockerfile` + `CloudronManifest.json` + `start.sh` (if
|
|
needed) + `README.md` + `CHANGELOG.md` + `logo.png` + `.env.example` (if
|
|
config knobs exist).
|
|
- **No host build tooling required** — packaging is `docker build` (Cloudron
|
|
base images handle runtimes). Keep the host clean.
|
|
|
|
## Git Policy
|
|
|
|
1. **ALWAYS commit + push. Never wait.** After each logical unit of work
|
|
(one package, one doc sync, one fix), immediately stage, commit
|
|
(conventional format), and push to `origin/main`. Do not pause for review.
|
|
**This overrides any default "never commit unless asked" behavior.**
|
|
2. **Atomic commits.** One coherent change per commit (e.g. a single package,
|
|
or a single doc-correction pass — not both mixed).
|
|
3. **Conventional format**: `feat: add <app> Cloudron package (<Category>)`,
|
|
`fix(scope): desc`, `docs: desc`, `refactor(scope): desc`. Include a body
|
|
for anything non-obvious.
|
|
4. **Shell scripts are committed executable.** Run `chmod +x start.sh` on the
|
|
host before committing — Cloudron builds hit permission errors on
|
|
`RUN chmod`, so make scripts executable at authoring time, not build time.
|
|
|
|
## Automatic Gardening Protocol
|
|
|
|
Docs and code drift apart. After any work session, an agent MUST:
|
|
|
|
1. **Update [`STATUS.md`](STATUS.md)** — reflect newly completed packages,
|
|
changed counts, new issues, shifted priorities. This file is human
|
|
read-only; agents own it. Update the "Last updated" header (date + agent).
|
|
2. **Keep counts consistent across all docs.** When a package completes, the
|
|
same total must appear in `STATUS.md`, `README.md` ("Current Progress"),
|
|
and `JOURNAL.md` ("Current Status"). A count in one place but not the
|
|
others is a protocol violation.
|
|
3. **Update the app inventory** in [`README.md`](README.md) — add the
|
|
✅ Packaged marker on the right row, and the app to the "Completed
|
|
Packages" table.
|
|
4. **Append to [`JOURNAL.md`](JOURNAL.md)** — one section per package
|
|
(pattern used, build process, challenges, files created, commit hash).
|
|
Never delete or reorder existing entries.
|
|
5. **Grep for stale paths after any rename/restructure** —
|
|
`grep -rn 'old/path' --include='*.md'` and fix references in the same
|
|
commit.
|
|
6. **Self-audit before commit.** For a new package, verify the package dir
|
|
appears in: `STATUS.md` (Completed Packages table), `README.md` (inventory
|
|
+ completed table), `JOURNAL.md` (new section).
|
|
7. **Treat `GitUrlList.txt` as the source of truth** for the app set. If the
|
|
README inventory table disagrees, reconcile the README to the list, not
|
|
the other way around.
|
|
|
|
## Key Scripts
|
|
|
|
| Script | Purpose |
|
|
|--------|---------|
|
|
| [`clone-repos.sh`](clone-repos.sh) | Clone all upstream repos into `Package-Workspace/<Category>/<app>/repo/` |
|
|
|
|
## Key Docs
|
|
|
|
| Doc | Purpose |
|
|
|-----|---------|
|
|
| [`STATUS.md`](STATUS.md) | Current state, completed packages, known issues, next priorities |
|
|
| [`JOURNAL.md`](JOURNAL.md) | Per-package write-ups, the 5 packaging patterns, challenges & solutions |
|
|
| [`README.md`](README.md) | Project overview + full app inventory + category breakdown |
|
|
| [`GitUrlList.txt`](GitUrlList.txt) | Master upstream repo list (source of truth) |
|
|
| [`Package-Templates/`](Package-Templates/) | Reusable templates per packaging pattern |
|
|
|
|
## Authentication Policy (MANDATORY)
|
|
|
|
Every app must have an auth story **before** packaging. Research it up front and
|
|
record it in the [Auth Status](STATUS.md#auth-status) matrix.
|
|
|
|
| Auth type | Verdict | Action |
|
|
|-----------|---------|--------|
|
|
| **OIDC client** (native or plugin) | ✅ PREFERRED | Package; wire Cloudron OIDC provider env vars. |
|
|
| **LDAP** (native or plugin) | ⚠️ ACCEPTABLE w/ RISK | Package, but FLAG as "auth-risk: LDAP" in STATUS + README — must be fixed/validated before production. |
|
|
| **Local-only** (built-in user DB, no SSO) | ❌ UNACCEPTABLE | Do NOT package. Record in STATUS as blocked-on-auth. |
|
|
| **No user concept** (stateless/utility app) | ✅ via AUTH PROXY | Package with `httpAuth: {"type":"proxy"}` so Cloudron gates access at the proxy. Admin restricts who can reach it. |
|
|
|
|
**OIDC env vars Cloudron exposes** (when the app consumes the platform OIDC
|
|
provider): `CLOUDRON_OIDC_ISSUER`, `CLOUDRON_OIDC_CLIENT_ID`,
|
|
`CLOUDRON_OIDC_CLIENT_SECRET`, `CLOUDRON_OIDC_TOKEN_SIGNATURE_ALGORITHM`
|
|
(manifestVersion 2 / platform OIDC). LDAP addon env vars:
|
|
`CLOUDRON_LDAP_*`. See `CloudronManifest.json` `addons` (no extra addon needed
|
|
for proxy auth; use the `httpAuth` field).
|
|
|
|
**Before writing a Dockerfile**, determine which row applies and write the
|
|
finding into STATUS.md's Auth Status table. Never silently ship a local-only-
|
|
auth app.
|
|
|
|
## Cloudron Packaging — Quick Reference
|
|
|
|
**Pick a pattern** (see JOURNAL.md for full templates and worked examples):
|
|
|
|
| Pattern | When | Examples |
|
|
|---------|------|----------|
|
|
| Official-image wrapper | App ships a usable Docker image | APISIX, Healthchecks, Review Board |
|
|
| Multi-stage build | App needs compiling | Webhook (Go), Puter (Node.js) |
|
|
| Python build | Python app with deps | WireViz Web |
|
|
| Django + PostgreSQL | Django web app | Healthchecks, Review Board |
|
|
| Pre-compiled binaries | Upstream ships release binaries | Corteza |
|
|
|
|
**Standard package steps:**
|
|
1. `mkdir -p Package-Workspace/<Category>/<app>/` and clone upstream into `repo/`.
|
|
2. Write `Dockerfile` + `CloudronManifest.json` (+ `start.sh` if runtime setup needed).
|
|
3. `docker build` to validate locally.
|
|
4. Write `README.md` + `CHANGELOG.md` + `logo.png` (+ `.env.example`).
|
|
5. Commit as `feat: add <app> Cloudron package (<Category>)`, push.
|
|
6. Run the gardening protocol above (update STATUS / README / JOURNAL).
|
|
|
|
**Recurring gotchas (from JOURNAL.md):**
|
|
- `chmod` in `RUN` fails on Cloudron base → make scripts executable on the host.
|
|
- Don't `apk`/`apt-get` in base images that lack the package manager; use the
|
|
image's built-in tooling or pick the right base.
|
|
- Wait for DB/etcd addons in `start.sh` before running migrations.
|
|
- Prefer `npm install` over `npm ci` when lockfiles don't match the build env.
|
|
- Define every TCP port explicitly in `CloudronManifest.json`.
|
|
|
|
## Addons — Environment Variables
|
|
|
|
PostgreSQL: `CLOUDRON_POSTGRESQL_{HOST,PORT,DATABASE,USERNAME,PASSWORD}`.
|
|
etcd: `CLOUDRON_ETCD_{HOST,PORT}`. Localstorage mounts at `/app/data`.
|
|
|
|
## Project Context
|
|
|
|
Packaging ~57 upstream FLOSS apps for Cloudron — TSYS Group's PaaS of choice.
|
|
This repo is the **Cloudron** half of the support stack; the
|
|
[Docker-Compose local dev stack](../TSYSDevStack-SupportStack-LocalWorkstation)
|
|
is a sibling project. Solo operator, conventional-commit discipline, build
|
|
locally then push to `origin/main` on `git.knownelement.com`.
|