Skip to content

In-Memory Adapters as Reference Implementations

Context and Problem Statement

Each output port Protocol needs at least one concrete implementation. Test stubs (used in service-level tests) satisfy the Protocol structurally but lack real behaviour — e.g., a stub PolicyRepository returns a fixed list regardless of the resource URI. Should we ship production-quality in-memory adapters alongside the package, or keep them as test-only fixtures?

Decision Drivers

  • In-memory adapters enable running the proxy without any external infrastructure (useful for development, demos, and CI)
  • They serve as executable documentation of what each port Protocol expects
  • Service-layer tests use minimal stubs; integration tests need adapters with real behaviour (e.g., glob matching, hashing)
  • New contributors can understand the port contract by reading the in-memory implementation

Considered Options

  • Test stubs only — in-memory logic lives in tests/ conftest fixtures
  • In-memory adapters as first-class code in src/hdc_auth_proxy/adapters/memory/
  • Abstract base classes with in-memory subclasses

Decision Outcome

Chosen option: "In-memory adapters as first-class code in adapters/memory/", because they provide a zero-dependency reference implementation for every output port while doubling as integration-test infrastructure.

Implementation

Each in-memory adapter lives in src/hdc_auth_proxy/adapters/memory/ and implements the corresponding port Protocol via structural subtyping (no explicit inheritance):

Adapter Protocol Key behaviour
InMemoryTokenValidator TokenValidator dict[str, TokenClaims] lookup by raw token string
InMemoryPrincipalResolver PrincipalResolver dict[str, Principal] lookup by subject_id
InMemoryApiKeyValidator ApiKeyValidator SHA-256 hash before lookup (see ADR-0008)
InMemoryPolicyRepository PolicyRepository fnmatch glob matching on resource_pattern
InMemoryResourceRepository ResourceRepository dict[str, ProtectedResource] lookup by URI

All adapters expose add_* methods for populating data in tests and development.

Consequences

  • Good, because the proxy can run end-to-end with zero external dependencies
  • Good, because integration tests use the same code that ships in the package
  • Good, because new port implementations can be validated against in-memory adapter behaviour
  • Neutral, because in-memory adapters are not suitable for production (no persistence, no distributed state)
  • Bad, because maintaining two sets of adapters (in-memory + production) increases surface area

Confirmation

  • tests/test_integration_inmemory.py wires all in-memory adapters through services and verifies end-to-end authentication + authorization
  • Architecture test test_all_adapters_modules_importable confirms all adapter modules import cleanly
  • from hdc_auth_proxy.adapters.memory import * exports all five adapters

More Information