@microsoft/agents-hosting 1.6.0-beta.9.gce9d8facd2 → 1.7.0-beta.1.g8bcd4f11a7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/package.json +4 -9
- package/dist/src/agent-client/agentClient.js +2 -2
- package/dist/src/agent-client/agentClient.js.map +1 -1
- package/dist/src/agent-client/agentResponseHandler.js +2 -2
- package/dist/src/agent-client/agentResponseHandler.js.map +1 -1
- package/dist/src/app/agentApplication.js +28 -2
- package/dist/src/app/agentApplication.js.map +1 -1
- package/dist/src/app/agentApplicationOptions.d.ts +10 -0
- package/dist/src/app/attachmentDownloader.js +5 -10
- package/dist/src/app/attachmentDownloader.js.map +1 -1
- package/dist/src/app/auth/authorizationManager.d.ts +4 -0
- package/dist/src/app/auth/authorizationManager.js +94 -67
- package/dist/src/app/auth/authorizationManager.js.map +1 -1
- package/dist/src/app/auth/handlers/azureBotAuthorization.js +2 -2
- package/dist/src/app/auth/handlers/azureBotAuthorization.js.map +1 -1
- package/dist/src/app/proactive/createConversationOptionsBuilder.js +10 -6
- package/dist/src/app/proactive/createConversationOptionsBuilder.js.map +1 -1
- package/dist/src/app/proactive/proactive.d.ts +1 -0
- package/dist/src/app/proactive/proactive.js +30 -15
- package/dist/src/app/proactive/proactive.js.map +1 -1
- package/dist/src/app/streaming/streamingResponse.d.ts +11 -0
- package/dist/src/app/streaming/streamingResponse.js +21 -0
- package/dist/src/app/streaming/streamingResponse.js.map +1 -1
- package/dist/src/app/teamsAttachmentDownloader.js +6 -14
- package/dist/src/app/teamsAttachmentDownloader.js.map +1 -1
- package/dist/src/auth/MemoryCache.d.ts +2 -1
- package/dist/src/auth/MemoryCache.js +7 -1
- package/dist/src/auth/MemoryCache.js.map +1 -1
- package/dist/src/auth/authConfiguration.d.ts +2 -143
- package/dist/src/auth/authConfiguration.js +336 -257
- package/dist/src/auth/authConfiguration.js.map +1 -1
- package/dist/src/auth/authConstants.d.ts +7 -7
- package/dist/src/auth/authConstants.js.map +1 -1
- package/dist/src/auth/connectionManager.d.ts +92 -0
- package/dist/src/auth/{msalConnectionManager.js → connectionManager.js} +48 -33
- package/dist/src/auth/connectionManager.js.map +1 -0
- package/dist/src/auth/index.d.ts +5 -3
- package/dist/src/auth/index.js +5 -3
- package/dist/src/auth/index.js.map +1 -1
- package/dist/src/auth/jwt-middleware.d.ts +6 -0
- package/dist/src/auth/jwt-middleware.js +34 -2
- package/dist/src/auth/jwt-middleware.js.map +1 -1
- package/dist/src/auth/msal/msalConnectionManager.d.ts +17 -0
- package/dist/src/auth/msal/msalConnectionManager.js +50 -0
- package/dist/src/auth/msal/msalConnectionManager.js.map +1 -0
- package/dist/src/auth/msal/msalConnectionSettings.d.ts +68 -0
- package/dist/src/auth/msal/msalConnectionSettings.js +7 -0
- package/dist/src/auth/msal/msalConnectionSettings.js.map +1 -0
- package/dist/src/auth/{msalTokenCredential.d.ts → msal/msalTokenCredential.d.ts} +1 -1
- package/dist/src/auth/{msalTokenCredential.js → msal/msalTokenCredential.js} +2 -2
- package/dist/src/auth/msal/msalTokenCredential.js.map +1 -0
- package/dist/src/auth/{msalTokenProvider.d.ts → msal/msalTokenProvider.d.ts} +30 -3
- package/dist/src/auth/msal/msalTokenProvider.js +733 -0
- package/dist/src/auth/msal/msalTokenProvider.js.map +1 -0
- package/dist/src/auth/settings.d.ts +336 -0
- package/dist/src/auth/settings.js +202 -0
- package/dist/src/auth/settings.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.d.ts +74 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js +181 -0
- package/dist/src/auth/sidecar/sidecarAuthProvider.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.d.ts +65 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js +7 -0
- package/dist/src/auth/sidecar/sidecarConnectionSettings.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.d.ts +95 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js +406 -0
- package/dist/src/auth/sidecar/sidecarHttpClient.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarModels.d.ts +110 -0
- package/dist/src/auth/sidecar/sidecarModels.js +48 -0
- package/dist/src/auth/sidecar/sidecarModels.js.map +1 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.d.ts +13 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js +39 -0
- package/dist/src/auth/sidecar/sidecarTokenExpiry.js.map +1 -0
- package/dist/src/cloudAdapter.d.ts +58 -1
- package/dist/src/cloudAdapter.js +233 -53
- package/dist/src/cloudAdapter.js.map +1 -1
- package/dist/src/connector-client/connectorClient.d.ts +12 -8
- package/dist/src/connector-client/connectorClient.js +99 -82
- package/dist/src/connector-client/connectorClient.js.map +1 -1
- package/dist/src/errorHelper.js +181 -7
- package/dist/src/errorHelper.js.map +1 -1
- package/dist/src/getProductInfo.d.ts +23 -0
- package/dist/src/getProductInfo.js +71 -1
- package/dist/src/getProductInfo.js.map +1 -1
- package/dist/src/headerPropagation.d.ts +17 -2
- package/dist/src/headerPropagation.js +46 -24
- package/dist/src/headerPropagation.js.map +1 -1
- package/dist/src/httpClient.d.ts +60 -0
- package/dist/src/httpClient.js +173 -0
- package/dist/src/httpClient.js.map +1 -0
- package/dist/src/index.d.ts +3 -2
- package/dist/src/index.js +8 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/oauth/userTokenClient.d.ts +17 -4
- package/dist/src/oauth/userTokenClient.js +119 -80
- package/dist/src/oauth/userTokenClient.js.map +1 -1
- package/dist/src/observability/traces.d.ts +11 -4
- package/dist/src/observability/traces.js +39 -7
- package/dist/src/observability/traces.js.map +1 -1
- package/dist/src/utils/env.d.ts +50 -0
- package/dist/src/utils/env.js +113 -0
- package/dist/src/utils/env.js.map +1 -0
- package/dist/src/utils.d.ts +10 -0
- package/dist/src/utils.js +18 -0
- package/dist/src/utils.js.map +1 -0
- package/package.json +4 -9
- package/src/agent-client/agentClient.ts +2 -2
- package/src/agent-client/agentResponseHandler.ts +2 -2
- package/src/app/agentApplication.ts +30 -3
- package/src/app/agentApplicationOptions.ts +11 -0
- package/src/app/attachmentDownloader.ts +6 -8
- package/src/app/auth/authorizationManager.ts +84 -41
- package/src/app/auth/handlers/azureBotAuthorization.ts +2 -2
- package/src/app/proactive/createConversationOptionsBuilder.ts +8 -4
- package/src/app/proactive/proactive.ts +39 -23
- package/src/app/streaming/streamingResponse.ts +24 -1
- package/src/app/teamsAttachmentDownloader.ts +7 -11
- package/src/auth/MemoryCache.ts +7 -1
- package/src/auth/authConfiguration.ts +350 -356
- package/src/auth/authConstants.ts +7 -7
- package/src/auth/{msalConnectionManager.ts → connectionManager.ts} +65 -44
- package/src/auth/index.ts +5 -3
- package/src/auth/jwt-middleware.ts +32 -2
- package/src/auth/msal/msalConnectionManager.ts +55 -0
- package/src/auth/msal/msalConnectionSettings.ts +79 -0
- package/src/auth/{msalTokenCredential.ts → msal/msalTokenCredential.ts} +2 -1
- package/src/auth/msal/msalTokenProvider.ts +881 -0
- package/src/auth/settings.ts +378 -0
- package/src/auth/sidecar/sidecarAuthProvider.ts +234 -0
- package/src/auth/sidecar/sidecarConnectionSettings.ts +72 -0
- package/src/auth/sidecar/sidecarHttpClient.ts +443 -0
- package/src/auth/sidecar/sidecarModels.ts +153 -0
- package/src/auth/sidecar/sidecarTokenExpiry.ts +35 -0
- package/src/cloudAdapter.ts +292 -13
- package/src/connector-client/connectorClient.ts +116 -94
- package/src/errorHelper.ts +206 -7
- package/src/getProductInfo.ts +79 -1
- package/src/headerPropagation.ts +55 -23
- package/src/httpClient.ts +223 -0
- package/src/index.ts +6 -2
- package/src/oauth/userTokenClient.ts +137 -84
- package/src/observability/traces.ts +39 -8
- package/src/utils/env.ts +105 -0
- package/src/utils.ts +14 -0
- package/dist/src/auth/msalConnectionManager.d.ts +0 -64
- package/dist/src/auth/msalConnectionManager.js.map +0 -1
- package/dist/src/auth/msalTokenCredential.js.map +0 -1
- package/dist/src/auth/msalTokenProvider.js +0 -485
- package/dist/src/auth/msalTokenProvider.js.map +0 -1
- package/src/auth/msalTokenProvider.ts +0 -562
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { debug } from '@microsoft/agents-telemetry'
|
|
7
|
+
import { ExceptionHelper } from '@microsoft/agents-activity'
|
|
8
|
+
import { Errors } from '../errorHelper'
|
|
9
|
+
import type { MsalConnectionSettings } from './msal/msalConnectionSettings'
|
|
10
|
+
import type { SidecarConnectionSettings } from './sidecar/sidecarConnectionSettings'
|
|
11
|
+
|
|
12
|
+
export type { MsalConnectionSettings } from './msal/msalConnectionSettings'
|
|
13
|
+
export type { SidecarConnectionSettings } from './sidecar/sidecarConnectionSettings'
|
|
14
|
+
|
|
15
|
+
const logger = debug('agents:authConfiguration')
|
|
16
|
+
|
|
17
|
+
const DEFAULT_CONNECTION = 'serviceConnection'
|
|
18
|
+
const AUTHORITY_DEFAULT = 'https://login.microsoftonline.com'
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A single entry in the connections map used to route an inbound activity
|
|
22
|
+
* (matched by audience and/or serviceUrl) to a named connection.
|
|
23
|
+
*/
|
|
24
|
+
export interface ConnectionMapItem {
|
|
25
|
+
serviceUrl: string
|
|
26
|
+
audience?: string
|
|
27
|
+
connection: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export const DEFAULT_CONNECTION_MAP: ConnectionMapItem = { serviceUrl: '*', connection: DEFAULT_CONNECTION }
|
|
31
|
+
|
|
32
|
+
export type ConnectionKeys = keyof Omit<AuthConfiguration, 'connections' | 'connectionsMap'>
|
|
33
|
+
export type ConnectionMapKeys = keyof ConnectionMapItem
|
|
34
|
+
|
|
35
|
+
export interface LoadEnv {
|
|
36
|
+
[upperKey: string]: { key: string, value: any }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function loadEnvSettings (callback: (key: string, value: string) => void) {
|
|
40
|
+
const env: LoadEnv = {}
|
|
41
|
+
for (const [envKey, envValue] of Object.entries(process.env)) {
|
|
42
|
+
if (!envValue?.trim()) {
|
|
43
|
+
continue
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
env[envKey.toUpperCase()] = { key: envKey, value: envValue }
|
|
47
|
+
|
|
48
|
+
callback(envKey, envValue)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return env
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export function applyDefaultSettings (config: AuthConfiguration) {
|
|
55
|
+
const settings = { ...config }
|
|
56
|
+
settings.authorityEndpoint ??= settings.authority ?? AUTHORITY_DEFAULT
|
|
57
|
+
settings.issuers ??= getDefaultIssuers(settings.tenantId ?? '', settings.authorityEndpoint)
|
|
58
|
+
|
|
59
|
+
// For backward compatibility
|
|
60
|
+
if (settings.federatedClientId) {
|
|
61
|
+
settings.FICClientId = settings.federatedClientId
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (settings.scopes?.length) {
|
|
65
|
+
settings.scope = settings.scopes?.[0]
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (settings.authorityEndpoint) {
|
|
69
|
+
settings.authority = settings.authorityEndpoint
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// .NET parity alias: keep altBlueprintConnectionName and alternateBlueprintConnectionName in sync.
|
|
73
|
+
settings.altBlueprintConnectionName ??= settings.alternateBlueprintConnectionName
|
|
74
|
+
if (settings.altBlueprintConnectionName) {
|
|
75
|
+
settings.alternateBlueprintConnectionName = settings.altBlueprintConnectionName
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (!settings.clientId && process.env.NODE_ENV?.toLowerCase() === 'production') {
|
|
79
|
+
throw ExceptionHelper.generateException(Error, Errors.ClientIdRequiredInProduction)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const defaultConnections = settings.connections?.size
|
|
83
|
+
? settings.connections
|
|
84
|
+
: new Map([[DEFAULT_CONNECTION, { ...settings }]])
|
|
85
|
+
const defaultConnectionsMap = settings.connectionsMap?.length
|
|
86
|
+
? settings.connectionsMap
|
|
87
|
+
: [DEFAULT_CONNECTION_MAP]
|
|
88
|
+
|
|
89
|
+
settings.connections = defaultConnections
|
|
90
|
+
settings.connectionsMap = defaultConnectionsMap
|
|
91
|
+
return settings
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* A type representing a parser settings object.
|
|
96
|
+
*/
|
|
97
|
+
type ParserSettings<K extends string> = {
|
|
98
|
+
[key in K]: (value: string) => { key?: string, value?: any } | undefined
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Creates an environment variable parser that maps the variable keys to parsing functions.
|
|
103
|
+
* @param settings An object where each key is an environment variable name and the value is a function
|
|
104
|
+
* that takes the variable value as input and returns an object with optional `key` and `value` properties.
|
|
105
|
+
* @remarks
|
|
106
|
+
* The `key` property in the returned object can be used to rename the environment variable key,
|
|
107
|
+
* while the `value` property contains the parsed value.
|
|
108
|
+
* @returns An object with a `parse` method that takes an environment variable key and value,
|
|
109
|
+
* and returns the parsed result.
|
|
110
|
+
*/
|
|
111
|
+
export function envParser<K extends string> (settings: ParserSettings<K> & ThisType<ParserSettings<K>>) {
|
|
112
|
+
const keys = Object.keys(settings) as K[]
|
|
113
|
+
const upperKeys = keys.reduce((acc, key) => {
|
|
114
|
+
acc[key.toUpperCase()] = key
|
|
115
|
+
return acc
|
|
116
|
+
}, {} as Record<string, K>)
|
|
117
|
+
return {
|
|
118
|
+
keys,
|
|
119
|
+
/**
|
|
120
|
+
* Parses the given environment variable key and value using the provided settings.
|
|
121
|
+
* @param key The environment variable key.
|
|
122
|
+
* @param value The environment variable value.
|
|
123
|
+
* @returns The parsed result with optional renamed key and parsed value.
|
|
124
|
+
*/
|
|
125
|
+
parse (key: K, value: string) {
|
|
126
|
+
const match = upperKeys[key.toUpperCase()]
|
|
127
|
+
if (!match) {
|
|
128
|
+
return {}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
const result = settings[match](value)
|
|
132
|
+
return { key: result?.key ?? match, value: result?.value }
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Utility functions for environment variable parsers.
|
|
139
|
+
*/
|
|
140
|
+
export const envParserUtils = {
|
|
141
|
+
/**
|
|
142
|
+
* Bypass parser that returns the value as is.
|
|
143
|
+
* @param value The environment variable value.
|
|
144
|
+
* @returns An object with the original value.
|
|
145
|
+
*/
|
|
146
|
+
bypass: (value: string) => ({ value }),
|
|
147
|
+
/**
|
|
148
|
+
* Redirects the parsing to another parser for a specific key.
|
|
149
|
+
* @param parser The target parser to redirect to.
|
|
150
|
+
* @param key The key to use in the target parser.
|
|
151
|
+
* @returns A function that takes the environment variable value and returns the parsed result from the target parser.
|
|
152
|
+
*/
|
|
153
|
+
redirect: <Parser extends ReturnType<typeof envParser>>(parser: Parser, key: Parameters<Parser['parse']>[0]) => (value: string) => parser.parse(key, value)
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Resolves the full authority URL including the tenant ID.
|
|
158
|
+
* Supports both patterns:
|
|
159
|
+
* - Tenant embedded in authority: https://login.microsoftonline.com/my-tenant
|
|
160
|
+
* - Authority + separate tenantId: https://login.microsoftonline.com + tenantId
|
|
161
|
+
* Also handles trailing slashes on authority.
|
|
162
|
+
*/
|
|
163
|
+
export function resolveAuthority (authority?: string, tenantId?: string): string {
|
|
164
|
+
const base = trimTrailingSlashes(authority ?? AUTHORITY_DEFAULT)
|
|
165
|
+
const url = new URL(base)
|
|
166
|
+
const hasPathSegment = url.pathname !== '/'
|
|
167
|
+
if (hasPathSegment) {
|
|
168
|
+
return base
|
|
169
|
+
}
|
|
170
|
+
return `${base}/${tenantId ?? 'botframework.com'}`
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function trimTrailingSlashes (value: string): string {
|
|
174
|
+
let end = value.length
|
|
175
|
+
while (end > 0 && value.charCodeAt(end - 1) === 47) {
|
|
176
|
+
end--
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
return end === value.length ? value : value.slice(0, end)
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
function getDefaultIssuers (tenantId: string, authority: string) : string[] {
|
|
183
|
+
// Convert empty string to undefined so resolveAuthority applies its 'botframework.com' default
|
|
184
|
+
const t = tenantId || undefined
|
|
185
|
+
if (!t) {
|
|
186
|
+
logger.warn('tenantId is not configured, defaulting to botframework.com')
|
|
187
|
+
}
|
|
188
|
+
return [
|
|
189
|
+
'https://api.botframework.com',
|
|
190
|
+
`${resolveAuthority('https://sts.windows.net', t)}/`,
|
|
191
|
+
`${resolveAuthority(authority, t)}/v2.0`
|
|
192
|
+
]
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Connection-level settings common to every authentication provider.
|
|
197
|
+
*
|
|
198
|
+
* @remarks
|
|
199
|
+
* Mirrors the .NET `Microsoft.Agents.Authentication.ConnectionSettingsBase` abstract class: these are
|
|
200
|
+
* the credential-agnostic properties shared by all connection types. Provider-specific settings
|
|
201
|
+
* extend this base (see {@link MsalConnectionSettings} for MSAL and {@link SidecarConnectionSettings}
|
|
202
|
+
* for the Entra sidecar). The active provider for a connection is selected
|
|
203
|
+
* by {@link ConnectionSettingsBase.authType | authType}; see `AuthProviderFactory`.
|
|
204
|
+
*/
|
|
205
|
+
export interface ConnectionSettingsBase {
|
|
206
|
+
/**
|
|
207
|
+
* The tenant ID for the authentication configuration.
|
|
208
|
+
*/
|
|
209
|
+
tenantId?: string
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* The client ID for the authentication configuration. Required in production.
|
|
213
|
+
*/
|
|
214
|
+
clientId?: string
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* The authentication type for the connection.
|
|
218
|
+
*/
|
|
219
|
+
authType?: AuthType | string
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* A list of valid issuers for the authentication configuration.
|
|
223
|
+
*/
|
|
224
|
+
issuers?: string[]
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* The connection name for the authentication configuration.
|
|
228
|
+
*/
|
|
229
|
+
connectionName?: string
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* @deprecated Use authorityEndpoint instead.
|
|
233
|
+
*
|
|
234
|
+
* Entra Authentication Endpoint to use.
|
|
235
|
+
*
|
|
236
|
+
* @remarks
|
|
237
|
+
* If not populated the Entra Public Cloud endpoint is assumed.
|
|
238
|
+
* This example of Public Cloud Endpoint is https://login.microsoftonline.com
|
|
239
|
+
* see also https://learn.microsoft.com/entra/identity-platform/authentication-national-cloud
|
|
240
|
+
*/
|
|
241
|
+
authority?: string
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Entra Authentication Endpoint to use.
|
|
245
|
+
*
|
|
246
|
+
* @remarks
|
|
247
|
+
* If not populated the Entra Public Cloud endpoint is assumed.
|
|
248
|
+
* This example of Public Cloud Endpoint is https://login.microsoftonline.com
|
|
249
|
+
* see also https://learn.microsoft.com/entra/identity-platform/authentication-national-cloud
|
|
250
|
+
*/
|
|
251
|
+
authorityEndpoint?: string
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* @deprecated Use scopes instead.
|
|
255
|
+
*/
|
|
256
|
+
scope?: string
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* The scopes for the authentication configuration.
|
|
260
|
+
*/
|
|
261
|
+
scopes?: string[]
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* An optional alternative blueprint Connection name used when constructing a connector client.
|
|
265
|
+
*
|
|
266
|
+
* @remarks
|
|
267
|
+
* Equivalent to the .NET `AlternateBlueprintConnectionName` connection setting. {@link alternateBlueprintConnectionName}
|
|
268
|
+
* is an alias of this property that matches the .NET name exactly; when both are provided this property takes precedence.
|
|
269
|
+
*/
|
|
270
|
+
altBlueprintConnectionName?: string
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Alias of {@link altBlueprintConnectionName} named to match the .NET `AlternateBlueprintConnectionName`
|
|
274
|
+
* connection setting exactly.
|
|
275
|
+
*
|
|
276
|
+
* @remarks
|
|
277
|
+
* Provided for stricter .NET parity. The two properties are kept in sync during configuration normalization;
|
|
278
|
+
* {@link altBlueprintConnectionName} takes precedence when both are set.
|
|
279
|
+
*/
|
|
280
|
+
alternateBlueprintConnectionName?: string
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* The complete settings for a single connection, across every provider.
|
|
285
|
+
*
|
|
286
|
+
* @remarks
|
|
287
|
+
* This is the per-connection unit that an `AuthProvider` consumes: it combines the common base
|
|
288
|
+
* ({@link ConnectionSettingsBase}) with the MSAL settings ({@link MsalConnectionSettings}) and the
|
|
289
|
+
* Entra sidecar settings ({@link SidecarConnectionSettings}). The active provider for a connection is
|
|
290
|
+
* selected by `authType`, so only the subset of these properties relevant to that provider is used.
|
|
291
|
+
*
|
|
292
|
+
* Conceptually this is the consumer-facing counterpart to the {@link AuthConfiguration} *container*:
|
|
293
|
+
* each value in {@link AuthConfiguration.connections} is the settings for one connection. It parallels
|
|
294
|
+
* the .NET `IConnectionSettings` (a single connection's settings) as distinct from the connection
|
|
295
|
+
* registry. {@link AuthConfiguration} extends this type for backward compatibility (it doubles as the
|
|
296
|
+
* settings for the legacy single connection).
|
|
297
|
+
*/
|
|
298
|
+
export interface ConnectionSettings extends MsalConnectionSettings, SidecarConnectionSettings {}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Represents the authentication configuration.
|
|
302
|
+
*
|
|
303
|
+
* @remarks
|
|
304
|
+
* The agent-level authentication container. It owns the connection registry
|
|
305
|
+
* (`connections`/`connectionsMap`) and, for backward compatibility, also extends
|
|
306
|
+
* {@link ConnectionSettings} so the legacy single-connection shape (a flat config with `clientId`,
|
|
307
|
+
* `clientSecret`, etc.) keeps working — in that mode the top-level object *is* the one connection's
|
|
308
|
+
* settings. The active provider for each connection is dispatched by `authType` via
|
|
309
|
+
* `AuthProviderFactory`, so a single connection only uses the subset of these properties relevant to
|
|
310
|
+
* its provider.
|
|
311
|
+
*/
|
|
312
|
+
export interface AuthConfiguration extends ConnectionSettings {
|
|
313
|
+
/**
|
|
314
|
+
* The connection registry: a map of connection name to that connection's settings.
|
|
315
|
+
*
|
|
316
|
+
* @remarks
|
|
317
|
+
* Each value is the {@link ConnectionSettings} for one connection (typed as {@link AuthConfiguration}
|
|
318
|
+
* for backward compatibility; only the connection-settings subset is consumed). An `AuthProvider` is
|
|
319
|
+
* created per entry by `AuthProviderFactory`, dispatched by `authType`.
|
|
320
|
+
*/
|
|
321
|
+
connections?: Map<string, AuthConfiguration>
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* A list of connection map items to map service URLs to connection names.
|
|
325
|
+
*/
|
|
326
|
+
connectionsMap?: ConnectionMapItem[]
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Supported authentication types for agent connections.
|
|
331
|
+
*/
|
|
332
|
+
export enum AuthType {
|
|
333
|
+
Certificate = 'Certificate',
|
|
334
|
+
CertificateSubjectName = 'CertificateSubjectName',
|
|
335
|
+
ClientSecret = 'ClientSecret',
|
|
336
|
+
UserManagedIdentity = 'UserManagedIdentity',
|
|
337
|
+
SystemManagedIdentity = 'SystemManagedIdentity',
|
|
338
|
+
FederatedCredentials = 'FederatedCredentials',
|
|
339
|
+
WorkloadIdentity = 'WorkloadIdentity',
|
|
340
|
+
IdentityProxyManager = 'IdentityProxyManager',
|
|
341
|
+
EntraAuthSideCar = 'EntraAuthSideCar'
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Resolves the authentication type for a given authentication configuration.
|
|
346
|
+
* @remarks
|
|
347
|
+
* The function checks various properties of the `authConfig` object to determine the appropriate authentication type.
|
|
348
|
+
* It returns a string representing the resolved authentication type or 'unknown' if it cannot be determined.
|
|
349
|
+
* @param authConfig The authentication configuration object.
|
|
350
|
+
* @returns The resolved authentication type as a string or 'unknown' if it cannot be determined.
|
|
351
|
+
*/
|
|
352
|
+
export function resolveAuthType (authConfig?: AuthConfiguration): AuthType | string {
|
|
353
|
+
if (!authConfig) {
|
|
354
|
+
return 'none'
|
|
355
|
+
}
|
|
356
|
+
if (authConfig.authType) {
|
|
357
|
+
return authConfig.authType
|
|
358
|
+
}
|
|
359
|
+
if (authConfig.WIDAssertionFile !== undefined) {
|
|
360
|
+
return AuthType.WorkloadIdentity
|
|
361
|
+
}
|
|
362
|
+
if (authConfig.federatedClientId !== undefined || authConfig.FICClientId !== undefined) {
|
|
363
|
+
return AuthType.FederatedCredentials
|
|
364
|
+
}
|
|
365
|
+
if (authConfig.clientSecret !== undefined) {
|
|
366
|
+
return AuthType.ClientSecret
|
|
367
|
+
}
|
|
368
|
+
if (authConfig.certPemFile !== undefined && authConfig.certKeyFile !== undefined) {
|
|
369
|
+
return AuthType.Certificate
|
|
370
|
+
}
|
|
371
|
+
if (authConfig.clientSecret === undefined && authConfig.certPemFile === undefined && authConfig.certKeyFile === undefined) {
|
|
372
|
+
return AuthType.UserManagedIdentity
|
|
373
|
+
}
|
|
374
|
+
if (authConfig.idpmResource !== undefined) {
|
|
375
|
+
return AuthType.IdentityProxyManager
|
|
376
|
+
}
|
|
377
|
+
return 'unknown'
|
|
378
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { debug } from '@microsoft/agents-telemetry'
|
|
7
|
+
import { ExceptionHelper } from '@microsoft/agents-activity'
|
|
8
|
+
import { Errors } from '../../errorHelper'
|
|
9
|
+
import { AuthConfiguration } from '../authConfiguration'
|
|
10
|
+
import { AuthProvider } from '../authProvider'
|
|
11
|
+
import { SidecarHttpClient } from './sidecarHttpClient'
|
|
12
|
+
import { resolveTokenExpiry } from './sidecarTokenExpiry'
|
|
13
|
+
import {
|
|
14
|
+
ResolvedSidecarConnectionSettings,
|
|
15
|
+
SidecarRequestOptions,
|
|
16
|
+
toSidecarConnectionSettings
|
|
17
|
+
} from './sidecarModels'
|
|
18
|
+
|
|
19
|
+
const logger = debug('agents:sidecar')
|
|
20
|
+
|
|
21
|
+
const GUID_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i
|
|
22
|
+
|
|
23
|
+
// Refresh slightly ahead of the real expiry so callers never receive a token that expires mid-flight.
|
|
24
|
+
const EXPIRY_BUFFER_MS = 30 * 1000
|
|
25
|
+
|
|
26
|
+
// Hard upper bound on cached entries; protects memory when many distinct identities are served.
|
|
27
|
+
const MAX_CACHE_ENTRIES = 500
|
|
28
|
+
|
|
29
|
+
interface CachedToken {
|
|
30
|
+
token: string
|
|
31
|
+
expiresOn: number
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Authentication provider that delegates token acquisition to the Microsoft Entra Agent ID
|
|
36
|
+
* sidecar (agent container). This replaces MSAL at the connection layer, using the sidecar's
|
|
37
|
+
* `/AuthorizationHeaderUnauthenticated/{serviceName}` endpoint for app-only and agentic identity
|
|
38
|
+
* flows. The sidecar performs the full Blueprint→Instance→User chain internally; no MSAL exchange is
|
|
39
|
+
* performed in-process.
|
|
40
|
+
*/
|
|
41
|
+
export class SidecarAuthProvider implements AuthProvider {
|
|
42
|
+
public readonly connectionSettings?: AuthConfiguration
|
|
43
|
+
private readonly _settings: ResolvedSidecarConnectionSettings
|
|
44
|
+
private readonly _httpClient: SidecarHttpClient
|
|
45
|
+
private readonly _tokenCache: Map<string, CachedToken> = new Map()
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new {@link SidecarAuthProvider}.
|
|
49
|
+
* @param connectionSettings The connection authentication configuration.
|
|
50
|
+
*/
|
|
51
|
+
constructor (connectionSettings?: AuthConfiguration) {
|
|
52
|
+
this.connectionSettings = connectionSettings
|
|
53
|
+
this._settings = toSidecarConnectionSettings(connectionSettings)
|
|
54
|
+
|
|
55
|
+
const resolvedUrl = SidecarHttpClient.resolveBaseUrl(this._settings.sidecarBaseUrl)
|
|
56
|
+
SidecarHttpClient.validateBaseUrl(resolvedUrl, this._settings.bypassLocalNetworkRestriction)
|
|
57
|
+
this._httpClient = new SidecarHttpClient(resolvedUrl, this._settings.requestTimeout, this._settings.retryCount)
|
|
58
|
+
logger.debug('SidecarAuthProvider initialized serviceName=%s blueprintServiceName=%s', this._settings.serviceName, this._settings.blueprintServiceName)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Acquires an app-only access token from the sidecar.
|
|
63
|
+
* @param scope The scope for the token.
|
|
64
|
+
*/
|
|
65
|
+
async getAccessToken (scope: string): Promise<string>
|
|
66
|
+
/**
|
|
67
|
+
* Acquires an app-only access token from the sidecar.
|
|
68
|
+
* @param authConfig The authentication configuration. Ignored by the sidecar provider, which
|
|
69
|
+
* owns the credential and derives the token from its configured service name; accepted only to
|
|
70
|
+
* satisfy the {@link AuthProvider} overload.
|
|
71
|
+
* @param scope The scope for the token.
|
|
72
|
+
*/
|
|
73
|
+
async getAccessToken (authConfig: AuthConfiguration, scope: string): Promise<string>
|
|
74
|
+
async getAccessToken (authConfigOrScope: AuthConfiguration | string, scope?: string): Promise<string> {
|
|
75
|
+
const actualScope = typeof authConfigOrScope === 'string' ? authConfigOrScope : scope
|
|
76
|
+
const options: SidecarRequestOptions = {
|
|
77
|
+
scopes: actualScope ? [actualScope] : this._settings.scopes,
|
|
78
|
+
requestAppToken: true
|
|
79
|
+
}
|
|
80
|
+
return this.getCachedToken(this._settings.serviceName, options)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Acquires the Blueprint (agent application) token from the sidecar.
|
|
85
|
+
* @param tenantId The tenant ID.
|
|
86
|
+
* @param agentAppInstanceId The agent instance ID (from the inbound activity); maps to `AgentIdentity`.
|
|
87
|
+
*/
|
|
88
|
+
async getAgenticApplicationToken (tenantId: string, agentAppInstanceId: string): Promise<string> {
|
|
89
|
+
this.ensureConnectionSettings()
|
|
90
|
+
const options: SidecarRequestOptions = {
|
|
91
|
+
agentIdentity: agentAppInstanceId,
|
|
92
|
+
tenant: tenantId
|
|
93
|
+
}
|
|
94
|
+
return this.getCachedToken(this._settings.blueprintServiceName, options)
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Acquires the autonomous agent (instance) token from the sidecar for the configured resource.
|
|
99
|
+
* @param tenantId The tenant ID.
|
|
100
|
+
* @param agentAppInstanceId The agent instance ID (from the inbound activity); maps to `AgentIdentity`.
|
|
101
|
+
*/
|
|
102
|
+
async getAgenticInstanceToken (tenantId: string, agentAppInstanceId: string): Promise<string> {
|
|
103
|
+
this.ensureConnectionSettings()
|
|
104
|
+
const options: SidecarRequestOptions = {
|
|
105
|
+
agentIdentity: agentAppInstanceId,
|
|
106
|
+
requestAppToken: true,
|
|
107
|
+
tenant: tenantId,
|
|
108
|
+
scopes: this._settings.scopes
|
|
109
|
+
}
|
|
110
|
+
return this.getCachedToken(this._settings.serviceName, options)
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Acquires the agentic user token from the sidecar for the configured resource.
|
|
115
|
+
* @param tenantId The tenant ID.
|
|
116
|
+
* @param agentAppInstanceId The agent instance ID (from the inbound activity); maps to `AgentIdentity`.
|
|
117
|
+
* @param upn The agentic user identifier. A GUID is sent as `AgentUserId`; otherwise as `AgentUsername`.
|
|
118
|
+
* @param scopes The OAuth scopes to request.
|
|
119
|
+
*/
|
|
120
|
+
async getAgenticUserToken (tenantId: string, agentAppInstanceId: string, upn: string, scopes: string[]): Promise<string> {
|
|
121
|
+
this.ensureConnectionSettings()
|
|
122
|
+
const isObjectId = GUID_REGEX.test(upn ?? '')
|
|
123
|
+
const options: SidecarRequestOptions = {
|
|
124
|
+
agentIdentity: agentAppInstanceId,
|
|
125
|
+
agentUsername: isObjectId ? undefined : upn,
|
|
126
|
+
agentUserId: isObjectId ? upn : undefined,
|
|
127
|
+
tenant: tenantId,
|
|
128
|
+
scopes: scopes ?? this._settings.scopes
|
|
129
|
+
}
|
|
130
|
+
return this.getCachedToken(this._settings.serviceName, options)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* On-behalf-of token exchange — not supported by the sidecar provider in Phase 1.
|
|
135
|
+
*/
|
|
136
|
+
async acquireTokenOnBehalfOf (scopes: string[], oboAssertion: string): Promise<string>
|
|
137
|
+
async acquireTokenOnBehalfOf (authConfig: AuthConfiguration, scopes: string[], oboAssertion: string): Promise<string>
|
|
138
|
+
async acquireTokenOnBehalfOf (
|
|
139
|
+
_authConfigOrScopes: AuthConfiguration | string[],
|
|
140
|
+
_scopesOrOboAssertion?: string[] | string,
|
|
141
|
+
_oboAssertion?: string
|
|
142
|
+
): Promise<string> {
|
|
143
|
+
throw ExceptionHelper.generateException(Error, Errors.OnBehalfOfNotSupportedBySidecar)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Checks sidecar availability via the `/healthz` endpoint.
|
|
148
|
+
* @returns `true` when the sidecar is reachable and healthy.
|
|
149
|
+
*/
|
|
150
|
+
async isHealthy (): Promise<boolean> {
|
|
151
|
+
return this._httpClient.isHealthy()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private ensureConnectionSettings (): void {
|
|
155
|
+
if (!this.connectionSettings) {
|
|
156
|
+
throw ExceptionHelper.generateException(Error, Errors.SidecarConnectionSettingsRequired)
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
private async getCachedToken (serviceName: string, options: SidecarRequestOptions): Promise<string> {
|
|
161
|
+
const forceRefresh = options.forceRefresh === true
|
|
162
|
+
const cacheKey = SidecarAuthProvider.buildCacheKey(serviceName, options)
|
|
163
|
+
|
|
164
|
+
const cached = this.cacheGet(cacheKey, forceRefresh)
|
|
165
|
+
if (cached) {
|
|
166
|
+
return cached
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const result = await this._httpClient.getAuthorizationHeaderUnauthenticated(serviceName, options)
|
|
170
|
+
// The hosting stack always transmits the token as `Bearer {token}`. Reject any other scheme
|
|
171
|
+
// (e.g. PoP) rather than silently emitting an invalid Authorization header.
|
|
172
|
+
if (result.scheme && result.scheme.toLowerCase() !== 'bearer') {
|
|
173
|
+
throw ExceptionHelper.generateException(Error, Errors.SidecarUnsupportedAuthScheme, undefined, { scheme: result.scheme })
|
|
174
|
+
}
|
|
175
|
+
this.cacheSet(cacheKey, { token: result.token, expiresOn: resolveTokenExpiry(result.token) })
|
|
176
|
+
return result.token
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
private cacheGet (cacheKey: string, forceRefresh: boolean): string | undefined {
|
|
180
|
+
const cached = this._tokenCache.get(cacheKey)
|
|
181
|
+
if (cached) {
|
|
182
|
+
if (!forceRefresh && cached.expiresOn >= Date.now() + EXPIRY_BUFFER_MS) {
|
|
183
|
+
return cached.token
|
|
184
|
+
}
|
|
185
|
+
this._tokenCache.delete(cacheKey)
|
|
186
|
+
}
|
|
187
|
+
return undefined
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
private cacheSet (cacheKey: string, token: CachedToken): void {
|
|
191
|
+
this._tokenCache.set(cacheKey, token)
|
|
192
|
+
if (this._tokenCache.size > MAX_CACHE_ENTRIES) {
|
|
193
|
+
this.pruneExpiredEntries()
|
|
194
|
+
if (this._tokenCache.size > MAX_CACHE_ENTRIES) {
|
|
195
|
+
this.evictNearestExpiry()
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
private pruneExpiredEntries (): void {
|
|
201
|
+
const now = Date.now()
|
|
202
|
+
for (const [key, value] of this._tokenCache) {
|
|
203
|
+
if (value.expiresOn <= now) {
|
|
204
|
+
this._tokenCache.delete(key)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
private evictNearestExpiry (): void {
|
|
210
|
+
const overflow = this._tokenCache.size - MAX_CACHE_ENTRIES
|
|
211
|
+
if (overflow <= 0) {
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
const sorted = [...this._tokenCache.entries()].sort((a, b) => a[1].expiresOn - b[1].expiresOn)
|
|
215
|
+
for (let i = 0; i < overflow; i++) {
|
|
216
|
+
this._tokenCache.delete(sorted[i][0])
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
private static buildCacheKey (serviceName: string, options: SidecarRequestOptions): string {
|
|
221
|
+
const scopes = options.scopes
|
|
222
|
+
? [...new Set(options.scopes.filter((s) => s && s.trim()))].sort().join(' ')
|
|
223
|
+
: ''
|
|
224
|
+
return [
|
|
225
|
+
serviceName,
|
|
226
|
+
options.agentIdentity ?? '',
|
|
227
|
+
options.agentUsername ?? '',
|
|
228
|
+
options.agentUserId ?? '',
|
|
229
|
+
options.tenant ?? '',
|
|
230
|
+
options.requestAppToken === true ? 'app' : 'user',
|
|
231
|
+
scopes
|
|
232
|
+
].join('|')
|
|
233
|
+
}
|
|
234
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
* Licensed under the MIT License.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { ConnectionSettingsBase } from '../settings'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Connection settings for the Entra Agent ID sidecar (agent container) authentication provider, used when a
|
|
10
|
+
* connection's `authType` is `'EntraAuthSideCar'`.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* Mirrors the .NET `Microsoft.Agents.Authentication.EntraAuthSidecar.Model.SidecarConnectionSettings`
|
|
14
|
+
* class, which likewise derives from `ConnectionSettingsBase`. These are the configuration-level
|
|
15
|
+
* properties; they are normalized (with defaults applied) before use by the sidecar token provider.
|
|
16
|
+
*/
|
|
17
|
+
export interface SidecarConnectionSettings extends ConnectionSettingsBase {
|
|
18
|
+
/**
|
|
19
|
+
* Optional base URL of the Entra Agent ID sidecar (agent container).
|
|
20
|
+
*
|
|
21
|
+
* @remarks
|
|
22
|
+
* Only used when `authType` is `'EntraAuthSideCar'`. Resolution order:
|
|
23
|
+
* `SIDECAR_URL` environment variable > this setting > `http://localhost:5178`.
|
|
24
|
+
* Regardless of how it is resolved, the host must be a loopback/private address
|
|
25
|
+
* unless `bypassLocalNetworkRestriction` is set.
|
|
26
|
+
*/
|
|
27
|
+
sidecarBaseUrl?: string
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The configured downstream API service name in the sidecar's DownstreamApis configuration.
|
|
31
|
+
*
|
|
32
|
+
* @remarks
|
|
33
|
+
* Only used when `authType` is `'EntraAuthSideCar'`. Defaults to `'default'`.
|
|
34
|
+
*/
|
|
35
|
+
serviceName?: string
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* The sidecar downstream API name used to acquire the Blueprint (agent application) token for the
|
|
39
|
+
* agentic FIC chain.
|
|
40
|
+
*
|
|
41
|
+
* @remarks
|
|
42
|
+
* Only used when `authType` is `'EntraAuthSideCar'`. Defaults to `'agenticblueprint'`. This
|
|
43
|
+
* downstream API must be configured app-only with the `api://AzureAdTokenExchange/.default` scope.
|
|
44
|
+
*/
|
|
45
|
+
blueprintServiceName?: string
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* When `true`, disables the loopback/private-address safety check on the resolved sidecar base URL.
|
|
49
|
+
*
|
|
50
|
+
* @remarks
|
|
51
|
+
* UNSAFE. Leave this `false` in all normal deployments. Only enable it for a carefully validated
|
|
52
|
+
* private-network configuration where the sidecar is reachable at a non-private address that the
|
|
53
|
+
* operator explicitly trusts. Only used when `authType` is `'EntraAuthSideCar'`.
|
|
54
|
+
*/
|
|
55
|
+
bypassLocalNetworkRestriction?: boolean
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* HTTP request timeout (in milliseconds) for sidecar calls.
|
|
59
|
+
*
|
|
60
|
+
* @remarks
|
|
61
|
+
* Only used when `authType` is `'EntraAuthSideCar'`. Defaults to 30000 (30 seconds).
|
|
62
|
+
*/
|
|
63
|
+
requestTimeout?: number
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Number of retry attempts for transient sidecar failures (5xx, 408, 429, network/timeout).
|
|
67
|
+
*
|
|
68
|
+
* @remarks
|
|
69
|
+
* Only used when `authType` is `'EntraAuthSideCar'`. Defaults to 3.
|
|
70
|
+
*/
|
|
71
|
+
retryCount?: number
|
|
72
|
+
}
|