https://github.com/integraal-klant-en-objectbeeld/iko
Welcome at the IKO (Integraal Klant & Objectbeeld) repository.
https://github.com/integraal-klant-en-objectbeeld/iko
apache-camel carbon-design-system docker-compose htmx jq oidc-provider spring-mvc thymeleaf-template-engine
Last synced: 4 months ago
JSON representation
Welcome at the IKO (Integraal Klant & Objectbeeld) repository.
- Host: GitHub
- URL: https://github.com/integraal-klant-en-objectbeeld/iko
- Owner: Integraal-Klant-en-Objectbeeld
- License: other
- Created: 2025-05-02T07:39:56.000Z (about 1 year ago)
- Default Branch: main
- Last Pushed: 2026-01-21T16:20:59.000Z (5 months ago)
- Last Synced: 2026-01-21T22:11:59.612Z (5 months ago)
- Topics: apache-camel, carbon-design-system, docker-compose, htmx, jq, oidc-provider, spring-mvc, thymeleaf-template-engine
- Language: Kotlin
- Homepage:
- Size: 21.2 MB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
- Security: SECURITY.md
Awesome Lists containing this project
README

### Integraal Klant & Objectbeeld (IKO)

IKO is a Kotlin/Spring Boot application that uses Apache Camel to integrate with external systems via connectors. It ships with an admin UI and a Docker-based local environment.
---
### Features
- Spring Boot 3.5.x, Kotlin 2.2, JDK 21
- OAuth2 (Keycloak) for admin login and JWT resource server
- Redis caching for improved performance
- Prometheus metrics endpoint for monitoring
- Dockerfile for containerized runs and GitHub Actions CI/CD
---
### Prerequisites
- Docker and Docker Compose
- GitHub account (to use CI/CD workflows)
- For local development: JDK 21 and Gradle wrapper
---
### Quick start with Docker
1. Start the local stack:
```bash
docker compose up -d
```
2. Add a hosts entry so Keycloak tokens use the hostname expected by configuration:
```text
127.0.0.1 keycloak
```
3. Open the admin UI: `http://localhost:8080/admin`
Notes:
- The shipped `Dockerfile` (repo root) builds a runnable IKO container.
- The compose file provides dependent services and sets up Keycloak for local login.
---
### Local development
- Copy `.env.template` to `.env` and adjust values to your local setup.
- For HTML live-refresh during local dev only, `.env.template` includes:
```
SPRING_THYMELEAF_PREFIX=file:src/main/resources/templates/
# SPRING_WEB_RESOURCES_STATIC-LOCATIONS=file:src/main/resources/static/
```
Remove or comment these when running inside Docker (the application defaults to classpath locations in `application.yml`).
- Run the app via Gradle (env injected by the Dotenv Gradle plugin):
```bash
./gradlew bootRun
```
---
### Configuration overview
- Main config: `src/main/resources/application.yml`
- Disables OSIV (`spring.jpa.open-in-view=false`)
- Camel YAML routes path: `classpath:camel/*.yaml`
- Security: OAuth2/OIDC login for admin (roles claim + required admin roles configurable via `iko.security.admin.rolesClaim` / `iko.security.admin.authorities`) and JWT resource server for APIs (authorities from claim `resource_access.iko.roles`)
---
### Build and test
- Run tests:
```bash
./gradlew test
```
- Build the application JAR:
```bash
./gradlew build
```
- Build a local Docker image:
```bash
docker build -t iko:local .
```
---
### Admin UI
- URL: `http://localhost:8080/admin`
- Tutorial (Aggregated Data Profile):
https://docs.integraal-klant-objectbeeld.nl/admin-configuratie/samengesteld-gegevensprofiel-aanmaken
---
### CI/CD
#### Validate Build (`.github/workflows/validate-build.yml`)
- Triggered on `pull_request` targeting the `main` branch.
- Runs gradle build on the sources to make sure the sources build.
- Is a requirement for merging a pull request to the `main` branch.
- Failing builds will not be allowed to merge.
#### Snapshot workflow (`.github/workflows/snapshot-releases.yml`)
- Triggered on `push` to the `main` branch or a manual `workflow_dispatch` against a chosen branch.
- Builds the Docker image with Buildx (single-arch `linux/amd64`).
- On `push` to `main`, pushes to GHCR (`ghcr.io//`) with tags such as:
- `main` (default branch)
- `sha-`
- `snapshot-YYYYMMDDHHmm`
- `branch-` for non-main branches
- Adds OCI labels/annotations (title, description, revision, source, created).
#### Manual release workflow (`.github/workflows/start-manual-release.yml`)
This workflow is used to cut a formal release that publishes a versioned container image and a GitHub Release.
- Trigger: manually via the Actions tab (`workflow_dispatch`).
- Input: `version` — a semantic version like `1.2.3` or `1.2.3-beta.1` (no leading `v`). The workflow validates this with a semver regex.
- Permissions: `contents: write` (create GitHub Release) and `packages: write` (push to GHCR).
How it works (two-job pipeline):
1. `build` job
- Checks out code, sets up QEMU and Buildx.
- Extracts Docker metadata for consistent OCI labels.
- Builds the Docker image once and exports it as a `docker`-format TAR (`iko-image.tar`) tagged locally as `iko:iko-`.
- Uploads the TAR as a short-lived artifact.
2. `push` job
- Downloads the image artifact and logs into GHCR with `GITHUB_TOKEN`.
- Loads the image from the TAR and retags it as:
- `ghcr.io//:`
- `ghcr.io//:latest`
- Pushes both tags.
- Creates a GitHub Release with tag `v` and autogenerated release notes. If the version contains a `-` (e.g., `-rc.1`), the release is marked as a prerelease.
When to use it:
- Use `start-manual-release.yml` when you are ready to publish a stable or pre-release version to consumers.
- Use `snapshot-releases.yml` for continuous builds on `main` or for verifying PRs.
How to run a manual release:
1. Go to GitHub → Actions → `Start release`.
2. Click `Run workflow` and enter a semver (e.g., `1.3.0` or `1.3.0-rc.1`).
3. Confirm to start. After completion you will have:
- GHCR images: `ghcr.io//:` and `:latest`.
- GitHub Release: tag `v` with autogenerated notes.
Notes and gotchas:
- Architecture: currently builds for `linux/amd64` only. Adjust `platforms` if you need multi-arch.
- Input version must be plain semver (e.g., `1.2.3`), not `v1.2.3`.
- The artifact retention is short (1 day) to avoid stale reuse; the image is built once and then retagged/pushed in the separate job.
---
### More documentation
You can find more documentation [here](./doc/README.md)
### Crypto
IKO uses AES encryption for config storage of connectors.
Please generate a Base64 key in the env var IKO_CRYPTO_KEY via the .env file for local development.
Kotlin notebook code helps run pieces of code or just ask AI.
```Kotlin
fun generateBase64AesKey(keySize: Int = 256): String {
val keyGen = KeyGenerator.getInstance("AES")
keyGen.init(keySize, SecureRandom())
val secretKey: SecretKey = keyGen.generateKey()
return Base64.getEncoder().encodeToString(secretKey.encoded)
}
fun main() {
val base64Key = generateBase64AesKey()
println("Generated AES key (Base64): $base64Key")
}
main()
```