Files
support_backend/specs/010-identity-auth/checklists/requirements.md
T
saqib mirandClaude Sonnet 5 40687f68fa feat(010-identity-auth): real staff login, session verification, and role gating
Replaces the no-op fastify.authenticate stub and the never-implemented
identity/auth login with real bcrypt password verification, JWT session
issuance/verification (reusing the existing JWT_SECRET), and a Redis-backed
revocation denylist for logout. Adds requireRole('ADMIN') to admin-only
configuration writes across 002-009 that previously relied on a decorator
that never actually checked anything. Adds self-identity (GET /auth/me,
re-validated against live account state) and admin-provisioned accounts
(POST /admin/users).

Making the auth check genuinely reject invalid/missing tokens exposed that
~18 pre-existing integration test files called already-gated routes with no
Authorization header (safe against the old no-op stub, broken against a real
one) — fixed via a shared tests/helpers/auth.ts (loginAs/authHeader) and a
file-by-file pass, plus two related SLA-run cleanup races exposed once admin
setup calls in those files' own beforeAll blocks started actually succeeding.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-07 12:45:37 +05:30

4.0 KiB

Specification Quality Checklist: Identity and Authentication

Purpose: Validate specification completeness and quality before proceeding to planning Created: 2026-09-07 Feature: spec.md

Content Quality

  • No implementation details (languages, frameworks, APIs)
  • Focused on user value and business needs
  • Written for non-technical stakeholders
  • All mandatory sections completed

Requirement Completeness

  • No [NEEDS CLARIFICATION] markers remain
  • Requirements are testable and unambiguous
  • Success criteria are measurable
  • Success criteria are technology-agnostic (no implementation details)
  • All acceptance scenarios are defined
  • Edge cases are identified
  • Scope is clearly bounded
  • Dependencies and assumptions identified

Feature Readiness

  • All functional requirements have clear acceptance criteria
  • User scenarios cover primary flows
  • Feature meets measurable outcomes defined in Success Criteria
  • No implementation details leak into specification

Notes

  • This feature was not on the original 11-phase roadmap — it surfaced as a genuine blocking gap while planning supporthub-web's 001-agent-admin-ui: fastify.authenticate has been a complete no-op stub since 002, and identity/auth's login endpoint has never taken a password. Numbered 010 in supporthub-api's own sequence since it's a real, immediately-needed backend prerequisite, not deferred hardening.
  • User/UserRole (with two seeded-but-passwordless demo accounts, admin@supporthub.internal/agent@supporthub.internal) and the AuthUser/JwtPayload types in src/common/types were all found already scaffolded, unwired, and clearly intended for exactly this feature since the original pre-speckit scaffold — this is a "finish the originally-intended wiring" feature, not a new design invented from nothing.
  • Scope is deliberately narrow: real login + real route gating + role checks + a self-identity endpoint + admin-created accounts + logout. Password reset, MFA, rate-limiting, and registration are explicitly out of scope (Assumptions), matching Phase 11's own "security hardening pass" as the more appropriate later home for those.
  • All items pass; no revision iterations were needed.
  • Implementation-time finding: making fastify.authenticate genuinely reject invalid/missing tokens (FR-004) had a far larger blast radius than this feature's own tasks.md anticipated. Dozens of routes across features 002-009 were already declared with fastify.authenticate as a preHandler — safe to write against a no-op stub, but every one of those pre-existing integration tests had been calling them with no Authorization header. Making the check real broke ~18 integration test files suite-wide, requiring a tests/helpers/auth.ts (loginAs/ authHeader) and a file-by-file pass adding real bearer tokens, well beyond the mechanical requireRole('ADMIN') rollout research.md had scoped for. A related, recurring bug: several files already declared a local const token = issueIntegrationToken(...) for the unrelated 002 customer-trust-boundary flow, and naming the new admin/agent token variable token in the same scope produced a ReferenceError: Cannot access 'token' before initialization — a genuine temporal-dead-zone collision, not a tooling bug — fixed by using a non-colliding name (authToken/adminToken/agentToken) per file.
  • A second, subtler implementation-time finding: once admin-setup calls in test beforeAll blocks started actually succeeding (previously they silently 401'd against the no-op stub), wildcard/global SLA policies created by one integration test file could genuinely match tickets created by another file running against the same shared throwaway Postgres, leaving orphaned sla_run rows that RESTRICT-violated the FK on cleanup. Fixed by widening the affected files' afterAll cleanup to delete sla_run rows by ticketId and by policyId, not just one or the other.