diff --git a/README.md b/README.md
index 5ded354..504b1a0 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,21 @@
# LOGAR: Edge-Thin Log Analysis & Temporal Verification System
-**LOGAR** is an enterprise log aggregation, verification, and anomaly detection architecture designed for heterogeneous server fleets (Windows & Linux). It combines lightweight zero-state edge forwarders with a centralized cloud hub that applies OpenPGP encryption, authenticated TCP streaming, temporal persistence tracking across 12-hour evaluation windows, an automated 4-run rule to filter transient warnings, and immediate pass-through for critical errors before reporting verified anomalies to **Hermes**.
+**LOGAR** is an enterprise log aggregation, verification, and anomaly detection architecture designed for heterogeneous server fleets (Windows & Linux). It combines lightweight zero-state edge forwarders with a centralized cloud hub that applies mutual TLS 1.3 (**mTLS**) authentication, dynamic PKI licensing and quota management, temporal persistence tracking across 12-hour evaluation windows, an automated 4-run rule to filter transient warnings, and immediate pass-through for critical errors before reporting verified anomalies to **Hermes**.
---
## Table of Contents
1. [Core Philosophy](#core-philosophy)
2. [Architecture & Data Flow](#architecture--data-flow)
-3. [Security & Cryptographic Model](#security--cryptographic-model)
+3. [mTLS Security, Dynamic PKI & Licensing](#mtls-security-dynamic-pki--licensing)
4. [Cloud-Side Temporal Persistence & 4-Run Rule](#cloud-side-temporal-persistence--4-run-rule)
-5. [Agentic Hermes Integration](#agentic-hermes-integration)
+5. [Agentic Hermes & Client Management API](#agentic-hermes--client-management-api)
6. [Dynamic Machine & Domain Identification](#dynamic-machine--domain-identification)
-7. [Repository & Shippables Structure](#repository--shippables-structure)
-8. [Getting Started & Installation](#getting-started--installation)
-9. [Running Tests](#running-tests)
-10. [Automated Releases via Gitea Actions](#automated-releases-via-gitea-actions)
+7. [Automated Service Installers (Linux & Windows)](#automated-service-installers-linux--windows)
+8. [Repository & Shippables Structure](#repository--shippables-structure)
+9. [Getting Started & Deployment](#getting-started--deployment)
+10. [Running Tests](#running-tests)
+11. [Automated Releases via Gitea Actions](#automated-releases-via-gitea-actions)
---
@@ -22,20 +23,20 @@
### 1. Edge Thinness & Zero State
Site agents running on Windows and Linux act strictly as lightweight forwarders:
-- **No Local Database**: Clients maintain zero state and no local SQLite or cache files.
-- **Source-Level Filtering**: Agents upload candidate entries spanning from informational events up to errors (`INFO`, `WARNING`, `ERROR`, `CRITICAL`), while stripping verbose debugging noise (`DEBUG`, audit entries) and skipping any entries older than 24 hours.
-- **End-to-End Encryption**: Logs are encrypted using the server's OpenPGP public key before leaving the edge node.
-- **Secure TCP Sockets**: Ingestion occurs over low-overhead authenticated TCP sockets rather than bulky HTTP/HTTPS endpoints.
+- **No Local Database**: Clients maintain zero local SQLite or heavy cache files.
+- **Source-Level Filtering**: Agents stream candidate entries from informational events up to errors (`INFO`, `WARNING`, `ERROR`, `CRITICAL`), stripping verbose debugging noise (`DEBUG`, trace entries) and skipping events older than 24 hours.
+- **Transport Security (mTLS 1.3)**: Logs are streamed directly over mutual TLS 1.3 sockets with hardware-bound / machine-unique client certificates.
+- **Zero Configuration Overhead**: Clients auto-bootstrap certificate enrollment on first run if configured with an enrollment secret.
### 2. Cloud-Side Temporal Persistence & Severity Routing
-The central Python/TCP hub handles the heavy lifting:
+The central Python hub handles state and verification:
- State tracking is managed centrally in SQLite (`logar_state.db`).
- Candidate issues are evaluated over a **12-hour temporal evaluation window**.
-- **Warning Persistence (4-Run Rule)**: `WARNING` level issues must persist across **at least 4 consecutive runs / cycles** within the 12-hour window to be confirmed as genuine anomalies, automatically filtering out transient blips.
+- **Warning Persistence (4-Run Rule)**: `WARNING` issues must persist across **at least 4 consecutive runs / cycles** within the 12-hour window to be confirmed as genuine anomalies, automatically filtering transient infrastructure blips.
- **Immediate Error Pass**: Critical errors (`ERROR`, `CRITICAL`, `FATAL`) bypass the 4-run threshold and are promoted immediately to `VERIFIED` on their first occurrence.
### 3. Agentic Integration with Hermes
-Instead of human engineers manually diving through noisy logs, **Hermes** ingests pre-filtered anomalies directly from the cloud hub (`GET /api/hermes/report`), treating verified errors and 4-run validated warnings as actionable system artifacts to trigger precise team notifications.
+Instead of engineers manually sifting through logs, **Hermes** ingests pre-filtered anomalies directly from the cloud hub (`GET /api/hermes/report`), treating verified errors and 4-run validated warnings as actionable system artifacts to trigger precise notifications and remediations.
---
@@ -43,34 +44,43 @@ Instead of human engineers manually diving through noisy logs, **Hermes** ingest
```mermaid
graph TB
- subgraph Edge Nodes [State-Tracking Edge Forwarders]
- W[Win_Client.py / Win_Client.exe / Win_Client.pyz
Windows Event Log Application]
- L[Linux_Client.py / Linux_Client.bin
systemd journalctl -p info]
+ subgraph Edge Nodes [Lightweight Edge Forwarders]
+ W[Win_Client.exe / Win_Client.py
Windows Event Log Ingestion]
+ L[Linux_Client.bin / Linux_Client.py
systemd journalctl -p warning]
end
- subgraph Security Layer [Security & Framing]
- E[OpenPGP Payload Encryption
Server Public Key & Fingerprint]
- S[Length-Prefixed Framing
4-byte Big-Endian + Auth Envelope]
+ subgraph Enrollment [Dynamic PKI & Licensing]
+ ENR[POST /api/client/enroll
License Quota & Secret Validation]
+ CA[Internal Root CA
Signs RSA-2048 Client Cert]
end
- subgraph Cloud Hub [LOGAR Central Server Hub]
- TCP[Authenticated TCP Listener
Port 9443]
- DEC[OpenPGP Decryption
Server Private Key]
- DB[(SQLite Persistence
active_issues & ingest_runs)]
+ subgraph Transport [mTLS 1.3 Security Layer]
+ MTLS[Mutual TLS 1.3 Handshake
Port 9443 - Client Cert Required]
+ AUTH[Extract Client CN & Fingerprint
Validate Active License in SQLite]
+ end
+
+ subgraph Hub [LOGAR Server Hub]
+ INGEST[Length-Prefixed Frame Ingestion]
+ DB[(SQLite Persistence
active_issues, clients, license_config)]
RULE{12h Window &
4-Run Rule}
end
- subgraph Agentic Reporting [Downstream Integration]
- API[FastAPI / Uvicorn Reporting
Port 8443]
+ subgraph Downstream [Hermes Agent & Monitoring]
+ API[FastAPI Reporting & Management
Port 8443]
HERMES[Hermes Agent
GET /api/hermes/report]
end
- W --> E
- L --> E
- E --> S
- S -->|TCP Stream| TCP
- TCP --> DEC
- DEC --> RULE
+ W -->|Auto-Enrollment| ENR
+ L -->|Auto-Enrollment| ENR
+ ENR --> CA
+ CA -->|ca.crt, client.crt, client.key| W
+ CA -->|ca.crt, client.crt, client.key| L
+
+ W -->|mTLS Stream| MTLS
+ L -->|mTLS Stream| MTLS
+ MTLS --> AUTH
+ AUTH --> INGEST
+ INGEST --> RULE
RULE --> DB
DB --> API
API --> HERMES
@@ -78,44 +88,44 @@ graph TB
---
-## Security & Cryptographic Model
+## mTLS Security, Dynamic PKI & Licensing
-### Pure-Python OpenPGP (RFC 4880)
-- **Zero OS Binary Dependency**: Utilizes `pgpy` and `cryptography` in pure Python. **No native GnuPG or `gpg` binary installation is required** on the server, Windows nodes, or Linux nodes.
-- **First-Run Automatic Key Generation**: On the first launch, if `server_config.json` is missing, `Server.py` automatically generates:
- - An OpenPGP RSA 2048 keypair with encryption-only usage flags.
- - An armored private key (`private_key`) and public key (`public_key`).
- - A SHA-256 public encryption fingerprint (`server_fingerprint`).
- - A cryptographically random authentication secret token (`auth_token`).
-- **Client Configuration Exporter**:
- ```bash
- python src/Server.py --create-client-config --server-host 127.0.0.1 --server-port 9443 --client-out client_config.json
- ```
- Produces an anonymous client config containing only the server socket coordinates, authentication token, and the encryption-only public key & fingerprint.
-- **Socket Protocol Framing**:
- - `[4 bytes big-endian unsigned int]` : Total envelope length.
- - `[JSON Envelope]` :
- ```json
- {
- "auth_token": "",
- "timestamp": "2026-09-03T...",
- "encrypted_payload": "-----BEGIN PGP MESSAGE-----\n..."
- }
- ```
- - Unauthorized clients or invalid authentication tokens are rejected immediately.
+### 1. TLS 1.3 Mutual Authentication (mTLS)
+- **Port 9443**: Ingestion occurs exclusively over TLS 1.3 sockets with `ssl.CERT_REQUIRED`.
+- Both the hub and edge clients verify each other's certificates:
+ - Client verifies server certificate against `ca.crt`.
+ - Server verifies client certificate against the Root CA.
+- **Client CN Identification**: In the TLS handshake, the server extracts the `commonName` attribute (`client_id`), validates that the client is marked `active` in the `clients` table, updates the `last_seen` timestamp, and drops unregistered or revoked certificates immediately.
+
+### 2. Dynamic PKI Hub Engine (`src/server_enrollment.py`)
+- **Root CA**: On first run, `Server.py` creates a self-signed Root CA (`ca.crt` / `ca.key`) valid for 10 years.
+- **Server TLS Certificate**: Generated automatically with Subject Alternative Names (SANs) for `localhost`, `127.0.0.1`, server IP, and hostnames.
+- **Authority Key Identifiers**: Full compliance with OpenSSL 3.x and Python 3.12–3.14 via `SubjectKeyIdentifier` and `AuthorityKeyIdentifier` extensions.
+- **Dynamic Client Certificates**: RSA-2048 keys and X.509 client certificates are issued on the fly via the enrollment API.
+
+### 3. Seat Accounting & Licensing
+- Stored in SQLite table `license_config`:
+ - `max_seats`: Maximum concurrent active client licenses (default: 10).
+ - `enrollment_secret`: Cryptographic secret required for initial client enrollment.
+- Stored in SQLite table `clients`:
+ - `client_id`: Unique client identifier (machine GUID or hardware hash).
+ - `hostname`, `os_type`, `cert_fingerprint`, `status` (`active` / `revoked`), `first_seen`, `last_seen`.
+- When a new client enrolls:
+ - If `active_seats >= max_seats`, the hub rejects registration with `HTTP 403 (License seat limit reached)`.
+ - Existing registered clients can re-enroll / renew seamlessly without consuming additional seats.
---
## Cloud-Side Temporal Persistence & 4-Run Rule
-
+
Incoming candidate logs are tracked in SQLite table `active_issues`:
- **Issue Fingerprint**: Formatted as `{site_name}:{server}:{signature}`.
- **12-Hour Evaluation Window**:
- - When an issue is observed, the hub compares `(now - last_seen)`.
- - If more than 12 hours have passed since the issue was last recorded, the previous window is expired and the cycle resets to `run_count = 1`.
+ - The hub compares `(now - last_seen)`.
+ - If more than 12 hours have elapsed since the issue was last recorded, the previous window expires and the cycle resets to `run_count = 1`.
- **4-Run Rule for Warnings**:
- - The 4-run persistence threshold specifically applies to `WARNING` (and `INFO`) events to eliminate transient operational noise.
- - For each distinct run batch, `run_count` increments.
+ - The 4-run persistence threshold applies to `WARNING` (and `INFO`) events to eliminate transient operational noise.
+ - Each distinct run batch increments `run_count`.
- Warnings with `run_count < 4` are marked as `TRANSIENT` and excluded from Hermes reports.
- When `run_count >= 4` within the active 12-hour window, the warning transitions to `VERIFIED`.
- **Immediate Verification for Errors**:
@@ -124,25 +134,64 @@ Incoming candidate logs are tracked in SQLite table `active_issues`:
---
-## Agentic Hermes Integration
+## Agentic Hermes & Client Management API
-The server hub serves a REST reporting API (default port `8443`):
+The server hub exposes a management and reporting REST API (default port `8443`):
+
+### `POST /api/client/enroll`
+Client enrollment endpoint:
+- **Request**:
+ ```json
+ {
+ "client_id": "web-worker-01.corp.internal",
+ "hostname": "web-worker-01",
+ "os": "linux",
+ "enrollment_secret": ""
+ }
+ ```
+- **Response**:
+ ```json
+ {
+ "ca_cert": "-----BEGIN CERTIFICATE-----\n...",
+ "client_cert": "-----BEGIN CERTIFICATE-----\n...",
+ "client_key": "-----BEGIN RSA PRIVATE KEY-----\n..."
+ }
+ ```
+
+### `GET /api/clients`
+Returns seat quota status and registered client telemetry:
+```json
+{
+ "active_seats": 2,
+ "max_seats": 10,
+ "clients": [
+ {
+ "client_id": "web-worker-01.corp.internal",
+ "hostname": "web-worker-01",
+ "os_type": "linux",
+ "cert_fingerprint": "7D5B660B...",
+ "status": "active",
+ "first_seen": "2026-09-04 18:00:00",
+ "last_seen": "2026-09-04 19:15:00"
+ }
+ ]
+}
+```
### `GET /api/hermes/report`
-Returns all **verified anomalies** (immediate critical errors and warnings verified after 4 consecutive runs within the 12-hour evaluation window):
-
+Returns all **verified anomalies** (immediate critical errors and warnings verified after 4 consecutive runs within the 12-hour window):
```json
[
{
- "fingerprint": "corp.internal:web-app-01.corp.internal:NginxWorkerCrash",
+ "fingerprint": "corp.internal:web-worker-01.corp.internal:PostgresPoolExhausted",
"site": "corp.internal",
- "server": "web-app-01.corp.internal",
- "signature": "NginxWorkerCrash",
- "severity": "ERROR",
- "message": "Worker process 4120 terminated with signal 11",
+ "server": "web-worker-01.corp.internal",
+ "signature": "PostgresPoolExhausted",
+ "severity": "WARNING",
+ "message": "Connection pool saturated (>95%) across 4 runs",
"os_type": "linux",
- "first_seen": "2026-09-03T09:00:00+00:00",
- "last_seen": "2026-09-03T21:00:00+00:00",
+ "first_seen": "2026-09-04T07:00:00+00:00",
+ "last_seen": "2026-09-04T19:00:00+00:00",
"consecutive_runs": 4,
"evaluation_window": "12h",
"verified": true,
@@ -152,19 +201,19 @@ Returns all **verified anomalies** (immediate critical errors and warnings verif
```
### `GET /api/hermes/all`
-Diagnostic endpoint listing all active issues (both `TRANSIENT` candidate blips and `VERIFIED` anomalies).
+Diagnostic endpoint listing all candidate issues (`TRANSIENT` and `VERIFIED`).
### `GET /health`
-Returns hub health, encryption fingerprint, and listener ports.
+Returns hub health, encryption fingerprint, listener ports, and mTLS status.
---
## Dynamic Machine & Domain Identification
-Client configurations intentionally contain **no machine name or site name**. Both forwarders dynamically identify their host and domain at runtime via `get_machine_identifier()`:
+Client configurations intentionally contain **no hardcoded machine name or site name**. Both forwarders dynamically identify their host and domain at runtime via `get_machine_identifier()`:
1. **Fully Qualified Domain Name (FQDN)**: Checked via `socket.getfqdn()`.
2. **OS-Specific Domain Discovery**:
- - **Windows**: Checks Active Directory environment variable `USERDNSDOMAIN` / `USERDOMAIN`.
+ - **Windows**: Checks Active Directory environment variables (`USERDNSDOMAIN`, `USERDOMAIN`).
- **Linux**: Parses `/etc/resolv.conf` `domain` and `search` directives.
3. **Reverse DNS Lookup**: Resolves canonical hostname via `socket.gethostbyaddr`.
4. **Fallback**: Local hostname `socket.gethostname()`.
@@ -173,51 +222,83 @@ The server automatically infers site attribution from domain qualifiers (e.g. `n
---
+## Automated Service Installers (Linux & Windows)
+
+LOGAR provides production-grade installation scripts and installer builders for automated service deployment:
+
+### 1. Linux Service Installers
+- **Client Installer (`compilation/install_linux_client.sh`)**:
+ - Non-interactive script deploying to `/opt/logar-client`.
+ - Automatically queries `/etc/machine-id` and enrolls with the hub via `curl`.
+ - Installs and enables `logar-client.service` systemd unit.
+ ```bash
+ sudo ./compilation/install_linux_client.sh "http://hub.example.com:8443" ""
+ ```
+- **Server Installer (`compilation/install_linux_server.sh`)**:
+ - Deploys server to `/opt/logar-server`.
+ - Configures logging and installs `logar-server.service` with `LimitNOFILE=65536`.
+ ```bash
+ sudo ./compilation/install_linux_server.sh
+ ```
+
+### 2. Windows Inno Setup Installers
+- Built using **Inno Setup 6** and bundled with **NSSM** (`compilation/nssm.exe`):
+ - **Client Setup (`compilation/installer_client.iss`)**: Compiles `LOGAR-Client-Setup.exe`. Installs `Win_Client.exe` into `{autopf}\LOGAR`, sets up `LOGAR_Client` service via NSSM with stdout/stderr redirection to `{commonappdata}\LOGAR\client.log`, and starts the service. Clean uninstallation stops and removes the service.
+ - **Server Setup (`compilation/installer_server.iss`)**: Compiles `LOGAR-Server-Setup.exe`. Installs `Server.exe` and sets up `LOGAR_Server` Windows service via NSSM.
+
+---
+
## Repository & Shippables Structure
```
LOGAR/
├── .gitea/
│ └── workflows/
-│ ├── ci.yml # Continuous Integration automated test suite (runs on every push)
-│ ├── release-linux.yml # Linux release workflow (compiles Server.bin, Linux_Client.bin, checksums)
-│ └── release-windows.yml # Windows release workflow (compiles Server.exe, Win_Client.exe, checksums)
-├── compilation/ # Build, packaging, and release automation tools
-│ ├── package_dist.py # Multi-platform standalone binary packaging script
-│ ├── requirements.txt # Unified project dependencies
-│ └── upload_release.py # Direct Gitea REST API release asset publisher
-├── src/ # Core application source modules
+│ ├── ci.yml # CI pipeline: syntax, 22 unit tests & mTLS pipeline test
+│ ├── release-linux.yml # Linux release workflow (compiles binaries & checksums)
+│ └── release-windows.yml # Windows release workflow (compiles .exe & Inno Setup installers)
+├── compilation/ # Packaging, installers, and release automation
+│ ├── install_linux_client.sh # Automated Linux client systemd installation script
+│ ├── install_linux_server.sh # Automated Linux server systemd installation script
+│ ├── installer_client.iss # Inno Setup Windows Client installer script
+│ ├── installer_server.iss # Inno Setup Windows Server installer script
+│ ├── nssm.exe # Official 64-bit NSSM service manager binary
+│ ├── package_dist.py # Standalone binary compiler & packager
+│ ├── requirements.txt # Unified project dependencies
+│ └── upload_release.py # Gitea REST API release asset publisher
+├── src/ # Core application source modules
│ ├── __init__.py
-│ ├── Server.py # Central TCP server and Hermes API
-│ ├── Win_Client.py # Windows edge forwarder
-│ └── Linux_Client.py # Linux edge forwarder
-├── tests/ # Automated test suites
-│ ├── test_linux_client.py # Linux client unit tests
-│ ├── test_pipeline.py # End-to-end integration test
-│ ├── test_server.py # Server unit tests
-│ └── test_win_client.py # Windows client unit tests
-├── .gitignore # Ignore venv, caches, DBs, and private keys
-├── README.md # Comprehensive documentation
-├── RELEASE_NOTES.md # Release history and changelog
-├── server_config.sample.json # Central server sample configuration
-└── out/ # Standalone deployment documentation & sample configs
+│ ├── Server.py # Central mTLS server, temporal engine, and Hermes REST API
+│ ├── server_enrollment.py # Dynamic PKI, Root CA, and client certificate generator
+│ ├── Win_Client.py # Windows edge forwarder with auto-enrollment
+│ └── Linux_Client.py # Linux edge forwarder with auto-enrollment
+├── tests/ # Automated test suites
+│ ├── test_linux_client.py # Linux client unit tests & mTLS certificate validation
+│ ├── test_pipeline.py # End-to-end mTLS integration & 4-run verification test
+│ ├── test_server.py # Server unit tests, PKI generation, and seat quota tests
+│ └── test_win_client.py # Windows client unit tests & mTLS certificate validation
+├── .gitignore # Ignores venv, caches, DBs, and private keys
+├── README.md # Architecture and usage documentation
+├── RELEASE_NOTES.md # Release history and changelog
+├── server_config.sample.json # Reference server configuration
+└── out/ # Component guides and sample configs
├── linux_server/
- │ ├── README.md # Linux systemd service installation & hub guide
- │ └── server_config.sample.json # Reference server configuration
+ │ ├── README.md
+ │ └── server_config.sample.json
├── win_server/
- │ ├── README.md # Windows service (NSSM/Task Scheduler) installation guide
- │ └── server_config.sample.json # Reference server configuration
+ │ ├── README.md
+ │ └── server_config.sample.json
├── linux_client/
- │ ├── README.md # Linux service & timer installation guide
- │ └── client_config.sample.json # Reference client configuration
+ │ ├── README.md
+ │ └── client_config.sample.json
└── win_client/
- ├── README.md # Windows service installation & configuration guide
- └── client_config.sample.json # Reference client configuration
+ ├── README.md
+ └── client_config.sample.json
```
---
-## Getting Started & Installation
+## Getting Started & Deployment
### 1. Central Server Hub
@@ -225,7 +306,7 @@ LOGAR/
```bash
pip install -r compilation/requirements.txt
```
-2. **Start the server** (generates `server_config.json` and keypair on first run):
+2. **Start the server** (generates `server_config.json`, Root CA, and server certs on first run):
```bash
python src/Server.py
```
@@ -235,153 +316,53 @@ LOGAR/
```
### 2. Windows Client Deployment
-
-#### Option A: Precompiled Standalone Executable (Recommended)
-1. Download `Win_Client.exe` (or `Win_Client.pyz`) from the repository releases.
-2. Place `client_config.json` (exported from the server) in the same directory.
-3. Run manually or schedule via Task Scheduler (every 3 hours):
- ```powershell
- .\Win_Client.exe --hours 24
- ```
-
-#### Option B: Python Source Execution
-1. Copy `Win_Client.py`, `requirements.txt`, and `client_config.json` to the target machine.
-2. Install client dependencies:
- ```powershell
- python -m pip install -r requirements.txt
- ```
-3. Run manually or schedule via Task Scheduler:
- ```powershell
- python Win_Client.py --hours 24
- ```
+1. Download `LOGAR-Client-Setup.exe` from releases and run it, or place `Win_Client.exe` and `client_config.json` in `C:\Program Files\LOGAR`.
+2. On first run with `client_config.json`, `Win_Client.exe` automatically enrolls with the hub, receives its mTLS certificates, and establishes secure streaming.
### 3. Linux Client Deployment
-
-#### Option A: Precompiled Standalone Binary (Recommended)
-1. Download `Linux_Client.bin` from the repository releases.
-2. Place `Linux_Client.bin` and `client_config.json` into `/opt/logar/` and make it executable:
+1. Run the automated installer:
```bash
- chmod +x /opt/logar/Linux_Client.bin
- ```
-3. Run via cron or systemd timer:
- ```bash
- 0 */3 * * * /opt/logar/Linux_Client.bin --hours 24
- ```
-
-#### Option B: Python Source Execution
-1. Copy `Linux_Client.py`, `requirements.txt`, and `client_config.json` to `/opt/logar/`.
-2. Install client dependencies:
- ```bash
- python3 -m pip install -r requirements.txt
- ```
-3. (Optional) Run `out/linux_client/build_bin.sh` to compile a standalone ELF binary locally if desired.
-4. Run via cron or systemd timer:
- ```bash
- 0 */3 * * * python3 /opt/logar/Linux_Client.py --hours 24
+ sudo ./compilation/install_linux_client.sh "http://:8443" ""
```
+2. The installer enrolls the client, configures `/etc/logar/certs`, and activates `logar-client.service`.
---
## Running Tests
-### 1. Component-Specific Unit Tests
-The test suite is located in `tests/` and exercises all components:
-
+### 1. Component Unit Tests
```bash
-# Run all unit tests
-python -m unittest discover -s tests
-
-# Or run component tests individually:
-python -m unittest tests/test_server.py
-python -m unittest tests/test_win_client.py
-python -m unittest tests/test_linux_client.py
+python -m unittest discover -s tests -v
```
+Runs all **22 unit tests**, covering:
+- Dynamic Root CA generation and server TLS certificate issuance.
+- Dynamic client certificate issuance with CN and authority key extensions.
+- Enrollment secret authentication, seat limits, and certificate revocation.
+- Windows & Linux event log collection, deduplication, and mTLS certificate verification.
+- 12-hour evaluation window and 4-run rule progression.
### 2. End-to-End Pipeline Integration Test
-The pipeline test exercises invalid token rejection, encrypted socket streaming, database persistence, status promotion upon the 4th run, and the Hermes API report output.
+```bash
+# 1. Initialize test configuration
+python src/Server.py --create-client-config --server-host 127.0.0.1 --server-port 9443 --client-out client_config.json
-1. **Start the server** in Shell 1 (creates `server_config.json` on first run):
- ```bash
- python src/Server.py
- ```
-2. **Export client configuration** in Shell 2 (required for testing):
- ```bash
- python src/Server.py --create-client-config --server-host 127.0.0.1 --server-port 9443 --client-out client_config.json
- ```
-3. **Execute the integration test** in Shell 2:
- ```bash
- python tests/test_pipeline.py
- ```
+# 2. Launch server in background
+python src/Server.py &
-## Continuous Integration via Gitea Actions
-
-Continuous integration is automated via [`.gitea/workflows/ci.yml`](.gitea/workflows/ci.yml) and triggers automatically on **every push** and pull request:
-1. **Syntax Compilation**: Validates all Python scripts (`src/Server.py`, `src/Win_Client.py`, `src/Linux_Client.py`, `compilation/package_dist.py`, `compilation/upload_release.py`, `tests/test_pipeline.py`, and test suites).
-2. **Component Unit Tests**: Discovers and runs all unit tests in `tests/` (`test_server.py`, `test_win_client.py`, `test_linux_client.py`).
-3. **End-to-End Pipeline Verification**: Automatically spins up the LOGAR server hub, generates test configs, runs `tests/test_pipeline.py` (testing socket authentication, 4-run rule persistence, Hermes API report, and client integrations), and shuts down the test instance.
+# 3. Run integration test
+python tests/test_pipeline.py
+```
+Tests client enrollment, secret rejection, mTLS TLS 1.3 socket handshake, warning 4-run rule promotion, immediate error promotion, and Hermes report output.
---
## Automated Releases via Gitea Actions
-Release builds are automated via two dedicated Gitea Actions workflows running concurrently on native platform runners:
-- [`.gitea/workflows/release-linux.yml`](.gitea/workflows/release-linux.yml) (`ubuntu-latest`)
-- [`.gitea/workflows/release-windows.yml`](.gitea/workflows/release-windows.yml) (`windows-latest`)
-
-### Publishing a Release
-Whenever you want to release a new version with compiled standalone binaries:
+Releases are triggered automatically on tag push (`v*`):
```bash
-git tag v1.0.2
-git push origin v1.0.2
+git tag v1.0.4
+git push origin v1.0.4
```
-*(You can also trigger builds manually via the Gitea UI using the **Run workflow** button (`workflow_dispatch`) on either workflow).*
-
-### Automated Multi-Platform Compilation:
-1. **Linux Runner** (`release-linux.yml`):
- - Compiles native Linux ELF executables: `Linux_Client.bin` and `Server.bin`.
- - Generates dedicated SHA-256 checksum files:
- - `linux_client_sha256sum` (verification for `Linux_Client.bin`)
- - `linux_agent_sha256sum` (alias for client/agent integrations)
- - `linux_server_sha256sum` (verification for `Server.bin`)
- - `SHA256SUMS_linux.txt` (summary manifest)
- - Attaches all Linux assets to the Gitea release.
-
-2. **Windows Runner** (`release-windows.yml`):
- - Compiles native Windows PE executables: `Win_Client.exe` and `Server.exe`.
- - Generates dedicated SHA-256 checksum files:
- - `win_client_sha256sum` (verification for `Win_Client.exe`)
- - `win_agent_sha256sum` (alias for client/agent integrations)
- - `win_server_sha256sum` (verification for `Server.exe`)
- - `SHA256SUMS_windows.txt` (summary manifest)
- - Attaches all Windows assets to the Gitea release.
-
-3. **Concurrent Publishing & Conflict Handling**:
- `upload_release.py` includes automatic retry and conflict resolution so concurrent Windows and Linux runners attach their respective assets to the release without collision.
-
-### Verifying Checksums
-- On Linux:
- ```bash
- sha256sum -c linux_client_sha256sum
- # or
- sha256sum -c linux_server_sha256sum
- ```
-- On Windows (PowerShell):
- ```powershell
- Get-FileHash .\Win_Client.exe -Algorithm SHA256
- Get-Content .\win_client_sha256sum
- ```
-
-### Local Packaging & Manual Upload
-You can also compile and package binaries locally anytime:
-```bash
-# Windows
-py -3.12 compilation/package_dist.py --target windows
-
-# Linux
-python3 compilation/package_dist.py --target linux
-```
-To upload local builds directly to Gitea:
-```powershell
-python compilation/upload_release.py --tag v1.0.2 --token
-```
-*(Environment variables `GITEA_TOKEN`, `GITEA_SERVER_URL`, `GITEA_REPOSITORY`, and `GITEA_REF_NAME` are also supported automatically).*
+Two dedicated workflows run in parallel:
+- **`release-linux.yml`** (`ubuntu-latest`): Compiles `Linux_Client.bin` and `Server.bin`, generating checksums.
+- **`release-windows.yml`** (`windows-latest`): Compiles `Win_Client.exe` and `Server.exe`, builds Inno Setup installers (`LOGAR-Client-Setup.exe`, `LOGAR-Server-Setup.exe`), and uploads all artifacts.