Skip to content

test(api): pin reshape security paths — STS-error fail-closed + region normalization regression guards #151

@cristim

Description

@cristim

Summary

PR #79 + the follow-up commit f44b06567 hardened resolveAWSCloudAccountID to fail closed on STS errors, preventing cross-tenant recommendation leaks in multi-tenant deployments. The fix landed without regression tests for the new failure paths — the existing internal/api/exchange_lookup_test.go covers the happy paths and the legitimate "no AWS context" fall-through but does not exercise:

  • Transient STS error → resolveAWSCloudAccountID returns a non-nil error, purchaseRecLookupFromStore aborts, handler returns 500/error to client.
  • AWS SDK config load failure → returns ("", nil) and skips the AccountIDs filter (legitimate path, distinct from the STS-error path).
  • Region query-string omitted → handler normalizes from cfg.Region, store query is region-scoped (the MAJOR fix from afc3aa1ff).
  • ListCloudAccounts error → bubbles up as wrapped error with list cloud accounts for reshape scope: prefix.

Without these, a future refactor can silently break the security gates that the recent fixes added.

Why these specifically

These arent UI/UX concerns — they are security regression guards. The CRITICAL failure mode they prevent is "transient STS error in a multi-tenant deployment shows tenant A their alternatives + tenant B sources mixed in". The fix is in place; the test pinning it isnt.

Proposed tests

All in internal/api/exchange_lookup_test.go:

// Mock the STS-resolver primitive to return an error.
func TestResolveAWSCloudAccountID_FailsClosedOnSTSError(t *testing.T) { ... }

// Same primitive returns ("", nil) — legitimate Azure/GCP host path.
func TestResolveAWSCloudAccountID_PassesNilWhenNoAWSContext(t *testing.T) { ... }

// Mock a fake recsLister returning an error from ListStoredRecommendations.
func TestPurchaseRecLookupFromStore_PropagatesStoreError(t *testing.T) { ... }

// Region query-string empty — handler normalizes from cfg.Region.
func TestHandleRIExchangeReshape_EmptyRegionUsesConfigRegion(t *testing.T) { ... }

The STS-error test is the most important — it pins the multi-tenant safety contract.

References

Severity

Low-Medium — no current bug, but a regression guard for an addressed CRITICAL.

Effort

Small — ~80 LOC, all in one test file. Mocking STS GetCallerIdentity requires an extra interface seam (stsClient) which doesnt exist today; either add it or use a higher-level test that drives the failure through the public Handler API.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions