Skip to main content

Runtime Security

Securing integrations in WSO2 Integrator at runtime involves hardening the JVM, managing keystores and certificates, running as non-root, and applying network-level controls. This page covers production security best practices.

Prerequisites
  • WSO2 Integrator installed and a working integration (Install guide)
  • A target environment: Linux VM, Docker, or Kubernetes cluster

JVM hardening

Disable unnecessary features

java \
-Djava.security.manager \
-Djava.rmi.server.hostname=localhost \
-Dcom.sun.management.jmxremote=false \
-XX:+UseG1GC \
-jar my_integration.jar
FlagPurpose
-Djava.security.managerEnable the Java Security Manager
-Dcom.sun.management.jmxremote=falseDisable remote JMX access
-Djava.rmi.server.hostname=localhostRestrict RMI to localhost
-XX:+UseContainerSupportRespect container memory limits
-XX:MaxRAMPercentage=75.0Limit heap to 75% of available RAM

Use the latest JDK

Always run on a supported, patched JDK version. Subscribe to security advisories:

java -version
# Ensure JDK 17.0.x or later with latest patch

Keystores and Truststores

Creating keystores and truststores is covered in detail in Keystores and Truststores. That page covers:

  • Generating keystores and truststores using keytool
  • Configuring TLS and mutual TLS for HTTP and gRPC services
  • Keeping certificate paths and passwords out of source code using Config.toml and environment variables

Non-root execution

Linux

Create a dedicated service account:

sudo useradd -r -s /usr/sbin/nologin ballerina
sudo chown -R ballerina:ballerina /opt/integrations

Run the integration as the ballerina user (see systemd unit file):

[Service]
User=ballerina
Group=ballerina

Docker

Use a non-root user in your Dockerfile:

FROM eclipse-temurin:17-jre
RUN addgroup --system ballerina && adduser --system --ingroup ballerina ballerina
COPY target/bin/my_integration.jar /app/my_integration.jar
COPY Config.toml /app/Config.toml
WORKDIR /app
USER ballerina
EXPOSE 9090
ENTRYPOINT ["java", "-jar", "my_integration.jar"]

Kubernetes

Set the security context in your Pod spec:

spec:
securityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
containers:
- name: integration
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]

File system security

PracticeImplementation
Read-only root filesystemMount writable paths explicitly (logs, temp)
Restrict config file permissionschmod 600 Config.toml
Separate data directoriesUse dedicated volumes for logs and temp files
volumeMounts:
- name: config
mountPath: /app/Config.toml
subPath: Config.toml
readOnly: true
- name: logs
mountPath: /app/logs
- name: tmp
mountPath: /tmp

Network security

Restrict listening interfaces

Bind to specific interfaces instead of 0.0.0.0:

[ballerinax.prometheus]
host = "127.0.0.1" # Only local access to metrics
port = 9797

Kubernetes network policies

Restrict pod-to-pod communication:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: integration-policy
spec:
podSelector:
matchLabels:
app: order-service
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: api-gateway
ports:
- protocol: TCP
port: 9090
egress:
- to:
- podSelector:
matchLabels:
app: database
ports:
- protocol: TCP
port: 5432

Security checklist

ItemStatus
Run as non-root userRequired
Enable TLS for all listenersRequired
Use PKCS12 keystores (not JKS)Recommended
Set read-only root filesystemRecommended
Drop all Linux capabilitiesRecommended
Restrict network with policiesRecommended
Disable JMX remote accessRequired
Use latest patched JDKRequired
Rotate certificates before expiryRequired
Encrypt secrets in Config.tomlRequired

See also