Skip to content

feat(vault): decompose Vault into HSM capability interfaces#12

Closed
canaan5 wants to merge 3 commits into
mainfrom
feat/vault-hsm-interfaces
Closed

feat(vault): decompose Vault into HSM capability interfaces#12
canaan5 wants to merge 3 commits into
mainfrom
feat/vault-hsm-interfaces

Conversation

@canaan5

@canaan5 canaan5 commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

The core interface-design step toward HSM support — making the vault façade ready for any HSM adapter to implement out of the box. Source-compatible (no method-set change), so it's safe to land before the v1 vault freeze.

What changed

vault.Vault is now the composition of three small capability interfaces:

type PINEncryptor interface { EncryptPINBlock(...) ([]byte, error) }   // issuer / trusted context (takes clear PIN)
type PINTranslator interface { TranslatePIN(...) ([]byte, error) }     // acquirer/switch (encrypted block in/out)
type Macer interface { GenerateMAC(...); VerifyMAC(...) }              // MAC under device-resident key

type Vault interface { PINEncryptor; PINTranslator; Macer }            // full façade (SoftVault, SealedVault)

So an adapter implements exactly what its hardware supports:

  • a general-purpose PKCS#11 HSMMacer (and possibly PINEncryptor)
  • a payment HSM (Thales payShield / Futurex) → also PINTranslator

Callers type-assert for the narrowest capability they need:

tr, ok := v.(vault.PINTranslator)
if !ok { return errors.New("configured vault cannot translate PINs") }

The PIN-security contract, encoded in the type system

PINTranslator's doc makes the rule explicit: a conforming hardware implementation must re-encipher atomically inside the device so the clear PIN never leaves it (PCI PIN Security). An adapter that can't (e.g. stock PKCS#11, which has no atomic-translate mechanism) must not implement the interface — its absence is the signal that PIN translation isn't available. This resolves the finding from #11.

Verification

  • Vault method set unchanged → SoftVault/SealedVault still satisfy it (compile-time assertions added for each capability).
  • New TestCapabilityDetection shows a MAC-only adapter is correctly not usable as a PINTranslator.
  • gofmt/vet clean; ./... builds; vault/flow/gateway pass under -race.

Next (separate PRs)

Touches CHANGELOG.md [Unreleased] like #8/#9 — trivial conflict for whichever merges later.

canaan5 added 2 commits June 4, 2026 03:04
Make the key-management façade HSM-adapter-ready by splitting it into small
capability interfaces, so an adapter implements exactly what its device supports.

- Add PINEncryptor, PINTranslator, and Macer. Vault is now their composition,
  so it keeps the same method set — source-compatible; SoftVault and SealedVault
  still satisfy Vault unchanged.
- PINTranslator documents the PCI PIN Security contract: a conforming hardware
  implementation must re-encipher the PIN block atomically inside the device so
  the clear PIN never leaves it; an adapter that cannot (e.g. stock PKCS#11) must
  not implement the interface, since callers rely on its presence to mean the
  operation is PIN-secure.
- A general-purpose PKCS#11 HSM provides Macer (and possibly PINEncryptor); a
  payment HSM (Thales payShield, Futurex) additionally provides PINTranslator.
  Callers type-assert for the narrowest capability they need.

Adds capability-detection tests. gofmt/vet clean; ./... builds, vault/flow/gateway
pass under -race.
@canaan5 canaan5 closed this Jun 9, 2026
@canaan5 canaan5 deleted the feat/vault-hsm-interfaces branch June 9, 2026 11:45
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant