Skip to content
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
25 changes: 13 additions & 12 deletions package-lock.json

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

21 changes: 19 additions & 2 deletions plugins/azure/contentSafety.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Agent } from 'https';
import {
HookEventType,
PluginContext,
Expand Down Expand Up @@ -63,7 +64,7 @@ export const handler: PluginHandler<{

const apiVersion = parameters.apiVersion || '2024-11-01';

const url = `https://${credentials.resourceName}.cognitiveservices.azure.com/contentsafety/text:analyze?api-version=${apiVersion}`;
const url = `${credentials.customHost || `https://${credentials.resourceName}.cognitiveservices.azure.com`}/contentsafety/text:analyze?api-version=${apiVersion}`;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Code Refactor

Issue: The URL construction doesn't validate if the customHost is a valid URL format.
Fix: Add a simple validation to ensure the customHost is properly formatted.
Impact: Prevents runtime errors from malformed URLs.

Suggested change
const url = `${credentials.customHost || `https://${credentials.resourceName}.cognitiveservices.azure.com`}/contentsafety/text:analyze?api-version=${apiVersion}`;
const baseUrl = credentials.customHost || `https://${credentials.resourceName}.cognitiveservices.azure.com`;
// Ensure the URL doesn't have trailing slashes that could cause path issues
const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');
const url = `${normalizedBaseUrl}/contentsafety/text:analyze?api-version=${apiVersion}`;


const { token, error: tokenError } = await getAccessToken(
credentials as any,
Expand All @@ -80,6 +81,17 @@ export const handler: PluginHandler<{
};
}

let agent: Agent | null = null;
// privatelink doesn't contain a valid certificate, skipping verification if it's customHost.
// SECURITY NOTE: The following disables SSL certificate validation for custom hosts.
// This is necessary for Azure Private Link endpoints that may use self-signed certificates,
// but should only be used with trusted private endpoints.
if (credentials.customHost) {
agent = new Agent({
rejectUnauthorized: false,
});
}

const headers: Record<string, string> = {
'Content-Type': 'application/json',
'User-Agent': 'portkey-ai-plugin/',
Expand All @@ -100,7 +112,12 @@ export const handler: PluginHandler<{
const timeout = parameters.timeout || 5000;
let response;
try {
response = await post(url, request, { headers }, timeout);
response = await post(
url,
request,
{ headers, dispatcher: agent },
timeout
);
} catch (e) {
return { error: e, verdict: true, data };
}
Expand Down
4 changes: 4 additions & 0 deletions plugins/azure/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,10 @@
"tenantId": {
"type": "string",
"description": "Tenant ID for Azure Entra ID authentication"
},
"customHost": {
"type": "string",
"description": "Custom host for Azure AI services (Private Link etc.)"
Comment on lines +127 to +129
Copy link
Contributor

Choose a reason for hiding this comment

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

📝 Documentation Improvement

Issue: The description for customHost doesn't mention the security implications of using this feature.
Fix: Enhance the description to include security considerations.
Impact: Improves user awareness of security implications when using custom hosts.

Suggested change
"customHost": {
"type": "string",
"description": "Custom host for Azure AI services (Private Link etc.)"
\"customHost\": {
\"type\": \"string\",
\"description\": \"Custom host for Azure AI services (Private Link etc.). Note: SSL verification is disabled when using custom hosts.\"

}
},
"anyOf": [
Expand Down
21 changes: 19 additions & 2 deletions plugins/azure/pii.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { Agent } from 'https';
import {
HookEventType,
PluginContext,
Expand Down Expand Up @@ -29,7 +30,7 @@ const redact = async (

const apiVersion = parameters.apiVersion || '2024-11-01';

const url = `https://${credentials?.resourceName}.cognitiveservices.azure.com/language/:analyze-text?api-version=${apiVersion}`;
const url = `${credentials?.customHost || `https://${credentials?.resourceName}.cognitiveservices.azure.com`}/language/:analyze-text?api-version=${apiVersion}`;
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Code Refactor

Issue: The URL construction doesn't validate if the customHost is a valid URL format.
Fix: Add a simple validation to ensure the customHost is properly formatted.
Impact: Prevents runtime errors from malformed URLs.

Suggested change
const url = `${credentials?.customHost || `https://${credentials?.resourceName}.cognitiveservices.azure.com`}/language/:analyze-text?api-version=${apiVersion}`;
const baseUrl = credentials?.customHost || `https://${credentials?.resourceName}.cognitiveservices.azure.com`;
// Ensure the URL doesn't have trailing slashes that could cause path issues
const normalizedBaseUrl = baseUrl.replace(/\\/+$/, '');
const url = `${normalizedBaseUrl}/language/:analyze-text?api-version=${apiVersion}`;


const { token, error: tokenError } = await getAccessToken(
credentials as any,
Expand All @@ -53,8 +54,24 @@ const redact = async (
throw new Error('Unable to get access token');
}

let agent: Agent | null = null;
Copy link
Collaborator

Choose a reason for hiding this comment

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

would suggest moving the initialization to a fetchUtils file and creating a method like getInsecureAgent()

// privatelink doesn't contain a valid certificate, skipping verification if it's customHost.
// SECURITY NOTE: The following disables SSL certificate validation for custom hosts.
// This is necessary for Azure Private Link endpoints that may use self-signed certificates,
// but should only be used with trusted private endpoints.
if (credentials?.customHost) {
agent = new Agent({
rejectUnauthorized: false,
});
}

const timeout = parameters.timeout || 5000;
const response = await post(url, body, { headers }, timeout);
const response = await post(
url,
body,
{ headers, dispatcher: agent },
timeout
);
return response;
};

Expand Down
1 change: 1 addition & 0 deletions plugins/azure/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export interface AzureCredentials {
clientId?: string;
clientSecret?: string;
tenantId?: string;
customHost?: string;
}
1 change: 1 addition & 0 deletions plugins/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { HookEventType, PluginContext } from './types';

interface PostOptions extends RequestInit {
headers?: Record<string, string>;
[key: string]: any;
}

export interface ErrorResponse {
Expand Down