create-hec-event-integration

作者: bitwarden

用於在 Bitwarden 網頁客戶端新增 HEC(HTTP 事件收集器)事件整合時使用。實作 Splunk 權杖驗證模型(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

來自 bitwarden 的更多技能

analyzing-git-sessions
bitwarden
分析指定時間範圍或提交範圍內的 Git 提交與變更,提供結構化摘要,適用於程式碼審查、回顧會議、工作日誌或工作階段…
official
figma-to-angular
bitwarden
此技能可將 Figma 設計規格轉換為 Bitwarden Clients 單一儲存庫中,具備 Storybook 故事的完整 Angular 元件。輸出結果應在視覺上符合設計,同時遵循所有程式碼庫慣例。
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
Audit GitHub Actions action usage across an org. Searches for a specific action (incident mode) or sweeps all workflow files for non-compliant action…
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
Apply Bitwarden brand standards — logo usage, color palette, typography, iconography, and capitalization rules — grounded in bitwarden.com/brand and the…
official
architecting-solutions
bitwarden
Architecting solutions at the team level while staying coherent with Bitwarden's holistic architecture. Covers security mindset, architectural judgment,…
official