mirror of
https://github.com/RayLabsHQ/gitea-mirror.git
synced 2026-10-30 22:21:58 +01:00
feat: read only API keys and an MCP endpoint over the REST API (#478)
- Read only API keys: an Access choice when creating a key, stored in the key metadata; the middleware refuses writes and most auth calls for them with 403 API_KEY_READ_ONLY. - POST /api/mcp: stateless MCP endpoint with 8 tools that call the REST API over loopback with the caller's key. Needs x-api-key, a cookie alone gets 401. MCP_INTERNAL_URL overrides the loopback address. - mcp/: gitea-mirror-mcp, a zero dependency stdio bridge to /api/mcp for Claude Desktop and Cursor, with a CI workflow that publishes it on an mcp-v* tag. - e2e spec for keys, the endpoint and the bridge; docs for the endpoint, the bridge and read only keys.
This commit is contained in:
1 parent
1ba20d7c47
commit
1b60a0334a
40 files changed
+3211
-59
No files matched your search
+12
-4
@@ -5,10 +5,18 @@ Gitea Mirror's web UI talks to a set of JSON endpoints under `/api`. With an API
|
||||
## Create a key
|
||||
|
||||
1. Sign in and open **Settings → Authentication**.
|
||||
2. In the **API Keys** section click **Create key**, give it a name and pick an expiry (never, 30 days, 90 days or a year).
|
||||
2. In the **API Keys** section click **Create key**, give it a name and pick an expiry (never, 30 days, 90 days or a year) and an access level (full access or read only).
|
||||
3. Copy the key. It is shown once; afterwards only its first characters are visible in the list.
|
||||
|
||||
Keys start with `gm_`, belong to the user who created them and carry the same rights as that user's session. Revoke a key from the same list at any time. Keys are stored hashed. They are not rate limited, so a runaway script is stopped by revoking its key.
|
||||
Keys start with `gm_` and belong to the user who created them. A full access key carries the same rights as that user's session. Revoke a key from the same list at any time. Keys are stored hashed. They are not rate limited, so a runaway script is stopped by revoking its key.
|
||||
|
||||
Pick **Read only** under **Access** for a key that only needs to look: it can call every `GET` endpoint and nothing else. Any `POST`, `PUT`, `PATCH` or `DELETE` with a read only key gets `403`:
|
||||
|
||||
```json
|
||||
{ "success": false, "error": "This API key is read only. Use a key with full access to make changes.", "code": "API_KEY_READ_ONLY" }
|
||||
```
|
||||
|
||||
Use a read only key for dashboards, monitoring and the [MCP server](../mcp/README.md) when you only want an assistant to answer questions. A key's access level cannot be changed after it is created; create a new key instead.
|
||||
|
||||
## Send the key
|
||||
|
||||
@@ -294,8 +302,8 @@ Manage keys through the settings UI or with a browser session. The key endpoints
|
||||
|
||||
| Call | Body | Result |
|
||||
| --- | --- | --- |
|
||||
| `POST /api/auth/api-key/create` | `{ "name": "ci", "expiresIn": 2592000 }` (`expiresIn` in seconds, omit for no expiry) | The new key, including `key`, shown only here. |
|
||||
| `GET /api/auth/api-key/list` | | `{ "apiKeys": [...], "total": n }`. Each entry has `id`, `name`, `start`, `createdAt`, `lastRequest` and `expiresAt`, never the secret. |
|
||||
| `POST /api/auth/api-key/create` | `{ "name": "ci", "expiresIn": 2592000 }` (`expiresIn` in seconds, omit for no expiry). Add `"metadata": { "access": "read" }` for a read only key. | The new key, including `key`, shown only here. |
|
||||
| `GET /api/auth/api-key/list` | | `{ "apiKeys": [...], "total": n }`. Each entry has `id`, `name`, `start`, `createdAt`, `lastRequest`, `expiresAt` and `metadata` (`{ "access": "read" }` on read only keys), never the secret. |
|
||||
| `POST /api/auth/api-key/delete` | `{ "keyId": "..." }` | Revokes the key. |
|
||||
|
||||
## Notes
|
||||
|
||||
Reference in new issue
Block a user