Files
DevRunbook-Public/packages/integrations/src/secret-envelope.test.ts
T
DevRunbook release export cfd2804e27
Managed validation / full (push) Successful in 3m18s
Publish DevRunbook source
2026-09-03 04:09:17 +02:00

63 lines
1.9 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import {
decryptIntegrationSecret,
encryptIntegrationSecret,
type SecretBinding,
} from './secret-envelope'
const binding: SecretBinding = {
workspaceId: 'workspace-a',
integrationId: 'integration-a',
secretKind: 'gitea-token',
}
const oldKey = Buffer.alloc(32, 7)
const activeKey = Buffer.alloc(32, 9)
const ring = { activeVersion: 'v2', keys: { v1: oldKey, v2: activeKey } }
describe('integration secret envelope', () => {
it('round-trips without exposing plaintext in the envelope', () => {
const plaintext = 'gitea-secret-token-value'
const envelope = encryptIntegrationSecret(plaintext, binding, ring)
expect(JSON.stringify(envelope)).not.toContain(plaintext)
expect(envelope).toMatchObject({
algorithm: 'AES-256-GCM',
envelopeVersion: 1,
keyVersion: 'v2',
})
expect(decryptIntegrationSecret(envelope, binding, ring)).toBe(plaintext)
})
it('decrypts an old key version through the key ring', () => {
const envelope = encryptIntegrationSecret('old-secret', binding, {
activeVersion: 'v1',
keys: { v1: oldKey },
})
expect(decryptIntegrationSecret(envelope, binding, ring)).toBe('old-secret')
})
it('rejects tampering, wrong AAD and unavailable key versions', () => {
const envelope = encryptIntegrationSecret('bound-secret', binding, ring)
expect(() =>
decryptIntegrationSecret(
{ ...envelope, ciphertext: Buffer.from('tampered').toString('base64') },
binding,
ring,
),
).toThrow('authentication failed')
expect(() =>
decryptIntegrationSecret(
envelope,
{ ...binding, workspaceId: 'workspace-b' },
ring,
),
).toThrow('authentication failed')
expect(() =>
decryptIntegrationSecret(envelope, binding, {
activeVersion: 'v3',
keys: { v3: Buffer.alloc(32, 1) },
}),
).toThrow('key version is unavailable')
})
})