subseam
control-plane/ auth/ resolve.ts/ resolvePrincipal
PR #142 · 3 seams disturbed
resolvePrincipal function
resolvePrincipal(token: string): Promise<Principal>
Analyze 2
Verify 71%
Secure 1
Enforce
source resolve.ts : 24–31
packages/control-plane/src/auth/resolve.ts
24export async function resolvePrincipal(token: string) {
25 if (!token) return AnonymousPrincipal;
26 const claims = await verifyToken(token);
27 const p = await db.principals.findByEmail(claims.email);
28 p.accounts = await accessibleAccounts(p.id);
29 return p;
30}
relationships
callers 3
  • cselectActiveAccountauth/select-active-account.ts
  • cmeRouteroutes/me.ts
  • cauthenticategateway/authenticate.ts
callees 3
  • cverifyTokenauth/verify-token.ts
  • cfindByEmaildb/principals.ts
  • caccessibleAccountsauth/accessible-accounts.ts
analysis 3 products · PR #142 scope
Analyzetension 2 findings · behavior changed
behavioral history
▶ TIP a1b2c3d changed
null-token path now returns AnonymousPrincipal; memberships resolved eagerly
9f8e7d2 changed
added account_identity join to principal resolution
6 commits · behavior preserved  
0c1d2e4 introduced
extracted from authMiddleware into a standalone seam
tension
trajectory
Resolution widened 3× across 4 commits — approaching god-function.
Each change added a fetch (claims, principal, accounts, memberships). The seam now owns four concerns. resolve.ts:24
co-change-gap
Callers in gateway/ not updated for the eager-membership change.
authenticate still assumes lazy membership load. gateway/authenticate.ts:51
Securetaint 1 path · sanitizer absent
sql · source → sink
Untrusted token claim reaches a SQL lookup with no sanitizer.
token·header claims.email findByEmail·sql
sanitizer absent   1 unresolved escape   db/principals.ts:18
Verifycoverage empirical-partial · 71%
asserted
71%
residue (gap)
29%
write a test: null-token → AnonymousPrincipal
write a test: revoked-token → raise
Enforcechecks
Convention & standards checks on this seam. Enable Enforce