Guidelines for AI agents working on this codebase.
The Apache Camel Kamelet Catalog is the default catalog of reusable Camel route templates ("Kamelets"), distributed as Kubernetes-style YAML and consumed by Camel, Camel K, Camel Quarkus and Camel Spring Boot.
- Version: 4.20.0
- Camel: 4.20.0
- Java: 17+
- Build: Maven (
mvn verify); Go is required for thescript/andcrds/generators - Issue tracker: GitHub — https://github.com/apache/camel-kamelets/issues
- Related repository:
apache/camel(Camel core — the Kamelet runtime lives there, not here)
These rules apply to ALL AI agents working on this codebase.
- All AI-generated content (GitHub PR descriptions, review comments, issue comments) MUST clearly identify itself as AI-generated and mention the human operator. Example: "Claude Code on behalf of [Human Name]"
- An agent MUST NOT open more than 10 PRs per day per operator to ensure human reviewers can keep up.
- Prioritize quality over quantity — fewer well-tested PRs are better than many shallow ones.
- An agent MUST NEVER push commits to a branch it did not create.
- If a contributor's PR needs changes, the agent may suggest changes via review comments, but must not push to their branch without explicit permission.
- An agent should prefer to use its own fork to push branches instead of the
main
apache/camel-kameletsrepository, to avoid filling the main repository with uncleaned branches. - Branch names: fix-issue →
ci-issue-<ISSUE_NUMBER>, quick-fix →quick-fix/<short-slug>, CI fix →ci-fix/<short-slug>. Include the topic and issue number where possible. - After a Pull Request is merged or rejected, delete the branch.
- An agent MUST ONLY pick up unassigned GitHub issues.
- If an issue is already assigned to a human, the agent must not reassign it or work on it.
- Before starting work, assign the issue to its operator.
- Beginner tasks carry the
good first issuelabel; experienced tasks carryhelp wanted.
- Fix an issue:
Fix #<ISSUE_NUMBER>: <brief description> - Quick fix / chore:
chore: <brief description> - CI fix:
ci: <brief description> - Always reference the GitHub issue when applicable. The repository accepts squash and rebase merges only (no merge commits).
When pushing new commits to a PR, always update the PR description (and
title if needed) to reflect the current state of the changeset. Use
gh pr edit --title "..." --body "..." after each push.
When creating a PR, always identify and request reviews from the most relevant committers:
- Run
git log --format='%an' --since='1 year' -- <affected-files> | sort | uniq -c | sort -rn | head -10to find who has been most active on the affected files. - Use
git blameon key modified files to identify who wrote the code. - Cross-reference with the committer list.
- Request review from at least 2 relevant committers via
gh pr edit --add-reviewer. - When all comments are addressed and checks are green, re-request review.
- An agent MUST NOT merge a PR if there are any unresolved review conversations.
- An agent MUST NOT merge a PR without at least one human approval.
- An agent MUST NOT approve its own PRs — human review is always required.
- Every new or changed Kamelet SHOULD include Citrus tests under
tests/camel-kamelets-itest/src/test/resources/<kamelet-name>/; Kamelets with passing behaviour tests are labelledcamel.apache.org/kamelet.verified=true. - After adding or modifying a Kamelet, regenerate and commit the generated
docs and validate, or CI will fail:
cd script/generator && go run . ../../kamelets/ ../../docs/modules/ROOT/ cd ../validator && go run . ../../kamelets/ # must report no ERRORS
nav.adocand the per-Kamelet doc pages are generated — do not hand-edit them.- A full
mvn verifyfrom the repository root must pass before pushing.
Do NOT use Thread.sleep() in test code; it leads to flaky, slow,
non-deterministic tests. Use the project's Citrus test constructs (or
Awaitility, where Java test code applies) with an explicit timeout instead.
Before implementing a fix, thoroughly investigate the issue. Kamelets are a long-lived shared catalog — a template often looks "wrong" but exists for a reason (compatibility with a Camel component default, an explicit insecure convenience Kamelet, an intentional inbound-header mapping).
- Validate the issue — confirm it is real and reproducible; question assumptions in the description.
- Check git history —
git log --oneline <file>andgit blame <file>; read commit messages and linked issues. - Search for related issues/PRs on GitHub for prior discussion or intentional decisions.
- Check the developer guide —
docs/modules/ROOT/pages/development.adocand the catalogREADME.mdfor authoring rules. - Check the runtime boundary — if the behaviour is in the
kamelet:component,{{property}}placeholder binding, ororg.apache.camel.kamelets.utils.*, the fix belongs inapache/camel, not here. - Check if the "fix" reverts prior work — if so, stop and reconsider; if still justified, acknowledge it explicitly in the PR description.
Present findings to the operator before implementing. Flag risks, ambiguities, or cases where the issue may be invalid.
AI agents have a training cutoff. Never make authoritative claims about external project state (Camel component options, dependency versions) based solely on training knowledge — verify against the Camel catalog, Maven Central, or release notes before relying on or questioning a version.
When writing or modifying .adoc documentation:
- Use
xref:for internal links, never externalhttps://camel.apache.org/...URLs for pages that exist in this module. - Do not hand-edit generated pages (
nav.adoc, per-Kamelet pages); change the Kamelet YAML and regenerate. - When reviewing doc PRs, check
xref:links and anchors resolve.
The Kamelet Catalog has a documented security model that defines who is
trusted, where the trust boundaries sit, what counts as a catalog
vulnerability, and what is route-author or operator responsibility. The
canonical document is
docs/modules/ROOT/pages/security-model.adoc.
It specialises the
Apache Camel Security Model;
where the catalog model is silent, the Camel model governs. Use it as the
reference when triaging security reports, deciding whether a finding warrants a
CVE, or reviewing a security-sensitive Kamelet PR.
For the vulnerability reporting convention,
SECURITY.md at the repository root is the entry point GitHub
and security tooling expect. It points to the security model for scope and to
the Apache Camel ASF process for private disclosure. An agent that discovers or
is handed a suspected vulnerability MUST NOT open a public issue, PR, or
mailing-list post about it — follow the private process and stop.
- Kamelet authors and the Camel PMC are trusted: the Kamelet template is route code, reviewed by the PMC. The catalog's special obligation is that the template author is the catalog, so a shipped template must be safe-by-default for the untrusted-data boundary.
- Route authors and operators are fully trusted. They bind every
property —
url,query,template,expression,executable, file paths, credentials — from configuration. Binding a property to attacker-controlled data is route-author error, not a catalog vulnerability. - Data flowing through a Kamelet (the message a source emits or a sink/action consumes) is untrusted. This is the primary attacker model.
- The Kamelet runtime is not in this repository. The
kamelet:component, placeholder binding andorg.apache.camel.kamelets.utils.*live inapache/camel; defects there are routed to that project.
The fundamental trust boundary is between the Kamelet (template + bound configuration) and the data flowing through it — unchanged from Camel, except the author of the trusted template is now the catalog.
A report is in scope when a shipped Kamelet template, in its default configuration, lets untrusted data cross a boundary the template — not the operator's wiring — should have held:
- A sink/action template that maps an untrusted inbound header/body into a
dispatch position (
CamelHttpUri,CamelFileName,Camel*DestinationName,CamelExec*,CamelBeanMethodName, …) without stripping/fixing the dispatch headers it does not deliberately consume. - A template that passes message data (not a
{{property}}) to asimple/template-language/JSONPath/query evaluator the Kamelet's purpose did not require. - A template that ships a Camel component with a security-relevant insecure
default (Java serialisation on an untrusted consumer, TLS verification off,
admin surface on
0.0.0.0, permissive header filter), reachable just by deploying the Kamelet. - A secret property not marked
format: password+x-descriptors: [urn:camel:group:credentials], or a missingpattern:that turns operator contract into reachable unintended behaviour (hardening tier).
- An operator/route author binding a property (
{{template}},{{query}},{{expression}},{{url}},{{executable}}, credentials, paths) to untrusted data — including all template-language and SQL/NoSQL/GraphQL Kamelets. - A Kamelet doing, by design, the dangerous thing it is named for
(
exec-sink,ssh-*,scp-sink) or network exposure of a source (webhook-source,http-source);*-secured-*means auth options exist, not that auth is on by default. - Explicitly-named insecure conveniences (
*-not-secured-*,kafka-not-secured-*). - Underlying Camel component or transitive-dependency CVEs not caused by the template.
- Defects in the Kamelet execution runtime (route to
apache/camel). - DoS via resource exhaustion (operator applies throttling/limits).
- The
data:imageicon annotation (metadata for tooling, never executed). camel-kamelets-catalog"parsing YAML" — it reads only build-bundled classpath YAML, not untrusted documents.- Build/CI/test/scaffolding code (
script/,crds/generator,tests/,templates/,kamelets-maven-plugin). - Scanner reports without a PoC through a shipped template.
When reviewing or recommending a deployment, surface:
- Treat a deployed Kamelet exactly like a route you wrote — same privileges and trust.
- Load Kamelets only from a trusted, integrity-checked catalog (an entity that can modify a Kamelet definition has arbitrary code execution by design).
- Never bind a property from untrusted message data.
- Strip
Camel*headers from untrusted producers before a sink Kamelet, even though many templates also do this for known dispatch headers. - Do not place
exec-sink/ssh-*/scp-sinkdownstream of untrusted input. - Secure inbound source Kamelets with network controls and the
*-secured-*auth options. - Resolve credentials through a Camel vault, not plaintext properties.
- Pin the catalog and Camel versions; follow Camel security announcements.
When reviewing a PR that adds or changes a Kamelet template:
- Does the template map an untrusted inbound header/body into a
dispatch-controlling position? It MUST strip or fix every Camel-internal
header it does not deliberately consume, before the dispatching step
(compare
http-sink'sremoveHeader: CamelHttpUri). - Does the template pass message data (not a
{{property}}) to an expression/template/query evaluator? That is the in-scope injection class — the evaluated input must be a bound property. - Does the template add a component with a security-relevant default? Ship the
safe default; if it must be relaxed, name the Kamelet
*-not-secured-*, document it, and get PMC sign-off. - Does a property carry a secret? It MUST be
format: passwordwithx-descriptors: [urn:camel:group:credentials]. - Does a free-form property feed an endpoint/resource URI? Add a
pattern:(operator-typo containment — not a trust control). - Does the change relax a default or widen what a template forwards? It needs an upgrade-guide entry and PMC review.
camel-kamelets/
├── kamelets/ # ~250 *.kamelet.yaml route templates (the product)
├── library/
│ ├── camel-kamelets/ # resource bundle (jars the YAML)
│ ├── camel-kamelets-bom/ # Maven BOM (pom only)
│ ├── camel-kamelets-catalog/ # runtime metadata reader (Java)
│ ├── camel-kamelets-crds/ # Fabric8-generated K8s CRD POJOs (Java)
│ └── kamelets-maven-plugin/ # build-time validation plugin
├── crds/ # Go CRD client generator (build/CI)
├── script/ # Go doc generator + YAML validator (build/CI)
├── templates/ # init .vm template + Pipe examples
├── tests/camel-kamelets-itest/ # Citrus integration tests
└── docs/modules/ROOT/ # Antora AsciiDoc (security-model.adoc lives here)
mvn verify # full build (from root)
mvn verify -Pcoverage # with coverage
cd script/generator && go run . ../../kamelets/ ../../docs/modules/ROOT/ # regen docs
cd script/validator && go run . ../../kamelets/ # validate- One
*.kamelet.yamlper Kamelet; file name MUST matchmetadata.name. - Each Kamelet is exactly one of
source,sink, oraction(camel.apache.org/kamelet.typelabel, mandatory). camel.apache.org/providerMUST be"Apache Software Foundation".- Icons MUST be embedded
data:image(no external URLs). - Source templates send to
kamelet:sink; sink templates consume fromkamelet:source. - Dependencies go in
spec.dependencies(camel:<component>,mvn:group:artifact:versionwith Apache-compatible license, orgithub:apache/...source only). - Properties are declared as JSON-schema in
spec.definition; mark secretsformat: password+x-descriptors: [urn:camel:group:credentials].