Public: anyone can read this; nobody can change it.
wiki: the three app tiers (anon, user, admin) and public apps #222
Check · Review · Land · Live — No review yet.
docs-app-roles → main 1 commit
A guest
This pull comes from a guest: its preview runs without the app's variables or a forge token until a person who can write here approves it.
This pull waits for a person who can write here to review it; it never lands on its own.
2 files
changed +16
−0
wiki/Security-Model.md +4
| @@ -49,3 +49,7 @@ Every app namespace is fenced independently of CI. `pod-security.kubernetes.io/e | ||
| 49 | 49 | ## Privacy defaults |
| 50 | 50 | |
| 51 | 51 | New repos and orgs are **private by default** (`DEFAULT_PRIVATE: private`, `DEFAULT_ORG_VISIBILITY: private`). `DEFAULT_ORG_MEMBER_VISIBLE: false` closes org and org-package enumeration. The bulk users page is disabled. Anonymous browsing shows only the public seed repos. Where registration is open, it uses a sovereign image CAPTCHA — no third-party service — and internal accounts only. A new member signs in and sees exactly their own orgs, nothing else. Roles and teams are covered in [](Users-Teams-and-Access). |
| 52 | ||
| 53 | ## Public apps | |
| 54 | ||
| 55 | An app is private by default: the edge signs every visitor in before the app is reached. An org can declare one app **public** (`apps/<app>/app.yaml`, `public: true`) so anonymous readers — link crawlers included — reach it. From then on the app's own door is the boundary: the template refuses every anonymous `/api` and `/openapi` request with one 401 before anything else can answer, keeps an explicit registry of anonymous reads, walks every route as a stranger in its tests, and adds a Content-Security-Policy, same-origin-only mutations and an anonymous rate limit. A signed-in stranger becomes a **user**; only Forgejo owners (or `PLAT_ADMIN_TEAMS`) are **admins**. Custom domains (`add_domain` → `verify_domain` → `set_app_domain`) get the same edge session through a host-bound handoff, so the shared login works on `shop.example` as it does on `*.__DOMAIN__`. |
wiki/Users-Teams-and-Access.md +12
| @@ -81,3 +81,15 @@ The platform derives each registry-bot password on demand and stores none. Agent | ||
| 81 | 81 | The platform is private-first. A new member sees their own orgs and repos, the public seed repos on `/explore`, and nothing else. Every org and app repo is born private (`DEFAULT_ORG_VISIBILITY=private`, `DEFAULT_PRIVATE=private`). Other tenants' work stays invisible unless a team or collaborator grant says otherwise. |
| 82 | 82 | |
| 83 | 83 | The first stop after sign-up is [](Build-Your-First-App). For app credentials, [](Secrets-and-Config) shows the self-serve channel. Secrets go in repo settings, never in issues or comments. |
| 84 | ||
| 85 | ## Inside an app: anon, user, admin | |
| 86 | ||
| 87 | Every app born from the template answers "who is asking?" with one of three tiers — decided in Forgejo, carried by the edge, never by a list of names in app code: | |
| 88 | ||
| 89 | | Tier | Who | How they get it | | |
| 90 | | --- | --- | --- | | |
| 91 | | **anon** | No identity. | Only reaches the app when the org declares it public — `apps/<app>/app.yaml` in the org's ground with `public: true` — so link previews work. Every `/api` route still answers a stranger 401 unless the app lists that exact read as public. | | |
| 92 | | **user** | A verified Forgejo identity. | Private app: anyone Forgejo lets read the repo (collaborator, team, org member). Public app: anyone who signs in. | | |
| 93 | | **admin** | A Forgejo **owner**. | Org owners on every org repo; a repo's own admins on that repo. To make an org **team** admins of one app, set `PLAT_ADMIN_TEAMS=<team>,<team>` in that app's secrets — membership then lives in Forgejo. | | |
| 94 | ||
| 95 | Granting access is therefore a Forgejo action: add someone to a team or a repo (user), make them a repo admin or an org owner (admin). Sign-in on a public app goes through the edge's `/_plat/login` on the app's own host; sign-out through `/_plat/logout`. The app's own wiki has a **Roles and Access** page with the guards and the door. |