3.4 KiB
TJWater Authentication and Metadata Management
Ownership
Keycloak owns login identity, credentials, token issuance, and token expiry. TJWater metadata stores only business snapshots and authorization data:
users.keycloak_idis the stable identity binding.users.username,users.email, andusers.last_login_atare Keycloak claim caches.users.role,users.is_active, andusers.is_superusercontrol TJWater system access.user_project_membership.project_rolecontrols project access.
The backend does not accept passwords, does not issue local JWTs, and does not trust frontend-supplied user IDs.
Login Snapshot Refresh
Every authenticated metadata-user resolution validates the Keycloak access token
and reads sub, preferred_username or username, and email claims. The
backend finds users by keycloak_id = sub, rejects inactive or missing users,
then refreshes username, email, and last_login_at.
This keeps local display data current without changing the identity binding. There is no Keycloak webhook requirement; second-level user or permission sync is out of scope unless explicitly requested later.
Admin APIs
All admin APIs require metadata admin access: users.is_superuser = true or
users.role = 'admin'.
User and membership management:
GET /api/v1/admin/mePOST /api/v1/admin/users/syncPOST /api/v1/admin/users/sync/batchGET /api/v1/admin/usersGET /api/v1/admin/users/{user_id}PATCH /api/v1/admin/users/{user_id}GET /api/v1/admin/projects/{project_id}/membersPOST /api/v1/admin/projects/{project_id}/membersPATCH /api/v1/admin/projects/{project_id}/members/{user_id}DELETE /api/v1/admin/projects/{project_id}/members/{user_id}
Project configuration:
GET /api/v1/admin/projectsPOST /api/v1/admin/projectsPATCH /api/v1/admin/projects/{project_id}GET /api/v1/admin/projects/{project_id}/databasesPUT /api/v1/admin/projects/{project_id}/databasesDELETE /api/v1/admin/projects/{project_id}/databases/{db_role}POST /api/v1/admin/projects/{project_id}/databases/{db_role}/health
Secret Handling
Admins submit plaintext DSNs only through HTTPS admin APIs. Operators should not write encrypted columns manually.
project_databases.dsn_encryptedis encrypted withDATABASE_ENCRYPTION_KEY.- Admin responses return only
has_dsn. - Audit logs record whether a secret was updated, but never store plaintext DSNs or other secrets.
Generate the database encryption key with:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"
Keep keys stable for the lifetime of encrypted metadata. Rotating a key requires decrypting with the old key and re-encrypting with the new key.
Metadata Schema Patches
Apply metadata patches in order:
resources/sql/004_metadata_auth_management.sqlresources/sql/005_metadata_project_configuration.sql
004 creates Keycloak-backed metadata users and project memberships. 005
creates project and project database routing tables with uniqueness, role/type,
and pool-size constraints.
Frontend System Management
/system-admin is shown only after GET /api/v1/admin/me confirms metadata
admin access. The page lets admins maintain metadata users, project members,
projects, project database routing for biz_data and iot_data, connection
health checks. This replaces direct SQL editing for normal project onboarding.