FreezeOS Overview

FreezeOS is a secure, immutable, fleet-managed Linux operating system designed for managed endpoints. Every device is enrolled with a central fleet server, encrypted with server-issued keys, and monitored via automatic health checks.

Key Concepts

  • Immutable Root — The base system is a read-only squashfs image. Changes are written to a persistent overlay. The core OS cannot be tampered with at runtime.
  • Two-Factor Encryption — System partitions are unlocked by server-issued tokens (automatic at boot). User data is unlocked by a PIN entered at login.
  • Fleet Management — All devices check in with the fleet server periodically. The server issues fresh tokens, collects health data, and pushes OTA updates.
  • A/B System Slots — Two system partitions enable zero-downtime updates with automatic rollback on failure.
  • Policy Enforcement — Organizations can define policies (security, network, power, restrictions) that are pushed to devices and enforced automatically.

System Requirements

ComponentMinimumRecommended
CPUx86_64, 2 cores4+ cores with AES-NI
RAM2 GB4+ GB
Storage40 GB64+ GB SSD
NetworkEthernet or WiFiEthernet
BootUEFIUEFI with Secure Boot

Quick Start

  1. Download the FreezeOS ISO from the download page
  2. Write to USB: dd if=freezeos-latest.iso of=/dev/sdX bs=4M status=progress
  3. Boot the target machine from USB
  4. Follow the enrollment wizard to register with your fleet server
  5. The installer will partition, encrypt, and install the OS automatically
  6. Reboot into your new FreezeOS installation

Installation

FreezeOS is installed from a live ISO environment. The ISO boots into an enrollment wizard that handles hardware diagnostics, fleet registration, and automated OS installation.

Writing the ISO

On Linux:

sudo dd if=freezeos-latest.iso of=/dev/sdX bs=4M status=progress conv=fdatasync

On macOS:

sudo dd if=freezeos-latest.iso of=/dev/rdiskN bs=4m
Warning

Double-check the target device. dd will overwrite the entire disk without confirmation.

Boot Menu Options

EntryDescription
FreezeOSNormal boot with KMS graphics
FreezeOS (verbose)Full kernel logging
FreezeOS (USB fix)Disables IOMMU for problematic USB controllers
FreezeOS (nomodeset)Disables KMS for GPU compatibility issues
FreezeOS (safe mode)Minimal boot with nomodeset + noacpi

Installation Process

The installation runs three sequential scripts:

  1. partition.sh (0-10%) — Creates GPT partition table with 10 partitions, sets up LUKS encryption on each, creates filesystems
  2. install-os.sh (10-90%) — Downloads the fleet system image (squashfs) from the fleet server and writes it to the system partition
  3. bootloader.sh (90-100%) — Installs GRUB EFI bootloader, builds initramfs with the FreezeOS init script, configures boot entries

First Boot

After installation, the device reboots into FreezeOS. The first boot performs several setup tasks.

Boot Sequence

  1. GRUB loads the kernel and initramfs
  2. The FreezeOS init script validates the system token
  3. System partition is LUKS-decrypted with the server key
  4. Squashfs integrity is verified via SHA-256
  5. OverlayFS mounts the immutable base + persistent overlay
  6. switch_root hands off to systemd
  7. LightDM presents the login screen
  8. User enters their PIN to unlock personal data partitions

First Login

Enter the PIN you chose during enrollment. This PIN derives the encryption key for your personal data, app data, and swap partitions via PBKDF2.

Tip

The system token refreshes automatically on each device checkin. If your device has been offline for more than 7 days, the token may expire — the device will need network connectivity to refresh.

Partition Layout

FreezeOS uses a 10-partition GPT layout. Each partition has a specific role in the security and update architecture. Several partitions are dynamically sized based on the total disk capacity (minimum 40 GB required).

#NameSizeTypeEncryptionPurpose
1ESP512 MBFAT32NoneEFI System Partition, GRUB bootloader
2/boot1 GBext4NoneKernels, initramfs, tokens, node config
3System A8 GBLUKSServer keyPrimary system slot (squashfs)
4AppsDynamicLUKSServer keyPersistent overlay (upper)
5User Storage60% of availableLUKSPIN-derived/home — personal data
6SwapRAM-sizedLUKSPIN-derivedEncrypted swap space
7BIOS Boot2 MBRawNoneLegacy GRUB (fallback)
8System B8 GBLUKSServer keySecondary system slot (A/B updates)
9App DataDynamicLUKSPIN-derivedApplication persistent data
10Recovery2 GBext4NoneRecovery environment and tools

Dynamic Sizing Algorithm

After subtracting all fixed-size partitions (ESP, /boot, System A/B, BIOS Boot, Recovery, Swap = ~19.5 GB + swap), the remaining space is called available space. Dynamic partitions scale proportionally with no caps:

PartitionFormulaMin
User Storage (Part 5)60% of available space
Apps (Part 4)25% of available space4 GB
App Data (Part 9)15% of available space4 GB
Swap (Part 6)Matches system RAM1 GB (max 16 GB)

Example Partition Sizes

Example sizes assuming 4 GB RAM (swap = 4 GB):

Disk SizeAppsApp DataSwapUser Storage
64 GB8.9 GB5.3 GB4 GB~21 GB
128 GB25.6 GB15.4 GB4 GB~61 GB
256 GB56.4 GB33.8 GB4 GB~135 GB
512 GB117.9 GB70.7 GB4 GB~283 GB
Minimum Disk

FreezeOS requires a minimum disk size of 40 GB. The installer will refuse to proceed on smaller disks.

Key Domains

  • Server-key partitions (3, 4, 8) — Unlocked automatically at boot using the key from the fleet server token. No user interaction required.
  • PIN-derived partitions (5, 6, 9) — Unlocked at login. Key is derived via PBKDF2-HMAC-SHA256(PIN, SHA256(cert) + salt, 600000, 64).
  • Unencrypted partitions (1, 2, 7, 10) — Required for boot and recovery. Contain no user data.

Boot Flow

The FreezeOS boot process is managed by a custom init script (~93KB) that runs in a minimal busybox initramfs environment.

Sequence

GRUB EFI → initramfs → Token Validate → LUKS Decrypt → SHA-256 Verify → Overlay Mount → switch_root → systemd → LightDM → PIN Unlock → Desktop

1. GRUB

Standalone EFI binary with all modules embedded. Loads kernel and initramfs from the /boot partition. Passes kernel parameters including log server URL.

2. Initramfs Init

The freezeos-init.sh script runs as PID 1 in a busybox environment. It handles:

  • Parsing kernel command line for tokens, recovery flags, log server
  • Loading crypto kernel modules (ECB → cryptd → crypto_simd → XTS → SHA512 → AES-NI)
  • Token validation (HMAC-SHA256 signature check, expiry check)
  • LUKS decryption of system and apps partitions
  • Squashfs integrity verification
  • OverlayFS mount (squashfs lower + apps upper)
  • Config injection (user, network, PAM hooks)
  • switch_root to the merged filesystem

3. Systemd

After switch_root, systemd takes over and boots normally. The freezeos-boot-success.service resets the boot attempt counter to prevent false rollbacks.

Immutable OS Model

FreezeOS uses an OverlayFS-based immutable OS design. The base system image is a read-only squashfs file that cannot be modified at runtime.

How It Works

┌──────────────────────────────────┐
│  Overlay Upper (Apps partition)  │  ← Read-Write (persistent)
├──────────────────────────────────┤
│      OverlayFS Merge Point       │  ← Unified root filesystem
├──────────────────────────────────┤
│  SquashFS Lower (System partition)│  ← Read-Only (immutable)
└──────────────────────────────────┘
  • User-installed packages and config changes write to the overlay upper on the Apps partition
  • The base system squashfs is never modified
  • OTA updates replace the squashfs image entirely
  • Safe mode boots with a tmpfs overlay, bypassing all user modifications
  • Factory reset wipes the overlay, restoring the pristine base image

A/B System Updates

FreezeOS maintains two system partitions (Slot A and Slot B) for zero-downtime updates with automatic rollback.

Update Process

  1. New squashfs image downloaded from fleet server
  2. SHA-256 integrity verified
  3. Written to the inactive slot
  4. A/B state file updated to flip active slot
  5. Device reboots into new system
  6. freezeos-boot-success.service confirms successful boot

Automatic Rollback

If the boot attempt counter exceeds 3, the init script automatically rolls back to the previous slot. This protects against bad updates that prevent the system from booting fully.

A/B State File

Located at /boot/freezeos/ab-state, this shell-sourceable file tracks:

ACTIVE_SLOT=A
SLOT_A_VERSION=2.9.86
SLOT_A_HASH=24117be33...
SLOT_B_VERSION=2.9.85
SLOT_B_HASH=abc123def...
BOOT_ATTEMPTS=0

Encryption

Every data partition on a FreezeOS device is encrypted with LUKS (Linux Unified Key Setup) using AES-XTS with 512-bit keys.

Encryption Specifications

ParameterValue
CipherAES-XTS-plain64
Key Size512 bits (256-bit AES + 256-bit XTS)
LUKS Key Size64 bytes
CertificateRSA-4096
Token SigningHMAC-SHA256
PIN Key DerivationPBKDF2-HMAC-SHA256, 600,000 iterations

Two Key Domains

Server-Controlled (System, Apps, System B)

The LUKS key is generated during enrollment and stored encrypted on the fleet server. At each checkin, the key is embedded in a signed token and delivered to the device. The init script extracts the key and unlocks these partitions automatically.

PIN-Derived (User Storage, App Data, Swap)

The LUKS key is derived from the user's PIN combined with the device certificate fingerprint:

key = PBKDF2-HMAC-SHA256(
    password = PIN,
    salt     = SHA256(DER(device_cert)) + enrollment_salt,
    iterations = 600000,
    key_length = 64 bytes
)

Token System

FreezeOS uses HMAC-SHA256 signed tokens to securely deliver LUKS encryption keys from the fleet server to devices.

Token Format

Tokens are Base64-encoded JSON with an HMAC-SHA256 signature. Each token contains:

  • node_id — The device identifier
  • key — Base64-encoded LUKS key
  • type — "system" or "apps"
  • issued_at — Token issue timestamp
  • expires_at — Token expiry timestamp
  • signature — HMAC-SHA256 of the payload

Token Lifetimes

TokenLifetimeStorage
System Token7 days/boot/freezeos/system_token.enc
Apps Token30 days/boot/freezeos/apps_token.enc
Note

Expired tokens are still accepted for key extraction — only tampered (bad signature) tokens are rejected. This means a device can boot even if it hasn't checked in recently, as long as the token hasn't been tampered with.

PIN Unlock

When a user logs in at the LightDM screen, their PIN is used to derive the encryption key for personal data partitions.

How It Works

  1. User enters PIN at LightDM login
  2. PAM hook (freezeos-data-unlock) intercepts the PIN
  3. Key derived: PBKDF2(PIN, SHA256(cert_DER) + salt, 600000, 64)
  4. LUKS unlock attempted on User Storage, App Data, and Swap partitions
  5. On success, partitions are mounted and login proceeds
  6. On failure, login is denied

Salt

A 32-byte hex salt is generated during enrollment and stored at /boot/freezeos/data.salt. Combined with the certificate fingerprint, this ensures the derived key is unique per device.

Certificates

Each FreezeOS device has an RSA-4096 client certificate issued by the fleet CA during enrollment.

Certificate Usage

  • mTLS Authentication — The client cert authenticates the device to the fleet server during checkins
  • PIN Key Derivation — The certificate fingerprint (SHA-256 of DER) is used as part of the PBKDF2 salt
  • Identity — The cert's CN contains the node ID

Certificate Renewal

Certificates are valid for 365 days. The freezeos-cert-renew service runs via systemd timer and renews certificates that expire within 2 days by contacting the fleet server's renew endpoint.

File Locations

/boot/freezeos/certs/client.crt    # Device certificate
/boot/freezeos/certs/client.key    # Private key
/boot/freezeos/certs/ca.crt        # Fleet CA certificate

Admin Security Hardening

The FreezeOS admin portal and fleet API implement defense-in-depth security controls aligned with NIST 800-53 and DISA STIG requirements.

Credential Management

All database credentials and cryptographic keys are loaded from environment variables. No passwords are stored in source code.

  • Environment file/etc/freezeos/fleet.env (mode 0640, owner:group tech:www-data)
  • PHP auto-loader — Config files auto-parse the env file via putenv()
  • Flask systemdEnvironmentFile=/etc/freezeos/fleet.env in service unit
  • Python routes — Centralized fleet/mysql_conn.py reads FLEET_MYSQL_* env vars

Security Headers

All HTTP responses include the following security headers:

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=(), usb=()
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'
Strict-Transport-Security: max-age=31536000; includeSubDomains
Cache-Control: no-store, no-cache, must-revalidate, private

Session cookies use Secure, HttpOnly, and SameSite=Strict flags.

Production Safeguards

  • Fail-fast on dev keys — Flask refuses to start in production mode (FLEET_DEBUG=0) if HMAC or master encryption keys are left at development defaults
  • 256-bit random keys — Token HMAC signing and LUKS key encryption use cryptographically random 256-bit keys
  • No shell_exec — LDAP connection tests use native PHP LDAP functions instead of shell commands
  • CSRF protection — All state-changing operations require a 256-bit CSRF token
  • Rate limiting — Login: 5 attempts / 15-minute lockout. Auth API: 5 failures / 5-minute window

NIST 800-53 Control Mapping

ControlTitleImplementation
AC-2Account ManagementAdmin user lifecycle, role assignment, deactivation
AC-3Access EnforcementRBAC permission checks on every page and API endpoint
AC-6Least Privilege5 roles: viewer, operator, auditor, admin, super_admin
AU-2Audit EventsLogin, logout, CRUD, role changes, MFA events, all admin actions
AU-3Content of Audit RecordsWho, what, when, where (IP), detail, user agent
IA-2Identification and AuthenticationBcrypt password hashing + TOTP multi-factor authentication
IA-5Authenticator ManagementPassword complexity (8+ chars, upper, digit, special), MFA recovery codes
SC-8Transmission ConfidentialityHTTPS enforced via HSTS, secure session cookies
SC-12Cryptographic Key EstablishmentAES-256-GCM for LUKS keys, HMAC-SHA256 for tokens, RSA-4096 for certificates
SC-28Protection of Information at RestMySQL TDE (InnoDB tablespace encryption), encrypted redo/undo/binlogs

Role-Based Access Control

The admin portal implements granular RBAC with 5 roles, enforced on every page and API endpoint.

Roles

RoleLevelAccess
Viewer1Read-only: dashboard, devices, hardware catalog, wiki
Auditor2Read-only on everything + audit log access
Operator3Manage devices, groups, OUs, printers, issues, wiki
Admin4Everything except role management and security settings
Super Admin5Full access including role assignment, MFA enforcement, security settings

Permission Matrix

Each action is mapped to a permission key (e.g., devices.manage) which lists allowed roles. Example permissions:

  • dashboard.view — All roles
  • devices.manage — Operator, Admin, Super Admin
  • policies.manage — Admin, Super Admin
  • users.roles — Super Admin only
  • audit.view — Auditor, Super Admin
  • security.manage — Super Admin only

Enforcement

Pages call require_permission('permission.name') after authentication. API endpoints call require_permission('permission.name', true) which returns HTTP 403 JSON instead of an HTML page. The sidebar navigation dynamically shows/hides links based on the current user's role.

Multi-Factor Authentication

FreezeOS supports TOTP-based MFA (RFC 6238) for admin portal access, meeting NIST 800-63B AAL2 requirements.

How It Works

  1. Admin navigates to MFA Settings in the sidebar
  2. Clicks Set Up Two-Factor Authentication
  3. Scans QR code with any authenticator app (Google Authenticator, Authy, 1Password, etc.)
  4. Enters the 6-digit code to verify setup
  5. Receives 8 one-time recovery codes (must be saved securely)

Login Flow with MFA

  1. Enter email + password (standard login)
  2. If MFA enabled: redirected to verification page
  3. Enter 6-digit TOTP code or a one-time recovery code
  4. Session established with mfa_verified=true flag

Technical Details

  • Algorithm: HMAC-SHA1 with 30-second time step (RFC 6238 compliant)
  • Secret: 20-byte random, stored encrypted in database
  • Window: ±1 period tolerance for clock skew
  • Recovery codes: 8 codes, 8-character hex, single-use
  • MFA timeout: Verification must complete within 5 minutes of password entry
  • Audit trail: All MFA events logged (setup, disable, recovery code use, failed attempts)

Audit Logging

Every admin action is recorded in an immutable audit log, meeting NIST 800-53 AU-2/AU-3/AU-12 controls.

What is Logged

CategoryEvents
Authenticationlogin, logout, login_failed, login_rate_limited, login_sso
MFAmfa_setup, mfa_disable, mfa_failed, mfa_recovery_used, mfa_recovery_regen
Devicesrevoke, suspend, restore, move (OU), group add/remove, policy toggle
Policiescreate, update, delete, assign, unassign, toggle
Organizationsmember add/remove/promote/demote, policy toggle
Printerscreate, update, delete, deploy, undeploy
Identityprovider change, LDAP test, Entra test
Usersaccount create, role change

Audit Record Fields

id           BIGINT     Auto-increment (immutable)
user_id      INT        Admin who performed the action
username     VARCHAR    Username at time of action
action       VARCHAR    Action verb (login, create, update, delete, revoke, etc.)
target_type  VARCHAR    Entity type (node, policy, user, org, session, etc.)
target_id    VARCHAR    Entity identifier (UUID, database ID)
detail       TEXT       Human-readable description
ip_address   VARCHAR    Source IP address
user_agent   VARCHAR    Browser/client user agent string
created_at   DATETIME   Timestamp (UTC)

Viewing the Audit Log

The audit log is accessible at System > Audit Log in the sidebar (requires Auditor or Super Admin role). It supports filtering by action, target type, username, date range, and free-text search.

Database Encryption at Rest

All database storage is encrypted using MySQL 8.0 Transparent Data Encryption (TDE), meeting NIST 800-53 SC-28.

What is Encrypted

  • All 35 InnoDB tablespaces — Every table uses ENCRYPTION='Y'
  • InnoDB redo logsinnodb_redo_log_encrypt=ON
  • InnoDB undo logsinnodb_undo_log_encrypt=ON
  • Binary logsbinlog_encryption=ON
  • New tablesdefault_table_encryption=ON (automatic)

Key Management

Encryption keys are managed by MySQL's keyring_file plugin. The master encryption key is stored in /var/lib/mysql-keyring/keyring (mode 0750, owned by mysql). Individual tablespace keys are encrypted by the master key and stored within the tablespace headers.

LUKS Keys (Application-Level)

In addition to database-level TDE, all LUKS encryption keys stored in the nodes table are encrypted with AES-256-GCM before database storage. The encryption master key is loaded from the FLEET_MASTER_KEY environment variable (256-bit random).

Enrollment

Device enrollment registers a new device with the fleet server, generates encryption keys, issues a client certificate, and provisions the device with tokens.

Enrollment Pipeline

  1. Boot the ISO on the target device
  2. The enrollment wizard runs hardware diagnostics
  3. User provides fleet server URL and credentials (or uses pre-configured URL)
  4. Device sends hardware profile to fleet server
  5. Fleet server generates LUKS keys, signs a client certificate, creates tokens
  6. Device receives tokens + certificate + node configuration
  7. Installer partitions the disk and installs the OS
  8. Device reboots and begins normal checkin cycle

Node Configuration

After enrollment, /boot/freezeos/node.json contains:

{
    "node_id": "abc123...",
    "fleet_url": "https://os.freeze2k.net",
    "machine_serial": "SERIALNO",
    "image_version": "2.9.86"
}

Device Checkin

Enrolled devices periodically check in with the fleet server to refresh tokens, report health data, and receive updates.

What Happens During Checkin

  1. Device POSTs to /api/fleet/checkin with node_id and optional health card
  2. Server verifies the device exists and is not revoked/suspended
  3. Server issues fresh system and apps tokens
  4. Server returns merged policies for the device
  5. Device stores new tokens in /boot/freezeos/

Checkin Triggers

  • Boot — Every boot triggers a checkin during init
  • Timer — Periodic checkin via systemd timer
  • Manual — Can be triggered from the system info panel

Health Monitoring

FreezeOS includes a built-in health check system that scores device health from 0-100 across 17+ component tests.

Health Check Categories

  • CPU — Temperature, frequency, load
  • Memory — Usage, errors, swap pressure
  • Storage — SMART data, disk usage, I/O performance
  • GPU — Driver status, rendering tests
  • Network — Connectivity, DNS resolution, fleet server reachability
  • Battery — Capacity, cycle count, charge health
  • USB — Controller status, device enumeration

Health cards are submitted with each checkin. The fleet portal displays health scores with color-coded badges (green >= 80, yellow >= 60, red < 60).

Policy Management

Organizations can create and assign policies to manage device configuration across their fleet.

Policy Categories

CategorySettings
Date/TimeNTP enable/disable, timezone, custom NTP servers, RTC local time mode
DisplayWallpaper URL & style (stretched/centered/tiled/zoomed), lock wallpaper, DPMS enable, standby timeout
ProxyProxy mode (none/manual/auto), HTTP/HTTPS/FTP proxy, no-proxy bypass list, PAC URL
SecurityScreen lock & delay, password min length/uppercase/digit, USB storage, SSH, firewall (UFW)
PowerSuspend on idle, lid close action, power button action, suspend when docked, CPU governor
NetworkWiFi on/off, hotspot, custom DNS servers, DNS-over-TLS, require VPN, allowed SSIDs whitelist
SoftwareAPT allowed, Flatpak allowed, blocked executables list, browser extensions, forced homepage
UpdatesAuto-update enable, schedule (daily/weekly/monthly), auto-reboot after update, update channel
RestrictionsTerminal, settings panel, file manager, external drives, printing, camera, microphone
Custom CommandsUp to 3 shell commands, custom script URL, cron scheduling expression

How Policies Work

  1. Admin creates a policy in the web portal and configures settings
  2. Policy is assigned to specific devices via the "Assign Devices" page
  3. During checkin, the device receives merged policies (higher priority wins)
  4. The freezeos-policy-enforce.sh script applies settings idempotently
  5. A systemd timer re-checks policies every 30 minutes

Policy Priority & Merging

Each policy has a priority number (0-999). When a device has multiple policies assigned, the fleet server merges them:

  • Settings from higher priority policies override lower priority ones
  • Settings not defined in any assigned policy use system defaults
  • The merged result is a single flat JSON object delivered to the device

Enforcement Cycle

Policy enforcement runs on a continuous cycle:

  1. Timer fires — A systemd timer triggers freezeos-policy-fetch.sh every 30 minutes
  2. Fetch policies — The script calls /api/fleet/policies?node_id={id} to get merged policies
  3. Hash check — The fetched JSON is hashed (SHA-256) and compared against the last-applied hash
  4. Enforce if changed — If the hash differs (or no prior hash exists), freezeos-policy-enforce.sh applies all settings idempotently
  5. Store hash — The new hash is saved for future comparison

Enforcement also runs on every device boot (via checkin) and can be triggered manually.

Custom Commands

The Custom Commands category allows organizations to run arbitrary shell commands on managed devices. This is useful for org-specific configuration that doesn't fit into standard policy categories.

SettingDescription
Custom Command 1-3Shell commands executed during each policy enforcement cycle
Custom Script URLURL to a shell script that is downloaded and executed on enforcement
Custom CronCron expression (e.g. */30 * * * *) for scheduling custom command execution independently of the enforcement cycle
Warning

Custom commands run as root. Use with caution. Script URLs must be trusted — they are downloaded and executed with full system privileges.

OTA Updates

FreezeOS receives over-the-air system updates from the fleet server. Updates replace the entire squashfs system image on the inactive A/B slot.

Update Pipeline

  1. Device queries /api/fleet/images/latest for the newest version
  2. If newer than current, downloads the squashfs image
  3. SHA-256 hash verified against server-provided hash
  4. Image written to the inactive system slot
  5. A/B state flipped to new slot
  6. Device reboots
  7. If boot fails 3 times, automatic rollback to previous slot

Update Channels

  • stable — Production-tested releases
  • beta — Pre-release testing
  • nightly — Latest builds

Recovery Modes

FreezeOS provides multiple recovery options for when things go wrong.

ModeHow to AccessDescription
Network RecoveryGRUB menu or freezeos.recovery=1Downloads fresh system image from fleet server
Safe ModeGRUB menu or freezeos.safemode=1Boots with tmpfs overlay, bypassing all user changes
Automatic RollbackAutomatic after 3 failed bootsReverts to previous A/B slot
Manual Rollbackfreezeos-system-update --rollbackManually switch to previous slot

Network Recovery

Network recovery re-provisions the device by downloading a fresh system image from the fleet server.

Process

  1. Select "FreezeOS Network Recovery" from the GRUB menu
  2. Init script detects freezeos.recovery=1 kernel parameter
  3. Establishes network connectivity (Ethernet or WiFi)
  4. Contacts fleet server, performs checkin to get fresh tokens
  5. Downloads latest system image
  6. Writes to active system slot
  7. Reboots into recovered system

Safe Mode

Safe mode boots with a tmpfs (RAM-based) overlay instead of the persistent Apps partition overlay. This bypasses all user-installed packages and configuration changes.

When to Use

  • A user-installed package breaks the system
  • Configuration change prevents login
  • Need to diagnose issues without user modifications

Changes made in safe mode are lost on reboot (they're in RAM only).

Factory Reset

Factory reset wipes the persistent overlay (Apps partition), restoring the device to the base squashfs image state.

Warning

Factory reset removes all user-installed packages, configuration changes, and overlay data. User personal data on the User Storage partition is not affected.

Desktop Environment

FreezeOS uses XFCE 4 with a custom "Tron" theme featuring cyan glow accents, dark backgrounds, and wireframe icons.

Included Applications

  • FreezeOS Diagnostics — GTK3 hardware health check UI
  • FreezeOS System Info — GTK3 system information panel
  • FreezeOS Commander — Fleet management and diagnostics terminal
  • System Update — OTA update GUI wizard
  • Firefox — Web browser (policy-configurable)
  • Thunar — File manager
  • XFCE Terminal — Terminal emulator

Diagnostics Tools

FreezeOS includes built-in diagnostic tools for hardware testing and system monitoring.

FreezeOS Diagnostics

A GTK3 application accessible from XFCE Settings Manager that runs comprehensive hardware tests and generates a health score.

FreezeOS Commander

A terminal-based fleet management tool that provides:

  • Device status and fleet server connectivity
  • Network diagnostics (ping, DNS, fleet reachability)
  • Manual checkin and token refresh
  • System update management
  • Log submission

Log Submission

Devices can submit diagnostic logs to the fleet server for remote debugging.

Usage

report_log              # Submit all logs
report_log kernel       # Submit kernel logs only
report_log network      # Submit network logs only

Submitted logs appear in the web portal under "My Logs" and expire after 30 days. Organization accounts can view logs from all member devices.

Web Portal

The FreezeOS web portal at os.freeze2k.net provides fleet management through a browser.

Portal Pages

PageAccessDescription
My DevicesAll usersView, deauthorize, restore, delete devices
My LogsAll usersView submitted diagnostic logs
AccountAll usersProfile info, password change
OrganizationOrg accountsAdd/remove members, manage roles
PoliciesOrg accountsCreate, edit, assign policies to devices
AdminAdmin accountsManage all users, orgs, devices, policies

Account Types

FreezeOS has three account types, each with escalating levels of access and control over the fleet.

User (Individual)

  • Enroll and manage own devices
  • View own device health, logs, and status
  • Change own password and account settings
  • Submit and view own diagnostic logs

Organization

Everything a User can do, plus:

  • Create an organization and invite members by email
  • View all devices across the organization
  • View aggregated logs from all member devices
  • Create, edit, and assign policies to member devices
  • Manage organization members (add, remove, promote)

Admin (Global)

Everything an Organization can do, plus:

  • Manage all users, organizations, and devices system-wide
  • Change any user's account type (user, org, admin)
  • Suspend or delete any account
  • View all logs across the entire fleet
  • Create and manage global policies
  • Manage system images and OTA updates

Permissions Matrix

ActionUserOrgAdmin
Enroll devices
View own devices
View own logs
Manage own account
Create organization
Add/remove members
View member devices
View member logs
Create/assign policies
Manage all users
Change account types
Suspend/delete accounts
View all logs
Manage system images

Organizations

Organization accounts can manage multiple users and their devices under a single umbrella.

Features

  • Member Management — Add users by email, assign admin or member roles
  • Aggregated Logs — View logs from all member devices with member filter
  • Policy Management — Create policies and assign to any member's device
  • Device Visibility — See all devices across the organization

Member Roles

RoleDescription
OwnerThe organization account itself. Full control over the org, its members, policies, and all member devices. Cannot be removed.
AdminCan manage other members (promote/demote/remove), create and assign policies, view all devices and logs
MemberDevices are visible to the org. Policies can be applied to their devices. Can view own devices and logs only.

Organization Scope

An organization has visibility and control over member devices as follows:

  • Device visibility — The org can see all devices enrolled by its members, including health scores, last checkin time, and system version
  • Log access — The org can view diagnostic logs submitted by any member device, with member-level filtering
  • Policy assignment — The org can assign policies to any member's device. Policies are enforced automatically on the device.
  • Device actions — The org can deauthorize, restore, or trigger updates on member devices

Policy Assignment Flow

  1. Org admin creates a policy in the portal with desired settings
  2. Org admin navigates to the policy's "Assign Devices" page
  3. Select one or more member devices to assign the policy to
  4. On the next device checkin, the fleet server merges all assigned policies (by priority) and returns the result
  5. The device's freezeos-policy-enforce.sh applies the merged settings

API Reference

The fleet server exposes a REST API for device management.

Endpoints

MethodEndpointDescription
POST/api/fleet/enrollEnroll a new device
POST/api/fleet/login-enrollEnroll with existing account
POST/api/fleet/checkinDevice checkin, token refresh
GET/api/fleet/images/latestGet latest system image metadata
GET/api/fleet/images/download/{version}Download system image
GET/api/fleet/policies?node_id={id}Get merged policies for a device
POST/api/fleet/update-reportReport update status
POST/api/fleet/submit-logSubmit diagnostic logs
GET/api/fleet/recovery/latestGet recovery image metadata
GET/api/fleet/scripts/latestGet latest scripts package
POST/api/fleet/re-provisionRe-provision a device
POST/api/fleet/deauthDeauthorize a device
GET/healthServer health check