feat(backend): wire Azure Key Vault secret resolution at startup

- Add bootstrap.ts as new entry point — resolves Key Vault secrets via
  DefaultAzureCredential before config/index.ts is evaluated, so all
  process.env reads pick up KV values (Azure CLI in dev, Managed Identity
  in prod). Falls back to .env if AZURE_KEYVAULT_URL is not set.
- Define INVTTRDG_SECRETS mappings for Cosmos, Azure OpenAI, product-id
- Add AZURE_OPENAI_ENDPOINT / KEY / DEPLOYMENT to config
- aiClient: prefer AzureOpenAIProvider (AI Foundry) when Azure OpenAI
  config is present; falls back to direct OpenAI if not configured
- Add @azure/identity, @azure/keyvault-secrets, @bytelyst/config deps
- Update dev/start scripts to use bootstrap.ts entry point
- Document AZURE_KEYVAULT_URL and Azure OpenAI vars in .env.example

Key Vault: https://kv-mywisprai.vault.azure.net/
Secrets prefix: invttrdg-*

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Saravana Achu Mac 2026-04-05 18:28:47 -07:00
parent bb59b918d6
commit aaa516122e
6 changed files with 307 additions and 5 deletions

View File

@ -13,11 +13,20 @@ PLATFORM_JWT_JWKS_URL=
# Product backend endpoint
TRADING_API_URL=http://localhost:4018/api
# Cosmos DB control-plane storage
# Azure Key Vault — set to enable secret resolution at startup (uses Azure CLI in dev, Managed Identity in prod)
AZURE_KEYVAULT_URL=https://kv-mywisprai.vault.azure.net/
# Cosmos DB control-plane storage (populated from Key Vault if AZURE_KEYVAULT_URL is set)
COSMOS_ENDPOINT=
COSMOS_KEY=
COSMOS_DATABASE=invttrdg
# Azure OpenAI (AI Foundry) — populated from Key Vault if AZURE_KEYVAULT_URL is set
# When set, takes precedence over direct OPENAI_API_KEY for the openai provider slot
AZURE_OPENAI_ENDPOINT=https://swedencentral.api.cognitive.microsoft.com/
AZURE_OPENAI_KEY=
AZURE_OPENAI_DEPLOYMENT=gpt-4o
# Web-specific public envs
NEXT_PUBLIC_PRODUCT_ID=invttrdg
NEXT_PUBLIC_PLATFORM_URL=http://localhost:4003/api

View File

@ -6,10 +6,10 @@
"main": "index.js",
"scripts": {
"test": "npm run check:websocket-contract && npm run check:session-rule-normalization",
"dev": "node --import tsx src/index.ts",
"dev": "node --import tsx src/bootstrap.ts",
"build": "tsc",
"typecheck": "tsc --noEmit",
"start": "node dist/index.js",
"start": "node dist/bootstrap.js",
"check:schema-contract": "node --import tsx verifySchemaContract.ts",
"check:rls-policies": "node --import tsx verifyRlsPolicies.ts",
"check:secret-hygiene": "node --import tsx verifySecretHygiene.ts",
@ -51,7 +51,10 @@
"license": "ISC",
"dependencies": {
"@azure/cosmos": "^4.3.0",
"@azure/identity": "^4.10.0",
"@azure/keyvault-secrets": "^4.9.0",
"@bytelyst/auth": "link:../../../learning_ai/learning_ai_common_plat/packages/auth",
"@bytelyst/config": "link:../../../learning_ai/learning_ai_common_plat/packages/config",
"@bytelyst/cosmos": "link:../../../learning_ai/learning_ai_common_plat/packages/cosmos",
"@bytelyst/llm": "link:../../../learning_ai/learning_ai_common_plat/packages/llm",
"@alpacahq/alpaca-trade-api": "^3.1.3",

31
backend/src/bootstrap.ts Normal file
View File

@ -0,0 +1,31 @@
/**
* Startup bootstrap resolves secrets from Azure Key Vault before loading
* the main application. Uses DefaultAzureCredential (Azure CLI in dev,
* Managed Identity in production). Falls back gracefully to .env values
* if Key Vault is unreachable or AZURE_KEYVAULT_URL is not set.
*
* Secret resolution happens here so that config/index.ts reads fully-populated
* process.env values when it is evaluated via the dynamic import below.
*/
import { resolveSecrets, type SecretMapping } from '@bytelyst/config';
const INVTTRDG_SECRETS: SecretMapping[] = [
{ kvName: 'invttrdg-cosmos-endpoint', envVar: 'COSMOS_ENDPOINT' },
{ kvName: 'invttrdg-cosmos-key', envVar: 'COSMOS_KEY' },
{ kvName: 'invttrdg-cosmos-database', envVar: 'COSMOS_DATABASE' },
{ kvName: 'invttrdg-azure-openai-endpoint', envVar: 'AZURE_OPENAI_ENDPOINT' },
{ kvName: 'invttrdg-azure-openai-key', envVar: 'AZURE_OPENAI_KEY' },
{ kvName: 'invttrdg-azure-openai-deployment', envVar: 'AZURE_OPENAI_DEPLOYMENT' },
{ kvName: 'invttrdg-product-id', envVar: 'PRODUCT_ID' },
];
// AZURE_KEYVAULT_URL must be set to trigger Key Vault resolution.
// If absent, resolveSecrets() is a no-op and .env values are used as-is.
await resolveSecrets(INVTTRDG_SECRETS, {
vaultUrl: process.env.AZURE_KEYVAULT_URL,
});
// Dynamic import ensures config/index.ts (and all transitive modules) evaluate
// AFTER process.env is fully populated above.
await import('./index.js');

View File

@ -16,6 +16,12 @@ export const config = {
COSMOS_KEY: process.env.COSMOS_KEY || '',
COSMOS_DATABASE: process.env.COSMOS_DATABASE || 'invttrdg',
// Azure OpenAI (AI Foundry) — populated from Key Vault via bootstrap
AZURE_OPENAI_ENDPOINT: process.env.AZURE_OPENAI_ENDPOINT || '',
AZURE_OPENAI_KEY: process.env.AZURE_OPENAI_KEY || '',
AZURE_OPENAI_DEPLOYMENT: process.env.AZURE_OPENAI_DEPLOYMENT || '',
AZURE_KEYVAULT_URL: process.env.AZURE_KEYVAULT_URL || '',
// Plug-and-Play Provider Selection
PROVIDER: process.env.PROVIDER || 'alpaca',
DATA_PROVIDER: process.env.DATA_PROVIDER || process.env.PROVIDER || 'alpaca',

View File

@ -1,4 +1,5 @@
import {
AzureOpenAIProvider,
createFallbackChain,
GeminiProvider,
OpenAIProvider,
@ -37,6 +38,18 @@ function resolveModel(provider: AIProvider): string {
}
}
function makeOpenAIProvider(): LLMProvider {
// Prefer Azure OpenAI when endpoint + key + deployment are all configured
if (config.AZURE_OPENAI_ENDPOINT && config.AZURE_OPENAI_KEY && config.AZURE_OPENAI_DEPLOYMENT) {
return new AzureOpenAIProvider({
endpoint: config.AZURE_OPENAI_ENDPOINT,
apiKey: config.AZURE_OPENAI_KEY,
deployment: config.AZURE_OPENAI_DEPLOYMENT,
});
}
return new OpenAIProvider({ apiKey: config.AI.OPENAI_API_KEY, model: resolveModel('openai') });
}
const PROVIDER_REGISTRY: ProviderEntry[] = [
{
name: 'perplexity',
@ -45,8 +58,8 @@ const PROVIDER_REGISTRY: ProviderEntry[] = [
},
{
name: 'openai',
make: () => new OpenAIProvider({ apiKey: config.AI.OPENAI_API_KEY, model: resolveModel('openai') }),
defaultModel: 'gpt-4o-mini',
make: makeOpenAIProvider,
defaultModel: 'gpt-4o',
},
{
name: 'gemini',

240
pnpm-lock.yaml generated
View File

@ -33,9 +33,18 @@ importers:
'@azure/cosmos':
specifier: ^4.3.0
version: 4.9.2(@azure/core-client@1.10.1)
'@azure/identity':
specifier: ^4.10.0
version: 4.13.1
'@azure/keyvault-secrets':
specifier: ^4.9.0
version: 4.10.0(@azure/core-client@1.10.1)
'@bytelyst/auth':
specifier: link:../../../learning_ai/learning_ai_common_plat/packages/auth
version: link:../../../learning_ai/learning_ai_common_plat/packages/auth
'@bytelyst/config':
specifier: link:../../../learning_ai/learning_ai_common_plat/packages/config
version: link:../../../learning_ai/learning_ai_common_plat/packages/config
'@bytelyst/cosmos':
specifier: link:../../../learning_ai/learning_ai_common_plat/packages/cosmos
version: link:../../../learning_ai/learning_ai_common_plat/packages/cosmos
@ -409,6 +418,10 @@ packages:
resolution: {integrity: sha512-g+n9GDm+N4iMPE3/ZfFClBvy33fE13oa60wJLKof05tEzcJF+4KsVNdjZkRNOTRBvpGGwD0CO/FGdxBuOb2+yg==}
engines: {node: '>=20.0.0'}
'@azure/identity@4.13.1':
resolution: {integrity: sha512-5C/2WD5Vb1lHnZS16dNQRPMjN6oV/Upba+C9nBIs15PmOi6A3ZGs4Lr2u60zw4S04gi+u3cEXiqTVP7M4Pz3kw==}
engines: {node: '>=20.0.0'}
'@azure/keyvault-common@2.0.0':
resolution: {integrity: sha512-wRLVaroQtOqfg60cxkzUkGKrKMsCP6uYXAOomOIysSMyt1/YM0eUn9LqieAWM8DLcU4+07Fio2YGpPeqUbpP9w==}
engines: {node: '>=18.0.0'}
@ -417,10 +430,26 @@ packages:
resolution: {integrity: sha512-eDT7iXoBTRZ2n3fLiftuGJFD+yjkiB1GNqzU2KbY1TLYeXeSPVTVgn2eJ5vmRTZ11978jy2Kg2wI7xa9Tyr8ag==}
engines: {node: '>=18.0.0'}
'@azure/keyvault-secrets@4.10.0':
resolution: {integrity: sha512-WvXc3h2hqHL1pMzUU7ANE2RBKoxjK3JQc0YNn6GUFvOWQtf2ZR+sH4/5cZu8zAg62v9qLCduBN7065nHKl+AOA==}
engines: {node: '>=18.0.0'}
'@azure/logger@1.3.0':
resolution: {integrity: sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA==}
engines: {node: '>=20.0.0'}
'@azure/msal-browser@5.6.3':
resolution: {integrity: sha512-sTjMtUm+bJpENU/1WlRzHEsgEHppZDZ1EtNyaOODg/sQBtMxxJzGB+MOCM+T2Q5Qe1fKBrdxUmjyRxm0r7Ez9w==}
engines: {node: '>=0.8.0'}
'@azure/msal-common@16.4.1':
resolution: {integrity: sha512-Bl8f+w37xkXsYh7QRkAKCFGYtWMYuOVO7Lv+BxILrvGz3HbIEF22Pt0ugyj0QPOl6NLrHcnNUQ9yeew98P/5iw==}
engines: {node: '>=0.8.0'}
'@azure/msal-node@5.1.2':
resolution: {integrity: sha512-DoeSJ9U5KPAIZoHsPywvfEj2MhBniQe0+FSpjLUTdWoIkI999GB5USkW6nNEHnIaLVxROHXvprWA1KzdS1VQ4A==}
engines: {node: '>=20'}
'@babel/code-frame@7.10.4':
resolution: {integrity: sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==}
@ -2834,12 +2863,19 @@ packages:
bser@2.1.1:
resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==}
buffer-equal-constant-time@1.0.1:
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
buffer-from@1.1.2:
resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
buffer@5.7.1:
resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
bundle-name@4.1.0:
resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==}
engines: {node: '>=18'}
bytes@3.1.2:
resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==}
engines: {node: '>= 0.8'}
@ -3175,6 +3211,14 @@ packages:
resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==}
engines: {node: '>=0.10.0'}
default-browser-id@5.0.1:
resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==}
engines: {node: '>=18'}
default-browser@5.5.0:
resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==}
engines: {node: '>=18'}
defaults@1.0.4:
resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==}
@ -3186,6 +3230,10 @@ packages:
resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==}
engines: {node: '>=8'}
define-lazy-prop@3.0.0:
resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==}
engines: {node: '>=12'}
define-properties@1.2.1:
resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
engines: {node: '>= 0.4'}
@ -3263,6 +3311,9 @@ packages:
eastasianwidth@0.2.0:
resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
ecdsa-sig-formatter@1.0.11:
resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==}
ee-first@1.1.1:
resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==}
@ -4145,6 +4196,11 @@ packages:
engines: {node: '>=8'}
hasBin: true
is-docker@3.0.0:
resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
hasBin: true
is-extglob@2.1.1:
resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
engines: {node: '>=0.10.0'}
@ -4165,6 +4221,11 @@ packages:
resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
engines: {node: '>=0.10.0'}
is-inside-container@1.0.0:
resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
engines: {node: '>=14.16'}
hasBin: true
is-map@2.0.3:
resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==}
engines: {node: '>= 0.4'}
@ -4239,6 +4300,10 @@ packages:
resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==}
engines: {node: '>=8'}
is-wsl@3.1.1:
resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==}
engines: {node: '>=16'}
isarray@2.0.5:
resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==}
@ -4363,6 +4428,10 @@ packages:
engines: {node: '>=6'}
hasBin: true
jsonwebtoken@9.0.3:
resolution: {integrity: sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==}
engines: {node: '>=12', npm: '>=6'}
jsx-ast-utils@3.3.5:
resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==}
engines: {node: '>=4.0'}
@ -4370,6 +4439,12 @@ packages:
just-extend@4.2.1:
resolution: {integrity: sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==}
jwa@2.0.1:
resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==}
jws@4.0.1:
resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==}
keyv@4.5.4:
resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
@ -4479,9 +4554,30 @@ packages:
lodash.debounce@4.0.8:
resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==}
lodash.includes@4.3.0:
resolution: {integrity: sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==}
lodash.isboolean@3.0.3:
resolution: {integrity: sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==}
lodash.isinteger@4.0.4:
resolution: {integrity: sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==}
lodash.isnumber@3.0.3:
resolution: {integrity: sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==}
lodash.isplainobject@4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
lodash.isstring@4.0.1:
resolution: {integrity: sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==}
lodash.merge@4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
lodash.once@4.1.1:
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
lodash.throttle@4.1.1:
resolution: {integrity: sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ==}
@ -4903,6 +4999,10 @@ packages:
resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==}
engines: {node: '>=4'}
open@10.2.0:
resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==}
engines: {node: '>=18'}
open@7.4.2:
resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==}
engines: {node: '>=8'}
@ -5400,6 +5500,10 @@ packages:
resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==}
engines: {node: '>= 18'}
run-applescript@7.1.0:
resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==}
engines: {node: '>=18'}
run-parallel@1.2.0:
resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
@ -6020,6 +6124,10 @@ packages:
resolution: {integrity: sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==}
hasBin: true
uuid@8.3.2:
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
hasBin: true
v8-compile-cache-lib@3.0.1:
resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==}
@ -6267,6 +6375,10 @@ packages:
utf-8-validate:
optional: true
wsl-utils@0.1.0:
resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==}
engines: {node: '>=18'}
xcode@3.0.1:
resolution: {integrity: sha512-kCz5k7J7XbJtjABOvkc5lJmkiDh8VhjVCGNiqdKCscmVpdVUpEAyXv1xmCLkQJ5dsHqx3IPO4XW+NTDhU/fatA==}
engines: {node: '>=10.0.0'}
@ -6477,6 +6589,22 @@ snapshots:
- '@azure/core-client'
- supports-color
'@azure/identity@4.13.1':
dependencies:
'@azure/abort-controller': 2.1.2
'@azure/core-auth': 1.10.1
'@azure/core-client': 1.10.1
'@azure/core-rest-pipeline': 1.23.0
'@azure/core-tracing': 1.3.1
'@azure/core-util': 1.13.1
'@azure/logger': 1.3.0
'@azure/msal-browser': 5.6.3
'@azure/msal-node': 5.1.2
open: 10.2.0
tslib: 2.8.1
transitivePeerDependencies:
- supports-color
'@azure/keyvault-common@2.0.0':
dependencies:
'@azure/abort-controller': 2.1.2
@ -6508,6 +6636,24 @@ snapshots:
- '@azure/core-client'
- supports-color
'@azure/keyvault-secrets@4.10.0(@azure/core-client@1.10.1)':
dependencies:
'@azure-rest/core-client': 2.5.1
'@azure/abort-controller': 2.1.2
'@azure/core-auth': 1.10.1
'@azure/core-http-compat': 2.3.2(@azure/core-client@1.10.1)(@azure/core-rest-pipeline@1.23.0)
'@azure/core-lro': 2.7.2
'@azure/core-paging': 1.6.2
'@azure/core-rest-pipeline': 1.23.0
'@azure/core-tracing': 1.3.1
'@azure/core-util': 1.13.1
'@azure/keyvault-common': 2.0.0
'@azure/logger': 1.3.0
tslib: 2.8.1
transitivePeerDependencies:
- '@azure/core-client'
- supports-color
'@azure/logger@1.3.0':
dependencies:
'@typespec/ts-http-runtime': 0.3.4
@ -6515,6 +6661,18 @@ snapshots:
transitivePeerDependencies:
- supports-color
'@azure/msal-browser@5.6.3':
dependencies:
'@azure/msal-common': 16.4.1
'@azure/msal-common@16.4.1': {}
'@azure/msal-node@5.1.2':
dependencies:
'@azure/msal-common': 16.4.1
jsonwebtoken: 9.0.3
uuid: 8.3.2
'@babel/code-frame@7.10.4':
dependencies:
'@babel/highlight': 7.25.9
@ -9371,6 +9529,8 @@ snapshots:
dependencies:
node-int64: 0.4.0
buffer-equal-constant-time@1.0.1: {}
buffer-from@1.1.2: {}
buffer@5.7.1:
@ -9378,6 +9538,10 @@ snapshots:
base64-js: 1.5.1
ieee754: 1.2.1
bundle-name@4.1.0:
dependencies:
run-applescript: 7.1.0
bytes@3.1.2: {}
c8@10.1.3:
@ -9710,6 +9874,13 @@ snapshots:
deepmerge@4.3.1: {}
default-browser-id@5.0.1: {}
default-browser@5.5.0:
dependencies:
bundle-name: 4.1.0
default-browser-id: 5.0.1
defaults@1.0.4:
dependencies:
clone: 1.0.4
@ -9722,6 +9893,8 @@ snapshots:
define-lazy-prop@2.0.0: {}
define-lazy-prop@3.0.0: {}
define-properties@1.2.1:
dependencies:
define-data-property: 1.1.4
@ -9788,6 +9961,10 @@ snapshots:
eastasianwidth@0.2.0: {}
ecdsa-sig-formatter@1.0.11:
dependencies:
safe-buffer: 5.2.1
ee-first@1.1.1: {}
electron-to-chromium@1.5.331: {}
@ -10923,6 +11100,8 @@ snapshots:
is-docker@2.2.1: {}
is-docker@3.0.0: {}
is-extglob@2.1.1: {}
is-finalizationregistry@1.1.1:
@ -10943,6 +11122,10 @@ snapshots:
dependencies:
is-extglob: 2.1.1
is-inside-container@1.0.0:
dependencies:
is-docker: 3.0.0
is-map@2.0.3: {}
is-negative-zero@2.0.3: {}
@ -11007,6 +11190,10 @@ snapshots:
dependencies:
is-docker: 2.2.1
is-wsl@3.1.1:
dependencies:
is-inside-container: 1.0.0
isarray@2.0.5: {}
isexe@2.0.0: {}
@ -11183,6 +11370,19 @@ snapshots:
json5@2.2.3: {}
jsonwebtoken@9.0.3:
dependencies:
jws: 4.0.1
lodash.includes: 4.3.0
lodash.isboolean: 3.0.3
lodash.isinteger: 4.0.4
lodash.isnumber: 3.0.3
lodash.isplainobject: 4.0.6
lodash.isstring: 4.0.1
lodash.once: 4.1.1
ms: 2.1.3
semver: 7.7.4
jsx-ast-utils@3.3.5:
dependencies:
array-includes: 3.1.9
@ -11192,6 +11392,17 @@ snapshots:
just-extend@4.2.1: {}
jwa@2.0.1:
dependencies:
buffer-equal-constant-time: 1.0.1
ecdsa-sig-formatter: 1.0.11
safe-buffer: 5.2.1
jws@4.0.1:
dependencies:
jwa: 2.0.1
safe-buffer: 5.2.1
keyv@4.5.4:
dependencies:
json-buffer: 3.0.1
@ -11277,8 +11488,22 @@ snapshots:
lodash.debounce@4.0.8: {}
lodash.includes@4.3.0: {}
lodash.isboolean@3.0.3: {}
lodash.isinteger@4.0.4: {}
lodash.isnumber@3.0.3: {}
lodash.isplainobject@4.0.6: {}
lodash.isstring@4.0.1: {}
lodash.merge@4.6.2: {}
lodash.once@4.1.1: {}
lodash.throttle@4.1.1: {}
lodash@4.18.1: {}
@ -11900,6 +12125,13 @@ snapshots:
dependencies:
mimic-fn: 1.2.0
open@10.2.0:
dependencies:
default-browser: 5.5.0
define-lazy-prop: 3.0.0
is-inside-container: 1.0.0
wsl-utils: 0.1.0
open@7.4.2:
dependencies:
is-docker: 2.2.1
@ -12498,6 +12730,8 @@ snapshots:
transitivePeerDependencies:
- supports-color
run-applescript@7.1.0: {}
run-parallel@1.2.0:
dependencies:
queue-microtask: 1.2.3
@ -13197,6 +13431,8 @@ snapshots:
uuid@7.0.3: {}
uuid@8.3.2: {}
v8-compile-cache-lib@3.0.1: {}
v8-to-istanbul@9.3.0:
@ -13429,6 +13665,10 @@ snapshots:
ws@8.20.0: {}
wsl-utils@0.1.0:
dependencies:
is-wsl: 3.1.1
xcode@3.0.1:
dependencies:
simple-plist: 1.3.1