create-hec-event-integration

Utiliser lors de l'ajout d'une nouvelle intégration d'événements HEC (HTTP Event Collector) au client web Bitwarden. Implémente le modèle d'authentification par jeton Splunk (jeton Bearer…

npx skills add https://github.com/bitwarden/clients --skill create-hec-event-integration

Create HEC Event Integration (Token Auth)

Step 1 - Prompts

Ask these questions one at a time — wait for each answer before proceeding.

Prompt 1 — Service name: "What is the service name for this integration?" (e.g. Splunk, CrowdStrike, Panther)

Use the answer as <ServiceName> throughout. The string value in the constant must exactly match what you use as the card's name in Step 4 — a mismatch silently saves the config with the wrong service name.

Prompt 2 — Authentication: "How is this integration authenticated?" (e.g. Token, API key)

  • If Token — continue with the steps below.
  • If anything else — stop and inform the user: "This skill currently only supports token-based authentication. Support for other authentication methods hasn't been added yet."

Prompt 3 — Logos: "Do you have the integration logo(s) ready to provide?"

  • If yes — ask for the light-mode SVG file path, and optionally a dark-mode SVG path. Copy both to apps/web/src/images/integrations/ using the naming convention logo-<service-name-kebab>-color.svg and logo-<service-name-kebab>-darkmode.svg. Use those filenames in Step 4.
  • If no — use placeholder paths in Step 4 and add a // TODO: add logo before shipping comment.

Step 2 — Add service name constant

File: bitwarden_license/bit-common/src/dirt/organization-integrations/models/organization-integration-service-type.ts

Add to OrganizationIntegrationServiceName:

export const OrganizationIntegrationServiceName = Object.freeze({
  CrowdStrike: "CrowdStrike",
  Datadog: "Datadog",
  Huntress: "Huntress",
  <ServiceName>: "<ServiceName>", // ← add here
} as const);

Step 3 — Add feature flag

File: libs/common/src/enums/feature-flag.enum.ts

Add the enum entry and its default. The enum key is PascalCase; the string value is kebab-case (e.g. CrowdStrike → crowdstrike, Sumo Logic → sumo-logic):

// In the FeatureFlag enum:
EventManagementFor<ServiceName> = "event-management-for-<service-name-kebab>",

// In the defaultFlags object:
[FeatureFlag.EventManagementFor<ServiceName>]: FALSE,

Example for Panther:

EventManagementForPanther = "event-management-for-panther",
[FeatureFlag.EventManagementForPanther]: FALSE,

Step 4 — Register the card behind the feature flag

File: bitwarden_license/bit-web/src/app/dirt/organization-integrations/organization-integrations.resolver.ts

If logos were provided, copy them to apps/web/src/images/integrations/ first, then use the actual filenames below. If not, use the placeholder paths with the TODO comment:

const <serviceName>FeatureEnabled = await firstValueFrom(
  this.configService.getFeatureFlag$(FeatureFlag.EventManagementFor<ServiceName>),
);

if (<serviceName>FeatureEnabled) {
  integrations.push({
    name: OrganizationIntegrationServiceName.<ServiceName>, // must match Step 1 exactly
    linkURL: "https://bitwarden.com/help/<service-name>-siem/",
    image: "../../../../../../../images/integrations/logo-<service-name>-color.svg", // TODO: add logo before shipping (if not yet provided)
    imageDarkMode: "../../../../../../../images/integrations/logo-<service-name>-darkmode.svg", // TODO: add logo before shipping (omit if no dark mode variant)
    type: IntegrationType.EVENT,
    canSetupConnection: true,
    integrationType: OrganizationIntegrationType.Hec,
  });
}

No changes needed to IntegrationCardComponent — new HEC services fall into the existing else branch, which calls openHecConnectDialog → saveHec → deleteHec. These methods already call buildHecConfiguration and buildHecTemplate using the card's name as the service name.

Step 5 — Add tests

File: bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.spec.ts

Add one it block inside the existing describe("buildHecConfiguration", ...) block, and one inside describe("buildHecTemplate", ...). Use typed property access — do not use JSON.parse:

// Inside describe("buildHecConfiguration", ...)
it("should work with <ServiceName> service name", () => {
  const config = OrgIntegrationBuilder.buildHecConfiguration(
    "https://test.<servicename>.com/hec",
    "test-token",
    OrganizationIntegrationServiceName.<ServiceName>,
  );

  expect(config).toBeInstanceOf(HecConfiguration);
  expect((config as HecConfiguration).uri).toBe("https://test.<servicename>.com/hec");
  expect((config as HecConfiguration).scheme).toBe("Bearer");
  expect((config as HecConfiguration).token).toBe("test-token");
  expect(config.bw_serviceName).toBe(OrganizationIntegrationServiceName.<ServiceName>);
});

// Inside describe("buildHecTemplate", ...)
it("should work with <ServiceName> service name", () => {
  const template = OrgIntegrationBuilder.buildHecTemplate(
    "test-index",
    OrganizationIntegrationServiceName.<ServiceName>,
  );

  expect(template).toBeInstanceOf(HecTemplate);
  expect((template as HecTemplate).index).toBe("test-index");
  expect(template.bw_serviceName).toBe(OrganizationIntegrationServiceName.<ServiceName>);
});

Step 6 — Run unit tests

Run the unit tests for the spec file and confirm they all pass before finishing:

npx jest bitwarden_license/bit-common/src/dirt/organization-integrations/models/integration-builder.spec.ts

All tests must pass. If any fail, fix them before proceeding.

Common Mistakes

MistakeFix
name in card doesn't match OrganizationIntegrationServiceName valueThey must be identical strings — saveHec() casts the name directly
Feature flag default not set to FALSEAlways add the default entry in defaultFlags; new flags without a default will not work correctly
Kebab-case mismatch in flag stringConvert consistently: lowercase, spaces → hyphens
Adding a new OrganizationIntegrationTypeNot needed — all HEC services share OrganizationIntegrationType.Hec
Creating a new config/template classNot needed — HecConfiguration and HecTemplate handle all HEC services
Referencing an image path without copying the fileCopy SVGs to apps/web/src/images/integrations/ first; if logos aren't ready, leave the TODO comment

Plus de skills de bitwarden

figma-to-angular
bitwarden
Cette compétence transforme un cahier des charges Figma en un composant Angular entièrement implémenté avec des stories Storybook dans le monorepo Bitwarden Clients. Le résultat doit correspondre visuellement au design tout en respectant toutes les conventions du codebase.
force-multiplier
bitwarden
Appliquez une intention unique à de nombreuses cibles à la fois — une flotte de dépôts à travers l’écosystème Bitwarden, ou de nombreux projets au sein d’un monorepo — comme N cohérents, …
analyzing-git-sessions
bitwarden
Analyse les commits et modifications Git dans un intervalle de temps ou une plage de commits, fournissant des résumés structurés pour la revue de code, les rétrospectives, les journaux de travail ou les sessions…
coordinating-cross-team-breakdown
bitwarden
Coordonner la revue et l'approbation inter-équipes pour un Bitwarden Tech Breakdown. Utiliser lors de l'identification des équipes concernées, de la construction du tableau d'approbation de la Partie 3, de la relance…
assessing-jira-issue-relevance
bitwarden
À utiliser lorsque l'utilisateur fournit une clé de ticket Jira unique et demande si elle est toujours pertinente, toujours applicable, toujours en attente, toujours un bug, a été corrigée, ou peut…
assessing-test-coverage
bitwarden
À utiliser pour déterminer quelle couverture de tests EXISTE déjà pour un changement spécifique (une PR, une clé Jira, un document Tech Breakdown, un CSV Testmo, des chemins modifiés ou des éléments nommés…
retrospecting
bitwarden
Effectue une analyse complète des sessions Claude Code, en examinant l'historique git, les journaux de conversation, les modifications de code, et en recueillant les retours utilisateurs pour générer…
reviewing-incremental-changes
bitwarden
Utilisez cette compétence lors de la re-vérification d'une PR qui contient déjà des commentaires ou lors de la réponse aux modifications du développeur après la vérification initiale. Appliquez-la lorsque des fils de discussion de PR existent ou…