From 9ec7d3e155323569b56ab5032ba36b3222428fa5 Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Thu, 7 May 2026 10:38:27 +0100 Subject: [PATCH] vault backup: 2026-05-07 10:38:27 --- 01 Projects/cc-dashboard/CC Dashboard.md | 5 + 99 Daily/2026-05-07.md | 10 ++ .../azure-ad-sso-migration-user-isolation.md | 92 +++++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 99 Daily/2026-05-07.md create mode 100644 wiki/tech-patterns/azure-ad-sso-migration-user-isolation.md diff --git a/01 Projects/cc-dashboard/CC Dashboard.md b/01 Projects/cc-dashboard/CC Dashboard.md index 72efcbb..ec24c69 100644 --- a/01 Projects/cc-dashboard/CC Dashboard.md +++ b/01 Projects/cc-dashboard/CC Dashboard.md @@ -177,6 +177,10 @@ All endpoints except `/auth/login` require valid JWT in `Authorization: Bearer { - **Recent fixes:** Accurate time tracking with interval union (no double-counting), project metadata fields, auto-detect repo URL from git remote, chart null-safety, async safety (selectinload, execute delete) ## Sessions +### 2026-05-07 – Set up SSO with user isolation, +**Asked:** Set up SSO with user isolation, disable personal login, and map vadymsamoilenko@oliver.agecny to VadymSamoilenko@oliver.agecny. +**Done:** Implemented Azure AD SSO authentication with JWKS token validation, disabled legacy login endpoints, added user isolation, and migrated user account mapping. + ### 2026-05-06 – Developer requested calendar view with project **Asked:** Developer requested calendar view with project time tracking, Azure DevOps sync, and daily task planner for work planning hub. **Done:** Implemented calendar display, cache control fixes, and Live Feed bug fixes; deployed to production server successfully. @@ -268,6 +272,7 @@ All endpoints except `/auth/login` require valid JWT in `Authorization: Bearer { ## Change Log | Date | Requested | Changed | Files | |------|-----------|---------|-------| +| 2026-05-07 | SSO setup with user isolation | sso.py, auth.py, models.py, routers/auth.py — JWKS validation, removed /login endpoint, added azure_oid field, user migration | src/sso.py, src/auth.py, src/models.py, src/routers/auth.py | | 2026-05-06 | Projects toFixed error | Add null checks and fallback values, verify rendering | ProjectsView.js, CardContent.vue | | 2026-05-06 | Fix undefined toFixed() | Add null check for toFixed() call, verify server deployment | ProjectsView-CZF7uexl.js, CardContent.vue | | 2026-05-06 | Fix Projects TypeError | Add null check before toFixed call | ProjectsView-CZF7uexl.js, CardContent.vue | diff --git a/99 Daily/2026-05-07.md b/99 Daily/2026-05-07.md new file mode 100644 index 0000000..2a31b0e --- /dev/null +++ b/99 Daily/2026-05-07.md @@ -0,0 +1,10 @@ +--- +date: 2026-05-07 +tags: [daily] +--- + +## Session Log + +- 10:37 (5min) | `cc-dashboard` + - **Asked:** Set up SSO with user isolation, disable personal login, and map vadymsamoilenko@oliver.agecny to VadymSamoilenko@oliver.agecny. + - **Done:** Implemented Azure AD SSO authentication with JWKS token validation, disabled legacy login endpoints, added user isolation, and migrated user account mapping. diff --git a/wiki/tech-patterns/azure-ad-sso-migration-user-isolation.md b/wiki/tech-patterns/azure-ad-sso-migration-user-isolation.md new file mode 100644 index 0000000..a9fe261 --- /dev/null +++ b/wiki/tech-patterns/azure-ad-sso-migration-user-isolation.md @@ -0,0 +1,92 @@ +--- +tags: [tech-patterns, auto-generated] +source: cc-dashboard +created: 2026-05-07 +--- + +# Azure AD SSO Integration with User Isolation + +## When to use +When migrating an existing application from local authentication to Azure AD Single Sign-On (SSO), requiring user account mapping between legacy and SSO identities, with complete isolation of local login mechanisms. + +## Prerequisites +- Azure AD tenant with application registration +- Application registered as Single Page Application (SPA) in Azure portal +- JWKS (JSON Web Key Set) endpoint available from Azure AD +- Backend framework supporting JWT token validation (Python/FastAPI recommended) +- Existing user database schema with password_hash and unique identifier columns + +## Steps + +1. **Register SPA in Azure AD** + - Add your application URL (e.g., `https://optical-dev.oliver.solutions/cc-dashboard/`) as a Redirect URI in Azure portal + - Note the Client ID and JWKS endpoint URL + +2. **Create SSO validation module** (`src/sso.py`) + - Implement JWKS token validation + - Cache public keys from Azure AD JWKS endpoint + - Validate token signature and claims (issuer, audience, expiration) + - Extract user identity from token (e.g., `preferred_username` claim) + +3. **Update authentication router** (`src/routers/auth.py`) + - Create new `POST /api/auth/microsoft` endpoint that accepts Azure AD tokens + - Remove legacy endpoints: `/login`, `/change-password`, `/register` + - Implement token validation and user lookup/creation in endpoint + +4. **Modify user model** (`src/models.py`) + - Add `azure_oid` column (nullable, unique) to store Azure AD object ID + - Make `password_hash` nullable to allow SSO-only users + - Add migration to alter existing schema + +5. **Map existing users to SSO identities** + - For each legacy user requiring SSO access, update `azure_oid` with their Azure AD object ID + - Example: map `vadymsamoilenko@oliver.agency` → `VadymSamoilenko@oliver.agecny` by setting matching `azure_oid` + +6. **Implement development bypass** (`src/auth.py`) + - Add `DEV_AUTH_BYPASS` flag for local development + - Auto-login with test user when SSO is unavailable locally + - Disable this in production environments + +7. **Remove password-based authentication** + - Disable local login endpoints completely + - Prevent password reset/change operations + - Ensure all user creation routes require SSO validation + +## Key Configuration + +```python +# .env or config +AZURE_AD_JWKS_URL=https://login.microsoftonline.com/{tenant}/discovery/v2.0/keys +AZURE_AD_CLIENT_ID=your-client-id +AZURE_AD_TENANT=your-tenant-id +DEV_AUTH_BYPASS=false # Set to true locally only +``` + +```python +# src/sso.py - Example validation +import jwt +from functools import lru_cache + +@lru_cache(maxsize=1) +def get_jwks(): + # Fetch and cache Azure AD public keys + pass + +def validate_token(token: str): + # Validate signature using JWKS + # Check issuer, audience, expiration + # Return claims + pass +``` + +## Gotchas + +- **User mapping case sensitivity**: Azure AD usernames may differ in casing from legacy usernames. Implement case-insensitive lookup or explicit mapping table. +- **Token expiration handling**: Azure AD tokens expire quickly. Implement token refresh logic on the frontend; don't rely on long-lived tokens. +- **JWKS caching**: Public keys rotate periodically. Implement cache invalidation or short TTL; don't cache indefinitely. +- **Nullable password fields**: Ensure password validation logic handles null values gracefully; add database constraint to prevent password-less local login attempts. +- **Development environment**: DEV_AUTH_BYPASS must be explicitly disabled in production; verify this during deployment checks. +- **Redirect URI matching**: Azure portal requires exact URL match (protocol, domain, path). Test with full deployment URL before going live. + +## Source +Project: cc-dashboard