fix: surface Gitea auth errors and document the service PAT
Two related issues made the connected MCP server return a bare "Internal server error" for tools that need real Gitea API access (e.g. list_repositories), while public-repo-by-path reads worked: 1. Gitea OIDC access tokens only carry openid/profile/email and cannot call the repository REST API, so pure-OAuth mode fails for most tools. A service PAT (GITEA_TOKEN) is required in practice; per-user permission is still enforced before each call, so this does not weaken authorization. 2. The tool handlers caught GiteaError broadly and re-raised it as RuntimeError. Because GiteaAuthenticationError/GiteaAuthorizationError subclass GiteaError, a clean 401/403 was masked as a generic internal error and the server's re-authorization guidance never fired. Changes: - read_tools.py / repository.py / write_tools.py: re-raise the auth/authz subclasses before the broad GiteaError catch so server.py returns actionable guidance instead of a generic 500. - .env.example + README.md: document GITEA_TOKEN as a least-privilege bot PAT, explain why it's needed and that OAuth remains authoritative, and note that list_repositories is intentionally unavailable in service-PAT mode. - tests: assert tool handlers propagate auth errors unwrapped. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -58,7 +58,23 @@ OAUTH_STATE_SECRET=<random-32-byte-minimum-secret>
|
||||
DCR_STORAGE_PATH=/var/lib/aegis-mcp/dcr_clients.json
|
||||
```
|
||||
|
||||
`GITEA_TOKEN` is optional in OAuth mode. Without it, Gitea REST calls use the user's OAuth access token directly, so Gitea enforces permissions on every API call. With it, the token acts as a service PAT for API execution, but the MCP server first checks the requesting user's permission on the target repository through Gitea and denies the call if the user lacks the required read/write permission.
|
||||
### 2b) Service PAT (`GITEA_TOKEN`) — needed in practice
|
||||
|
||||
Gitea issues **OIDC access tokens** that carry only `openid/profile/email`. They establish identity but **cannot call the repository REST API**, so in pure-OAuth mode most tools fail (you will see a generic error, or `list_repositories` returning nothing usable). Configure a service PAT so the tools actually work:
|
||||
|
||||
1. Create a **dedicated bot account** in Gitea (not a personal account).
|
||||
2. Generate a Personal Access Token with least privilege:
|
||||
- `read:repository`
|
||||
- `write:repository` only if you enable `WRITE_MODE`
|
||||
3. Set it in `.env`:
|
||||
|
||||
```env
|
||||
GITEA_TOKEN=<bot-personal-access-token>
|
||||
```
|
||||
|
||||
This does **not** weaken per-user security. OAuth remains authoritative: before every repository call the server verifies that the signed-in user has permission on the target repo through Gitea (`_verify_user_repository_access`) and denies it otherwise. The PAT only performs the API call after that check; OAuth provides identity, per-user authorization, and audit attribution.
|
||||
|
||||
Note: with a service PAT, `list_repositories` is intentionally blocked because it has no repository target to authorize per user — use the repository-scoped tools (`get_repository_info`, `get_file_contents`, `list_issues`, …) instead.
|
||||
|
||||
### 2a) Required writable volumes (read-only container)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user