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

Adding APK Conf related implementation for AI Provider and Backend API Key Security #2453

Merged
merged 1 commit into from
Sep 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 0 additions & 4 deletions adapter/internal/operator/controllers/dp/api_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -1086,10 +1086,6 @@ func (apiReconciler *APIReconciler) traverseAPIStateAndUpdateOwnerReferences(ctx
for _, backendJwt := range apiState.BackendJWTMapping {
apiReconciler.retriveParentAPIsAndUpdateOwnerReferene(ctx, &backendJwt)
}
if apiState.AIProvider != nil && apiState.AIProvider.Name != "" {
loggers.LoggerAPKOperator.Infof("Owner Reference .AIProvider override found in API State. AI Provider Name %s", apiState.AIProvider.Name)
apiReconciler.retriveParentAPIsAndUpdateOwnerReferene(ctx, apiState.AIProvider)
}

}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: dp.wso2.com/v1alpha3
kind: AIProvider
metadata:
name: ai-provider-azure-ai
namespace: {{ .Release.Namespace }}
spec:
providerName : "AzureAI"
providerAPIVersion : "2024-06-01"
organization : "default"
model:
in: "Body"
value: "model"
rateLimitFields:
promptTokens:
in: "Body"
value: "$usage.promptTokens"
completionToken:
in: "Body"
value: "$usage.completionTokens"
totalToken:
in: "Body"
value: "$usage.totalTokens"

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: dp.wso2.com/v1alpha3
kind: AIProvider
metadata:
name: ai-provider-open-ai
namespace: {{ .Release.Namespace }}
spec:
providerName : "OpenAI"
providerAPIVersion : "v1"
organization : "default"
model:
in: "Body"
value: "model"
rateLimitFields:
promptTokens:
in: "Body"
value: "$usage.promptTokens"
completionToken:
in: "Body"
value: "$usage.completionTokens"
totalToken:
in: "Body"
value: "$usage.totalTokens"

35 changes: 32 additions & 3 deletions runtime/config-deployer-service/ballerina/APIClient.bal
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ public class APIClient {
apiArtifact.rateLimitPolicies[rateLimitPolicyCR.metadata.name] = rateLimitPolicyCR;
}
}
if apkConf.apiPolicies != () || apkConf.corsConfiguration != () || apkConf.subscriptionValidation == true {
if apkConf.apiPolicies != () || apkConf.corsConfiguration != () || apkConf.aiProvider != () || apkConf.subscriptionValidation == true {
model:APIPolicy? apiPolicyCR = check self.generateAPIPolicyAndBackendCR(apiArtifact, apkConf, (), apkConf.apiPolicies, organization, apiArtifact.uniqueId);
if apiPolicyCR != () {
apiArtifact.apiPolicies[apiPolicyCR.metadata.name] = apiPolicyCR;
Expand Down Expand Up @@ -721,6 +721,21 @@ public class APIClient {
defaultSpecData.cORSPolicy = cORSPolicy;
}
}
AIProvider? aiProvider = apkConf.aiProvider;
if aiProvider is AIProvider {
string aiProviderRef;
if aiProvider.name == "AzureAI" {
aiProviderRef = "ai-provider-azure-ai";
} else if aiProvider.name == "OpenAI" {
aiProviderRef = "ai-provider-open-ai";
} else if aiProvider.name == "GoogleAI" {
aiProviderRef = "ai-provider-google-ai";
} else {
aiProviderRef = aiProvider.name;
}
model:AIProviderReference aIProviderPolicy = {name: aiProviderRef};
defaultSpecData.aiProvider = aIProviderPolicy;
}
if defaultSpecData != {} {
model:APIPolicy? apiPolicyCR = self.generateAPIPolicyCR(apkConf, targetRefName, operations, organization, defaultSpecData);
if apiPolicyCR != () {
Expand Down Expand Up @@ -1278,8 +1293,10 @@ public class APIClient {
}
if endpointSecurity is EndpointSecurity {
if endpointSecurity?.enabled ?: false {
// When user adds basic auth endpoint security username and password
BasicEndpointSecurity? securityType = endpointSecurity.securityType;
// When user adds basic auth endpoint security username and password should be provided.
// When user adds api key endpoint security api key name and api key value should be provided.
BasicEndpointSecurity|APIKeyEndpointSecurity? securityType = endpointSecurity.securityType;
log:printDebug("Security Type: "+ securityType.toString());

if securityType is BasicEndpointSecurity {
securityConfig = {
Expand All @@ -1292,6 +1309,18 @@ public class APIClient {
}
};
}
if securityType is APIKeyEndpointSecurity {
securityConfig = {
apiKey: {
name: <string>securityType.apiKeyNameKey,
'in: <string>securityType.'in,
valueFrom: {
name: <string>securityType.secretName,
valueKey: <string>securityType.apiKeyValueKey
}
}
};
}
}
backendService.spec.security = securityConfig;
}
Expand Down
17 changes: 8 additions & 9 deletions runtime/config-deployer-service/ballerina/Dependencies.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ modules = [
[[package]]
org = "ballerina"
name = "crypto"
version = "2.6.2"
version = "2.6.3"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "time"}
Expand All @@ -70,7 +70,7 @@ modules = [
[[package]]
org = "ballerina"
name = "http"
version = "2.10.12"
version = "2.10.15"
dependencies = [
{org = "ballerina", name = "auth"},
{org = "ballerina", name = "cache"},
Expand Down Expand Up @@ -102,7 +102,7 @@ modules = [
[[package]]
org = "ballerina"
name = "io"
version = "1.6.0"
version = "1.6.2"
dependencies = [
{org = "ballerina", name = "jballerina.java"},
{org = "ballerina", name = "lang.value"}
Expand Down Expand Up @@ -273,7 +273,7 @@ dependencies = [
[[package]]
org = "ballerina"
name = "observe"
version = "1.2.2"
version = "1.2.3"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -302,7 +302,7 @@ modules = [
[[package]]
org = "ballerina"
name = "sql"
version = "1.11.1"
version = "1.11.2"
dependencies = [
{org = "ballerina", name = "io"},
{org = "ballerina", name = "jballerina.java"},
Expand Down Expand Up @@ -335,15 +335,15 @@ modules = [
[[package]]
org = "ballerina"
name = "time"
version = "2.4.0"
version = "2.4.1"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]

[[package]]
org = "ballerina"
name = "url"
version = "2.4.0"
version = "2.4.1"
dependencies = [
{org = "ballerina", name = "jballerina.java"}
]
Expand Down Expand Up @@ -424,8 +424,7 @@ dependencies = [
modules = [
{org = "wso2", packageName = "apk_common_lib", moduleName = "apk_common_lib"},
{org = "wso2", packageName = "apk_common_lib", moduleName = "apk_common_lib.java.io"},
{org = "wso2", packageName = "apk_common_lib", moduleName = "apk_common_lib.java.lang"},
{org = "wso2", packageName = "apk_common_lib", moduleName = "apk_common_lib.org.wso2.apk.common"}
{org = "wso2", packageName = "apk_common_lib", moduleName = "apk_common_lib.java.lang"}
]

[[package]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ public type APIPolicyData record {
CORSPolicy cORSPolicy?;
BackendJwtReference backendJwtPolicy?;
boolean subscriptionValidation?;
AIProviderReference aiProvider?;
};

public type InterceptorReference record {
Expand All @@ -44,6 +45,10 @@ public type BackendJwtReference record {
string name?;
};

public type AIProviderReference record {
string name?;
};

public type APIPolicyList record {
string apiVersion = "dp.wso2.com/v1alpha3";
string kind = "APIPolicyList";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,18 @@ public type BasicSecurityConfig record {

public type SecurityConfig record {
BasicSecurityConfig basic?;
APIKeySecurityConfig apiKey?;
};

public type APIKeySecurityConfig record {
string name;
string 'in;
ValueFrom valueFrom;
};

public type ValueFrom record {
string name;
string valueKey;
};

public type SecretRefConfig record {
Expand All @@ -52,7 +64,6 @@ public type SecretRefConfig record {
string passwordKey = "password";
};


public type RefConfig record {
string key;
string name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ components:
Environment of the API
endpointConfigurations:
$ref: "#/components/schemas/EndpointConfigurations"
aiProvider:
$ref: "#/components/schemas/AIProvider"
operations:
type: array
items:
Expand Down Expand Up @@ -325,6 +327,14 @@ components:
- Day
example: Minute
additionalProperties: false
AIProvider:
title: AI Provider
properties:
name:
type: string
apiVersion:
type: string
additionalProperties: false
EndpointConfigurations:
title: Endpoint configs
properties:
Expand Down Expand Up @@ -368,6 +378,7 @@ components:
securityType:
oneOf:
- $ref: "#/components/schemas/BasicEndpointSecurity"
- $ref: "#/components/schemas/APIKeyEndpointSecurity"
additionalProperties: false
BasicEndpointSecurity:
type: object
Expand All @@ -379,6 +390,22 @@ components:
passwordKey:
type: string
additionalProperties: false
APIKeyEndpointSecurity:
type: object
properties:
secretName:
type: string
in:
type: string
enum:
- Header
- Query
default: Header
apiKeyNameKey:
type: string
apiKeyValueKey:
type: string
additionalProperties: false
Resiliency:
type: object
properties:
Expand Down
32 changes: 28 additions & 4 deletions runtime/config-deployer-service/ballerina/types.bal
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public type ErrorListItem record {
# + securityType - Configuration for the basic endpoint security.
public type EndpointSecurity record {
boolean enabled?;
BasicEndpointSecurity securityType?;
BasicEndpointSecurity|APIKeyEndpointSecurity securityType?;
};

# Configuration for Custom Claims.
Expand Down Expand Up @@ -102,9 +102,22 @@ public type RateLimit record {
# + userNameKey - The key to retrieve the username from the secret.
# + passwordKey - The key to retrieve the password from the secret.
public type BasicEndpointSecurity record {
string secretName?;
string userNameKey?;
string passwordKey?;
string secretName;
string userNameKey;
string passwordKey;
};

# Configuration for API Key Endpoint Security.
#
# + secretName - The name of the secret containing the API key.
# + in - The mode of sending Ex: header/query.
# + apiKeyNameKey - API key Header name.
# + apiKeyValueKey - Key to retrieve API key Header value from the secret.
public type APIKeyEndpointSecurity record {
string secretName;
string 'in;
string apiKeyNameKey;
string apiKeyValueKey;
};

# Configuration for APK Operations.
Expand Down Expand Up @@ -407,6 +420,7 @@ public type InterceptorPolicy record {
# + subscriptionValidation - Is subscription validation enabled for the API.
# + environment - Environment of the API.
# + endpointConfigurations - Sandbox and production endpoint configurations of the API
# + aiProvider - AI provider configuration for the API.
# + operations - List of operations for this API.
# + apiPolicies - Policies like interceptor to be added to the entire API.
# + rateLimit - Rate limiting configuration for the API.
Expand All @@ -427,6 +441,7 @@ public type APKConf record {
boolean subscriptionValidation = false;
string environment?;
EndpointConfigurations endpointConfigurations?;
AIProvider aiProvider?;
APKOperations[] operations?;
APIOperationPolicies apiPolicies?;
RateLimit rateLimit?;
Expand All @@ -435,6 +450,15 @@ public type APKConf record {
CORSConfiguration corsConfiguration?;
};

# Configuration for an AI provider.
#
# + name - The name of the AI provider.
# + apiVersion - The version of the AI provider.
public type AIProvider record {
string name;
string apiVersion;
};

# Configuration for Interceptor Policy parameters.
#
# + backendUrl - Backend URL of the interceptor service.
Expand Down
Loading
Loading