Skip to content
Merged

V5 #41

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
10 changes: 8 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ jobs:
with:
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Set up Node.js 22
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: eventlens-ui/package-lock.json

- name: Give execute permission for gradlew
run: chmod +x gradlew
Expand All @@ -48,7 +52,9 @@ jobs:
with:
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Give execute permission for gradlew
run: chmod +x gradlew
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,18 @@ jobs:
with:
java-version: '21'
distribution: 'temurin'

- name: Set up Gradle
if: matrix.language == 'java'
uses: gradle/actions/setup-gradle@v4

- name: Set up Node.js 22
if: matrix.language == 'java'
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: eventlens-ui/package-lock.json

- name: Build Java
if: matrix.language == 'java'
Expand Down
21 changes: 19 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,40 @@ jobs:
with:
java-version: '21'
distribution: 'temurin'
cache: gradle

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Set up Node.js 22
uses: actions/setup-node@v6
with:
node-version: '22'
cache: 'npm'
cache-dependency-path: eventlens-ui/package-lock.json

- name: Give execute permission for gradlew
run: chmod +x gradlew

- name: Build the Fat JAR
run: ./gradlew clean :eventlens-app:shadowJar --no-daemon

- name: Generate SBOM and dependency report
run: ./gradlew sbom dependencyScan --no-daemon

- name: Upload release security artifacts
uses: actions/upload-artifact@v4
with:
name: release-security-artifacts
path: |
build/reports/**
build/libs/**

- name: Create Release
uses: softprops/action-gh-release@v2
with:
files: eventlens-app/build/libs/eventlens*.jar
files: |
eventlens-app/build/libs/eventlens*.jar
build/reports/**
generate_release_notes: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
13 changes: 7 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ RUN --mount=type=cache,target=/root/.gradle \
&& chmod +x gradlew \
&& ./gradlew :eventlens-app:shadowJar -x test --no-daemon

## 2) Runtime stage – slim multi-arch JRE image (7.1)
FROM docker.io/library/eclipse-temurin:21-jre-alpine AS base
## 2) Runtime stage – glibc-based JRE image for native-library compatibility
FROM docker.io/library/eclipse-temurin:21-jre-jammy AS base

ARG TARGETARCH

RUN addgroup -g 1000 eventlens && \
adduser -u 1000 -G eventlens -s /bin/sh -D eventlens
RUN groupadd --gid 1000 eventlens && \
useradd --uid 1000 --gid eventlens --shell /bin/bash --create-home eventlens

WORKDIR /app

Expand All @@ -56,7 +56,9 @@ COPY --from=build --chown=eventlens:eventlens /workspace/eventlens-app/build/lib
COPY --from=build --chown=eventlens:eventlens /workspace/eventlens.yaml /app/eventlens.yaml

# Health check dependency
RUN apk add --no-cache curl
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*

USER eventlens

Expand All @@ -73,4 +75,3 @@ ENTRYPOINT ["java", \
"-XX:MaxRAMPercentage=75.0", \
"-Djava.security.egd=file:/dev/urandom", \
"-jar", "/app/eventlens.jar"]

18 changes: 15 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -614,8 +614,13 @@ EventLens primarily runs **read-only queries** against your event store. To keep
- **Health endpoint**: `GET /api/health`
- Verifies:
- DB connectivity,
- event store statistics,
- Kafka consumer status (if enabled).
- metadata DB connectivity when v5 security metadata is enabled,
- event store statistics.
- **Readiness endpoints**:
- `GET /api/v1/health/live`
- `GET /api/v1/health/ready`
- **Metrics endpoint**: `GET /api/v1/metrics`
- Includes JVM metrics plus security counters for auth attempts, authz denials, session lifecycle, sensitive actions, API key lifecycle, and audit persistence failures.
- **Logging**:
- Controlled via `logback.xml` in `eventlens-core`.
- Includes:
Expand Down Expand Up @@ -649,9 +654,16 @@ In containerized environments, direct logs to stdout/stderr and collect them via

- Configure a **read-only** Postgres user in your environment.
- Add or adjust indexes to match your event table shape.
- Enable basic auth **behind an HTTPS reverse proxy** in `eventlens.yaml` for production deployments.
- For shared environments, set `security.production-mode: true`, configure explicit `server.allowed-origins`, and keep metadata/audit enabled for OIDC, RBAC, API keys, or PII reveal.
- Enable auth **behind an HTTPS reverse proxy** in `eventlens.yaml` for production deployments.
- Build and run the Docker image alongside your own PostgreSQL/Kafka infrastructure, or reuse the provided `docker-compose.yml` for local debugging.

## 8. Release Security Artifacts

- Generate an OWASP dependency report with `./gradlew dependencyScan`
- Generate a CycloneDX SBOM with `./gradlew sbom`
- Release CI attaches these artifacts so operators can review the shipped dependency surface

---

## Project Info
Expand Down
14 changes: 11 additions & 3 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,20 @@ Instead, please send an email to the maintainers or use GitHub Security Advisori
EventLens is designed to be a safe, read-only window into your event store, but you should still follow these best practices when deploying it:

1. **Read-Only Database Access**: Ensure EventLens connects to your database using a read-only role, as it never mutates data.
2. **Authentication & HTTPS**: When exposing EventLens in a shared environment, enable basic authentication (`server.auth.enabled: true` in your configuration) and place EventLens behind a reverse proxy with TLS (HTTPS) enabled.
3. **CORS Restrictions**: For production deployments, change `server.allowed-origins` in your configuration to specifically whitelist the domains that are permitted to reach your dashboard.
4. **Regular Updates**: Keep your EventLens deployment updated to the latest version to receive security patches and updates to dependencies.
2. **Production Mode**: For shared environments, enable `security.production-mode: true`. This turns unsafe startup combinations into hard configuration failures instead of soft warnings.
3. **Authentication & HTTPS**: In shared environments, enable either legacy basic auth, OIDC browser sessions, or API keys, and place EventLens behind TLS (HTTPS). Production mode rejects completely unauthenticated deployments.
4. **CORS Restrictions**: In production mode, `server.allowed-origins` must be an explicit allowlist. Wildcard origins are rejected.
5. **Audit & Metadata**: Keep `audit.enabled: true` when using OIDC, RBAC, API keys, or PII reveal. Use file-backed SQLite metadata instead of in-memory metadata for persisted sessions, audit, and API keys.
6. **Regular Updates**: Keep your EventLens deployment updated to the latest version to receive security patches and updates to dependencies.

## Information about Dependencies

EventLens strives to keep all dependencies and packages up to date. We rely on standard open-source tooling like Dependabot to alert us to potential problems in our upstream dependencies.

If you are using a Docker image for EventLens, we periodically rebuild images to ensure the base images contain the latest security updates. Please make sure to pull the latest `alphasudo2/eventlens-app:latest` or specific version tag to stay protected.

Release builds now generate:
- an OWASP dependency check report
- a CycloneDX SBOM (`./gradlew sbom`)

These artifacts should be retained with the release so operators can review the exact dependency surface they are deploying.
7 changes: 7 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
plugins {
java
id("org.owasp.dependencycheck") version "12.2.0"
id("org.cyclonedx.bom") version "3.2.0"
}

// Shared versions
Expand Down Expand Up @@ -71,6 +72,12 @@ tasks.register("dependencyScan") {
dependsOn("dependencyCheckAggregate")
}

tasks.register("sbom") {
group = "verification"
description = "Generate a CycloneDX software bill of materials"
dependsOn("cyclonedxBom")
}

dependencyCheck {
// Do not fail local builds if the NVD feed cannot be updated (e.g. no API key).
failOnError = false
Expand Down
5 changes: 4 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ services:
app:
build: .
container_name: eventlens-app
restart: on-failure
depends_on:
postgres:
condition: service_healthy
Expand All @@ -54,10 +55,11 @@ services:
EVENTLENS_CONFIG: /app/eventlens.yaml
volumes:
- ./eventlens.yaml:/app/eventlens.yaml:ro
- eventlens_data:/app/data
ports:
- "9090:9090"
healthcheck:
test: [ "CMD-SHELL", "curl -sf http://localhost:9090/api/health || exit 1" ]
test: [ "CMD-SHELL", "curl -sf http://localhost:9090/api/v1/health/ready || exit 1" ]
interval: 10s
timeout: 5s
retries: 5
Expand All @@ -66,3 +68,4 @@ services:
volumes:
pg_data:
kafka_data:
eventlens_data:
4 changes: 4 additions & 0 deletions eventlens-api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ dependencies {
implementation(project(":eventlens-spi"))
implementation("io.javalin:javalin:7.1.0")
implementation("com.fasterxml.jackson.core:jackson-databind:2.21.2")
implementation("com.nimbusds:nimbus-jose-jwt:10.8")
implementation("ch.qos.logback:logback-classic:1.5.32")
implementation("io.micrometer:micrometer-core:1.16.4")
implementation("io.micrometer:micrometer-registry-prometheus:1.16.4")
Expand All @@ -14,3 +15,6 @@ dependencies {
testImplementation("org.testcontainers:mysql:1.20.1")
}

tasks.named("processResources") {
dependsOn(":eventlens-ui:npmBuild")
}
Loading
Loading