Skip to content
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

add BackendSecurityPolicy for traffic (authN/authZ) from gateway to provider #43

Merged
merged 47 commits into from
Jan 8, 2025
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
08be1f7
Set up API for AUTH api
aabchoo Dec 12, 2024
2ac7698
Signed-off-by: Aaron Choo <achoo30@bloomberg.net>
aabchoo Dec 12, 2024
5ff638f
api: make LLMRoute reference HTTPRoute (#39)
mathetake Dec 10, 2024
c625ebe
api: adds BackendRef into LLMBackendSpec (#40)
mathetake Dec 12, 2024
e200702
updating test-cel
aabchoo Dec 12, 2024
43f77fc
add llm provider policy as part of crd
aabchoo Dec 12, 2024
ea69193
Merge remote-tracking branch 'origin/main' into aaron/authorization-api
aabchoo Dec 12, 2024
7e9315c
typo in test-cel
aabchoo Dec 12, 2024
57e0fa1
update llmproviderpolicy -> llmsecuritypolicy
aabchoo Dec 13, 2024
bc0dadd
ref to llmsecuritypolicy in the backend
aabchoo Dec 13, 2024
b071160
update documentation and tests
aabchoo Dec 16, 2024
d2f72ed
update crd name
aabchoo Dec 16, 2024
52ef4f9
update to generalize aws auth
aabchoo Dec 16, 2024
7b811b7
update llmproviderpolicy type
aabchoo Dec 18, 2024
7dbb202
auto gen update
aabchoo Dec 18, 2024
c04ec5e
add oidc as part of security policy spec
aabchoo Dec 18, 2024
e977a3d
update test to make with new changes
aabchoo Dec 18, 2024
a692194
llmsecurity -> backendsecurity and introduced oidc + static key authz
aabchoo Dec 19, 2024
41db68a
drop inline and static key + add backendref in backendsecuritypolicy
aabchoo Dec 20, 2024
6ea6f94
remove inline from llmproviderapikey definition
aabchoo Dec 20, 2024
3e1d587
introduce dedicated types for aws backend security
aabchoo Jan 2, 2025
2a42311
add more context for oidc
aabchoo Jan 2, 2025
191f9a7
added cel-validation for aws_iam types
aabchoo Jan 2, 2025
fbf1c27
add aws region
aabchoo Jan 2, 2025
b0cd4ca
add target ref backendSpec -> backendSecurityPolicy
aabchoo Jan 2, 2025
3d9ff5a
add security policy ref
aabchoo Jan 2, 2025
c91b45f
remove llm from security policy
aabchoo Jan 3, 2025
c5237b3
remove provider type for backend spec
aabchoo Jan 3, 2025
ddfcb33
rename odicCredential to oidcFederation
aabchoo Jan 3, 2025
130b1bf
remove unused fields
aabchoo Jan 3, 2025
6c68980
remove auth bear token
aabchoo Jan 3, 2025
ef3158c
Update api/v1alpha1/api.go
aabchoo Jan 3, 2025
5ff45c2
update prefix for auth mechanism
aabchoo Jan 3, 2025
1f5e736
update oidcFederation -> oidcExchangeToken
aabchoo Jan 3, 2025
658c1dd
update manifest
aabchoo Jan 3, 2025
2bcda7a
update comment
aabchoo Jan 3, 2025
f7ee160
Update api/v1alpha1/api.go
aabchoo Jan 6, 2025
c4f7baf
Update api/v1alpha1/api.go
aabchoo Jan 6, 2025
6b8f698
make secretRef required
aabchoo Jan 6, 2025
1d71e7a
Update api/v1alpha1/api.go
aabchoo Jan 6, 2025
70a4b29
Update api/v1alpha1/api.go
aabchoo Jan 6, 2025
99e8ae3
Add validation and comments to BackendSecurityPolicy
aabchoo Jan 6, 2025
70aa411
credentialFile to ref secret
aabchoo Jan 6, 2025
27df777
Merge branch 'main' into aaron/authorization-api
aabchoo Jan 6, 2025
dbc37e2
update description of oidc audience
aabchoo Jan 7, 2025
21db108
update backendSecurityPolicy type + add CloudProvider type
aabchoo Jan 8, 2025
480b26b
flatten cloudprovivder
aabchoo Jan 8, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions api/v1alpha1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,12 @@ type LLMBackendSpec struct {
//
// +kubebuilder:validation:Required
BackendRef egv1a1.BackendRef `json:"backendRef"`

// SecurityPolicyName list the LLMSecurityPolicy that this backend will depend on.
//
// A SecurityPolicy specifies authentication, JWT, and API Key.
//
SecurityPolicyName *string `json:"securityPolicyName,omitempty"`
}

// LLMAPISchema defines the API schema of either LLMRoute (the input) or LLMBackend (the output).
Expand Down Expand Up @@ -144,3 +150,65 @@ const (
// This can be used to describe the routing behavior in HTTPRoute referenced by LLMRoute.
LLMModelHeaderKey = "x-envoy-ai-gateway-llm-model"
)

// LLMProviderType specifies the type of the LLMSecurityPolicy.
type LLMProviderType string

const (
LLMProviderTypeAPIKey LLMProviderType = "APIKey"
)

// +kubebuilder:object:root=true

// LLMSecurityPolicy specifies the provider specific configuration like authorization, JWT, and API Key.
type LLMSecurityPolicy struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec LLMSecurityPolicySpec `json:"spec,omitempty"`
}

// LLMSecurityPolicySpec specifies a provider (e.g.AWS Bedrock, Azure etc.) specific-configuration like auth
type LLMSecurityPolicySpec struct {
// Type specifies the type of the provider. Currently, only "APIKey" and "AWSBedrock" are supported.
//
// +kubebuilder:validation:Enum=APIKey;AWSBedrock
Type LLMProviderType `json:"type"`

// APIKey specific configuration. The API key will be injected into the Authorization header.
// +optional
APIKey *LLMProviderAPIKey `json:"apiKey,omitempty"`
}

// +kubebuilder:object:root=true

// LLMSecurityPolicyList contains a list of LLMSecurityPolicy
type LLMSecurityPolicyList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []LLMSecurityPolicy `json:"items"`
}

// LLMProviderAPIKey specifies the API key.
type LLMProviderAPIKey struct {
// Type specifies the type of the API key. Currently, "SecretRef" and "Inline" are supported.
// This defaults to "SecretRef".
//
// +kubebuilder:validation:Enum=SecretRef;Inline
// +kubebuilder:default=SecretRef
Type LLMProviderAPIKeyType `json:"type"`

// SecretRef is the reference to the secret containing the API key.
// ai-gateway must be given the permission to read this secret.
// The key of the secret should be "apiKey".
//
// +optional
SecretRef *gwapiv1.SecretObjectReference `json:"secretRef"`

// Inline specifies the inline API key.
//
// +optional
Inline *string `json:"inline,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We probably do not want to support inline API key as it is a security leak.

}

// LLMProviderAPIKeyType specifies the type of LLMProviderAPIKey.
type LLMProviderAPIKeyType string
1 change: 1 addition & 0 deletions api/v1alpha1/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
func init() {
SchemeBuilder.Register(&LLMRoute{}, &LLMRouteList{})
SchemeBuilder.Register(&LLMBackend{}, &LLMBackendList{})
SchemeBuilder.Register(&LLMSecurityPolicy{}, &LLMSecurityPolicyList{})
}

const GroupName = "aigateway.envoyproxy.io"
Expand Down
109 changes: 109 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,12 @@ spec:
required:
- schema
type: object
securityPolicyName:
description: |-
SecurityPolicyName list the LLMSecurityPolicy that this backend will depend on.

A SecurityPolicy specifies authentication, JWT, and API Key.
type: string
required:
- backendRef
- outputSchema
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
---
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
annotations:
controller-gen.kubebuilder.io/version: v0.16.2
name: llmsecuritypolicies.aigateway.envoyproxy.io
spec:
group: aigateway.envoyproxy.io
names:
kind: LLMSecurityPolicy
listKind: LLMSecurityPolicyList
plural: llmsecuritypolicies
singular: llmsecuritypolicy
scope: Namespaced
versions:
- name: v1alpha1
schema:
openAPIV3Schema:
description: LLMSecurityPolicy specifies the provider specific configuration
like authorization, JWT, and API Key.
properties:
apiVersion:
description: |-
APIVersion defines the versioned schema of this representation of an object.
Servers should convert recognized schemas to the latest internal value, and
may reject unrecognized values.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
type: string
kind:
description: |-
Kind is a string value representing the REST resource this object represents.
Servers may infer this from the endpoint the client submits requests to.
Cannot be updated.
In CamelCase.
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
type: string
metadata:
type: object
spec:
description: LLMSecurityPolicySpec specifies a provider (e.g.AWS Bedrock,
Azure etc.) specific-configuration like auth
properties:
apiKey:
description: APIKey specific configuration. The API key will be injected
into the Authorization header.
properties:
inline:
description: Inline specifies the inline API key.
type: string
secretRef:
description: |-
SecretRef is the reference to the secret containing the API key.
ai-gateway must be given the permission to read this secret.
The key of the secret should be "apiKey".
properties:
group:
default: ""
description: |-
Group is the group of the referent. For example, "gateway.networking.k8s.io".
When unspecified or empty string, core API group is inferred.
maxLength: 253
pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$
type: string
kind:
default: Secret
description: Kind is kind of the referent. For example "Secret".
maxLength: 63
minLength: 1
pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$
type: string
name:
description: Name is the name of the referent.
maxLength: 253
minLength: 1
type: string
namespace:
description: |-
Namespace is the namespace of the referenced object. When unspecified, the local
namespace is inferred.

Note that when a namespace different than the local namespace is specified,
a ReferenceGrant object is required in the referent namespace to allow that
namespace's owner to accept the reference. See the ReferenceGrant
documentation for details.

Support: Core
maxLength: 63
minLength: 1
pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
type: string
required:
- name
type: object
type:
default: SecretRef
description: |-
Type specifies the type of the API key. Currently, "SecretRef" and "Inline" are supported.
This defaults to "SecretRef".
enum:
- SecretRef
- Inline
type: string
required:
- type
type: object
type:
description: Type specifies the type of the provider. Currently, only
"APIKey" and "AWSBedrock" are supported.
enum:
- APIKey
- AWSBedrock
type: string
required:
- type
type: object
type: object
served: true
storage: true
33 changes: 33 additions & 0 deletions tests/cel-validation/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func runTest(m *testing.M) int {
for _, crd := range []string{
"aigateway.envoyproxy.io_llmroutes.yaml",
"aigateway.envoyproxy.io_llmbackends.yaml",
"aigateway.envoyproxy.io_llmsecuritypolicies.yaml",
} {
crds = append(crds, filepath.Join(base, crd))
}
Expand Down Expand Up @@ -134,3 +135,35 @@ func TestLLMBackends(t *testing.T) {
})
}
}

func TestLLMSecurityPolicies(t *testing.T) {
ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(30*time.Second))
defer cancel()

for _, tc := range []struct {
name string
expErr string
}{
{name: "basic.yaml"},
{
name: "unknown_provider.yaml",
expErr: "spec.type: Unsupported value: \"UnknownType\": supported values: \"APIKey\", \"AWSBedrock\"",
},
} {
t.Run(tc.name, func(t *testing.T) {
data, err := tests.ReadFile(path.Join("testdata/llmsecuritypolicies", tc.name))
require.NoError(t, err)

llmSecurityPolicy := &aigv1a1.LLMSecurityPolicy{}
err = yaml.UnmarshalStrict(data, llmSecurityPolicy)
require.NoError(t, err)

if tc.expErr != "" {
require.ErrorContains(t, c.Create(ctx, llmSecurityPolicy), tc.expErr)
} else {
require.NoError(t, c.Create(ctx, llmSecurityPolicy))
require.NoError(t, c.Delete(ctx, llmSecurityPolicy))
}
})
}
}
Loading
Loading