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. CrowdStrikecrowdstrike, Sumo Logicsumo-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 openHecConnectDialogsaveHecdeleteHec. 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

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…
official
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.
official
agent-access
bitwarden
Retrieve login credentials, API keys, and secrets (username, password, TOTP) from the user's Bitwarden vault via aac. Use when you need credentials to sign…
official
action-audit
bitwarden
Auditer l'utilisation des actions GitHub Actions dans une organisation. Recherche une action spécifique (mode incident) ou analyse tous les fichiers de workflow pour détecter les actions non conformes…
official
action-remediate
bitwarden
Remediate GitHub Actions action findings identified by the action-audit skill. Applies the appropriate fix per action type — `@main` ref for internal…
official
analyzing-code-security
bitwarden
This skill should be used when the user asks to "analyze code for security issues", "check for OWASP vulnerabilities", "review code against CWE Top 25", "find…
official
applying-bitwarden-branding
bitwarden
Appliquer les normes de marque Bitwarden — utilisation du logo, palette de couleurs, typographie, iconographie et règles de capitalisation — fondées sur bitwarden.com/brand et les…
official
architecting-solutions
bitwarden
Architecting solutions at the team level while staying coherent with Bitwarden's holistic architecture. Covers security mindset, architectural judgment,…
official