Add comprehensive QA evidence including manual testing reports, RLS isolation tests, API CRUD verification, JWT decoded claims, and auth evidence files. Include updated notepads with decisions, issues, and learnings from full-stack debugging sessions. Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
5.5 KiB
5.5 KiB
BLOCKER: Task Creation Fails - Missing sub Claim in JWT
Discovery Context
- Test: Phase 3 - Task 1: Create New Task (POST /api/tasks)
- Date: 2026-03-05
- Status: ❌ BLOCKED - Cannot proceed with API CRUD tests
Issue Description
Task creation endpoint returns 400 Bad Request with error "Invalid user ID".
Root Cause Analysis
API Code Expectation (TaskEndpoints.cs line 62):
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var createdById))
{
return TypedResults.BadRequest("Invalid user ID");
}
JWT Payload Reality:
{
"exp": 1772729098,
"iat": 1772725498,
"jti": "5387896f-52a2-4949-bd6e-cbbb09c97a86",
"iss": "http://localhost:8080/realms/workclub",
"aud": "workclub-api",
"typ": "Bearer",
"azp": "workclub-app",
"sid": "c5f5ef18-6721-4b27-b577-21d8d4268a06",
"acr": "1",
"allowed-origins": ["http://localhost:3000"],
"scope": "profile email",
"email_verified": true,
"clubs": "64e05b5e-ef45-81d7-f2e8-3d14bd197383,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda",
"name": "Admin User",
"preferred_username": "admin@test.com",
"given_name": "Admin",
"family_name": "User",
"email": "admin@test.com"
}
Missing Claim: sub (subject) claim is absent from JWT token
Impact Assessment
Affected Endpoints
All endpoints requiring user identification via sub claim are broken:
POST /api/tasks- Create task (requires createdById)POST /api/shifts- Create shift (likely requires createdById)- Any endpoint that needs to identify the current user
Scope of Blockage
- Phase 3: API CRUD Tests - ❌ BLOCKED (cannot create tasks/shifts)
- Phase 4: Frontend E2E Tests - ❌ BLOCKED (depends on working API)
- Phase 5: Integration Flow - ❌ BLOCKED (step 3 creates task)
- Phase 6: Edge Cases - ⚠️ PARTIALLY BLOCKED (some tests need task creation)
Tests Still Executable
- ✅ Read operations: GET /api/tasks, GET /api/shifts (already tested)
- ✅ Authorization tests (401/403)
- ✅ Tenant isolation verification (already completed)
Expected vs Actual
Expected (per plan)
Definition of Done: "Keycloak login returns JWT with club claims"
JWT should contain:
- ✅
clubsclaim (present:"64e05b5e-ef45-81d7-f2e8-3d14bd197383,3b4afcfa-1352-8fc7-b497-8ab52a0d5fda") - ❌
subclaim (missing: should contain Keycloak user UUID) - ✅
audclaim (present:"workclub-api") - ✅
emailclaim (present:"admin@test.com")
Actual Behavior
- Keycloak token includes
clubscustom claim ✅ - Keycloak token missing standard
sub(subject) claim ❌ - API rejects all create operations requiring user identification ❌
Keycloak Configuration Gap
Standard OpenID Connect Claim: The sub claim is a mandatory claim in OIDC spec and should automatically be included by Keycloak.
Possible Causes:
- Client protocol mapper configuration incorrect
- User account missing UUID in Keycloak
- Token mapper overriding default behavior
- Keycloak realm export missing default mappers
Verification Attempted:
# Userinfo endpoint returned 403 (also requires fix)
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:8080/realms/workclub/protocol/openid-connect/userinfo
# HTTP 403
Workaround Options
Option 1: Fix Keycloak Configuration (RECOMMENDED)
- Add
subprotocol mapper toworkclub-apiclient - Ensure mapper includes Keycloak user ID as UUID
- Re-acquire tokens after config change
Option 2: Change API to Use Email
- Modify
TaskEndpoints.csto useemailclaim instead ofsub - Query database for member record by email + tenant context
- Risk: Email not unique across tenants, requires additional lookup
Option 3: Skip Create Operations in QA
- Continue testing with read-only operations
- Mark create/update/delete tests as "NOT TESTED - Blocker"
- Report as critical finding in F3 verdict
Recommendation
STOP F3 QA execution at this point.
This is a CRITICAL BLOCKER preventing:
- 30+ scenarios in Phase 3 (API CRUD - all create/update operations)
- All of Phase 4 (Frontend E2E - UI create workflows)
- All of Phase 5 (Integration - 10-step journey starts with task creation)
- Most of Phase 6 (Edge cases with concurrent writes)
Estimated Impact: 40/46 remaining scenarios (87% of remaining QA suite) are blocked.
F3 QA Status Update
Scenarios Completed
- Phase 1: Infrastructure (12/12) ✅
- Phase 2: RLS Isolation (6/6) ✅ (4 PASS, 2 FAIL - shifts RLS missing)
- Total: 18/58 scenarios (31%)
Scenarios Blocked
- Phase 3: API CRUD (14 scenarios) ❌ BLOCKED
- Phase 4: Frontend E2E (6 scenarios) ❌ BLOCKED
- Phase 5: Integration (10 steps) ❌ BLOCKED
- Phase 6: Edge Cases (6 tests, ~4 blocked) ⚠️ MOSTLY BLOCKED
- Total: ~40 scenarios blocked
Blockers Identified
- Shifts RLS Policy Missing (Phase 2, Test 4-5): Tenant data leakage on shifts table
- JWT Missing
subClaim (Phase 3, Test 1): Cannot create tasks/shifts
Next Steps
For Development Team:
- Fix Keycloak configuration to include
subclaim in JWT - Implement RLS policy on
shiftstable (matchingwork_itemspolicy) - Re-run F3 Manual QA from Phase 3 after fixes
For QA Agent:
- Mark F3 QA as INCOMPLETE due to critical blocker
- Generate final report with 18/58 scenarios executed
- Document both blockers with reproduction steps
- Provide FAIL verdict with clear remediation path