Skip to content

2026-02-09

Webhook Normalization: One Format for Every System

Intended Team · Founding Team

The Format Fragmentation Problem

Every SaaS platform, every infrastructure provider, and every internal tool sends webhooks in its own format. GitHub sends push events with a completely different schema than Jira sends issue updates. Salesforce uses a different event structure than ServiceNow. AWS CloudTrail logs look nothing like Kubernetes audit logs.

If you are building governance policies for AI agents that operate across these systems, you have two options. Option one: write system-specific policies for every platform. You end up with separate policy sets for GitHub actions, Jira actions, Salesforce actions, and ServiceNow actions. The policy logic is duplicated, the maintenance burden multiplies, and coverage gaps are inevitable.

Option two: normalize everything into a single format and write policies once. That is what Intended's connector framework does.

The Unified Intent Format

Intended normalizes every incoming event into a common intent format. Regardless of the source system, every event becomes an intent object with the same structure: domain, category, action, resource, agent, parameters, and context.

This normalization happens at the connector level, before the intent reaches the Authority Engine. The Authority Engine does not know or care whether an intent originated from GitHub, Jira, or an internal API. It evaluates every intent against the same policy framework using the same risk scoring model.

The unified format has several properties that make it suitable for cross-system governance. It is system-agnostic: no system-specific fields leak through to the policy layer. It is complete: every field the Authority Engine needs is present, with sensible defaults for fields the source system does not provide. And it is typed: every field has a defined type and valid range, so policy evaluation is deterministic.

How Normalization Works

Each Intended connector includes a normalizer: a transformation layer that maps the source system's event format to the unified intent format. Here is how the normalization process works for four common systems.

GitHub

GitHub sends webhook events as JSON payloads with an `X-GitHub-Event` header identifying the event type. A push event, for example, includes the repository, the branch, the commits, the author, and various metadata.

The GitHub normalizer maps this into an intent as follows. The event type (push, pull_request, deployment, etc.) maps to an action category. The repository and branch map to the resource identifier. The author maps to the agent identity (with cross-reference to the organization's agent registry). The commits map to parameters describing the scope of the change.

A GitHub push to the main branch of a production repository becomes:

json
{
  "domain": "sdlc",
  "category": "code_deployment",
  "action": "sdlc.code.push",
  "resource": {
    "type": "repository_branch",
    "identifier": "org/repo:main",
    "environment": "production"
  }
}

Jira

Jira sends webhook events with a `webhookEvent` field identifying the event type and an `issue` object containing the issue details. The event format is deeply nested and includes extensive metadata.

The Jira normalizer extracts the essential governance fields from the nested structure. The event type (issue_created, issue_updated, comment_added) maps to an action category. The issue key and project map to the resource. The user who triggered the event maps to the agent.

Critically, the normalizer also extracts context from custom fields. If your Jira instance uses a custom field for environment designation or risk classification, the normalizer can be configured to include those fields in the intent parameters.

Salesforce

Salesforce sends platform events and change data capture events using its own event format. The event payload includes the object type, the record ID, the changed fields, and the user who made the change.

The Salesforce normalizer maps object types to Intended resource types. Account objects map to customer resources. Opportunity objects map to financial resources. Case objects map to support resources. The normalizer also handles Salesforce's field-level change tracking, translating individual field changes into parameters on the intent object.

ServiceNow

ServiceNow sends business rule events and REST API notifications with its own schema. The normalizer handles ServiceNow's table-based data model, mapping table names to resource types and record operations to action categories.

ServiceNow's incident management events are particularly important for governance because they indicate active incidents that should influence risk scoring. The normalizer flags incident-related events with a context marker that the Authority Engine uses to adjust risk calculations during active incidents.

The Normalization Pipeline

The normalization process follows a four-stage pipeline.

**Stage 1: Ingestion.** The connector receives the raw webhook payload. It validates the webhook signature (HMAC for GitHub, JWT for Salesforce, etc.) to ensure authenticity. Invalid signatures are rejected immediately.

**Stage 2: Parsing.** The connector parses the raw payload into an intermediate representation. This stage handles system-specific quirks: nested objects, encoded fields, pagination tokens, and format variations between API versions.

**Stage 3: Mapping.** The parsed intermediate representation is mapped to the unified intent format. Each field in the intent format has a mapping rule that specifies where in the intermediate representation to find the value, how to transform it, and what default to use if the value is missing.

**Stage 4: Validation.** The mapped intent is validated against the intent schema. Required fields must be present. Field values must be within valid ranges. The domain and category must exist in the MIR taxonomy. If validation fails, the intent is routed to an error queue for investigation rather than being dropped silently.

Custom Connectors

Intended ships connectors for the most common systems: GitHub, GitLab, Jira, Salesforce, ServiceNow, AWS, and Kubernetes. But organizations frequently need to connect internal systems, custom APIs, or niche platforms.

The connector SDK provides a framework for building custom connectors. You implement three functions: a signature validator (to verify webhook authenticity), a parser (to convert the raw payload to the intermediate representation), and a mapper (to convert the intermediate representation to the unified intent format).

A basic custom connector can be built in under 200 lines of code. The SDK handles the ingestion infrastructure, rate limiting, retry logic, and error handling. You focus on the system-specific transformation logic.

Why Normalization Matters for Governance

Normalization is not just a data engineering convenience. It is a governance requirement.

Without normalization, you cannot write universal policies. A policy that says "deny all production database deletions" needs to understand what a "production database deletion" looks like in every connected system. In AWS, it is a DeleteDBInstance API call. In Kubernetes, it is a delete operation on a StatefulSet. In a custom system, it is whatever that system calls it. Without normalization, you need system-specific policy variants for every rule.

With normalization, the policy is simple: if domain is "data_management" and action is "database.delete" and environment is "production," then deny. One policy. Every system. Every agent.

This is the power of the unified intent format. It turns the multi-system complexity of modern AI agent operations into a single, consistent policy evaluation surface. Write your governance policies once. Apply them everywhere.