Operating System Installation
This section provides a complete, step-by-step guide for installing and configuring the IS Blocks KMS system on an Ubuntu 24.04 / 26.04 LTS server (bare metal physical machine or virtual machine).
Prerequisites & System Requirements
Before beginning the installation, ensure the server meets the following minimum specifications:
- Operating System: Ubuntu 24.04 LTS or 26.04 LTS (64-bit x86_64 / ARM64)
- Hardware Requirements:
- CPU: 4+ Cores (8+ Cores recommended for production signing workloads)
- RAM: 8 GB minimum (16 GB recommended)
- Storage: 50 GB+ SSD storage
- Network & DNS: A fully qualified domain name (FQDN, e.g.,
kms.example.com) resolving to the server's IP address with inbound access on ports80(HTTP) and443(HTTPS). - Privileges:
sudo/ root administrative access.
Update system packages and install essential utilities:
sudo apt update && sudo apt upgrade -y
sudo apt install -y curl wget git gnupg lsb-release build-essential jq unzip software-properties-common
Install JDK
IS Blocks KMS and Keycloak require Java 21 LTS (or Java 25 LTS).
-
Install OpenJDK 21:
sudo apt install -y openjdk-21-jdk -
Verify the Java installation:
java -version -
Configure the
JAVA_HOMEenvironment variable:echo "JAVA_HOME=/usr/lib/jvm/java-21-openjdk-amd64" | sudo tee -a /etc/environmentsource /etc/environment
Install PostgreSQL
PostgreSQL serves as the relational database backend for Keycloak Identity and Access Management.
-
Install PostgreSQL and contrib packages:
sudo apt install -y postgresql postgresql-contribsudo systemctl enable --now postgresql -
Create the Keycloak database, user, and permissions:
sudo -u postgres psql <<EOFCREATE DATABASE keycloak WITH ENCODING 'UTF8';CREATE USER keycloak WITH ENCRYPTED PASSWORD 'StrongKeycloakDBPass123!';GRANT ALL PRIVILEGES ON DATABASE keycloak TO keycloak;ALTER DATABASE keycloak OWNER TO keycloak;\qEOF
Install MongoDB / FerretDB
IS Blocks KMS uses a document database to store keys metadata, certificates, constraints, rings, and audit trails. You can install MongoDB Community Edition or FerretDB (running on PostgreSQL).
Installing MongoDB Community Edition:
-
Import the MongoDB public GPG key and add the repository:
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmorecho "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu $(lsb_release -cs)/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list -
Install and start MongoDB:
sudo apt updatesudo apt install -y mongodb-orgsudo systemctl enable --now mongod -
Verify MongoDB is active and listening on
127.0.0.1:27017:mongosh --eval "db.adminCommand('ping')"
Install Keycloak
-
Download and extract Keycloak:
KEYCLOAK_VERSION="24.0.5"cd /optsudo wget https://github.com/keycloak/keycloak/releases/download/${KEYCLOAK_VERSION}/keycloak-${KEYCLOAK_VERSION}.tar.gzsudo tar -xzf keycloak-${KEYCLOAK_VERSION}.tar.gzsudo mv keycloak-${KEYCLOAK_VERSION} /opt/keycloaksudo rm keycloak-${KEYCLOAK_VERSION}.tar.gz -
Create a dedicated system user:
sudo useradd -r -d /opt/keycloak -s /bin/false keycloaksudo chown -R keycloak:keycloak /opt/keycloak -
Configure
/opt/keycloak/conf/keycloak.conf:# Database configurationdb=postgresdb-username=keycloakdb-password=StrongKeycloakDBPass123!db-url=jdbc:postgresql://localhost:5432/keycloak# HTTP & Proxy Settings (Behind NGINX)proxy=edgehttp-enabled=truehttp-port=8080http-relative-path=/authhostname=kms.example.com -
Build Keycloak configuration:
sudo -u keycloak /opt/keycloak/bin/kc.sh build -
Create a systemd service file
/etc/systemd/system/keycloak.service:[Unit]Description=Keycloak Identity & Access ManagementAfter=network.target postgresql.serviceWants=postgresql.service[Service]Type=execUser=keycloakGroup=keycloakEnvironment="KEYCLOAK_ADMIN=admin"Environment="KEYCLOAK_ADMIN_PASSWORD=AdminSecurePassword123!"ExecStart=/opt/keycloak/bin/kc.sh start --optimizedRestart=on-failureRestartSec=10[Install]WantedBy=multi-user.target -
Enable and start Keycloak:
sudo systemctl daemon-reloadsudo systemctl enable --now keycloak
Create TLS Certificates
Generate valid TLS certificates for HTTPS termination. For production servers with public DNS, use Let's Encrypt Certbot:
sudo apt install -y certbot python3-certbot-nginx
sudo certbot certonly --standalone -d kms.example.com --non-interactive --agree-tos -m admin@example.com
(For staging/offline environments, generate a self-signed certificate using openssl req -x509 -nodes -days 365 -newkey rsa:4096 -keyout /etc/ssl/private/kms.key -out /etc/ssl/certs/kms.crt)
Install NGINX
NGINX acts as the unified reverse proxy, SSL termination endpoint, and static frontend file server.
-
Install NGINX:
sudo apt install -y nginx -
Create the NGINX site configuration
/etc/nginx/sites-available/isblocks-kms:server {listen 80;server_name kms.example.com;return 301 https://$host$request_uri;}server {listen 443 ssl http2;server_name kms.example.com;ssl_certificate /etc/letsencrypt/live/kms.example.com/fullchain.pem;ssl_certificate_key /etc/letsencrypt/live/kms.example.com/privkey.pem;ssl_protocols TLSv1.2 TLSv1.3;ssl_ciphers HIGH:!aNULL:!MD5;# Dashboard React SPA Frontendlocation / {root /var/www/isblocks-dashboard;index index.html;try_files $uri $uri/ /index.html;}# KMS Spring Boot Backend APIlocation /api/ {proxy_pass http://127.0.0.1:9080/api/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto https;}# Spring OpenAPI / Swaggerlocation /public/ {proxy_pass http://127.0.0.1:9080/public/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto https;}# Keycloak Authentication Serverlocation /auth/ {proxy_pass http://127.0.0.1:8080/auth/;proxy_set_header Host $host;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header X-Forwarded-Proto https;proxy_buffer_size 128k;proxy_buffers 4 256k;proxy_busy_buffers_size 256k;}} -
Enable the site and test configuration:
sudo ln -sf /etc/nginx/sites-available/isblocks-kms /etc/nginx/sites-enabled/sudo rm -f /etc/nginx/sites-enabled/defaultsudo nginx -tsudo systemctl restart nginx
Setup the Dashboard Service
-
Create the web root directory:
sudo mkdir -p /var/www/isblocks-dashboard -
Build and copy the
isblocks-react-dashboardproduction distribution (dist/*) into/var/www/isblocks-dashboard/:sudo cp -r /path/to/isblocks-react-dashboard/dist/* /var/www/isblocks-dashboard/sudo chown -R www-data:www-data /var/www/isblocks-dashboardsudo chmod -R 755 /var/www/isblocks-dashboard
Setup the Spring Boot Service
-
Create application directories:
sudo mkdir -p /opt/isblocks-kmssudo useradd -r -s /bin/false isblocks -
Place
isblocks-spring-kms.jarinto/opt/isblocks-kms/. -
Create the production configuration file
/opt/isblocks-kms/application.properties:server.port=9080# Keycloak OIDC Configurationkeycloak.auth-server-url=https://kms.example.com/auth/keycloak.realm=isblockskmskeycloak.resource=kmskeycloak.principal-attribute=preferred_usernamespring.security.oauth2.client.provider.keycloak.issuer-uri=https://kms.example.com/auth/realms/isblockskmsspring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://kms.example.com/auth/realms/isblockskms/protocol/openid-connect/certsjwt.auth.converter.resourceId=kmsjwt.auth.converter.resource-id=kmsjwt.auth.converter.principal-attribute=preferred_username# MongoDB Connectionspring.mongodb.uri=mongodb://127.0.0.1:27017/kmsspring.mongodb.database=kms# SoftHSM & PKCS#11 Library Pathsisblocks.pkcs11.library.path.1=/usr/lib/softhsm/libsofthsm2.soisblocks.pkcs11.library.name.1=SoftHSMv2# Swagger / OpenAPIspringdoc.api-docs.path=/public/api-docsspringdoc.swagger-ui.path=/public/swagger-ui.html -
Create systemd unit
/etc/systemd/system/isblocks-kms.service:[Unit]Description=IS Blocks KMS Spring Boot BackendAfter=network.target mongod.service keycloak.serviceWants=mongod.service[Service]Type=simpleUser=isblocksGroup=isblocksWorkingDirectory=/opt/isblocks-kmsExecStart=/usr/bin/java -Xms1024m -Xmx4096m -jar /opt/isblocks-kms/isblocks-spring-kms.jar --spring.config.location=file:/opt/isblocks-kms/application.propertiesRestart=alwaysRestartSec=10[Install]WantedBy=multi-user.target -
Set permissions:
sudo chown -R isblocks:isblocks /opt/isblocks-kms
Create the Keycloak Realm, Client and User
- Open your browser and navigate to
https://kms.example.com/auth/admin(log in with the admin credentials set inkeycloak.service). - Create Realm:
- Create a new Realm named
isblockskms.
- Create a new Realm named
- Create Client:
- In realm
isblockskms, navigate to Clients $\rightarrow$ Create client. - Client ID:
kms - Client type: OpenID Connect
- Client Authentication: Off (Public Client)
- Valid Redirect URIs:
https://kms.example.com/* - Valid Post-Logout Redirect URIs:
https://kms.example.com/* - Web Origins:
+(orhttps://kms.example.com)
- In realm
- Create Roles & Administrator User:
- In Realm Roles, add roles
admin,kms-admin, andkms-user. - In Users, create a new user (e.g.
kmsadmin), set password, and assign theadminrole under Role Mapping.
- In Realm Roles, add roles
Start the Services
Enable and start all system services:
sudo systemctl daemon-reload
sudo systemctl enable postgresql mongod keycloak isblocks-kms nginx
sudo systemctl restart postgresql mongod keycloak isblocks-kms nginx
Verify service status:
sudo systemctl status postgresql --no-pager
sudo systemctl status mongod --no-pager
sudo systemctl status keycloak --no-pager
sudo systemctl status isblocks-kms --no-pager
sudo systemctl status nginx --no-pager
Test the System
-
Verify Backend Health & API Documentation:
curl -I https://kms.example.com/public/api-docs -
Verify Keycloak OIDC OpenID Configuration:
curl -s https://kms.example.com/auth/realms/isblockskms/.well-known/openid-configuration | jq .issuer -
Verify Dashboard Web Access:
- Open
https://kms.example.com/in your web browser. - You will be redirected to Keycloak authentication.
- Log in with your configured
kmsadmincredentials. - Verify access to the KMS Rings, Keys, and Constraints modules.
- Open