python-jose jwt.decode() requires audience as string or None, not list. Now extract and validate audience from unverified claims first, then use token's actual audience for JWT decode. Fixes "audience must be a string or None" error. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
14 KiB
14 KiB
Changelog
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.10.8] - 2026-01-08
Fixed
- OIDC audience validation - python-jose requires string audience, not list
- Extract and validate audience from unverified claims first
- Use token's actual audience for JWT decode (after validating it's allowed)
- Fixes "audience must be a string or None" error
[1.10.7] - 2026-01-08
Added
- Multi-issuer OIDC support - Accept tokens from multiple OAuth providers
- Changed
oidc_issuer(string) tooidc_issuers(list) - Each issuer has its own JWKS endpoint, now cached per-issuer
- Validates token issuer against allowed list before fetching JWKS
- Supports tokens from:
core-api,tatlock-ui,tatlockOAuth applications - Completes fix for environment endpoint user resolution
- Changed
Removed
- Deprecated
src/config.py- consolidated tosrc/shared/config.py - Deprecated
src/security.py- consolidated tosrc/shared/security.py
[1.10.6] - 2026-01-08
Fixed
- OIDC audience mismatch - Accept tokens from multiple clients
- Changed
oidc_audience(string) tooidc_audiences(list) - Now accepts tokens with audience:
core-api,tatlock-ui, ortatlock - Fixes environment endpoint returning "default" user instead of authenticated username
- Fixed main.py to use
oidc_audiences[0]for Swagger UI OAuth client
- Changed
Changed
- Documentation cleanup in README
[1.10.4] - 2026-01-07
Removed
- Ollama integration removed - AI inference is no longer handled by this API
- Removed
src/models/ollama_client.pyand all Ollama-related configuration - Removed
src/models/embeddings.pyandsrc/models/embeddings_ollama.py - Removed model aliases and AI configuration from settings
- Health endpoints no longer check Ollama status
- Tests updated to reflect database-only health checks
- Removed
Changed
- Health check
/health/fullnow only checks database connectivity - Diagnostics endpoint simplified (removed Ollama component info)
[1.10.3] - 2026-01-07
Fixed
- OIDC config not applied to domains module - Both
src.auth.oidcandsrc.domains.auth.oidcconfigs are now initialized- Previously only
src.auth.oidcwas configured, leaving domains tools using hardcoded "local" user - Environment endpoint now correctly uses authenticated user from OIDC token
- Previously only
[1.10.2] - 2026-01-07
Changed
- Enhanced environment endpoint logging - Added detailed user claim logging for debugging
- Logs both
preferred_usernameandsubclaims when resolving user - Distinguishes between authenticated and unauthenticated requests
- Logs both
[1.10.1] - 2026-01-06
Fixed
- Fix OIDC import path in tools controller (
src.oidc.dependencies→src.auth.oidc)- Environment endpoint was returning
user: "local"instead of authenticated username - Caused queries to wrong Qdrant collection (
volatile_localvsvolatile_{username})
- Environment endpoint was returning
[1.10.0] - 2026-01-06
Added
- Environment Data API - Qdrant-backed endpoint for weather, forecast, and sun position data
GET /tools/environment- Fetch environment data from user's volatile collection- Weather: current temperature, conditions, humidity, wind speed
- Forecast: multi-day outlook with high/low temperatures
- Sun times: sunrise, sunset, daylight duration
- Air quality: AQI and quality level (when available)
- Data sourced from
volatile_{user}Qdrant collection - Uses
preferred_usernamefrom OIDC, falls back todefault
qdrant-clientdependency for vector database accessQdrantReadClientwrapper for read-only collection queries- Comprehensive test suite for environment service parsing
[1.9.4] - 2026-01-04
Fixed
- Fix SQLAlchemy async lazy loading error for new users in
/auth/sync- Initialize
user.roles = []anduser.preferencesto avoid greenlet error - Was causing "MissingGreenlet: greenlet_spawn has not been called" on new user creation
- Initialize
[1.9.3] - 2026-01-04
Fixed
- Handle non-UUID
subclaim in/auth/sync- Authentik JWT may return non-UUID subject identifiers- Now derives deterministic UUID from sub string if direct parsing fails
[1.9.2] - 2026-01-04
Fixed
/auth/users/meendpoint now supports both NPM forward auth headers AND JWT Bearer tokens- Added
get_current_user_or_forward_auth()combined auth dependency - Fixes web authentication where NPM passes
X-authentik-*headers instead of JWT - Mobile/native clients continue to use JWT Bearer tokens as before
- Added
[1.9.1] - 2026-01-03
Fixed
- CORS configuration now uses explicit origins instead of
"*"- When
allow_credentials=True, wildcard origins are rejected by browsers - Added
home.schweitz.net,tatlock.schweitz.net, and localhost origins
- When
[1.9.0] - 2026-01-03
Added
- NPM Forward Auth Support - Web authentication via Nginx Proxy Manager forward auth
GET /auth/me- Get current user from NPM forward auth headers (X-authentik-uid, X-authentik-email, etc.)- Auto-creates user on first web login if not in database
- Syncs roles from NPM forward auth groups header
get_user_by_emailandget_user_by_authentik_idmethods in AuthService- Comprehensive tests for
/auth/meendpoint
[1.8.0] - 2026-01-03
Added
- Group-Role Mapping & Permissions (Phase 3)
- Decoupled group-role architecture (groups from Authentik, roles admin-managed)
- Permission format:
domain.category:actionwith action hierarchy require_permissionandrequire_any_permissiondependency factories- Global admin override (
admin.general:admin)
- User Profile & API Keys (Phase 4)
GET /auth/users/me- Full user profile with roles and preferencesGET/PATCH /auth/users/me/preferences- User preferences managementGET/POST/DELETE /auth/users/me/api-keys- API key lifecycle- API keys with
tak_prefix, SHA-256 hashing, shown only once on creation
[1.7.0] - 2026-01-03
Added
- System Stats API - Host system resource monitoring for dashboard widgets
GET /tools/system/stats- Real-time host system statistics- CPU: usage percentage, core count, load averages
- Memory: usage percentage, total/used/available bytes
- Disks: all mounted filesystems with usage stats (auto-discovers mounts)
- Network: total bytes sent/received
- GPU/VRAM: NVIDIA GPU memory usage (via nvidia-smi if available)
psutildependency for cross-platform system metrics
[1.6.1] - 2026-01-03
Added
link_typefield to quick links for iframe vs new tab behavior
[1.6.0] - 2026-01-03
Added
- Dashboard API - Quick links and widgets management for Organizr-style dashboard
GET /dashboard/quick-links- List quick links with category/visibility filteringGET /dashboard/quick-links/{id}- Get single quick linkPOST /dashboard/quick-links- Create quick linkPUT /dashboard/quick-links/{id}- Update quick linkDELETE /dashboard/quick-links/{id}- Delete quick linkPOST /dashboard/quick-links/reorder- Reorder quick links by positionGET /dashboard/widgets- List dashboard widgetsGET /dashboard/widgets/{id}- Get single widgetPOST /dashboard/widgets- Create widgetPUT /dashboard/widgets/{id}- Update widgetDELETE /dashboard/widgets/{id}- Delete widget
- Database migrations for
quick_linksanddashboard_widgetstables - Static file controller for serving Organizr widgets (
/static/widgets) - Default local user authentication when OIDC is disabled
Changed
- Domain-based architecture - Refactored codebase to domain-driven structure
src/domains/- Domain modules (auth, dashboard, health, housekeeping, infrastructure, tools)src/shared/- Shared utilities (base, config, database, logging, security, clients)
- Test suite updated for new domain structure (285 tests passing)
[1.5.0] - 2026-01-01
Added
- Groups Management - Authentik group synchronization
GET /auth/groups- List all groups with search and paginationPOST /auth/groups/sync-from-authentik- Bulk sync groups from Authentik admin API
- Database model and migration for groups table
[1.4.6] - 2026-01-01
Changed
- Code cleanup: move inline
reimport to top of auth/service.py
[1.4.5] - 2026-01-01
Fixed
- Separate httpx and SQLAlchemy async contexts in bulk sync (fixes greenlet error)
[1.4.4] - 2026-01-01
Fixed
- Use
uuidfield instead ofpkfor Authentik user sync (pk is integer, uuid is proper UUID) - Skip internal_service_account type users during bulk sync
[1.4.3] - 2026-01-01
Fixed
- Manually extract and send session cookies for Authentik flow auth (fixes cross-domain cookie handling)
[1.4.2] - 2026-01-01
Fixed
- Use Authentik domain URL (auth.schweitz.net) instead of IP to fix cookie domain matching
[1.4.1] - 2026-01-01
Fixed
- Authentik config now uses AUTHENTIK_USERNAME/PASSWORD to match production env vars
[1.4.0] - 2026-01-01
Added
- Authentication & User Management - Authentik integration for user synchronization
GET /auth/me- Get current authenticated user infoGET /auth/users- List all users with search and paginationPOST /auth/users/sync-from-authentik- Bulk sync users from Authentik admin API
- PostgreSQL database integration with async SQLAlchemy
- Alembic database migrations for schema management
- Database models: User, Role, UserPreferences, ApiKey
- Token validation via Authentik userinfo endpoint
- Role synchronization from Authentik groups
- Health check now includes database connectivity status
Changed
- Authentik configuration now uses username/password for admin API access
- Health endpoint includes database status in diagnostics
[1.3.1] - 2025-12-31
Changed
- Simplified configuration: all settings now read from environment variables/.env only
- Removed Docker socket fallback for container operations (Portainer API is now required)
- Updated default search provider to SearXNG
Removed
src/credentials.py- credentials now managed via environment variables- Docker socket fallback methods from Portainer client
- Unused search API settings (Brave, Google)
[1.3.0] - 2025-12-31
Added
- Stack Management Endpoints for Tatlock Control Room integration
GET /infrastructure/stacks/{stackId}/compose- Get stack Docker Compose YAMLPUT /infrastructure/stacks/{stackId}/compose- Update stack Docker Compose YAMLGET /infrastructure/stacks/{stackId}/env- Get stack environment variablesPUT /infrastructure/stacks/{stackId}/env- Update stack environment variablesPOST /infrastructure/stacks/{stackId}/deploy- Redeploy stackPOST /infrastructure/stacks/{stackId}/rebuild- Pull images and recreate containers
DELETE /infrastructure/containers/{id}- Delete container with optional force flag- Portainer client methods:
get_stack_file,redeploy_stack,update_stack_env,delete_container,restart_container
Removed
- REQUESTED_SERVICES.md - endpoint specifications now implemented
[1.2.1] - 2025-12-17
Fixed
- Device control endpoint now returns correct new state after action (added 300ms delay for HA state propagation)
Added
- AGENTS.md with project coding guidelines and release flow documentation
Changed
- Removed obsolete web scraper settings from .env.example
[1.2.0] - 2025-12-17
Added
- Housekeeping API - Home Assistant integration for smart home control
GET /housekeeping/health- HA connection statusGET /housekeeping/devices- List controllable devices with optional domain/area filteringGET /housekeeping/devices/{entity_id}- Get device detailsPOST /housekeeping/devices/{entity_id}/control- Control devices (turn_on, turn_off, toggle, set_brightness)GET /housekeeping/scenes- List available scenesPOST /housekeeping/scenes/{scene_id}/activate- Activate a sceneGET /housekeeping/scripts- List available scriptsPOST /housekeeping/scripts/{script_id}/run- Run a scriptGET /housekeeping/automations- List automationsPOST /housekeeping/automations/{automation_id}/toggle- Enable/disable automationGET /housekeeping/history- Query state historyGET /housekeeping/areas- List rooms/areas
- Home Assistant REST API client (
src/clients/homeassistant_client.py) - Home Assistant configuration in credentials and settings
- Comprehensive test suite with 65% code coverage (285 tests)
- Tests for NPM client, Ollama client, AI client, OIDC authentication
- Tests for infrastructure, health, tools, and housekeeping endpoints
Removed
- Web Scraper - Entire web scraping module removed
src/web_scraper/directory deleted/web-scraper/scrapeendpoint removed- Trafilatura and BeautifulSoup dependencies removed from scraping use
Changed
- Updated README.md with current architecture and all endpoints
- Tools controller now only contains DNS lookup functionality
- Health controller endpoints list updated to reflect current features
[1.1.2] - 2024-12-14
Added
- Version field to /health endpoint response
[1.1.1] - 2024-12-14
Added
- Watchtower trigger step in CI workflow for automatic container updates
[1.1.0] - 2024-12-14
Removed
- Uptime Kuma integration (kuma_client.py deleted)
- All /infrastructure/monitors endpoints
- Kuma monitor pause/resume from service start/stop operations
- Uptime percentage display from service control widget
- Kuma-related configuration and credentials
- Stale memory tests (memory functionality moved to core-ai service)
Changed
- Service control widget now uses Portainer container status exclusively
- Simplified widget-data endpoint response (removed monitors field)
- Updated service start/stop to only manage containers via Portainer
[1.0.0] - 2024-12-14
Added
- Initial release of Core Code API service extracted from portainer-core
- Infrastructure management endpoints for Portainer, NPM, and Uptime Kuma
- Web scraping service with content extraction
- DNS management endpoints
- Health check endpoints with diagnostics
- OIDC authentication support via Authentik
- Ollama integration for embeddings
- OpenAPI documentation (Swagger UI and ReDoc)
- Docker containerization with CI/CD workflow