<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Catalog |</title><link>https://kaoto.io/tags/catalog/</link><atom:link href="https://kaoto.io/tags/catalog/index.xml" rel="self" type="application/rss+xml"/><description>Catalog</description><generator>HugoBlox Kit (https://hugoblox.com)</generator><language>en-us</language><lastBuildDate>Thu, 24 Sep 2026 00:00:00 +0000</lastBuildDate><image><url>https://kaoto.io/media/logo_hu_1f7af02082a0d76a.png</url><title>Catalog</title><link>https://kaoto.io/tags/catalog/</link></image><item><title>Stop copy-pasting your data filter: build a reusable Kamelet in Kaoto</title><link>https://kaoto.io/blog/2026/custom-kamelets/</link><pubDate>Thu, 24 Sep 2026 00:00:00 +0000</pubDate><guid>https://kaoto.io/blog/2026/custom-kamelets/</guid><description>&lt;p&gt;&lt;strong&gt;What you&amp;rsquo;ll learn&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why the &lt;strong&gt;Content Filter&lt;/strong&gt; pattern belongs in a reusable Kamelet, not copy-pasted route steps&lt;/li&gt;
&lt;li&gt;How a multi-route Camel file makes the sensitive data leak obvious before you fix it&lt;/li&gt;
&lt;li&gt;How to &lt;strong&gt;build&lt;/strong&gt; a custom action Kamelet in Kaoto with an &lt;strong&gt;&lt;code&gt;allowlist&lt;/code&gt;&lt;/strong&gt; property&lt;/li&gt;
&lt;li&gt;How each route configures its own allowlist in the step form — without duplicating filter logic&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="the-problem-when-your-data-filter-lives-in-two-places-it-breaks-in-one"&gt;The problem: when your data filter lives in two places, it breaks in one&lt;/h2&gt;
&lt;p&gt;Imagine a shipping integration. Orders arrive with everything fulfillment needs: customer name, email, address, SKU, amount. Downstream you also feed analytics &lt;strong&gt;and&lt;/strong&gt; an external partner (for example a carrier status API). Those consumers must &lt;strong&gt;not&lt;/strong&gt; see personally identifiable information (PII) — things like a customer&amp;rsquo;s name, email address, or physical address.&lt;/p&gt;
&lt;p&gt;Someone adds a few Camel steps on the analytics route to keep only safe fields. It works — until the partner export needs the same rule. Then someone pastes the steps again. Then a field is renamed (&lt;code&gt;customer_name&lt;/code&gt; becomes &lt;code&gt;first_name&lt;/code&gt; and &lt;code&gt;last_name&lt;/code&gt;). Then one route is updated and the other isn&amp;rsquo;t. The &amp;ldquo;policy&amp;rdquo; was never a policy; it was a snippet.&lt;/p&gt;
&lt;p&gt;That snippet is the
pattern: remove data from a message so the receiver only sees what it should. &lt;strong&gt;The filter is company policy.&lt;/strong&gt; Policy is exactly what you want as a reusable building block.&lt;/p&gt;
&lt;p&gt;Apache Camel already has that building block: &lt;strong&gt;Kamelets&lt;/strong&gt;. Kaoto makes the last mile pleasant — create the Kamelet in the editor, save it into the workspace, and the tile shows up in the catalog so you can wire it into routes visually.&lt;/p&gt;
&lt;h2 id="what-were-building"&gt;What we&amp;rsquo;re building&lt;/h2&gt;
&lt;p&gt;A four-route integration in one YAML file that fans an incoming order out to fulfillment, analytics, and a partner export:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Should see PII?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;order-ingest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Creates a sample order and fans out&lt;/td&gt;
&lt;td&gt;Yes (source of truth)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;order-fulfillment&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Warehouse / ops — needs contact data&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Yes&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;order-analytics&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Internal metrics — must not see PII&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;order-partner-export&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Carrier / partner feed — must not see PII&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;No&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The build goes in three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Start with all four routes &lt;strong&gt;without&lt;/strong&gt; a filter (analytics and partner-export still log everything — the bug is visible).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build&lt;/strong&gt; a custom &lt;code&gt;content-filter-action&lt;/code&gt; Kamelet in Kaoto with &lt;strong&gt;one &lt;code&gt;allowlist&lt;/code&gt; property&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Place that Kamelet on analytics and partner-export, then set a &lt;strong&gt;different allowlist on each route&lt;/strong&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="step-1-four-routes-one-file-no-filter-yet"&gt;Step 1: Four routes, one file (no filter yet)&lt;/h2&gt;
&lt;p&gt;Create &lt;code&gt;orders.camel.yaml&lt;/code&gt; (or any &lt;code&gt;*.camel.yaml&lt;/code&gt; file Kaoto recognises). Paste the YAML below as-is from the &lt;strong&gt;View YAML&lt;/strong&gt; tab. Notice on the &lt;strong&gt;Image Preview&lt;/strong&gt; tab that &lt;strong&gt;analytics and partner-export do not call a Kamelet yet&lt;/strong&gt; — they log the full body, including PII.&lt;/p&gt;
&lt;div class="toggle-wrapper chroma"&gt;
&lt;input type="checkbox" id="toggle-1790698243126522274" class="toggle-input"&gt;
&lt;div class="toggle-image-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label class="tab active"&gt;Image Preview&lt;/label&gt;
&lt;label for="toggle-1790698243126522274" class="tab inactive"&gt;View YAML&lt;/label&gt;
&lt;/div&gt;
&lt;div class="content-area"&gt;
&lt;img src="./canvas-with-no-content-filter-nodes.png" alt="Toggle Image" class="expandable-image" onclick="document.getElementById('modal-toggle-1790698243126522274').showModal()"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="toggle-code-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label for="toggle-1790698243126522274" class="tab inactive"&gt;View Image&lt;/label&gt;
&lt;label class="tab active"&gt;YAML Source&lt;/label&gt;
&lt;/div&gt;
&lt;label for="toggle-1790698243126522274" class="content-area"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-ingest&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Produce a sample order and fan out to fulfillment, analytics, and partner export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;timer:orders&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;period&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;10000&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;repeatCount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;1&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;setBody&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;constant&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;order_id&amp;#34;: &amp;#34;ORD-1001&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;customer_name&amp;#34;: &amp;#34;Ada Lovelace&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;customer_email&amp;#34;: &amp;#34;ada@example.com&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;ship_to_address&amp;#34;: &amp;#34;12 Analytical Engine Rd&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;item_sku&amp;#34;: &amp;#34;SKU-ABC-42&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;quantity&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;amount&amp;#34;: 149.99,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;destination_country&amp;#34;: &amp;#34;US&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;shipping_priority&amp;#34;: &amp;#34;NEXT_DAY&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; &amp;#34;status&amp;#34;: &amp;#34;NEW&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; }&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Ingest accepted order ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;multicast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parallelProcessing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:fulfillment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-fulfillment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Ops path — needs PII to contact the customer&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:fulfillment&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loggingLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FULFILLMENT (full payload): ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Analytics path — should not see PII (filter not applied yet)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loggingLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ANALYTICS (unfiltered — problem): ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;&amp;gt;-&lt;/span&gt;&lt;span class="sd"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; Partner / carrier export — functional downstream that only needs
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="sd"&gt; shipping facts, not customer identity (filter not applied yet)&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loggingLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;PARTNER-EXPORT (unfiltered — problem): ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;dialog id="modal-toggle-1790698243126522274" class="image-modal" onclick="if(event.target === this) this.close()"&gt;
&lt;img class="modal-content" src="./canvas-with-no-content-filter-nodes.png" alt="Expanded Image"&gt;
&lt;/dialog&gt;
&lt;script&gt;
document.getElementById('modal-toggle-1790698243126522274').addEventListener('toggle', function(e) {
document.querySelector('.modal-close').style.display = this.open ? 'block' : 'none';
});
&lt;/script&gt;
&lt;h3 id="what-you-should-see-when-it-runs-before-the-fix"&gt;What you should see when it runs (before the fix)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fulfillment&lt;/strong&gt; correctly has identity fields, &lt;strong&gt;Analytics&lt;/strong&gt; and &lt;strong&gt;partner-export&lt;/strong&gt; incorrectly have the same full payload:
&lt;div class="toggle-wrapper chroma"&gt;
&lt;input type="checkbox" id="toggle-1790698243127893862" class="toggle-input"&gt;
&lt;div class="toggle-image-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label class="tab active"&gt;Image Preview&lt;/label&gt;
&lt;label for="toggle-1790698243127893862" class="tab inactive"&gt;View YAML&lt;/label&gt;
&lt;/div&gt;
&lt;div class="content-area"&gt;
&lt;img src="./terminal-output-with-no-content-filter-nodes.png" alt="Toggle Image" class="expandable-image" onclick="document.getElementById('modal-toggle-1790698243127893862').showModal()"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="toggle-code-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label for="toggle-1790698243127893862" class="tab inactive"&gt;View Image&lt;/label&gt;
&lt;label class="tab active"&gt;YAML Source&lt;/label&gt;
&lt;/div&gt;
&lt;label for="toggle-1790698243127893862" class="content-area"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FULFILLMENT (full payload): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;customer_name&amp;#34;:&amp;#34;Ada Lovelace&amp;#34;,&amp;#34;customer_email&amp;#34;:&amp;#34;ada@example.com&amp;#34;, ...}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ANALYTICS (unfiltered — problem): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;customer_name&amp;#34;:&amp;#34;Ada Lovelace&amp;#34;,&amp;#34;customer_email&amp;#34;:&amp;#34;ada@example.com&amp;#34;, ...}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PARTNER-EXPORT (unfiltered — problem): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;customer_name&amp;#34;:&amp;#34;Ada Lovelace&amp;#34;,&amp;#34;customer_email&amp;#34;:&amp;#34;ada@example.com&amp;#34;, ...}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;dialog id="modal-toggle-1790698243127893862" class="image-modal" onclick="if(event.target === this) this.close()"&gt;
&lt;img class="modal-content" src="./terminal-output-with-no-content-filter-nodes.png" alt="Expanded Image"&gt;
&lt;/dialog&gt;
&lt;script&gt;
document.getElementById('modal-toggle-1790698243127893862').addEventListener('toggle', function(e) {
document.querySelector('.modal-close').style.display = this.open ? 'block' : 'none';
});
&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the teachable moment: two different consumers (metrics vs partner API), &lt;strong&gt;one shared mistake&lt;/strong&gt; — no &lt;strong&gt;Content Filter&lt;/strong&gt; yet.&lt;/p&gt;
&lt;h2 id="step-2-build-the-custom-content-filter-kamelet-in-kaoto"&gt;Step 2: Build the custom Content Filter Kamelet in Kaoto&lt;/h2&gt;
&lt;p&gt;You&amp;rsquo;re &lt;strong&gt;not&lt;/strong&gt; going to paste a hard-coded allowlist into every route, and you&amp;rsquo;re &lt;strong&gt;not&lt;/strong&gt; going to clone &lt;code&gt;setBody&lt;/code&gt; JSON on each route either. Instead, you&amp;rsquo;ll create the Kamelet once in Kaoto:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create a new Kamelet by clicking on New File in Kaoto view(perspective) integrations nav bar, set the name to &lt;code&gt;content-filter-action&lt;/code&gt; and the type to &lt;strong&gt;action&lt;/strong&gt; — not source (which produces messages) or sink (which consumes them), but action, because this Kamelet sits between existing steps in a route and transforms the message in place.&lt;/li&gt;
&lt;li&gt;Add a single property: &lt;strong&gt;&lt;code&gt;allowlist&lt;/code&gt;&lt;/strong&gt; (string) — one control that each route will configure independently.&lt;/li&gt;
&lt;li&gt;Give it a sensible default: the company baseline of safe shipping fields (no customer identity).&lt;/li&gt;
&lt;li&gt;On the Kamelet canvas, wire &lt;code&gt;kamelet:source&lt;/code&gt; → &lt;code&gt;unmarshal&lt;/code&gt; JSON → &lt;code&gt;setBody&lt;/code&gt; to keep only the fields named in &lt;code&gt;{{allowlist}}&lt;/code&gt; → &lt;code&gt;marshal&lt;/code&gt; JSON.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Save&lt;/strong&gt; the Kamelet into the workspace (for example &lt;code&gt;content-filter-action.kamelet.yaml&lt;/code&gt;). No IDE restart needed.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="reference-yaml"&gt;Reference YAML&lt;/h3&gt;
&lt;p&gt;Use this as a check against &lt;strong&gt;Source Code&lt;/strong&gt; view after building in Kaoto — or paste the code from the &lt;strong&gt;YAML Source&lt;/strong&gt; directly if you&amp;rsquo;re skipping the visual designer:&lt;/p&gt;
&lt;div class="toggle-wrapper chroma"&gt;
&lt;input type="checkbox" id="toggle-1790698243128115168" class="toggle-input"&gt;
&lt;div class="toggle-image-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label class="tab active"&gt;Image Preview&lt;/label&gt;
&lt;label for="toggle-1790698243128115168" class="tab inactive"&gt;View YAML&lt;/label&gt;
&lt;/div&gt;
&lt;div class="content-area"&gt;
&lt;img src="./canvas-with-content-filter-kamelet.png" alt="Toggle Image" class="expandable-image" onclick="document.getElementById('modal-toggle-1790698243128115168').showModal()"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="toggle-code-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label for="toggle-1790698243128115168" class="tab inactive"&gt;View Image&lt;/label&gt;
&lt;label class="tab active"&gt;YAML Source&lt;/label&gt;
&lt;/div&gt;
&lt;label for="toggle-1790698243128115168" class="content-area"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-txt" data-lang="txt"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; name: content-filter-action
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; labels:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; camel.apache.org/kamelet.type: action
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; annotations: {}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;spec:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; template:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; route:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; from:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id: from-3051
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; uri: kamelet:source
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; parameters: {}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; steps:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - unmarshal:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id: unmarshal-1466
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; json: {}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - setBody:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id: setBody-2579
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; groovy:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; expression: &amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; def src = request.body
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; def allowed = &amp;#39;{{allowlist}}&amp;#39;.split(&amp;#39;,&amp;#39;)*.trim().findAll { it
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; } as Set
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; def out = new LinkedHashMap()
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; allowed.each { key -&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; if (src.containsKey(key)) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; out.put(key, src[key])
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; return out
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; - marshal:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; id: marshal-2137
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; json:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; prettyPrint: true
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; definition:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; description: &amp;#34;Strips PII from an order JSON body. Configure which safe fields
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; each route may keep via the allowlist property (Content Filter EIP). Use
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; via to: kamelet:content-filter-action.&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; properties:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; allowlist:
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; type: string
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; title: Fields to keep
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; description: Comma-separated field names from the safe set (order_id, item_sku,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; quantity, amount, destination_country, shipping_priority,
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; status). Do not include customer_* or address fields.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; default: order_id,item_sku,quantity,amount,destination_country,shipping_priority,status
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;dialog id="modal-toggle-1790698243128115168" class="image-modal" onclick="if(event.target === this) this.close()"&gt;
&lt;img class="modal-content" src="./canvas-with-content-filter-kamelet.png" alt="Expanded Image"&gt;
&lt;/dialog&gt;
&lt;script&gt;
document.getElementById('modal-toggle-1790698243128115168').addEventListener('toggle', function(e) {
document.querySelector('.modal-close').style.display = this.open ? 'block' : 'none';
});
&lt;/script&gt;
&lt;p&gt;Save if you edited source. Workspace Kamelets are picked up automatically when Kaoto refreshes the catalog tiles.&lt;/p&gt;
&lt;h3 id="alternative-one-boolean-property-per-field"&gt;Alternative: one boolean property per field&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;d rather give teams explicit toggles in the form (one checkbox per field), define properties such as &lt;code&gt;includeOrderId&lt;/code&gt;, &lt;code&gt;includeAmount&lt;/code&gt;, … (&lt;code&gt;type: boolean&lt;/code&gt;, defaults &lt;code&gt;true&lt;/code&gt;) and branch in Groovy with &lt;code&gt;if ({{includeOrderId}}) out.put('order_id', src['order_id'])&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That approach makes it harder to accidentally request a PII field by typo, but it needs heavier logic to process all seven boolean properties. For this post we stick with a single &lt;strong&gt;&lt;code&gt;allowlist&lt;/code&gt;&lt;/strong&gt; string.&lt;/p&gt;
&lt;h2 id="step-3-wire-the-policy-into-your-routes"&gt;Step 3: Wire the policy into your routes&lt;/h2&gt;
&lt;p&gt;This is the step that turns a Camel feature into a team practice.&lt;/p&gt;
&lt;h3 id="open-the-integration-in-kaoto"&gt;Open the integration in Kaoto&lt;/h3&gt;
&lt;p&gt;Open &lt;code&gt;orders.camel.yaml&lt;/code&gt; in VS Code with the Kaoto extension. You should see all four routes on the canvas.&lt;/p&gt;
&lt;h3 id="find-the-kamelet-in-the-catalog--no-catalog-rebuild-needed"&gt;Find the Kamelet in the catalog — no catalog rebuild needed&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Confirm &lt;code&gt;content-filter-action.kamelet.yaml&lt;/code&gt; is saved in the workspace.&lt;/li&gt;
&lt;li&gt;On the &lt;strong&gt;order-analytics&lt;/strong&gt; route, open the catalog (add step before the log).&lt;/li&gt;
&lt;li&gt;Switch to the &lt;strong&gt;Kamelets&lt;/strong&gt; tab and search for &lt;code&gt;content-filter&lt;/code&gt; or &lt;code&gt;Content Filter&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;figure class="image"&gt;&lt;img src="https://kaoto.io/blog/2026/custom-kamelets/catalog-modal-with-content-filter-tile.png"
alt="Catalog modal with content filter tile"&gt;&lt;figcaption&gt;
&lt;p&gt;Content Filter Kamelet tile on the catalog modal&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;blockquote class="border-l-4 border-neutral-300 dark:border-neutral-600 pl-4 italic text-neutral-600 dark:text-neutral-400 my-6"&gt;
&lt;p&gt;&lt;strong&gt;Expected:&lt;/strong&gt; The tile appears without regenerating a Camel catalog archive. Workspace Kamelets are merged in automatically when Kaoto refreshes its catalog tiles.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="apply-it-where-pii-must-not-leave"&gt;Apply it where PII must not leave&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Fulfillment&lt;/strong&gt; stays as a plain &lt;code&gt;log&lt;/code&gt; step — ops still need contact data.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Analytics&lt;/strong&gt; and &lt;strong&gt;partner-export&lt;/strong&gt; each get the &lt;strong&gt;same&lt;/strong&gt; Kamelet tile inserted before their log step. The difference is the &lt;code&gt;allowlist&lt;/code&gt; value you set on each:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Insert &lt;strong&gt;Content Filter&lt;/strong&gt; on &lt;code&gt;order-analytics&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Open the step&amp;rsquo;s configuration form — you&amp;rsquo;ll see a single &lt;strong&gt;Fields to keep&lt;/strong&gt; / &lt;code&gt;allowlist&lt;/code&gt; control.&lt;/li&gt;
&lt;li&gt;Leave analytics on the default (full safe set), or edit the comma-separated list as needed.&lt;/li&gt;
&lt;li&gt;Insert &lt;strong&gt;Content Filter&lt;/strong&gt; on &lt;code&gt;order-partner-export&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On &lt;strong&gt;that&lt;/strong&gt; step&amp;rsquo;s form, set a narrower allowlist — for example, drop &lt;code&gt;amount&lt;/code&gt; and &lt;code&gt;shipping_priority&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You&amp;rsquo;re editing the allowlist &lt;strong&gt;per route usage&lt;/strong&gt;, through the Kamelet parameter — not by duplicating filter YAML into each route.&lt;/p&gt;
&lt;p&gt;After wiring, the source looks like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:analytics&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kamelet:content-filter-action&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;to-4189&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loggingLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ANALYTICS: ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;- &lt;span class="nt"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order-partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Partner&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;direct:partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;steps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;uri&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;kamelet:content-filter-action&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;content-filter-kamelet-on-order-partner-export&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;allowlist&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;order_id,item_sku,quantity,destination_country,status&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;- &lt;span class="nt"&gt;log&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;loggingLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;INFO&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;PARTNER-EXPORT: ${body}&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Same tile, two &lt;code&gt;allowlist&lt;/code&gt; values. Fulfillment still has no filter.&lt;/p&gt;
&lt;figure class="image"&gt;&lt;img src="https://kaoto.io/blog/2026/custom-kamelets/config-form-content-filter-node-on-order-partner-export.png"
alt="Config form of content filter node on order-partner-export"&gt;&lt;figcaption&gt;
&lt;p&gt;Config form (Modified tab) of the Content Filter node on the order-partner-export route&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id="what-you-should-see-after-the-fix"&gt;What you should see after the fix&lt;/h3&gt;
&lt;div class="toggle-wrapper chroma"&gt;
&lt;input type="checkbox" id="toggle-1790698243128812338" class="toggle-input"&gt;
&lt;div class="toggle-image-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label class="tab active"&gt;Image Preview&lt;/label&gt;
&lt;label for="toggle-1790698243128812338" class="tab inactive"&gt;View YAML&lt;/label&gt;
&lt;/div&gt;
&lt;div class="content-area"&gt;
&lt;img src="./terminal-output-with-content-filter-nodes.png" alt="Toggle Image" class="expandable-image" onclick="document.getElementById('modal-toggle-1790698243128812338').showModal()"&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;div class="toggle-code-block"&gt;
&lt;div class="tab-bar"&gt;
&lt;label for="toggle-1790698243128812338" class="tab inactive"&gt;View Image&lt;/label&gt;
&lt;label class="tab active"&gt;YAML Source&lt;/label&gt;
&lt;/div&gt;
&lt;label for="toggle-1790698243128812338" class="content-area"&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;FULFILLMENT (full payload): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;customer_name&amp;#34;:&amp;#34;Ada Lovelace&amp;#34;,&amp;#34;customer_email&amp;#34;:&amp;#34;ada@example.com&amp;#34;, ...}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ANALYTICS (filtered): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;item_sku&amp;#34;:&amp;#34;SKU-ABC-42&amp;#34;,&amp;#34;quantity&amp;#34;:2,&amp;#34;amount&amp;#34;:149.99,&amp;#34;destination_country&amp;#34;:&amp;#34;US&amp;#34;,&amp;#34;shipping_priority&amp;#34;:&amp;#34;NEXT_DAY&amp;#34;,&amp;#34;status&amp;#34;:&amp;#34;NEW&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;PARTNER-EXPORT (filtered): {&amp;#34;order_id&amp;#34;:&amp;#34;ORD-1001&amp;#34;,&amp;#34;item_sku&amp;#34;:&amp;#34;SKU-ABC-42&amp;#34;,&amp;#34;quantity&amp;#34;:2,&amp;#34;destination_country&amp;#34;:&amp;#34;US&amp;#34;,&amp;#34;status&amp;#34;:&amp;#34;NEW&amp;#34;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/label&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;dialog id="modal-toggle-1790698243128812338" class="image-modal" onclick="if(event.target === this) this.close()"&gt;
&lt;img class="modal-content" src="./terminal-output-with-content-filter-nodes.png" alt="Expanded Image"&gt;
&lt;/dialog&gt;
&lt;script&gt;
document.getElementById('modal-toggle-1790698243128812338').addEventListener('toggle', function(e) {
document.querySelector('.modal-close').style.display = this.open ? 'block' : 'none';
});
&lt;/script&gt;
&lt;p&gt;Partner-export has no &lt;code&gt;amount&lt;/code&gt; or &lt;code&gt;shipping_priority&lt;/code&gt; — configured on that step only. The analytics route uses the same Kamelet but with a different allowlist configured.&lt;/p&gt;
&lt;h3 id="two-ways-to-change-policy"&gt;Two ways to change policy&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Change&lt;/th&gt;
&lt;th&gt;Where&lt;/th&gt;
&lt;th&gt;Effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-route allowlist&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kaoto form / &lt;code&gt;parameters.allowlist&lt;/code&gt; on that &lt;code&gt;to: kamelet:...&lt;/code&gt; step&lt;/td&gt;
&lt;td&gt;Only that consumer&amp;rsquo;s field set changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Baseline default&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Kamelet definition &lt;code&gt;properties.allowlist.default&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;What every new usage starts with before you edit the form&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To change what &lt;strong&gt;one&lt;/strong&gt; consumer receives, edit that step&amp;rsquo;s &lt;code&gt;allowlist&lt;/code&gt; in Kaoto. To change the &lt;strong&gt;starting default&lt;/strong&gt; for all new usages, update the property default in the Kamelet editor, save, and re-open the step form.&lt;/p&gt;
&lt;h2 id="takeaways"&gt;Takeaways&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Show the leak first&lt;/strong&gt; — a multi-route file makes it obvious that analytics and partner-export share the same problem.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Build the Content Filter as a Kamelet of type &lt;code&gt;action&lt;/code&gt;&lt;/strong&gt; — actions sit mid-route and transform the message, which is exactly what a filter does. One template, many call sites, zero duplication.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kaoto closes the loop&lt;/strong&gt; — save the Kamelet → catalog tile appears → drop it onto routes → edit each &lt;code&gt;allowlist&lt;/code&gt; in the form.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Keep PII out of allowlists by convention&lt;/strong&gt; — the property description and code review are your guardrails.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The same approach works beyond data filtering. Anywhere you catch yourself copy-pasting the same transformation, enrichment, or validation logic across routes — currency conversion, audit stamping, schema validation, payload size trimming — a custom action Kamelet is the right fix. Define the logic once, expose the variable parts as properties, and let each route configure its own values through the Kaoto form.&lt;/p&gt;
&lt;h2 id="further-reading"&gt;Further reading&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Enterprise Integration Patterns —
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="lets-build-it-together"&gt;Let&amp;rsquo;s build it together&lt;/h2&gt;
&lt;p&gt;Let us know what you think by joining us in the
.
Do you have an idea for improving Kaoto&amp;rsquo;s Kamelet support? Would you love to see a useful feature implemented or simply ask a question? Please
.&lt;/p&gt;
&lt;h2 id="give-it-a-try"&gt;Give it a try&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Kaoto online
&lt;/li&gt;
&lt;li&gt;Kaoto is available as a
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Happy integrating! 🚀&lt;/p&gt;</description></item></channel></rss>