From ed9a71c5c7cbb635b113c3211d79f763621f24e8 Mon Sep 17 00:00:00 2001 From: Adam Wolfman Date: Tue, 24 Mar 2026 13:23:28 -0600 Subject: [PATCH 1/4] Add Vault events --- src/common/interfaces/event.interface.ts | 132 +++++- src/common/serializers/event.serializer.ts | 65 +++ src/events/events.spec.ts | 420 ++++++++++++++++++ src/vault/interfaces/index.ts | 1 + src/vault/interfaces/vault-event.interface.ts | 106 +++++ .../serializers/vault-event.serializer.ts | 97 ++++ 6 files changed, 819 insertions(+), 2 deletions(-) create mode 100644 src/vault/interfaces/vault-event.interface.ts create mode 100644 src/vault/serializers/vault-event.serializer.ts diff --git a/src/common/interfaces/event.interface.ts b/src/common/interfaces/event.interface.ts index 7a0c0e54e..4bc339c78 100644 --- a/src/common/interfaces/event.interface.ts +++ b/src/common/interfaces/event.interface.ts @@ -54,6 +54,26 @@ import { FeatureFlag, FeatureFlagResponse, } from '../../feature-flags/interfaces'; +import { + VaultDataCreatedEventData, + VaultDataCreatedEventResponseData, + VaultDataUpdatedEventData, + VaultDataUpdatedEventResponseData, + VaultDataReadEventData, + VaultDataReadEventResponseData, + VaultDataDeletedEventData, + VaultDataDeletedEventResponseData, + VaultMetadataReadEventData, + VaultMetadataReadEventResponseData, + VaultNamesListedEventData, + VaultNamesListedEventResponseData, + VaultKekCreatedEventData, + VaultKekCreatedEventResponseData, + VaultDekReadEventData, + VaultDekReadEventResponseData, + VaultDekDecryptedEventData, + VaultDekDecryptedEventResponseData, +} from '../../vault/interfaces/vault-event.interface'; export interface EventBase { id: string; @@ -732,6 +752,96 @@ export interface FlagRuleUpdatedEventResponse extends EventResponseBase { data: FeatureFlagResponse; } +export interface VaultDataCreatedEvent extends EventBase { + event: 'vault.data.created'; + data: VaultDataCreatedEventData; +} + +export interface VaultDataCreatedEventResponse extends EventResponseBase { + event: 'vault.data.created'; + data: VaultDataCreatedEventResponseData; +} + +export interface VaultDataUpdatedEvent extends EventBase { + event: 'vault.data.updated'; + data: VaultDataUpdatedEventData; +} + +export interface VaultDataUpdatedEventResponse extends EventResponseBase { + event: 'vault.data.updated'; + data: VaultDataUpdatedEventResponseData; +} + +export interface VaultDataReadEvent extends EventBase { + event: 'vault.data.read'; + data: VaultDataReadEventData; +} + +export interface VaultDataReadEventResponse extends EventResponseBase { + event: 'vault.data.read'; + data: VaultDataReadEventResponseData; +} + +export interface VaultDataDeletedEvent extends EventBase { + event: 'vault.data.deleted'; + data: VaultDataDeletedEventData; +} + +export interface VaultDataDeletedEventResponse extends EventResponseBase { + event: 'vault.data.deleted'; + data: VaultDataDeletedEventResponseData; +} + +export interface VaultNamesListedEvent extends EventBase { + event: 'vault.names.listed'; + data: VaultNamesListedEventData; +} + +export interface VaultNamesListedEventResponse extends EventResponseBase { + event: 'vault.names.listed'; + data: VaultNamesListedEventResponseData; +} + +export interface VaultMetadataReadEvent extends EventBase { + event: 'vault.metadata.read'; + data: VaultMetadataReadEventData; +} + +export interface VaultMetadataReadEventResponse extends EventResponseBase { + event: 'vault.metadata.read'; + data: VaultMetadataReadEventResponseData; +} + +export interface VaultKekCreatedEvent extends EventBase { + event: 'vault.kek.created'; + data: VaultKekCreatedEventData; +} + +export interface VaultKekCreatedEventResponse extends EventResponseBase { + event: 'vault.kek.created'; + data: VaultKekCreatedEventResponseData; +} + +export interface VaultDekReadEvent extends EventBase { + event: 'vault.dek.read'; + data: VaultDekReadEventData; +} + +export interface VaultDekReadEventResponse extends EventResponseBase { + event: 'vault.dek.read'; + data: VaultDekReadEventResponseData; +} + +export interface VaultDekDecryptedEvent extends EventBase { + event: 'vault.dek.decrypted'; + data: VaultDekDecryptedEventData; +} + +export interface VaultDekDecryptedEventResponse extends EventResponseBase { + event: 'vault.dek.decrypted'; + data: VaultDekDecryptedEventResponseData; +} + export type Event = | AuthenticationEmailVerificationSucceededEvent | AuthenticationMfaSucceededEvent @@ -797,7 +907,16 @@ export type Event = | FlagCreatedEvent | FlagUpdatedEvent | FlagDeletedEvent - | FlagRuleUpdatedEvent; + | FlagRuleUpdatedEvent + | VaultDataCreatedEvent + | VaultDataUpdatedEvent + | VaultDataReadEvent + | VaultDataDeletedEvent + | VaultNamesListedEvent + | VaultMetadataReadEvent + | VaultKekCreatedEvent + | VaultDekReadEvent + | VaultDekDecryptedEvent; export type EventResponse = | AuthenticationEmailVerificationSucceededEventResponse @@ -864,6 +983,15 @@ export type EventResponse = | FlagCreatedEventResponse | FlagUpdatedEventResponse | FlagDeletedEventResponse - | FlagRuleUpdatedEventResponse; + | FlagRuleUpdatedEventResponse + | VaultDataCreatedEventResponse + | VaultDataUpdatedEventResponse + | VaultDataReadEventResponse + | VaultDataDeletedEventResponse + | VaultNamesListedEventResponse + | VaultMetadataReadEventResponse + | VaultKekCreatedEventResponse + | VaultDekReadEventResponse + | VaultDekDecryptedEventResponse; export type EventName = Event['event']; diff --git a/src/common/serializers/event.serializer.ts b/src/common/serializers/event.serializer.ts index b0db209e8..ac159af9e 100644 --- a/src/common/serializers/event.serializer.ts +++ b/src/common/serializers/event.serializer.ts @@ -26,6 +26,17 @@ import { deserializeApiKey } from '../../api-keys/serializers/api-key.serializer import { deserializeOrganizationRoleEvent } from '../../authorization/serializers/organization-role.serializer'; import { deserializePermission } from '../../authorization/serializers/permission.serializer'; import { deserializeFeatureFlag } from '../../feature-flags/serializers/feature-flag.serializer'; +import { + deserializeVaultDataCreatedEvent, + deserializeVaultDataUpdatedEvent, + deserializeVaultDataReadEvent, + deserializeVaultDataDeletedEvent, + deserializeVaultNamesListedEvent, + deserializeVaultMetadataReadEvent, + deserializeVaultKekCreatedEvent, + deserializeVaultDekReadEvent, + deserializeVaultDekDecryptedEvent, +} from '../../vault/serializers/vault-event.serializer'; export const deserializeEvent = (event: EventResponse): Event => { const eventBase: EventBase = { @@ -224,5 +235,59 @@ export const deserializeEvent = (event: EventResponse): Event => { event: event.event, data: deserializeFeatureFlag(event.data), }; + case 'vault.data.created': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDataCreatedEvent(event.data), + }; + case 'vault.data.updated': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDataUpdatedEvent(event.data), + }; + case 'vault.data.read': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDataReadEvent(event.data), + }; + case 'vault.data.deleted': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDataDeletedEvent(event.data), + }; + case 'vault.names.listed': + return { + ...eventBase, + event: event.event, + data: deserializeVaultNamesListedEvent(event.data), + }; + case 'vault.metadata.read': + return { + ...eventBase, + event: event.event, + data: deserializeVaultMetadataReadEvent(event.data), + }; + case 'vault.kek.created': + return { + ...eventBase, + event: event.event, + data: deserializeVaultKekCreatedEvent(event.data), + }; + case 'vault.dek.read': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDekReadEvent(event.data), + }; + case 'vault.dek.decrypted': + return { + ...eventBase, + event: event.event, + data: deserializeVaultDekDecryptedEvent(event.data), + }; } }; diff --git a/src/events/events.spec.ts b/src/events/events.spec.ts index 26d62d5e8..62a28e46f 100644 --- a/src/events/events.spec.ts +++ b/src/events/events.spec.ts @@ -8,6 +8,24 @@ import { FlagCreatedEvent, FlagCreatedEventResponse, ListResponse, + VaultDataCreatedEvent, + VaultDataCreatedEventResponse, + VaultDataUpdatedEvent, + VaultDataUpdatedEventResponse, + VaultDataReadEvent, + VaultDataReadEventResponse, + VaultDataDeletedEvent, + VaultDataDeletedEventResponse, + VaultNamesListedEvent, + VaultNamesListedEventResponse, + VaultMetadataReadEvent, + VaultMetadataReadEventResponse, + VaultKekCreatedEvent, + VaultKekCreatedEventResponse, + VaultDekReadEvent, + VaultDekReadEventResponse, + VaultDekDecryptedEvent, + VaultDekDecryptedEventResponse, } from '../common/interfaces'; import { WorkOS } from '../workos'; import { ConnectionType } from '../sso/interfaces'; @@ -197,6 +215,408 @@ describe('Event', () => { }); }); + describe('vault events', () => { + it('deserializes vault.data.created events', async () => { + const response: VaultDataCreatedEventResponse = { + id: 'event_01VAULT00001', + created_at: '2026-03-24T12:00:00.000Z', + context: { client_id: 'client_01234ABCD' }, + event: 'vault.data.created', + data: { + actor_id: 'user_01ABC', + actor_source: 'dashboard', + actor_name: 'Jane Doe', + kv_name: 'secret-key', + key_id: 'key_01ABC', + key_context: { env: 'production' }, + }, + }; + + const expected: VaultDataCreatedEvent = { + id: 'event_01VAULT00001', + createdAt: '2026-03-24T12:00:00.000Z', + context: { client_id: 'client_01234ABCD' }, + event: 'vault.data.created', + data: { + actorId: 'user_01ABC', + actorSource: 'dashboard', + actorName: 'Jane Doe', + kvName: 'secret-key', + keyId: 'key_01ABC', + keyContext: { env: 'production' }, + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.data.created'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.data.updated events', async () => { + const response: VaultDataUpdatedEventResponse = { + id: 'event_01VAULT00002', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.data.updated', + data: { + actor_id: 'user_01ABC', + actor_source: 'api', + actor_name: 'API Key', + kv_name: 'secret-key', + key_id: 'key_01ABC', + key_context: { env: 'staging' }, + }, + }; + + const expected: VaultDataUpdatedEvent = { + id: 'event_01VAULT00002', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.data.updated', + data: { + actorId: 'user_01ABC', + actorSource: 'api', + actorName: 'API Key', + kvName: 'secret-key', + keyId: 'key_01ABC', + keyContext: { env: 'staging' }, + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.data.updated'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.data.read events', async () => { + const response: VaultDataReadEventResponse = { + id: 'event_01VAULT00003', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.data.read', + data: { + actor_id: 'user_01ABC', + actor_source: 'api', + actor_name: 'API Key', + kv_name: 'secret-key', + key_id: 'key_01ABC', + }, + }; + + const expected: VaultDataReadEvent = { + id: 'event_01VAULT00003', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.data.read', + data: { + actorId: 'user_01ABC', + actorSource: 'api', + actorName: 'API Key', + kvName: 'secret-key', + keyId: 'key_01ABC', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.data.read'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.data.deleted events', async () => { + const response: VaultDataDeletedEventResponse = { + id: 'event_01VAULT00004', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.data.deleted', + data: { + actor_id: 'user_01ABC', + actor_source: 'dashboard', + actor_name: 'Jane Doe', + kv_name: 'secret-key', + }, + }; + + const expected: VaultDataDeletedEvent = { + id: 'event_01VAULT00004', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.data.deleted', + data: { + actorId: 'user_01ABC', + actorSource: 'dashboard', + actorName: 'Jane Doe', + kvName: 'secret-key', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.data.deleted'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.names.listed events', async () => { + const response: VaultNamesListedEventResponse = { + id: 'event_01VAULT00005', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.names.listed', + data: { + actor_id: 'user_01ABC', + actor_source: 'dashboard', + actor_name: 'Jane Doe', + }, + }; + + const expected: VaultNamesListedEvent = { + id: 'event_01VAULT00005', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.names.listed', + data: { + actorId: 'user_01ABC', + actorSource: 'dashboard', + actorName: 'Jane Doe', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.names.listed'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.metadata.read events', async () => { + const response: VaultMetadataReadEventResponse = { + id: 'event_01VAULT00006', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.metadata.read', + data: { + actor_id: 'user_01ABC', + actor_source: 'api', + actor_name: 'API Key', + kv_name: 'secret-key', + }, + }; + + const expected: VaultMetadataReadEvent = { + id: 'event_01VAULT00006', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.metadata.read', + data: { + actorId: 'user_01ABC', + actorSource: 'api', + actorName: 'API Key', + kvName: 'secret-key', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.metadata.read'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.kek.created events', async () => { + const response: VaultKekCreatedEventResponse = { + id: 'event_01VAULT00007', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.kek.created', + data: { + actor_id: 'user_01ABC', + actor_source: 'dashboard', + actor_name: 'Jane Doe', + key_name: 'my-kek', + key_id: 'key_01ABC', + }, + }; + + const expected: VaultKekCreatedEvent = { + id: 'event_01VAULT00007', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.kek.created', + data: { + actorId: 'user_01ABC', + actorSource: 'dashboard', + actorName: 'Jane Doe', + keyName: 'my-kek', + keyId: 'key_01ABC', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.kek.created'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.dek.read events', async () => { + const response: VaultDekReadEventResponse = { + id: 'event_01VAULT00008', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.dek.read', + data: { + actor_id: 'user_01ABC', + actor_source: 'api', + actor_name: 'API Key', + key_ids: ['key_01ABC', 'key_02DEF'], + key_context: { env: 'production' }, + }, + }; + + const expected: VaultDekReadEvent = { + id: 'event_01VAULT00008', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.dek.read', + data: { + actorId: 'user_01ABC', + actorSource: 'api', + actorName: 'API Key', + keyIds: ['key_01ABC', 'key_02DEF'], + keyContext: { env: 'production' }, + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.dek.read'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + + it('deserializes vault.dek.decrypted events', async () => { + const response: VaultDekDecryptedEventResponse = { + id: 'event_01VAULT00009', + created_at: '2026-03-24T12:00:00.000Z', + event: 'vault.dek.decrypted', + data: { + actor_id: 'user_01ABC', + actor_source: 'api', + actor_name: 'API Key', + key_id: 'key_01ABC', + }, + }; + + const expected: VaultDekDecryptedEvent = { + id: 'event_01VAULT00009', + createdAt: '2026-03-24T12:00:00.000Z', + context: undefined, + event: 'vault.dek.decrypted', + data: { + actorId: 'user_01ABC', + actorSource: 'api', + actorName: 'API Key', + keyId: 'key_01ABC', + }, + }; + + fetchOnce({ + object: 'list', + data: [response], + list_metadata: {}, + }); + + const list = await workos.events.listEvents({ + events: ['vault.dek.decrypted'], + }); + + expect(list).toEqual({ + object: 'list', + data: [expected], + listMetadata: {}, + }); + }); + }); + describe('directory user updated events', () => { describe('with a role', () => { const directoryUserUpdated: DsyncUserUpdatedEvent = { diff --git a/src/vault/interfaces/index.ts b/src/vault/interfaces/index.ts index 2f2196956..4b491fa32 100644 --- a/src/vault/interfaces/index.ts +++ b/src/vault/interfaces/index.ts @@ -8,3 +8,4 @@ export * from './object/list-objects.interface'; export * from './object/read-object.interface'; export * from './object/update-object.interface'; export * from './object.interface'; +export * from './vault-event.interface'; diff --git a/src/vault/interfaces/vault-event.interface.ts b/src/vault/interfaces/vault-event.interface.ts new file mode 100644 index 000000000..7186fc531 --- /dev/null +++ b/src/vault/interfaces/vault-event.interface.ts @@ -0,0 +1,106 @@ +export type VaultActorSource = 'api' | 'dashboard'; + +export interface VaultActor { + actorId: string; + actorSource: VaultActorSource; + actorName: string; +} + +export interface VaultActorResponse { + actor_id: string; + actor_source: VaultActorSource; + actor_name: string; +} + +// vault.data.created +export interface VaultDataCreatedEventData extends VaultActor { + kvName: string; + keyId: string; + keyContext: Record; +} + +export interface VaultDataCreatedEventResponseData extends VaultActorResponse { + kv_name: string; + key_id: string; + key_context: Record; +} + +// vault.data.updated +export interface VaultDataUpdatedEventData extends VaultActor { + kvName: string; + keyId: string; + keyContext: Record; +} + +export interface VaultDataUpdatedEventResponseData extends VaultActorResponse { + kv_name: string; + key_id: string; + key_context: Record; +} + +// vault.data.read +export interface VaultDataReadEventData extends VaultActor { + kvName: string; + keyId: string; +} + +export interface VaultDataReadEventResponseData extends VaultActorResponse { + kv_name: string; + key_id: string; +} + +// vault.data.deleted +export interface VaultDataDeletedEventData extends VaultActor { + kvName: string; +} + +export interface VaultDataDeletedEventResponseData extends VaultActorResponse { + kv_name: string; +} + +// vault.metadata.read +export interface VaultMetadataReadEventData extends VaultActor { + kvName: string; +} + +export interface VaultMetadataReadEventResponseData + extends VaultActorResponse { + kv_name: string; +} + +// vault.names.listed +export type VaultNamesListedEventData = VaultActor; + +export type VaultNamesListedEventResponseData = VaultActorResponse; + +// vault.kek.created +export interface VaultKekCreatedEventData extends VaultActor { + keyName: string; + keyId: string; +} + +export interface VaultKekCreatedEventResponseData extends VaultActorResponse { + key_name: string; + key_id: string; +} + +// vault.dek.read +export interface VaultDekReadEventData extends VaultActor { + keyIds: string[]; + keyContext: Record; +} + +export interface VaultDekReadEventResponseData extends VaultActorResponse { + key_ids: string[]; + key_context: Record; +} + +// vault.dek.decrypted +export interface VaultDekDecryptedEventData extends VaultActor { + keyId: string; +} + +export interface VaultDekDecryptedEventResponseData + extends VaultActorResponse { + key_id: string; +} diff --git a/src/vault/serializers/vault-event.serializer.ts b/src/vault/serializers/vault-event.serializer.ts new file mode 100644 index 000000000..d865bd998 --- /dev/null +++ b/src/vault/serializers/vault-event.serializer.ts @@ -0,0 +1,97 @@ +import { + VaultActorResponse, + VaultActor, + VaultDataCreatedEventData, + VaultDataCreatedEventResponseData, + VaultDataUpdatedEventData, + VaultDataUpdatedEventResponseData, + VaultDataReadEventData, + VaultDataReadEventResponseData, + VaultDataDeletedEventData, + VaultDataDeletedEventResponseData, + VaultMetadataReadEventData, + VaultMetadataReadEventResponseData, + VaultNamesListedEventData, + VaultNamesListedEventResponseData, + VaultKekCreatedEventData, + VaultKekCreatedEventResponseData, + VaultDekReadEventData, + VaultDekReadEventResponseData, + VaultDekDecryptedEventData, + VaultDekDecryptedEventResponseData, +} from '../interfaces/vault-event.interface'; + +const deserializeVaultActor = (actor: VaultActorResponse): VaultActor => ({ + actorId: actor.actor_id, + actorSource: actor.actor_source, + actorName: actor.actor_name, +}); + +export const deserializeVaultDataCreatedEvent = ( + data: VaultDataCreatedEventResponseData, +): VaultDataCreatedEventData => ({ + ...deserializeVaultActor(data), + kvName: data.kv_name, + keyId: data.key_id, + keyContext: data.key_context, +}); + +export const deserializeVaultDataUpdatedEvent = ( + data: VaultDataUpdatedEventResponseData, +): VaultDataUpdatedEventData => ({ + ...deserializeVaultActor(data), + kvName: data.kv_name, + keyId: data.key_id, + keyContext: data.key_context, +}); + +export const deserializeVaultDataReadEvent = ( + data: VaultDataReadEventResponseData, +): VaultDataReadEventData => ({ + ...deserializeVaultActor(data), + kvName: data.kv_name, + keyId: data.key_id, +}); + +export const deserializeVaultDataDeletedEvent = ( + data: VaultDataDeletedEventResponseData, +): VaultDataDeletedEventData => ({ + ...deserializeVaultActor(data), + kvName: data.kv_name, +}); + +export const deserializeVaultMetadataReadEvent = ( + data: VaultMetadataReadEventResponseData, +): VaultMetadataReadEventData => ({ + ...deserializeVaultActor(data), + kvName: data.kv_name, +}); + +export const deserializeVaultNamesListedEvent = ( + data: VaultNamesListedEventResponseData, +): VaultNamesListedEventData => ({ + ...deserializeVaultActor(data), +}); + +export const deserializeVaultKekCreatedEvent = ( + data: VaultKekCreatedEventResponseData, +): VaultKekCreatedEventData => ({ + ...deserializeVaultActor(data), + keyName: data.key_name, + keyId: data.key_id, +}); + +export const deserializeVaultDekReadEvent = ( + data: VaultDekReadEventResponseData, +): VaultDekReadEventData => ({ + ...deserializeVaultActor(data), + keyIds: data.key_ids, + keyContext: data.key_context, +}); + +export const deserializeVaultDekDecryptedEvent = ( + data: VaultDekDecryptedEventResponseData, +): VaultDekDecryptedEventData => ({ + ...deserializeVaultActor(data), + keyId: data.key_id, +}); From ceea4fb0f29141bf1bd553bc1dcbf9b03efe104f Mon Sep 17 00:00:00 2001 From: Adam Wolfman Date: Tue, 24 Mar 2026 13:29:57 -0600 Subject: [PATCH 2/4] Run prettier --- src/vault/interfaces/vault-event.interface.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/vault/interfaces/vault-event.interface.ts b/src/vault/interfaces/vault-event.interface.ts index 7186fc531..c1735174e 100644 --- a/src/vault/interfaces/vault-event.interface.ts +++ b/src/vault/interfaces/vault-event.interface.ts @@ -63,8 +63,7 @@ export interface VaultMetadataReadEventData extends VaultActor { kvName: string; } -export interface VaultMetadataReadEventResponseData - extends VaultActorResponse { +export interface VaultMetadataReadEventResponseData extends VaultActorResponse { kv_name: string; } @@ -100,7 +99,6 @@ export interface VaultDekDecryptedEventData extends VaultActor { keyId: string; } -export interface VaultDekDecryptedEventResponseData - extends VaultActorResponse { +export interface VaultDekDecryptedEventResponseData extends VaultActorResponse { key_id: string; } From 59b3bc5d3aeb911b3376416935c91a9a5bc30042 Mon Sep 17 00:00:00 2001 From: Adam Wolfman Date: Tue, 24 Mar 2026 15:43:29 -0600 Subject: [PATCH 3/4] Update review items --- src/vault/interfaces/vault-event.interface.ts | 24 +++++++------------ .../serializers/vault-event.serializer.ts | 4 +--- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/src/vault/interfaces/vault-event.interface.ts b/src/vault/interfaces/vault-event.interface.ts index c1735174e..d41c3bb5f 100644 --- a/src/vault/interfaces/vault-event.interface.ts +++ b/src/vault/interfaces/vault-event.interface.ts @@ -12,31 +12,25 @@ export interface VaultActorResponse { actor_name: string; } -// vault.data.created -export interface VaultDataCreatedEventData extends VaultActor { +// vault.data.created / vault.data.updated (identical shapes) +interface VaultDataMutatedEventData extends VaultActor { kvName: string; keyId: string; keyContext: Record; } -export interface VaultDataCreatedEventResponseData extends VaultActorResponse { +interface VaultDataMutatedEventResponseData extends VaultActorResponse { kv_name: string; key_id: string; key_context: Record; } -// vault.data.updated -export interface VaultDataUpdatedEventData extends VaultActor { - kvName: string; - keyId: string; - keyContext: Record; -} - -export interface VaultDataUpdatedEventResponseData extends VaultActorResponse { - kv_name: string; - key_id: string; - key_context: Record; -} +export type VaultDataCreatedEventData = VaultDataMutatedEventData; +export type VaultDataUpdatedEventData = VaultDataMutatedEventData; +export type VaultDataCreatedEventResponseData = + VaultDataMutatedEventResponseData; +export type VaultDataUpdatedEventResponseData = + VaultDataMutatedEventResponseData; // vault.data.read export interface VaultDataReadEventData extends VaultActor { diff --git a/src/vault/serializers/vault-event.serializer.ts b/src/vault/serializers/vault-event.serializer.ts index d865bd998..b2dd0971b 100644 --- a/src/vault/serializers/vault-event.serializer.ts +++ b/src/vault/serializers/vault-event.serializer.ts @@ -69,9 +69,7 @@ export const deserializeVaultMetadataReadEvent = ( export const deserializeVaultNamesListedEvent = ( data: VaultNamesListedEventResponseData, -): VaultNamesListedEventData => ({ - ...deserializeVaultActor(data), -}); +): VaultNamesListedEventData => deserializeVaultActor(data); export const deserializeVaultKekCreatedEvent = ( data: VaultKekCreatedEventResponseData, From ff1f4b513044330bd9e83d4f4ebd6fe3ddec05c3 Mon Sep 17 00:00:00 2001 From: Adam Wolfman Date: Wed, 25 Mar 2026 12:37:23 -0600 Subject: [PATCH 4/4] Update vault-event-interface to use KeyContext interface --- src/vault/interfaces/vault-event.interface.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/vault/interfaces/vault-event.interface.ts b/src/vault/interfaces/vault-event.interface.ts index d41c3bb5f..94a4934b2 100644 --- a/src/vault/interfaces/vault-event.interface.ts +++ b/src/vault/interfaces/vault-event.interface.ts @@ -1,4 +1,5 @@ export type VaultActorSource = 'api' | 'dashboard'; +import type { KeyContext } from './key.interface'; export interface VaultActor { actorId: string; @@ -16,13 +17,13 @@ export interface VaultActorResponse { interface VaultDataMutatedEventData extends VaultActor { kvName: string; keyId: string; - keyContext: Record; + keyContext: KeyContext; } interface VaultDataMutatedEventResponseData extends VaultActorResponse { kv_name: string; key_id: string; - key_context: Record; + key_context: KeyContext; } export type VaultDataCreatedEventData = VaultDataMutatedEventData; @@ -80,12 +81,12 @@ export interface VaultKekCreatedEventResponseData extends VaultActorResponse { // vault.dek.read export interface VaultDekReadEventData extends VaultActor { keyIds: string[]; - keyContext: Record; + keyContext: KeyContext; } export interface VaultDekReadEventResponseData extends VaultActorResponse { key_ids: string[]; - key_context: Record; + key_context: KeyContext; } // vault.dek.decrypted