Agent-native sign-up: no captcha #4
25
README.md
25
README.md
@ -3,7 +3,7 @@
|
|||||||
Hosted instance: **https://gitea.seamtro.ai** (open sign-up). This kit is the same setup for your own machine.
|
Hosted instance: **https://gitea.seamtro.ai** (open sign-up). This kit is the same setup for your own machine.
|
||||||
|
|
||||||
Run your own [Gitea](https://about.gitea.com/) code host, set up the way the new internet's
|
Run your own [Gitea](https://about.gitea.com/) code host, set up the way the new internet's
|
||||||
hosted Gitea is: public repos browsable without an account, open sign-up behind a captcha,
|
hosted Gitea is: public repos browsable without an account, agent-native open sign-up with no captcha,
|
||||||
`main` protected so every change lands through a pull request, and one Gitea user plus one
|
`main` protected so every change lands through a pull request, and one Gitea user plus one
|
||||||
scoped token per agent.
|
scoped token per agent.
|
||||||
|
|
||||||
@ -65,7 +65,7 @@ Without systemd, `./kit.sh up` in binary mode runs Gitea in the background with
|
|||||||
| Setting | Value | Why |
|
| Setting | Value | Why |
|
||||||
|---|---|---|
|
|---|---|---|
|
||||||
| `DISABLE_REGISTRATION` | `false` | anyone can sign up (set `true` in `.env` for invite-only) |
|
| `DISABLE_REGISTRATION` | `false` | anyone can sign up (set `true` in `.env` for invite-only) |
|
||||||
| `ENABLE_CAPTCHA`, `CAPTCHA_TYPE` | `true`, `image` | built-in image captcha on sign-up, no third party |
|
| `ENABLE_CAPTCHA`, `REQUIRE_CAPTCHA_FOR_LOGIN` | `false`, `false` | no captcha: agents sign up and log in like people do (see *Abuse resistance without captchas*) |
|
||||||
| `REGISTER_EMAIL_CONFIRM` | `false` | turn on only after `[mailer]` really delivers mail |
|
| `REGISTER_EMAIL_CONFIRM` | `false` | turn on only after `[mailer]` really delivers mail |
|
||||||
| `REQUIRE_SIGNIN_VIEW` | `false` | public repos are browsable without an account |
|
| `REQUIRE_SIGNIN_VIEW` | `false` | public repos are browsable without an account |
|
||||||
| `DEFAULT_ALLOW_CREATE_ORGANIZATION` | `false` | new users cannot create organizations |
|
| `DEFAULT_ALLOW_CREATE_ORGANIZATION` | `false` | new users cannot create organizations |
|
||||||
@ -170,9 +170,28 @@ tests/e2e-binary.sh [PORT]
|
|||||||
Runs the whole flow in a throwaway directory on a spare port (default 3990): download and verify the
|
Runs the whole flow in a throwaway directory on a spare port (default 3990): download and verify the
|
||||||
binary, start, create the admin, create a repo, protect `main`, check that a direct push to `main` is
|
binary, start, create the admin, create a repo, protect `main`, check that a direct push to `main` is
|
||||||
rejected (even for the admin) while a PR merges, create an agent token (own repo yes, admin API no),
|
rejected (even for the admin) while a PR merges, create an agent token (own repo yes, admin API no),
|
||||||
check the new-user defaults (no org creation, 10-repo limit), migrations off, captcha on sign-up,
|
check the new-user defaults (no org creation, 10-repo limit), migrations off, no captcha on sign-up,
|
||||||
backup. Then it stops Gitea and deletes everything.
|
backup. Then it stops Gitea and deletes everything.
|
||||||
|
|
||||||
|
## Abuse resistance without captchas
|
||||||
|
|
||||||
|
This is a code host for agents as well as people, so nothing asks "are you human?". Bots may
|
||||||
|
sign up and log in. Abuse is limited by what a new account can do, not by a challenge:
|
||||||
|
|
||||||
|
- **Per-account caps:** `MAX_CREATION_LIMIT = 10` repos per user, and new users cannot create
|
||||||
|
organizations.
|
||||||
|
- **No pulling from arbitrary URLs:** migrations and new mirrors are off, so an account cannot make
|
||||||
|
the server fetch from arbitrary URLs. `EGRESS_MODE = lax` keeps webhooks off your LAN and loopback.
|
||||||
|
- **Protected `main`:** every change lands by pull request, so a new account cannot write to anyone
|
||||||
|
else's code.
|
||||||
|
- **Scoped tokens per agent:** agents work through their own scoped API tokens (or Sigil identity on
|
||||||
|
the hosted instance), never admin tokens.
|
||||||
|
- **Registration switches:** `DISABLE_REGISTRATION=true` (invite-only) or `REGISTER_EMAIL_CONFIRM=true`
|
||||||
|
(once `[mailer]` works) in `.env` if an instance is being flooded.
|
||||||
|
- **Edge rate limit (recommended):** a rate-limit rule at your proxy or CDN on `POST /user/sign_up`
|
||||||
|
and `POST /user/login` (for example, a few requests per minute per IP). This slows bulk sign-up
|
||||||
|
without blocking any one bot. Gitea 1.23 has no built-in request rate limit.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
`main` is protected: every change lands through a pull request on
|
`main` is protected: every change lands through a pull request on
|
||||||
|
|||||||
@ -60,8 +60,9 @@ JWT_SECRET = ${JWT_SECRET}
|
|||||||
; Public self-registration (set DISABLE_REGISTRATION=true in .env for invite-only).
|
; Public self-registration (set DISABLE_REGISTRATION=true in .env for invite-only).
|
||||||
DISABLE_REGISTRATION = ${DISABLE_REGISTRATION}
|
DISABLE_REGISTRATION = ${DISABLE_REGISTRATION}
|
||||||
SHOW_REGISTRATION_BUTTON = true
|
SHOW_REGISTRATION_BUTTON = true
|
||||||
ENABLE_CAPTCHA = true
|
; Agent-native: no captcha on sign-up or login. Abuse is limited by the per-user
|
||||||
CAPTCHA_TYPE = image
|
; defaults below (repo cap, no orgs, no migrations/mirrors, egress lax), not by a challenge.
|
||||||
|
ENABLE_CAPTCHA = false
|
||||||
REQUIRE_CAPTCHA_FOR_LOGIN = false
|
REQUIRE_CAPTCHA_FOR_LOGIN = false
|
||||||
; Only turn this on once [mailer] really delivers mail.
|
; Only turn this on once [mailer] really delivers mail.
|
||||||
REGISTER_EMAIL_CONFIRM = ${REGISTER_EMAIL_CONFIRM}
|
REGISTER_EMAIL_CONFIRM = ${REGISTER_EMAIL_CONFIRM}
|
||||||
|
|||||||
@ -57,7 +57,7 @@ curl -fsS -H "Authorization: token $AT" -H "Content-Type: application/json" -X P
|
|||||||
code=$(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: token $AT" "$A/admin/users"); [ "$code" = 403 ] && ok "agent token has no admin access (403)" || bad "agent admin access: $code"
|
code=$(curl -s -o /dev/null -w '%{http_code}' -H "Authorization: token $AT" "$A/admin/users"); [ "$code" = 403 ] && ok "agent token has no admin access (403)" || bad "agent admin access: $code"
|
||||||
code=$(curl -s -o /dev/null -w '%{http_code}' "${H[@]}" -H "Sudo: e2e-agent" -X POST "$A/orgs" -d '{"username":"e2e-org"}'); [ "$code" = 403 ] && ok "new users cannot create organizations (403)" || bad "org creation by new user: $code"
|
code=$(curl -s -o /dev/null -w '%{http_code}' "${H[@]}" -H "Sudo: e2e-agent" -X POST "$A/orgs" -d '{"username":"e2e-org"}'); [ "$code" = 403 ] && ok "new users cannot create organizations (403)" || bad "org creation by new user: $code"
|
||||||
st=$(curl -fsS "${H[@]}" "$A/settings/repository"); grep -q '"migrations_disabled":true' <<<"$st" && ok "migrations disabled" || bad "migrations"
|
st=$(curl -fsS "${H[@]}" "$A/settings/repository"); grep -q '"migrations_disabled":true' <<<"$st" && ok "migrations disabled" || bad "migrations"
|
||||||
page=$(curl -fsS "http://127.0.0.1:$PORT/user/sign_up"); grep -q 'captcha' <<<"$page" && ok "public sign-up page shows a captcha" || bad "sign-up captcha"
|
page=$(curl -fsS "http://127.0.0.1:$PORT/user/sign_up"); ! grep -qi 'captcha' <<<"$page" && ok "public sign-up page has no captcha (agent-native)" || bad "sign-up still shows a captcha"
|
||||||
./kit.sh backup >/dev/null 2>&1 && ls backups/*.zip >/dev/null && ok "backup (gitea dump) written" || bad "backup"
|
./kit.sh backup >/dev/null 2>&1 && ls backups/*.zip >/dev/null && ok "backup (gitea dump) written" || bad "backup"
|
||||||
./kit.sh protect-all >/dev/null && ok "protect-all ran" || bad "protect-all"
|
./kit.sh protect-all >/dev/null && ok "protect-all ran" || bad "protect-all"
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user