From 5dd73eb4cd70ed47bae94ea3e99691e34777dab0 Mon Sep 17 00:00:00 2001 From: "m2 (AI Agent)" Date: Thu, 2 Jul 2026 06:16:24 +0200 Subject: [PATCH] =?UTF-8?q?feat(003-gpt-identity):=20spec=20=E2=80=94=20m2?= =?UTF-8?q?-gpt=20as=20credential=20authority=20for=20market-web?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 --- specs/003-gpt-identity/spec.md | 38 ++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 specs/003-gpt-identity/spec.md diff --git a/specs/003-gpt-identity/spec.md b/specs/003-gpt-identity/spec.md new file mode 100644 index 0000000..906123b --- /dev/null +++ b/specs/003-gpt-identity/spec.md @@ -0,0 +1,38 @@ +# Feature Specification: m2-gpt identity for M2 Market Web + +**Feature Branch**: `003-gpt-identity` · **Created**: 2026-07-02 · **Status**: Draft +**Input**: Operator: "we need a central credential system and ledger" — m2-gpt becomes the +credential authority; market-web stops using the shared fleet passcode. + +## Stories +1. (P1) An operator logs into market.machinemachine.ai with their m2-gpt admin + credentials (email+password). The session is BOUND to their identity (email, role, + tenant_id) — wallet defaults to their operator identity; no picker for non-admins. +2. (P1) fleet_admin sessions keep the operator picker (fleet oversight). +3. (P2) Transition: FLEET_PASSCODE login stays available behind AUTH_MODE=passcode|gpt|both + (default both) until the operator retires it. + +## Requirements +- FR-201: /api/login accepts {email,password} → backend forwards to m2-gpt + POST /admin/v1/auth/login (M2GPT_URL env) over TLS; on 200 binds the session cookie to + {email, role, tenant_id, fleet_admin} from the token response. Credentials are never + stored; the m2-gpt JWT is kept server-side in the session only if needed for refresh. +- FR-202: operator_id mapping: tenant_id when set, else email local-part; fleet_admin may + view any wallet (picker), others only their own (403 otherwise). +- FR-203: when M2GPT_INTROSPECTION_KEY env is set, the backend revalidates sessions via + POST /admin/v1/auth/introspect (the m2-gpt PR in flight) at most once per 10 min. +- FR-204: passcode mode unchanged when enabled; UI shows both forms per AUTH_MODE. +- FR-205: secrets discipline unchanged (SC-103 scan must stay green; no credential or JWT + in client code/storage beyond the opaque session cookie). + +## Success criteria +- SC-201: login with real m2-gpt operator credentials → wallet shows THEIR operator_id + without a picker; wrong password → 401. +- SC-202: non-admin requesting another wallet → 403. +- SC-203: secrets scan green; AUTH_MODE=passcode still works. + +## Assumptions (flagged) +- Ledger wallets keyed by tenant_id going forward; existing ad-hoc wallet ids (m2bd, + sdjs-operator, chris-operator) remain and are reachable by fleet_admin — a formal + identity migration is deferred to the ledger-federation proposal (m2-gpt PR step 2/3). +- m2-gpt admin login is reachable from the web container (same coolify network / public).