Skip to content

Commit 4e3d257

Browse files
committed
fix(integrations): hash vanta client secret in token cache keys
1 parent 6519dac commit 4e3d257

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

apps/sim/tools/vanta/utils.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,20 @@ const vantaTokenExchanges = new Map<string, Promise<string>>()
153153
/** Evict cached tokens well before their one-hour expiry. */
154154
const VANTA_TOKEN_EXPIRY_BUFFER_MS = 10 * 60 * 1000
155155

156-
function vantaTokenCacheKey(params: VantaTokenParams): string {
157-
return [params.region ?? 'us', params.scope, params.clientId, params.clientSecret].join('|')
156+
/**
157+
* Derives the cache key for a credential set. The client secret is included
158+
* only as a SHA-256 digest so plaintext secrets never persist in the
159+
* long-lived cache maps.
160+
*/
161+
async function vantaTokenCacheKey(params: VantaTokenParams): Promise<string> {
162+
const digest = await crypto.subtle.digest(
163+
'SHA-256',
164+
new TextEncoder().encode(`${params.clientId}:${params.clientSecret}`)
165+
)
166+
const secretHash = Array.from(new Uint8Array(digest))
167+
.map((byte) => byte.toString(16).padStart(2, '0'))
168+
.join('')
169+
return [params.region ?? 'us', params.scope, params.clientId, secretHash].join('|')
158170
}
159171

160172
async function exchangeVantaToken(params: VantaTokenParams, cacheKey: string): Promise<string> {
@@ -205,7 +217,7 @@ export async function getVantaAccessToken(
205217
params: VantaTokenParams,
206218
options?: { forceRefresh?: boolean }
207219
): Promise<string> {
208-
const cacheKey = vantaTokenCacheKey(params)
220+
const cacheKey = await vantaTokenCacheKey(params)
209221
if (!options?.forceRefresh) {
210222
const cached = vantaTokenCache.get(cacheKey)
211223
if (cached && cached.expiresAt > Date.now()) {

0 commit comments

Comments
 (0)