5. Data Security & Privacy

Levi’s Buy Plan Platform · posture reference & v2 revalidation
v2 · Sprint 13
Jun 27 – Jul 4, 2026

Assertion: the security architecture is unchanged by design — v2 added no new trust boundaries, external services, or data flows — and the controls were re-verified under change.

5.1 Posture statement (unchanged in v2)

The reference table for compliance filing. Every control below predates v2 and was carried through it unchanged; the only v2-adjacent movement is the role model, which expanded within the existing RBAC framework (noted in 5.2).

DomainControlImplementation
AuthenticationPasswordless OTP (primary) + password (alternative)Cryptographically random 6-digit OTP, 5-minute TTL, 3-attempt lockout with 60s cooldown, response shaped to prevent account enumeration; passwords hashed with bcrypt (cost 10).
Session managementShort-lived signed tokens, no refreshJWT (HS256, server-side secret), 12-hour TTL, stored in per-tab sessionStorage; users re-authenticate on expiry; token carries user, role, franchise and environment context.
AuthorizationRole-based access control + route guardsRole model enforced by middleware guards on every route; role normalization on input; v1 shipped four roles, v2 six (see 5.2).
Data-level accessFranchise-scoped filteringStore visibility filtered by the user’s franchise assignments (MSF-code matching) as parameterized SQL WHERE clauses — applied to every data query, independent of UI.
Injection defense100% parameterized SQLEvery database query is fully parameterized — zero string-built SQL — and independently audited against injection; comprehensive input sanitization on all request payloads.
Web hardeningSecurity headers + controlled CORSEnforced security headers on every response; CORS origins controlled per environment via configuration, never wildcarded in production.
Upload securityWhitelist + verification + hard limitsStrict file-type whitelisting with MIME verification (extension alone is not trusted); hard limits of 300 MB and 1M rows per upload.
Encryption in transitTLS 1.2+ everywhereHTTPS for browser→app and browser→API; TLS to database, SMTP, and S3.
Encryption at restAWS-managed encryptionAurora automatic encryption (AWS KMS); uploads/exports in S3 with SSE-S3.
Secrets managementEnvironment configuration, never codeSecrets injected via environment at deployment; deployment checklist mandates strong per-environment JWT_SECRET; committed env files hold template values only.
Data residencySingle AWS regionAll compute and data in one AWS region (single AZ); no cross-region replication by design.
PII handlingMinimal by design + full log maskingThe system processes business planning data, not consumer PII; user records hold business contact fields (name, work email, phone). Logs automatically mask sensitive data: passwords, tokens, and OTPs fully redacted; PII partially masked to remain traceable without exposure; error responses and diagnostics sanitized against information leakage.
Audit & loggingStructured logs with correlation IDsApplication/error/access logs retained 30 days with automated archival to S3 under lifecycle policies, supporting audit and compliance needs; cell-level audit metadata (who changed what and when) kept indefinitely inline in the database across all planning data; database-level audit logs not enabled (see 5.3).
BackupsPlatform-managedAurora automated backups with configurable retention; recovery relies on AWS-managed features per the NFR baseline.
Environment isolationSchema-per-environmentSeasonal environments isolated at the database-schema level; connection search-path is set per request and reset on release to prevent cross-environment access.

5.2 Revalidation for v2

v2 changed the data model, the UI, and the role model — the three places where a release of this shape could regress security. The bundled test log records 150+ security and privacy test cases passing post-v2 (itemized by category in Section 4.2 of the Code Quality page); the rows below map them to the specific questions v2 raises:

Question v2 raisesStatusEvidence
Does the new 4th hierarchy level open an access-control gap? VERIFIED BY DESIGN + TESTS Authorization is franchise/store-scoped, not hierarchy-level-scoped — the Platform level inherits the same route guards and SQL filters as existing levels. The passing suite (log) exercises this directly: store access allowed within the user’s franchise, denied outside it with a 404 (anti-enumeration), 403 when no franchise is configured, explicit admin/superadmin bypass tests, and access grants/denials logged — plus platform-level planning integration tests.
Was the role-model expansion (4 → 6 roles) done safely? TESTED Roles remain enforced by the same guard framework: the log shows per-endpoint role checks on the new v2 admin endpoints (dashboard summary, franchisee list, and store drill-down each require ADMIN/SUPERADMIN; FRANCHISE_MANAGER, LEVIS_MANAGER, and VIEWER explicitly rejected), invalid role names (SUPERUSER, ROOT, GUEST…) rejected with case normalization, and privilege escalation via token manipulation blocked. The expansion also fixed two v1 auth gaps: standard-user login and the non-functional change-password flow.
Any new code-level security findings after the v2 changes? CLEAN Post-v2 SonarQube analysis: 0 security issues, 0 security hotspots, rating A (dashboard).
Does the security test baseline still hold? TESTED Security testing aligned to the OWASP Top 10 — 0 critical/high findings (internal assessment; independent penetration test was out of scope): all 10 categories pass, including broken access control (5 tests), injection (6), and auth failures (5); plus targeted suites — OTP rate limiting (11), SQL parameterization (7), CORS/headers (11), upload security (30+).
Dependency CVE status? CLEAN npm audit records 0 critical / 0 high vulnerabilities (OWASP A06 record).
Secrets exposure? NO FINDINGS Deployment checklist enforces environment-based secrets; committed env files are template-only; no credentials in source.
Does the new UI or logging expose personal data? TESTED The new admin dashboard and user directory display business contact data (work email, login recency) and are role-gated to admin routes. Passing tests verify: password hashes never appear in API responses; the user bulk-upload CSV excludes password columns and values; onboarding passwords are shown once and excluded from result DTOs; error messages sanitize credential patterns; audit logs record failures without passwords and with obfuscated emails (t***t@e***e.c***m). The new exports table stores job metadata (storage key, status, expiry), not file contents.