- Add migration 013_city_map_coordinates.sql with map coordinates, zones, and agents table - Add /city/map API endpoint in city-service - Add /city/agents and /city/agents/online endpoints - Extend presence aggregator to include agents[] in snapshot - Add AgentsSource for fetching agent data from DB - Create CityMap component with interactive room tiles - Add useCityMap hook for fetching map data - Update useGlobalPresence to include agents - Add map/list view toggle on /city page - Add agent badges to room cards and map tiles
6.8 KiB
TASK: PHASE 4.5 — REAL PASSKEY AUTH (WebAuthn) + ACTOR CONTEXT INTEGRATION
Goal: Замість stub-автентифікації додати повноцінний WebAuthn Passkey login/registration. Підключити це до auth-service, PDP та всього DAARION фронтенду (onboarding + dashboards + agent hub).
Result: Після виконання task користувач заходить у DAARION повністю через Passkey (FaceID/TouchID), без паролів, без сторонніх логінів. ActorIdentity формується автоматично.
1) BACKEND — AUTH-SERVICE (FastAPI)
Directory: services/auth-service/
Add new files:
routes_passkey.pywebauthn_utils.pyschemas_passkey.pypasskey_store.py(PostgreSQL logic)
Update:
main.pymodels.pyactor_context.pyDockerfileREADME.md
1.1 Passkey Backend Endpoints (WebAuthn Standard)
Implement these endpoints:
POST /auth/passkey/register/start
→ Генерує challenge + options для WebAuthn credential creation
Response:
{
"challenge": "...",
"rp": { "name": "DAARION", "id": "localhost" },
"user": {
"id": "base64url(user_id)",
"name": "user:93",
"displayName": "@username"
},
"pubKeyCredParams": [ { "type": "public-key", "alg": -7 } ],
"timeout": 60000
}
POST /auth/passkey/register/finish
→ Валідує client attestation + зберігає credential в базу
Request:
{
"id": "...",
"rawId": "...",
"type": "public-key",
"response": { "attestationObject": "...", "clientDataJSON": "..." }
}
POST /auth/passkey/authenticate/start
→ Генерує challenge для login
POST /auth/passkey/authenticate/finish
→ Валідує assertion, повертає session_token
Response:
{
"session_token": "...",
"actor": { ...ActorIdentity... }
}
All validation strictly follows WebAuthn spec.
1.2 passkey_store.py — Database tables
Add migrations:
CREATE TABLE passkeys (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id UUID NOT NULL,
credential_id TEXT NOT NULL UNIQUE,
public_key TEXT NOT NULL,
sign_count INTEGER NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
last_used_at TIMESTAMPTZ,
device_name TEXT
);
CREATE INDEX idx_passkeys_user_id ON passkeys(user_id);
CREATE INDEX idx_passkeys_credential_id ON passkeys(credential_id);
CREATE TABLE sessions (
token TEXT PRIMARY KEY,
user_id UUID NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expires_at TIMESTAMPTZ NOT NULL,
last_activity_at TIMESTAMPTZ
);
CREATE INDEX idx_sessions_user_id ON sessions(user_id);
CREATE INDEX idx_sessions_expires_at ON sessions(expires_at);
CREATE TABLE passkey_challenges (
challenge TEXT PRIMARY KEY,
user_id UUID,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
expires_at TIMESTAMPTZ NOT NULL,
challenge_type TEXT NOT NULL -- 'register' or 'authenticate'
);
CREATE INDEX idx_passkey_challenges_expires_at ON passkey_challenges(expires_at);
Implement functions:
create_passkey(user_id, credential_id, public_key, ...)get_passkeys_by_user_id(user_id)update_sign_count(credential_id, new_counter)store_challenge(challenge, user_id, type)verify_challenge(challenge)
1.3 actor_context.py
Extend:
def build_actor_context(request):
- if session_token → load user
- resolve all microDAO memberships
- resolve all roles (microdao_owner, admin, member)
- return ActorIdentity
This will be used by:
- messaging-service (PEP)
- agent-runtime
- toolcore
- pdp-service
2) FRONTEND — REACT + VITE
Directory:
src/features/onboarding/scenes/PasskeyScene.tsxsrc/features/auth/passkey/
Add files:
src/features/auth/hooks/usePasskeyRegister.tssrc/features/auth/hooks/usePasskeyLogin.tssrc/api/auth/passkey.tssrc/store/authStore.ts
Fix onboarding flow:
- User arrives at PasskeyScene
- Calls
/auth/passkey/register/start navigator.credentials.create(...)- Calls
/auth/passkey/register/finish - Receives
session_token - Store
session_tokenin localStorage - Update global auth state
2.1 API calls (frontend)
POST /auth/passkey/register/start
POST /auth/passkey/register/finish
POST /auth/passkey/authenticate/start
POST /auth/passkey/authenticate/finish
Global auth store:
interface AuthStore {
sessionToken: string | null;
actor: ActorIdentity | null;
isAuthenticated: boolean;
setSession: (token: string, actor: ActorIdentity) => void;
clearSession: () => void;
}
Add helpers:
setSession(token)clearSession()
3) INTEGRATION: PDP + AUTH + UI
3.1 PDP
No changes required — Passkey login provides ActorIdentity → PDP already works.
3.2 messaging-service
Update PEP middleware to:
actor = auth_service.build_actor_context()
Make no stub assumptions.
3.3 agent-runtime
Replace old stub:
agent_identity = get_identity_from_stub()
With:
actor_identity = call auth_service /auth/me
3.4 All frontend pages:
Wrap:
/city-v2/space/messenger/agent-hub(future)
With:
if (!isAuthenticated) → redirect("/onboarding")
4) SECURITY RULES (WebAuthn Compliance)
Implement:
- Challenge stored per-user + expires in 5 min
- RPID:
"localhost"for dev;"daarion.city"for prod - Allowed origins:
http://localhost:3000https://daarion.city
- Counter validation (sign_count)
- Token rotation
5) DOCKER + ENV
auth-service must expose:
port: 7011
env:
RP_ID: localhost
RP_NAME: DAARION
ORIGIN: http://localhost:3000
Add to docker-compose.phase4.yml:
auth-service:
build: ./services/auth-service
ports: ["7011:7011"]
environment:
RP_ID: "localhost"
RP_NAME: "DAARION"
ORIGIN: "http://localhost:3000"
JWT_SECRET: "your-secret-key"
6) ACCEPTANCE CRITERIA
- [PASS] User can register Passkey in onboarding
- [PASS] User can login via Passkey (no passwords)
- [PASS] auth-service returns ActorIdentity
- [PASS] PDP uses correct actor roles
- [PASS] messenger-service prevents unauthorized send_message
- [PASS] agent-runtime resolves agent identity correctly
- [PASS] UI prevents access without auth
- [PASS] Audit logs show passkey login events
7) LIBRARIES & DEPENDENCIES
Backend (Python):
webauthn==1.11.1
cryptography==41.0.7
Frontend (TypeScript):
@simplewebauthn/browser
@simplewebauthn/typescript-types
END OF TASK
Status: Ready for implementation
Time Estimate: 2-4 days
Priority: High (blocks Agent Hub UI)