-
Notifications
You must be signed in to change notification settings - Fork 1.2k
feat(proxy): bind static credentials to provider endpoints #2510
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
44 commits
Select commit
Hold shift + click to select a range
2e32588
feat(proxy): bind static credentials to provider endpoints
johntmyers 271ad76
test(e2e): verify static credential endpoint isolation
johntmyers 025f3d6
docs(provider): explain static credential endpoint binding
johntmyers 12f380a
fix(e2e): use valid endpoint isolation fixtures
johntmyers 5f1957a
docs(provider): explain static credential endpoint binding
johntmyers 3226457
fix(credentials): preserve binding identity across rotations
johntmyers b6b2b82
fix(proxy): enforce bindings across request lifecycle
johntmyers afaf003
fix(proxy): close credential relay gaps
johntmyers 6725c2d
docs(credentials): clarify binding failure behavior
johntmyers 0f701f7
fix(credentials): hash selected provider profile scope
johntmyers 279cb41
fix(proxy): resolve credentials after request admission
johntmyers a33d6d0
docs(credentials): clarify binding failure diagnostics
johntmyers c6b14e7
fix(proxy): align single-route credential denials
johntmyers b8f6316
fix(credentials): harden endpoint-bound rotation
johntmyers e2eb64b
fix(credentials): enforce identity and authority binding
johntmyers 082165f
fix(credentials): snapshot provider environment atomically
johntmyers 8ead9ed
test(e2e): include authority port in query proxy requests
johntmyers 203be0a
fix(credentials): close credential revocation gaps
johntmyers 8ab4c8f
docs(proxy): explain authority mismatch diagnostics
johntmyers dd75dd0
fix(credentials): enforce binding lifecycle invariants
johntmyers c93b7dd
fix(provider): reject credential config collisions
johntmyers 42ff95d
fix(network): capture credential scope atomically
johntmyers ba979ab
fix(network): distinguish origin and absolute targets
johntmyers b5d50a2
fix(provider): isolate endpointless profile credentials
johntmyers 960d882
fix(network): normalize IPv6 request authorities
johntmyers eb0307d
docs(credentials): clarify endpointless profile isolation
johntmyers 761518f
feat(policy): bind endpointless provider credentials
johntmyers ff0260b
fix(credentials): use current GCP placeholder revision
johntmyers 758307c
docs(providers): explain policy credential bindings
johntmyers 524cd7b
test(credentials): cover endpointless fail-closed invariant
johntmyers da3f44e
test(policy): expect ambiguity rejection at creation
johntmyers c01b2e4
test(server): authenticate rebased policy requests
johntmyers 212d22d
refactor(proxy): share credential mismatch finding builder
johntmyers 9c60c86
test(credentials): cover malformed binding metadata
johntmyers a176e2c
test(credentials): verify multi-key endpoint isolation
johntmyers e0ac1b0
test(e2e): cover same-host credential path denial
johntmyers 9de1ab1
docs(credentials): document serialized refresh contract
johntmyers bcf713a
refactor(proxy): consolidate L7 log formatting
johntmyers 1b21351
perf(credentials): precompile endpoint binding patterns
johntmyers bf3a81f
perf(credentials): share identity epoch revisions
johntmyers 2c85001
test(proxy): require explicit request default ports
johntmyers 29e7927
fix(policy): validate SigV4 credential sources
johntmyers 43ff639
fix(credentials): preserve endpoint bindings for credential handles
johntmyers 284120c
feat(go-sdk): expose network credential bindings
johntmyers File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| // SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
| // SPDX-License-Identifier: Apache-2.0 | ||
|
|
||
| //! Canonical provider endpoint path matching shared by policy and runtime code. | ||
|
|
||
| /// A compiled provider endpoint path pattern. | ||
| /// | ||
| /// Invalid glob syntax retains the existing fail-closed behavior: it matches | ||
| /// only when the request path is exactly equal to the configured pattern. | ||
| #[derive(Debug, Clone)] | ||
| pub struct EndpointPathPattern { | ||
| source: String, | ||
| kind: EndpointPathPatternKind, | ||
| } | ||
|
|
||
| #[derive(Debug, Clone)] | ||
| enum EndpointPathPatternKind { | ||
| Any, | ||
| Subtree(String), | ||
| Glob(glob::Pattern), | ||
| Invalid, | ||
| } | ||
|
|
||
| impl EndpointPathPattern { | ||
| #[must_use] | ||
| pub fn new(pattern: &str) -> Self { | ||
| let kind = if pattern.is_empty() || pattern == "**" || pattern == "/**" { | ||
| EndpointPathPatternKind::Any | ||
| } else if let Some(prefix) = pattern.strip_suffix("/**") { | ||
| EndpointPathPatternKind::Subtree(prefix.to_string()) | ||
| } else { | ||
| glob::Pattern::new(pattern).map_or( | ||
| EndpointPathPatternKind::Invalid, | ||
| EndpointPathPatternKind::Glob, | ||
| ) | ||
| }; | ||
| Self { | ||
| source: pattern.to_string(), | ||
| kind, | ||
| } | ||
| } | ||
|
|
||
| #[must_use] | ||
| pub fn matches(&self, path: &str) -> bool { | ||
| if self.source == path { | ||
| return true; | ||
| } | ||
| match &self.kind { | ||
| EndpointPathPatternKind::Any => true, | ||
| EndpointPathPatternKind::Subtree(prefix) => { | ||
| path == prefix | ||
| || path | ||
| .strip_prefix(prefix) | ||
| .is_some_and(|suffix| suffix.starts_with('/')) | ||
| } | ||
| EndpointPathPatternKind::Glob(pattern) => pattern.matches(path), | ||
| EndpointPathPatternKind::Invalid => false, | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /// Return whether `path` is selected by a provider endpoint path pattern. | ||
| /// | ||
| /// Empty paths and `**` match every request path. A trailing `/**` matches the | ||
| /// named path itself and every descendant. Other patterns use glob semantics. | ||
| #[must_use] | ||
| pub fn matches(pattern: &str, path: &str) -> bool { | ||
| EndpointPathPattern::new(pattern).matches(path) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::{EndpointPathPattern, matches}; | ||
|
|
||
| #[test] | ||
| fn matches_canonical_endpoint_patterns() { | ||
| assert!(matches("", "/v1/messages")); | ||
| assert!(matches("/**", "/v1/messages")); | ||
| assert!(matches("/v1/**", "/v1")); | ||
| assert!(matches("/v1/**", "/v1/messages")); | ||
| assert!(matches("/v*/messages", "/v1/messages")); | ||
| assert!(matches("/v1/*", "/v1/chat/messages")); | ||
| assert!(!matches("/v1/**", "/v2/messages")); | ||
| assert!(!matches("/v1/*/messages", "/v1/chat/completions")); | ||
| } | ||
|
|
||
| #[test] | ||
| fn compiled_patterns_preserve_canonical_matching() { | ||
| let subtree = EndpointPathPattern::new("/v1/**"); | ||
| assert!(subtree.matches("/v1")); | ||
| assert!(subtree.matches("/v1/chat/messages")); | ||
| assert!(!subtree.matches("/v2/messages")); | ||
|
|
||
| let glob = EndpointPathPattern::new("/v*/messages"); | ||
| assert!(glob.matches("/v1/messages")); | ||
| assert!(!glob.matches("/v1/completions")); | ||
|
|
||
| let invalid = EndpointPathPattern::new("["); | ||
| assert!(invalid.matches("[")); | ||
| assert!(!invalid.matches("/v1/messages")); | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.