docs: replace daedalus-service basic auth with per-user DRF tokens
This commit is contained in:
@@ -367,9 +367,12 @@ Mnemosyne validates the JWT against `MCPSigningKey` keyed by `kid`.
|
||||
|
||||
## 7. REST API — Mnemosyne team lifecycle
|
||||
|
||||
All endpoints live under `/mcp_server/api/teams/` and are protected
|
||||
by the existing `daedalus-service` HTTP Basic account (same auth as
|
||||
`/library/api/workspaces/` and `/library/api/ingest/`).
|
||||
All endpoints live under `/mcp_server/api/teams/` and are authenticated
|
||||
as the Mnemosyne user the team belongs to via a per-user DRF token
|
||||
(`Authorization: Token <key>`, surfaced on `/profile/settings/`). Each
|
||||
team has an `owner` FK; non-owners receive 404 (never 403) so a team's
|
||||
existence isn't disclosed across users. `/library/api/workspaces/` and
|
||||
`/library/api/ingest/` use the same per-user auth model.
|
||||
|
||||
### 7.1 `POST /mcp_server/api/teams/`
|
||||
Create a team.
|
||||
@@ -733,7 +736,8 @@ escape hatch for hard compartmentalization.
|
||||
* `TeamWorkspaceAssignment` PUT is idempotent and replaces, not
|
||||
unions.
|
||||
* `/mcp_server/api/teams/` endpoints: create, delete, rotate,
|
||||
workspaces PUT, all authenticated as `daedalus-service`.
|
||||
workspaces PUT, all authenticated with a per-user DRF token and
|
||||
scoped to the team's `owner` (non-owner requests return 404).
|
||||
|
||||
### 14.2 Daedalus test surface
|
||||
* `on_pallas_registered` populates `team_jwt_encrypted` and transitions
|
||||
|
||||
@@ -92,14 +92,6 @@ docker compose -f /srv/mnemosyne/docker-compose.yaml \
|
||||
docker compose -f /srv/mnemosyne/docker-compose.yaml \
|
||||
run --rm app setup
|
||||
|
||||
# Create the daedalus-service user (HTTP Basic auth for ingest API)
|
||||
# Pass --password from vault; idempotent if user already exists.
|
||||
docker compose -f /srv/mnemosyne/docker-compose.yaml \
|
||||
run --rm app \
|
||||
python manage.py ensure_service_user \
|
||||
--username daedalus-service \
|
||||
--password "{{ vault_mnemosyne_daedalus_service_password }}"
|
||||
|
||||
# Seed the MCPSigningKey used to sign long-lived Pallas team JWTs.
|
||||
# --retire-other deactivates any previously-active key. The hex
|
||||
# emitted to stdout is persisted in Mnemosyne's database and is
|
||||
@@ -321,13 +313,16 @@ curl -f http://puck.incus:23181/healthz
|
||||
curl http://puck.incus:23181/metrics | head -5
|
||||
```
|
||||
|
||||
### Verify the daedalus-service account
|
||||
### Verify Daedalus auth (per-user API token)
|
||||
|
||||
Daedalus now authenticates as a Mnemosyne user via the DRF token shown
|
||||
on `/profile/settings/`. To smoke-test from a deploy host:
|
||||
|
||||
```bash
|
||||
curl -u daedalus-service:<password> \
|
||||
https://mnemosyne.ouranos.helu.ca/library/api/workspaces/ \
|
||||
curl -H "Authorization: Token <user-api-token>" \
|
||||
https://mnemosyne.ouranos.helu.ca/library/api/workspaces/ws_smoke/ \
|
||||
-o /dev/null -w "%{http_code}"
|
||||
# Expect: 200
|
||||
# Expect: 200 if the workspace exists for that user, 404 otherwise.
|
||||
```
|
||||
|
||||
### Verify MCP connectivity (from a client with a valid MCPToken)
|
||||
@@ -401,6 +396,5 @@ will report as a failure.
|
||||
| `vault_daedalus_s3_read_secret` | `DAEDALUS_S3_SECRET_ACCESS_KEY` |
|
||||
| `vault_rabbitmq_password` | embedded in `CELERY_BROKER_URL` |
|
||||
| `vault_mnemosyne_llm_encryption_key` | `LLM_API_SECRETS_ENCRYPTION_KEY` |
|
||||
| `vault_mnemosyne_daedalus_service_password` | passed to `ensure_service_user --password` |
|
||||
| `vault_mnemosyne_casdoor_client_id` | `CASDOOR_CLIENT_ID` |
|
||||
| `vault_mnemosyne_casdoor_client_secret` | `CASDOOR_CLIENT_SECRET` |
|
||||
|
||||
@@ -8,7 +8,7 @@ This document describes Mnemosyne's role in the Daedalus + Pallas architecture a
|
||||
|
||||
Mnemosyne exposes two interfaces for the wider Ouranos ecosystem:
|
||||
|
||||
1. **REST API** (`/library/api/*`) — consumed by the Daedalus backend (HTTP Basic auth, service account `daedalus-service`) for workspace lifecycle and asynchronous file ingestion. Phase 1, **implemented**.
|
||||
1. **REST API** (`/library/api/*`) — consumed by the Daedalus backend authenticated as the owning Mnemosyne user via a per-user DRF token (`Authorization: Token <key>`, surfaced on `/profile/settings/`) for workspace lifecycle and asynchronous file ingestion. Phase 1, **implemented**.
|
||||
2. **MCP Server** (port 22091 internal, `/mcp/` via nginx on 23090) — exposes search, browse, and retrieval tools. Phase 5 of Mnemosyne's own roadmap, **implemented** with workspace-scoped access control via long-lived team JWTs. Consumed by Pallas FastAgents in production (Daedalus integration Phase 2, **implemented** — see [Phase 3 of this doc](#3-phase-3-long-lived-team-jwt-access-control-for-pallas-instances)).
|
||||
|
||||
### Phase status
|
||||
@@ -105,7 +105,7 @@ Auth is controlled by `MCP_REQUIRE_AUTH` in `.env`. Production sets it to `True`
|
||||
|
||||
## 2. REST API for Daedalus
|
||||
|
||||
All endpoints require HTTP Basic auth as `daedalus-service`. They are consumed by the Daedalus FastAPI backend only — not by any frontend.
|
||||
All endpoints require an `Authorization: Token <key>` header carrying the DRF token of the Mnemosyne user the workspace belongs to (surfaced on `/profile/settings/`). Workspaces are scoped to their creating user via the `Library.owner_username` property; cross-user access returns 404. They are consumed by the Daedalus FastAPI backend only — not by any frontend.
|
||||
|
||||
### Workspace lifecycle
|
||||
|
||||
@@ -354,7 +354,7 @@ mnemosyne_s3_operations_total{operation,status} counter
|
||||
- [x] `GET /library/api/jobs/{job_id}/`, `POST .../retry/`, `GET /library/api/jobs/`
|
||||
- [x] `library.tasks.ingest_from_daedalus` Celery task with content-hash-aware supersede logic
|
||||
- [x] `library.services.daedalus_s3` cross-bucket fetch + copy
|
||||
- [x] HTTP Basic auth via `daedalus-service` user
|
||||
- [x] Per-user DRF token auth (`Authorization: Token <key>`); workspaces scoped to the owning user via `Library.owner_username`
|
||||
|
||||
### Phase 2 — MCP Server (Mnemosyne roadmap Phase 5) ✅ Implemented
|
||||
- [x] `mcp_server/` module following the [Django MCP Pattern](Pattern_Django-MCP_V1-00.md)
|
||||
|
||||
Reference in New Issue
Block a user