Skip to content

TT-17102: Add features to support gateway wiring#153

Open
vladzabolotnyi wants to merge 13 commits into
TT-17100from
feat/TT-17102/add-features-to-support-gateway-wiring
Open

TT-17102: Add features to support gateway wiring#153
vladzabolotnyi wants to merge 13 commits into
TT-17100from
feat/TT-17102/add-features-to-support-gateway-wiring

Conversation

@vladzabolotnyi

@vladzabolotnyi vladzabolotnyi commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Description

Next tickets were reviewed, approved and merged to this branch:
TT-17242
TT-17487
TT-17244
TT-17243
TT-17245
TT-17246

Performance

This PR adds benchmarks covering the epic's performance acceptance criteria.
Run on Apple M4 Pro (darwin/arm64), Go benchmarks with in-process backends
(mocks / httptest), so the numbers isolate library overhead — real network
latency comes on top and is deployment-specific. Reproduce with:
go test -bench=. -run=XXX ./kv/internal/resolve ./kv/internal/store ./kv/registry

1. Whole-document resolution (ResolveAll — the startup path)

References in document ns/op per reference
20 23,364 ~1.2 µs
50 57,038 ~1.1 µs
100 110,233 ~1.1 µs

Scaling is linear at ~1.1 µs per reference (parse + walk + substitute +
re-serialize, zero-latency providers). Resolution cost is dominated by the
per-document JSON round trip, not by reference count.

2. Per-request Get through the SecretStore wrapper

Mode ns/op
cache hit 36 ns
cache disabled 1,844 ns

A cache-resident lookup costs ~36 ns.

3. Full production stack against a co-located Vault (KVv2 over httptest)

NewFromConfig registry → SecretStore → real Vault API client → HTTP:

Mode ns/op
cache off (every Get = one backend round trip) 44,368 (~44 µs)
cache on (steady state) 35.5 ns

One co-located Vault round trip through the entire stack costs ~44 µs;
the cache collapses that to nanoseconds.

Related Issue

Motivation and Context

Test Coverage For This Change

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Refactoring or add test (improvements in base code or adds test coverage to functionality)
  • Documentation updates or improvements.

Checklist

  • I have reviewed the guidelines for contributing to this repository.
  • Make sure you are requesting to pull a topic/feature/bugfix branch (right side). If PRing from your fork, don't come from your master!
  • Make sure you are making a pull request against our master branch (left side). Also, it would be best if you started your change off our latest master.
  • My change requires a change to the documentation.
    • I have manually updated the README(s)/documentation accordingly.
    • If you've changed APIs, describe what needs to be updated in the documentation.
  • I have updated the documentation accordingly.
  • Modules and vendor dependencies have been updated; run go mod tidy && go mod vendor
  • When updating library version must provide reason/explanation for this update.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • Check your code additions will not fail linting checks:
    • gofmt -s -w .
    • go vet ./...

* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add ability to override default factories when WithFactories opt is used

* test: add tests covering logic with factories overriding

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

CLA Assistant Lite bot:
Thank you for your submission, we really appreciate it. Like many open-source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution. You can sign the CLA by just posting a Pull Request Comment same as the below format.


I have read the CLA Document and I hereby sign the CLA


0 out of 2 committers have signed the CLA.
@vladzabolotnyi
@vlad Zabolotnyi
Vlad Zabolotnyi seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You can retrigger this bot by commenting recheck in this Pull Request

@vladzabolotnyi
vladzabolotnyi changed the base branch from main to TT-17100 July 7, 2026 07:06
@probelabs

probelabs Bot commented Jul 7, 2026

Copy link
Copy Markdown

This pull request introduces a comprehensive, pluggable Key-Value (KV) secrets management system. This new system supports multiple backends (Vault, Consul, environment variables, files, and inline configuration) and features a sophisticated two-phase initialization process. This allows remote secret stores to be configured using credentials sourced from local providers, resolving a common bootstrap challenge.

Files Changed Analysis

This is a large, primarily additive PR, introducing a new, well-tested subsystem. The changes are concentrated in the kv/ directory.

  • New Providers: The core of the feature is the introduction of five new secret providers in kv/providers/: env, file, inline, consul, and vault. Each is self-contained and comes with extensive tests.
  • Initialization Logic: The new file kv/registry/from_config.go implements the complex two-phase initialization logic, which is the central architectural pattern of this PR.
  • Resolution Enhancements: kv/internal/resolve/resolver.go is modified to include a WithLenientMode. This mode is critical for the two-phase init, as it allows references to not-yet-initialized remote stores to pass through as literals during the first phase.
  • Cache Bypass: A new cache-bypass mechanism is introduced via kv/context.go and implemented in kv/internal/store/store.go, allowing for forced re-fetching of secrets.
  • Dependency Updates: go.mod and go.sum have been updated to include new HashiCorp client libraries for Vault and Consul integration.
  • High Test Coverage: A substantial portion of the 4,700+ new lines consists of tests, indicating a high degree of validation for this new critical subsystem.

Architecture & Impact Assessment

  • What this PR accomplishes

    • Decouples secret management from static configuration, allowing secrets to be sourced dynamically from multiple backends.
    • Solves the bootstrap problem where credentials for a remote secret store (e.g., a Vault token) are themselves secrets, by allowing them to be sourced from a local provider (e.g., an environment variable).
    • Introduces security-hardened local providers for file and environment variable access.
  • Key technical changes introduced

    1. Two-Phase Initialization: registry.NewFromConfig first initializes local providers (env, file, inline) which have no external dependencies. It then uses a lenient resolver to process the configurations for remote providers (vault, consul), resolving any references to the already-initialized local stores. Finally, it initializes the remote providers with their resolved configurations.
    2. Security-Hardened Local Providers: The file provider is confined to a mandatory, absolute base_path to prevent directory traversal attacks. The env provider requires a prefix to limit the scope of accessible environment variables.
    3. Context-Driven Cache Bypass: The new kv.WithCacheBypass(ctx) function allows callers to instruct the system to ignore any cached secret value, fetch it directly from the source provider, and update the cache. This is useful for operational tasks like manual secret rotation.
  • Affected system components

    • The primary impact is on the application's startup and configuration-loading process. All components that consume secrets will now rely on this new KV registry.
  • Two-Phase Initialization Flow

graph TD
subgraph phase1 ["Phase 1: Bootstrap & Resolve"]
A[NewFromConfig with raw config] --> B{Parse kv.stores};
B --> C{Categorize Local vs. Remote stores};
C --|Local (env, file, inline)|--> D[Init Temp Registry with Local Stores];
D --> E[Resolve references in Remote Store configs];
E -- "Uses Lenient Resolver" --> F[Resolved Remote Configs];
end

subgraph phase2 ["Phase 2: Final Initialization"]
    G[Create Final Registry] --> H{Init All Stores};
    F -- "Feeds into" --> H;
    C -- "Local configs also feed into" --> H;
    H --> I[Final Registry Ready];
end

A --> G;

## Scope Discovery & Context Expansion
- **Broader Impact**: This is a foundational change that aligns the application with modern deployment practices (e.g., 12-factor app), where configuration and secrets are injected into the environment rather than being hardcoded. It provides a standardized and secure way to manage secrets across the entire application.
- **Further Exploration for Reviewers**:
  - Pay close attention to the logic in `kv/registry/from_config.go`, as it orchestrates the complex initialization flow.
  - Review the security implementations in `kv/providers/file/file.go` and `kv/providers/env/env.go` to validate the confinement mechanisms.
  - Note that the `k8s_files` provider type has been removed from `kv/provider.go`. Its functionality is now covered by the more generic and secure `file` provider, which is designed to handle Kubernetes' `AtomicWriter` symlink patterns for secret updates.
- **Performance**: The PR includes benchmarks demonstrating high performance. Cache hits for secrets are in the nanosecond range (~36ns), while a full round trip to a co-located Vault backend takes ~44µs. Document resolution at startup scales linearly at ~1.1µs per reference.


<details>
  <summary>Metadata</summary>

  - Review Effort: 4 / 5
  - Primary Label: feature


</details>
<!-- visor:section-end id="overview" -->

<!-- visor:thread-end key="TykTechnologies/storage#153@e889a78" -->

---

*Powered by [Visor](https://probelabs.com/visor) from [Probelabs](https://probelabs.com)*

*Last updated: 2026-07-10T11:37:38.340Z | Triggered by: pr_updated | Commit: e889a78*

💡 **TIP:** You can chat with Visor using `/visor ask <your question>`
<!-- /visor-comment-id:visor-thread-overview-TykTechnologies/storage#153 -->

@probelabs

probelabs Bot commented Jul 7, 2026

Copy link
Copy Markdown

Security Issues (2)

Severity Location Issue
🟡 Warning kv/providers/consul/consul.go:40
The Consul provider configuration allows disabling TLS certificate validation via `insecure_skip_verify`. When set to `true`, this makes the connection to Consul vulnerable to Man-in-the-Middle (MITM) attacks by allowing it to accept any certificate. While this may be necessary for development or testing with self-signed certificates, its use in production environments introduces a significant security risk.
💡 SuggestionAdd a prominent warning in the documentation for this feature, advising against its use in production. Consider logging a warning at application startup if this option is enabled to ensure operators are aware of the insecure configuration.
🟡 Warning kv/providers/env/env.go:83-92
The `env` provider allows an empty key, which results in a lookup of the environment variable named by the `prefix` itself. This is inconsistent with the `file` and `inline` providers, which both explicitly reject empty keys. This inconsistency can violate the principle of least surprise and may lead to unexpected behavior or misconfigurations.
💡 SuggestionFor consistency and to prevent potential confusion, consider rejecting empty keys in the `env` provider, similar to the other providers. This can be done by adding a check at the beginning of the `Get` method.
func (ep *envProvider) Get(_ context.Context, key string) (string, error) {
	if ep.prefix == &#34;&#34; {
		return &#34;&#34;, ErrPrefixRequired
	}

	if key == &#34;&#34; {
		// It&#39;s better to use a shared error for this if possible,
		// but for now we can define one in the env provider.
		return &#34;&#34;, errors.New(&#34;env: key must not be empty&#34;)
	}

	if ep.uppercase {
		key = strings.ToUpper(key)
	}

	return os.Getenv(ep.prefix + key), nil
}

Security Issues (2)

Severity Location Issue
🟡 Warning kv/providers/consul/consul.go:40
The Consul provider configuration allows disabling TLS certificate validation via `insecure_skip_verify`. When set to `true`, this makes the connection to Consul vulnerable to Man-in-the-Middle (MITM) attacks by allowing it to accept any certificate. While this may be necessary for development or testing with self-signed certificates, its use in production environments introduces a significant security risk.
💡 SuggestionAdd a prominent warning in the documentation for this feature, advising against its use in production. Consider logging a warning at application startup if this option is enabled to ensure operators are aware of the insecure configuration.
🟡 Warning kv/providers/env/env.go:83-92
The `env` provider allows an empty key, which results in a lookup of the environment variable named by the `prefix` itself. This is inconsistent with the `file` and `inline` providers, which both explicitly reject empty keys. This inconsistency can violate the principle of least surprise and may lead to unexpected behavior or misconfigurations.
💡 SuggestionFor consistency and to prevent potential confusion, consider rejecting empty keys in the `env` provider, similar to the other providers. This can be done by adding a check at the beginning of the `Get` method.
func (ep *envProvider) Get(_ context.Context, key string) (string, error) {
	if ep.prefix == &#34;&#34; {
		return &#34;&#34;, ErrPrefixRequired
	}

	if key == &#34;&#34; {
		// It&#39;s better to use a shared error for this if possible,
		// but for now we can define one in the env provider.
		return &#34;&#34;, errors.New(&#34;env: key must not be empty&#34;)
	}

	if ep.uppercase {
		key = strings.ToUpper(key)
	}

	return os.Getenv(ep.prefix + key), nil
}
\n\n ### Architecture Issues (2)
Severity Location Issue
🟡 Warning kv/registry/from_config.go:50-53
The documentation for `NewFromConfig` states that 'A store config may reference any local-type store by name', but the implementation in `resolveStoreConfigReferences` only resolves references within remote store configurations. Local store configs are treated as literal and are not resolved. This mismatch could lead to user confusion when trying to create references between local stores (e.g., an `inline` store referencing an `env` store).
💡 SuggestionUpdate the comment to accurately reflect that only remote store configurations can contain references to local stores. For example: 'A *remote* store config may reference any local-type store by name...'
🟡 Warning kv/registry/registry.go:307-313
The error messages for provider creation and initialization failures have been changed, removing the provider type from the output (e.g., 'hashicorp_vault'). This information is valuable context for debugging configuration errors, and its removal is a regression in diagnosability.
💡 SuggestionRe-add the provider type to the error messages to improve diagnostics. For example, change `fmt.Errorf("create provider for %q store: %w", name, err)` back to something similar to `fmt.Errorf("create provider for %q store (type: %s): %w", name, storeCfg.Type, err)`.

Performance Issues (1)

Severity Location Issue
🟡 Warning kv/providers/vault/vault.go:245-248
The construction of the physical path for Vault KVv2 secrets involves `strings.Split` and `strings.Join`, which can lead to unnecessary memory allocations on each call. This code is on the hot path for every cache miss to the Vault provider. For keys with multiple path segments, this creates an intermediate slice of strings, which is then discarded.
💡 SuggestionTo reduce allocations, consider replacing the `strings.Split`/`strings.Join` combination with `strings.Index` and string slicing/concatenation. This avoids creating an intermediate slice for all path segments.
🔧 Suggested Fix
i := strings.Index(key, "/")
if i == -1 {
    return key + "/data", nil
}
return key[:i] + "/data" + key[i:]

Quality Issues (1)

Severity Location Issue
🟡 Warning kv/registry/registry.go:276-282
The error messages for provider creation and initialization have been simplified, which removes the provider type from the error context. While the store name is preserved in the final error message from the calling `InitStores` function, the type (e.g., 'hashicorp_vault') is lost. This information is valuable for debugging configuration issues, especially when multiple stores of different types are in use.
💡 SuggestionRestore the provider type to the error messages within `buildSingleStore` to improve debuggability. For example, for the provider creation error, change the formatting to include the store name and type, similar to the original version.

Original:
return nil, fmt.Errorf(&#34;failed to create provider %q (type: %s): %w&#34;, name, storeCfg.Type, err)

Proposed change to restore context:
return nil, fmt.Errorf(&#34;failed to create provider for store %q (type %s): %w&#34;, name, storeCfg.Type, err)


Powered by Visor from Probelabs

Last updated: 2026-07-10T11:37:11.203Z | Triggered by: pr_updated | Commit: e889a78

💡 TIP: You can chat with Visor using /visor ask <your question>

vladzabolotnyi and others added 5 commits July 7, 2026 00:10
* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add file provider with tests

* feat: add sentinel errors and rework current errors

* feat: update returning error when file is not exist on the provided key

* feat: adapt the KeyNotFoundError to the standalone providers

* refactor: put the provider_test to kv_test to test public methods and interfaces

* feat: add ability to override default factories when WithFactories opt is used

* feat: add file provider registration at the default registry

* test: add tests covering logic with factories overriding

* fix: update the logic with rejecting retrieving when basePath is not provided

* fix: add case to cover empty keys

* fix: add guard against non-abs for base_path

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add file provider with tests

* feat: add sentinel errors and rework current errors

* feat: update returning error when file is not exist on the provided key

* feat: adapt the KeyNotFoundError to the standalone providers

* refactor: put the provider_test to kv_test to test public methods and interfaces

* feat: add ability to override default factories when WithFactories opt is used

* feat: add file provider registration at the default registry

* test: add tests covering logic with factories overriding

* fix: update the logic with rejecting retrieving when basePath is not provided

* fix: add case to cover empty keys

* fix: add guard against non-abs for base_path

* feat: add base implementation for env provider

* feat: force mandatory prefix to prevent accessing undesired env variables

* chore: remove comment

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add file provider with tests

* feat: add sentinel errors and rework current errors

* feat: update returning error when file is not exist on the provided key

* feat: adapt the KeyNotFoundError to the standalone providers

* refactor: put the provider_test to kv_test to test public methods and interfaces

* feat: add ability to override default factories when WithFactories opt is used

* feat: add file provider registration at the default registry

* test: add tests covering logic with factories overriding

* fix: update the logic with rejecting retrieving when basePath is not provided

* fix: add case to cover empty keys

* fix: add guard against non-abs for base_path

* feat: add base implementation for env provider

* feat: force mandatory prefix to prevent accessing undesired env variables

* chore: remove comment

* feat: add inline provider

* test: add integration tests to prove that NewFromConfig is working with local providers like gateway expects it

* docs: add doc comment explaining when provider factories MUST return an error to let other devs learn the principle

* fix: address sonarqube issues

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add file provider with tests

* feat: add sentinel errors and rework current errors

* feat: update returning error when file is not exist on the provided key

* feat: adapt the KeyNotFoundError to the standalone providers

* refactor: put the provider_test to kv_test to test public methods and interfaces

* feat: add ability to override default factories when WithFactories opt is used

* feat: add file provider registration at the default registry

* test: add tests covering logic with factories overriding

* fix: update the logic with rejecting retrieving when basePath is not provided

* fix: add case to cover empty keys

* fix: add guard against non-abs for base_path

* feat: add base implementation for env provider

* feat: force mandatory prefix to prevent accessing undesired env variables

* chore: remove comment

* feat: add inline provider

* test: add integration tests to prove that NewFromConfig is working with local providers like gateway expects it

* docs: add doc comment explaining when provider factories MUST return an error to let other devs learn the principle

* fix: address sonarqube issues

* feat: add init implementaiton of vault provider

* docs: update docs for the NewFactory

* fix: json.Encoder is adding a new line symbol in the end of the encoded value, reworked with test

* fix: add comments explaining why some decisions are made

* docs: add more comments

* fix: address linter comment with huge param and passing config as pointer instead

* chore: add nolint:errcheck to silence an error

* refactor: fold tests to table tests

* feat: update adding vault to default registry and add integration test

* fix: remove structviewer as it doesn't used on the lib

* fix: tidy deps

* feat: add mount_path config to adapt provider to not hardcoded mount pathes

* fix: add path.Clean() to reject traversal paths

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
* feat: add implementation to Resolve func

* feat: add resolveAll implementation

* test: add test cases for json pointer extraction

* refactor: update error messages and make error handlin more consistent

* refactor: update resolve tests

* refactor: update resolveAll tests with grouping error cases

* fix: added malformed err with tests, added docs string

* test: add test suite with path routing

* fix: remove redundant assertions and update comment

* test: add test case that resolve all resolved mixed values

* fix: use decoding with numbers to avoid losing large integers and update doc strings explaining inner behavior

* fix: add checks with tests to avoid processing values when store or key is empty string

* fix: remove spaces around em-dashes and add missing tests for missing stores and keys

* chore: remove redundant comments

* fix: address sonarqube comment with avoiding duplication

* fix: add json validation on document even if it doesn't contain kv refs

* refactor: split resolver for public and private parts to hide inner logic with lenient mode in future

* chore: replace background context with test one

* feat: add cache bypass context logic to skip serving the value from cache when its desired

* feat: add lenient mode to the resolver

* feat: add base implementation of new from config

* refactor: update implementation with clear func separation and code simplification; add docs

* fix: lint errors

* chore: remove redundant comments

* feat: add file provider as a type with registry processing it as a local type provider

* refactor: add more comments and explanation about phase1 and phase2 and why we need them to increase readability

* refactor: remove isLocalType func and attach the logic to provider type to avoid OCP and increase discoverability

* fix: missing pieces from last commit

* docs: update docstring and comment explaining better why process should resolved value for non-local stores only

* feat: add file provider with tests

* feat: add sentinel errors and rework current errors

* feat: update returning error when file is not exist on the provided key

* feat: adapt the KeyNotFoundError to the standalone providers

* refactor: put the provider_test to kv_test to test public methods and interfaces

* feat: add ability to override default factories when WithFactories opt is used

* feat: add file provider registration at the default registry

* test: add tests covering logic with factories overriding

* fix: update the logic with rejecting retrieving when basePath is not provided

* fix: add case to cover empty keys

* fix: add guard against non-abs for base_path

* feat: add base implementation for env provider

* feat: force mandatory prefix to prevent accessing undesired env variables

* chore: remove comment

* feat: add inline provider

* test: add integration tests to prove that NewFromConfig is working with local providers like gateway expects it

* docs: add doc comment explaining when provider factories MUST return an error to let other devs learn the principle

* fix: address sonarqube issues

* feat: add init implementaiton of vault provider

* docs: update docs for the NewFactory

* fix: json.Encoder is adding a new line symbol in the end of the encoded value, reworked with test

* fix: add comments explaining why some decisions are made

* docs: add more comments

* fix: address linter comment with huge param and passing config as pointer instead

* chore: add nolint:errcheck to silence an error

* refactor: fold tests to table tests

* feat: update adding vault to default registry and add integration test

* fix: remove structviewer as it doesn't used on the lib

* fix: tidy deps

* feat: add mount_path config to adapt provider to not hardcoded mount pathes

* fix: add path.Clean() to reject traversal paths

* deps: add consul library

* feat: add NewFactory with tests

* feat: add implementation with tests for the Get method

* feat: add registration of consul default factory on registry

* test: add consul integration test on the registry side

* refactor: add docs comments and isolate the processing of TLS config

* chore: remove redundant comments

---------

Co-authored-by: Vlad Zabolotnyi <vlad.z@tyk.io>
@github-actions

Copy link
Copy Markdown

🚨 Jira Linter Failed

Commit: e889a78
Failed at: 2026-07-10 11:35:19 UTC

The Jira linter failed to validate your PR. Please check the error details below:

🔍 Click to view error details
configuration error: Jira user email is required for API authentication

Next Steps

  • Ensure your branch name contains a valid Jira ticket ID (e.g., ABC-123)
  • Verify your PR title matches the branch's Jira ticket ID
  • Check that the Jira ticket exists and is accessible

This comment will be automatically deleted once the linter passes.

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Passed Quality Gate passed

Issues
9 New issues
0 Accepted issues

Measures
0 Security Hotspots
93.1% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarQube Cloud

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant