Skip to content

Add KeyResolver for transaction context to credential key mapping#56

Merged
arnaugiralt merged 5 commits intomasterfrom
feat/key-resolver
Mar 9, 2026
Merged

Add KeyResolver for transaction context to credential key mapping#56
arnaugiralt merged 5 commits intomasterfrom
feat/key-resolver

Conversation

@arnaugiralt
Copy link
Member

@arnaugiralt arnaugiralt commented Mar 6, 2026

Summary

Adds a KeyResolver abstraction that lets providers resolve credential keys (e.g., tenant IDs) from standard transaction context fields instead of requiring explicit overrides in tx.Data on every request.

  • KeyResolver interface + ResolveFromContext helper with strict fallback chain: tx.Data override → resolver → error. Malformed overrides never fall through (fail-strict).
  • StaticMapping built-in implementation: declarative rule table with glob patterns, specificity ranking, and fail-closed on no match. Ambiguous rules (equal specificity, overlapping patterns) are detected and warned at construction time — no per-request overhead.
  • Integrated into microsoft.RefreshTokenSourceTenantID is now resolvable via KeyResolver when absent from tx.Data. Resource remains required in tx.Data (per-request concern). validTenantID regex runs regardless of source.
  • Reference docs, tutorial, and onboarding guide updated.

Motivation

The Connect platform only sends explicit credential keys (like TenantID) in context data when a connector overrides them. Most requests carry only standard fields (VendorID, MarketplaceID, etc.). Without a resolver, every request must include TenantID — a requirement that doesn't match real-world usage.

Design

Follows the module's existing pattern: interface + built-in implementation, optional in Config.

Existing pattern New parallel
TokenStore interface KeyResolver interface
FileStore built-in impl StaticMapping built-in impl
Config struct with optional field KeyResolver in Config, optional

Changes from review

  • Ambiguous rule detection moved to startup (cae15f2): StaticMapping now detects overlapping rule pairs at construction time using the same fieldsMayOverlap heuristic as Mux.Handle (PR feat(contrib): add reusable auth building blocks and request multiplexer #48 precedent). Per-request tie-breaking warning removed from ResolveKey — hot path is allocation-free. Disjoint literal values are recognized as non-overlapping and do not warn.

Test plan

  • ResolveFromContext unit tests: present/absent/malformed values, resolver delegation, error propagation
  • StaticMapping unit tests: specificity ranking, glob matching, tie-breaking, catch-all, empty key panic, no-match error
  • StaticMapping overlap detection: glob overlap warns at startup, disjoint literals no warning, different specificity no warning
  • Microsoft integration tests: resolver used when TenantID absent, tx.Data overrides resolver, malformed data errors with resolver configured, no resolver no data errors, resolver error propagated, path traversal rejected from resolver
  • make test-race passes
  • make lint passes

@arnaugiralt arnaugiralt force-pushed the feat/contrib-auth-flows branch from 890204a to c411a2f Compare March 6, 2026 15:06
arnaugiralt and others added 4 commits March 6, 2026 16:25
Introduce the KeyResolver interface for mapping transaction context to
credential keys, and the ResolveFromContext shared helper that providers
call instead of reading tx.Data directly. The helper implements a strict
fallback chain: tx.Data override → resolver → error. Malformed overrides
never fall through to the resolver (fail-strict).

Also adds ErrNoMappingMatch sentinel for StaticMapping (next commit).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Declarative rule table that maps transaction context fields to credential
keys using glob patterns. Rules are ranked by specificity (most non-empty
fields wins); ties are broken by registration order with a warning log.
No match returns ErrNoMappingMatch (fail-closed by design).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace extractString with ResolveFromContext in RefreshTokenSource.
TenantID is now resolved via tx.Data override → KeyResolver → error.
Resource remains required in tx.Data (per-request concern, nil resolver).

The validTenantID regex check runs after resolution regardless of source,
preventing path traversal from both tx.Data and resolver values.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Update contrib-plugins reference with KeyResolver interface,
ResolveFromContext helper, StaticMapping API, and MappingRule fields.
Update Microsoft SAM tutorial with resolver guidance in "Going further".
Update onboarding guide with KeyResolver cross-reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Base automatically changed from feat/contrib-auth-flows to master March 6, 2026 15:46
@arnaugiralt arnaugiralt marked this pull request as ready for review March 6, 2026 15:46
…r-request

Move tie-breaking warning from ResolveKey (per-request hot path) to
NewStaticMapping (construction time), matching the pattern established
for Mux.Handle in PR #48. Add rulesMayOverlap heuristic that reuses
the existing fieldsMayOverlap/containsGlob helpers from mux.go.

Disjoint literal values (e.g., "EU-germany" vs "US-east") are
recognized as non-overlapping and do not trigger a warning.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@arnaugiralt arnaugiralt requested a review from qarlosh March 9, 2026 08:50
@arnaugiralt arnaugiralt merged commit 1469d70 into master Mar 9, 2026
12 checks passed
@arnaugiralt arnaugiralt deleted the feat/key-resolver branch March 9, 2026 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants