| 2026-05-24 |

Add API token auth system for headless/micro clients
...
Backend:
- navi/auth/_ddl.py: add api_tokens table with boot-time migration
- navi/auth/deps.py: _resolve_user now falls back to X-Api-Token header
and ?api_token query param for WebSocket auth
- navi/auth/__init__.py: add ApiToken pydantic model
- navi/api/routes/api_tokens.py: CRUD endpoints (POST/GET/DELETE)
- navi/main.py: wire api_tokens router
Frontend:
- webclient/src/App.vue: add #settings hash routing
- webclient/src/components/settings/: SettingsView, ApiKeysPanel,
CreateKeyModal with copy-to-clipboard flow
- webclient/src/api/index.js: token CRUD API functions
- webclient/src/stores/apiTokens.js: Pinia store
- webclient/src/components/sidebar/AppSidebar.vue: settings link
- webclient/src/composables/useWebSocket.js: append ?api_token= when
localStorage token is present
Tests:
- tests/unit/auth/test_api_tokens.py: 10 unit tests covering token
resolution (header + query param), revoke, missing/revoked tokens,
orphan users, and CRUD endpoints
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 24 May
|
| 2026-05-08 |
Fix missing columns in navi_users: add boot-time ALTER TABLE migration
...
The navi_users table already existed on this deployment, so the updated
CREATE TABLE IF NOT EXISTS was a no-op. Run ALTER TABLE ADD COLUMN for
username, first_name, last_name, phone, birth_date, country, city, locale
if they are missing (checked via information_schema.columns).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|
Propagate user profile to LLM context via current_user_info ContextVar
...
- Extend User model: username, first_name, last_name, phone, birth_date,
country, city, locale (all from gnexus-auth profile)
- navi_users DDL: add new profile columns
- auth/deps + auth/callback: populate new fields on upsert
- /auth/me: return all profile fields
- Add current_user_info ContextVar for full user profile propagation
- websocket + messages: set current_user_info before agent.run()
- run_ephemeral: inherit and restore current_user_info
- ContextBuilder: _user_context_msg() injects [User context] with name,
email, location, locale, role into LLM system messages
- _security_policy_msg: reads user_id/role from ContextVar directly
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 8 May
|
| 2026-05-03 |
Fix DDL race condition and PostgreSQL syntax error on startup
...
- _ensure_auth_tables now uses raw asyncpg.connect instead of get_session_store,
avoiding PgSessionStore._MIGRATE running before navi_users exists
- Move _ensure_auth_tables before ensure_tables in startup so navi_users is
created before any foreign-key references
- Replace invalid "ADD CONSTRAINT IF NOT EXISTS" with DO $$ block for
memory_facts_user_cat_key
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 3 May
|
Multi-user auth via gnexus-auth OAuth + hybrid role/permission model
...
- Integrate gnexus-auth-client-py (GAuthClient) for OAuth flow, token refresh,
and webhook parsing
- Add navi/auth/ package: User model, Fernet encryptor, client singleton,
deps (get_current_user, require_admin, require_permission)
- New tables: navi_users, user_auth_sessions (auto-created on startup)
- Session/memory isolation by user_id with legacy NULL support
- Cookie-based auth proxy: /auth/login, /callback, /logout, /me
- Webhook receiver /webhooks/gnexus-auth handling user events, global logout,
session revocation, role/permission changes
- Admin endpoints (/admin/*) gated by role + permissions
- Webclient auth store with isAdmin/hasPermission guards
- Admin-only profile filtering in /agents/profiles
- 200/200 tests passing
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Eugene Sukhodolskiy
committed
on 3 May
|