Skip to content

CAMEL-23305: Add camel-spiffe example (workload identity with SPIFFE and SPIRE) - #260

Open
oscerd wants to merge 1 commit into
mainfrom
feature/CAMEL-23305-spiffe-example
Open

CAMEL-23305: Add camel-spiffe example (workload identity with SPIFFE and SPIRE)#260
oscerd wants to merge 1 commit into
mainfrom
feature/CAMEL-23305-spiffe-example

Conversation

@oscerd

@oscerd oscerd commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

What

A new spiffe example (category Security) for the camel-spiffe component that ships in Camel 4.23 (CAMEL-23305).

It runs four Camel Main applications and a SPIRE deployment with Docker Compose, all in the trust domain example.org:

Container Unix uid SPIFFE ID What it may do
frontend 1001 spiffe://example.org/frontend GET /api/orders on the backend (200); the audit trail is denied (403)
auditor 1003 spiffe://example.org/auditor GET /api/audit on the backend (200); the orders are denied (403)
backend 1002 spiffe://example.org/backend serves the orders and the audit trail, calls the inventory with its own identity
inventory 1004 spiffe://example.org/inventory serves the stock levels to the backend only

All three operations of the component are used:

  • fetchJwtSvid: the clients get JWT-SVIDs minted for the backend and present them as bearer tokens; the backend does the same towards the inventory (second hop), passing the original caller along for auditing. The wrong-audience route uses the CamelSpiffeAudience header to request a token for another service, which the backend rejects (401).
  • validateJwtSvid: a shared workload identity policy (a route configuration with interceptFrom + onException) validates the token, checks the caller against per-route allow-lists in application.properties, and records an audit trail, before the routes run.
  • fetchX509Svid: every application logs a summary of its X.509-SVID once a minute, which shows the rotation done by the SPIRE agent.

The auditor runs the very same code and image as the frontend, but as another Unix user, so the SPIRE agent gives it another identity with opposite permissions: identity comes from the platform, not from the code.

Infrastructure

  • A single spire container copies the SPIRE 1.15.3 server and agent binaries into Alpine and bootstraps everything (join token, trust bundle, registration entries with unix:uid selectors).
  • The Camel applications share the SPIRE container's PID namespace so that the unix workload attestor can see them, and run as distinct uids.
  • io.spiffe:grpc-netty-linux is added at runtime scope: java-spiffe-core pulls no gRPC transport for the Unix domain socket (the README documents the macOS artifacts).

Tests

16 unit tests run without SPIRE: a Mockito mock of WorkloadApiClient is bound to the registry and autowired by the component. The backend and the inventory are tested over HTTP on the embedded server of Camel Main (JDK HttpClient), the backend test stubs the inventory on the same server to check the second hop.

Verified end to end on Linux with docker compose up --build: 200/403/401 matrix, second hop with X-On-Behalf-Of, X.509-SVID rotation at half TTL, and no token or on-behalf-of header leaking into HTTP responses. Apache RAT passes.

The root README.adoc index was regenerated with ./mvnw -N process-resources (it also drops the two removed csimple examples from the count).

🤖 Generated with Claude Code

…and SPIRE)

A Docker Compose example for the camel-spiffe component: a SPIRE server
and agent issue identities to four Camel Main applications, which
authenticate each other with JWT-SVIDs (fetchJwtSvid / validateJwtSvid),
authorize by SPIFFE ID with per-route allow-lists in a shared route
configuration, make a second hop with their own identity, and log their
rotating X.509-SVIDs (fetchX509Svid).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@oscerd
oscerd force-pushed the feature/CAMEL-23305-spiffe-example branch from 824bb37 to dd6f528 Compare September 4, 2026 09:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant