Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion README.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ readme's instructions.
== Examples

// examples: START
Number of Examples: 72 (2 deprecated)
Number of Examples: 71 (0 deprecated)

[width="100%",cols="4,2,4",options="header"]
|===
Expand Down Expand Up @@ -162,6 +162,8 @@ Number of Examples: 72 (2 deprecated)

| link:vault/google-secret-manager-reloading/README.adoc[Google Secret Manager Reloading] (google-secret-manager-reloading) | Security | An example for showing Google Secret Manager Camel component with reloading

| link:spiffe/README.adoc[SPIFFE] (spiffe) | Security | An example for showing workload identity with the Camel SPIFFE component (JWT-SVID and X.509-SVID issued by SPIRE)

| link:salesforce-consumer/README.adoc[Salesforce Consumer] (salesforce-consumer) | Social | An example that uses Salesforce Rest Streaming API

| link:telegram/README.adoc[Telegram] (telegram) | Social | An example that uses Telegram API
Expand Down
1 change: 1 addition & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
<module>routetemplate-xml</module>
<module>routes-configuration</module>
<module>salesforce-consumer</module>
<module>spiffe</module>
<module>spring</module>
<module>spring-pulsar</module>
<module>spring-xquery</module>
Expand Down
373 changes: 373 additions & 0 deletions spiffe/README.adoc

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions spiffe/compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
## Licensed to the Apache Software Foundation (ASF) under one or more
## contributor license agreements. See the NOTICE file distributed with
## this work for additional information regarding copyright ownership.
## The ASF licenses this file to You under the Apache License, Version 2.0
## (the "License"); you may not use this file except in compliance with
## the License. You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.

# everything the three Camel applications have in common: the same image, the SPIFFE Workload API socket of the
# SPIRE agent, and the PID namespace of the SPIRE container (the agent attests a workload by looking up the process
# that connects to the Workload API, so it must be able to see it)
x-camel-application: &camel-application
build:
context: .
dockerfile: src/main/docker/Dockerfile
image: camel-example-spiffe
pid: "service:spire"
volumes:
- spire-sockets:/run/spire/sockets
depends_on:
spire:
condition: service_healthy

services:

# SPIRE server and agent in one container (see spire/entrypoint.sh): the server issues the identities,
# the agent attests the workloads and hands them their SVIDs through the SPIFFE Workload API
spire:
build: ./spire
volumes:
- spire-sockets:/run/spire/sockets
healthcheck:
test: ["CMD", "/opt/spire/bin/spire-agent", "healthcheck", "-socketPath", "/run/spire/sockets/agent.sock"]
interval: 5s
timeout: 3s
retries: 30
start_period: 5s

# the second hop: an HTTP API that only the backend may call. uid 1004 is registered as
# spiffe://example.org/inventory
inventory:
<<: *camel-application
command: ["org.apache.camel.example.spiffe.inventory.InventoryApplication"]
user: "1004:1004"
environment:
CAMEL_MAIN_NAME: inventory
SPIFFE_ENDPOINT_SOCKET: unix:///run/spire/sockets/agent.sock
ports:
- "8081:8080"

# the HTTP API the clients talk to, which calls the inventory with its own identity.
# uid 1002 is registered as spiffe://example.org/backend
backend:
<<: *camel-application
command: ["org.apache.camel.example.spiffe.backend.BackendApplication"]
user: "1002:1002"
environment:
CAMEL_MAIN_NAME: backend
SPIFFE_ENDPOINT_SOCKET: unix:///run/spire/sockets/agent.sock
ports:
- "8080:8080"
depends_on:
spire:
condition: service_healthy
inventory:
condition: service_started

# the client that is allowed to read the orders (but not the audit trail): uid 1001 is registered as
# spiffe://example.org/frontend
frontend:
<<: *camel-application
command: ["org.apache.camel.example.spiffe.frontend.FrontendApplication"]
user: "1001:1001"
environment:
CAMEL_MAIN_NAME: frontend
SPIFFE_ENDPOINT_SOCKET: unix:///run/spire/sockets/agent.sock
depends_on:
spire:
condition: service_healthy
backend:
condition: service_started

# the very same code and image as the frontend, but another Unix user, hence another identity: uid 1003 is
# registered as spiffe://example.org/auditor, which may read the audit trail but not the orders
auditor:
<<: *camel-application
command: ["org.apache.camel.example.spiffe.frontend.FrontendApplication"]
user: "1003:1003"
environment:
CAMEL_MAIN_NAME: auditor
SPIFFE_ENDPOINT_SOCKET: unix:///run/spire/sockets/agent.sock
depends_on:
spire:
condition: service_healthy
backend:
condition: service_started

volumes:
# the Unix domain socket of the SPIFFE Workload API, shared between the SPIRE agent and the workloads
spire-sockets:
160 changes: 160 additions & 0 deletions spiffe/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--

Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>org.apache.camel.example</groupId>
<artifactId>camel-examples</artifactId>
<version>4.23.0-SNAPSHOT</version>
</parent>

<artifactId>camel-example-spiffe</artifactId>
<packaging>jar</packaging>
<name>Camel :: Example :: SPIFFE</name>
<description>An example for showing workload identity with the Camel SPIFFE component (JWT-SVID and X.509-SVID issued by SPIRE)</description>

<properties>
<category>Security</category>
<title>SPIFFE</title>
<maven-dependency-plugin-version>3.8.1</maven-dependency-plugin-version>
</properties>

<dependencyManagement>
<dependencies>
<!-- Add Camel BOM -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-bom</artifactId>
<version>${camel.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>

<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-main</artifactId>
</dependency>
<!-- talks to the SPIFFE Workload API (SPIRE agent) -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-spiffe</artifactId>
</dependency>
<!-- the Workload API is a gRPC service on a Unix domain socket; java-spiffe needs a native transport for that.
This is the Linux one, which is what runs inside the containers of this example. When running the
applications directly on macOS use io.spiffe:grpc-netty-macos or io.spiffe:grpc-netty-macos-aarch64 instead. -->
<dependency>
<groupId>io.spiffe</groupId>
<artifactId>grpc-netty-linux</artifactId>
<version>${java-spiffe-version}</version>
<scope>runtime</scope>
</dependency>
<!-- embedded HTTP server for the backend -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-platform-http-main</artifactId>
</dependency>
<!-- HTTP client for the frontend -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-timer</artifactId>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
</dependency>

<!-- logging -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j2-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${log4j2-version}</version>
<scope>runtime</scope>
</dependency>

<!-- for testing -->
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-test-main-junit6</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>${mockito-version}</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<!-- to run via mvn camel:run (the backend by default, use -Dcamel.mainClass=... for the frontend) -->
<plugin>
<groupId>org.apache.camel</groupId>
<artifactId>camel-maven-plugin</artifactId>
<version>${camel.version}</version>
<configuration>
<logClasspath>false</logClasspath>
<mainClass>org.apache.camel.example.spiffe.backend.BackendApplication</mainClass>
</configuration>
</plugin>

<!-- copy the runtime dependencies to target/lib so the container image can pick them up -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>${maven-dependency-plugin-version}</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<includeScope>runtime</includeScope>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>

</project>
32 changes: 32 additions & 0 deletions spiffe/spire/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# The official SPIRE images are built from scratch and have no shell. This image copies their static binaries
# into a small Alpine image, so that entrypoint.sh can bootstrap a complete SPIRE deployment for the example:
# a server, an agent and the registration entries of the workloads.
FROM ghcr.io/spiffe/spire-server:1.15.3 AS spire-server
FROM ghcr.io/spiffe/spire-agent:1.15.3 AS spire-agent

FROM alpine:3.22

COPY --from=spire-server /opt/spire/bin/spire-server /opt/spire/bin/spire-server
COPY --from=spire-agent /opt/spire/bin/spire-agent /opt/spire/bin/spire-agent
COPY server.conf agent.conf /opt/spire/conf/
COPY entrypoint.sh /opt/spire/entrypoint.sh

RUN chmod 0755 /opt/spire/entrypoint.sh \
&& mkdir -p /opt/spire/data/server /opt/spire/data/agent /run/spire/sockets /tmp/spire-server/private

ENTRYPOINT ["/opt/spire/entrypoint.sh"]
43 changes: 43 additions & 0 deletions spiffe/spire/agent.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# SPIRE agent configuration, see https://github.com/spiffe/spire/blob/main/doc/spire_agent.md
agent {
data_dir = "/opt/spire/data/agent"
log_level = "INFO"
server_address = "127.0.0.1"
server_port = "8081"
# the SPIFFE Workload API: the Camel applications connect here (SPIFFE_ENDPOINT_SOCKET in compose.yaml)
socket_path = "/run/spire/sockets/agent.sock"
# the CA bundle of the server, exported by entrypoint.sh before the agent starts
trust_bundle_path = "/opt/spire/data/bootstrap.crt"
trust_domain = "example.org"
}

plugins {
KeyManager "memory" {
plugin_data {}
}

NodeAttestor "join_token" {
plugin_data {}
}

# attests the workloads that connect to the Workload API by their Unix user id, group id, and so on.
# The registration entries of this example use the unix:uid selector (see entrypoint.sh)
WorkloadAttestor "unix" {
plugin_data {}
}
}
Loading
Loading