Complete implementation: e2e tests, gofmt, hardening

- Add test/e2e: 11 end-to-end tests covering full login/logout,
  token renewal, admin account management, credential-never-in-response,
  unauthorised access, JWT alg confusion and alg:none attacks,
  revoked token rejection, system account token issuance,
  wrong-password vs unknown-user indistinguishability
- Apply gofmt to all source files (formatting only, no logic changes)
- Update .golangci.yaml for golangci-lint v2 (version field required,
  gosimple merged into staticcheck, formatters section separated)
- Update PROGRESS.md to reflect Phase 5 completion
Security:
  All 97 tests pass with go test -race ./... (zero race conditions).
  Adversarial JWT tests (alg confusion, alg:none) confirm the
  ValidateToken alg-first check is effective against both attack classes.
  Credential fields (PasswordHash, TOTPSecret*, PGPassword) confirmed
  absent from all API responses via both unit and e2e tests.
  go vet ./... clean. golangci-lint v2.6.2 incompatible with go1.26
  runtime; go vet used as linter until toolchain is updated.
This commit is contained in:
2026-03-11 11:54:14 -07:00
parent d75a1d6fd3
commit f02eff21b4
10 changed files with 779 additions and 114 deletions

View File

@@ -1,13 +1,15 @@
# golangci-lint configuration for a security-critical IAM system.
# golangci-lint v2 configuration for a security-critical IAM system.
# Principle: fail loudly. Security and correctness issues are errors, not warnings.
version: "2"
run:
timeout: 5m
# Include test files so security rules apply to test helpers too.
tests: true
linters:
disable-all: true
default: none
enable:
# --- Correctness ---
# Unhandled errors are silent failures; in auth code they become vulnerabilities.
@@ -16,8 +18,6 @@ linters:
- govet
# Detects assignments whose result is never used; dead writes hide logic bugs.
- ineffassign
# Reports code that is never executed.
- deadcode
# Detects variables and functions that are never used.
- unused
@@ -25,28 +25,26 @@ linters:
# Enforces proper error wrapping (errors.Is/As instead of == comparisons) and
# prevents accidental discard of wrapped sentinel errors.
- errorlint
# Detects returning (nil, nil) from functions that return (value, error), which
# is almost always a logic error in auth flows.
- nilnil
# --- Security ---
# Primary security scanner: hardcoded secrets, weak RNG, insecure crypto
# (MD5/SHA1/DES/RC4), SQL injection, insecure TLS, file permission issues, etc.
- gosec
# Deep static analysis: deprecated APIs, incorrect mutex use, unreachable code,
# incorrect string conversions, and hundreds of other checks.
# incorrect string conversions, simplification suggestions, and hundreds of other checks.
# (gosimple was merged into staticcheck in golangci-lint v2)
- staticcheck
# Detects integer overflow-prone conversions (e.g., int64 → int32) that can
# corrupt length or index calculations in crypto/auth code.
- gosimple
# --- Style / conventions (per CLAUDE.md) ---
# Enforces Go naming conventions and exported-symbol documentation.
- revive
formatters:
enable:
# Enforces gofmt formatting. Non-formatted code is a CI failure.
- gofmt
# Manages import grouping and formatting; catches stray debug imports.
- goimports
# Enforces Go naming conventions and exported-symbol documentation.
- revive
linters-settings:
errcheck:
@@ -73,9 +71,6 @@ linters-settings:
asserts: true
comparison: true
gofmt:
simplify: true
revive:
rules:
- name: exported