Skip to content

Architecture Overview

This page explains how ntkDeploy stores data across its shell and workspace databases, how the app starts up, how profiles are built into deployable artifacts, and how those artifacts reach Windows devices. Read this page if you want to understand why the app behaves the way it does before you start working through tutorials.

Prerequisites

  • Familiarity with Windows networking (UNC paths, SMB shares) and basic configuration management concepts.
  • See the Glossary for any unfamiliar terms.

Local-Only Data Storage

ntkDeploy stores all data locally on the administrator's workstation using embedded SQLite databases accessed through the Drift ORM. There is no cloud database, no central server, and no requirement for internet connectivity.

The app now uses a two-layer local storage model:

Storage Default location Purpose
Shell database Application Support ntkdeploy_shell.db Workspace catalog, selected workspace, theme mode, deployment defaults, artifact base directory, and workspace-scoped policy/conductor settings index
Workspace database Application Support workspaces/{workspaceId}/ntkdeploy.db Profiles, providers, assignments, rollout history, audit history, and workspace-local app settings
Artifact tree <artifact base directory>/{workspaceId}/ Built artifacts and exported files for the active workspace

On first launch after upgrading from the older single-database layout, ntkDeploy migrates the legacy ntkdeploy.db file into the default workspace and archives the old file as ntkdeploy.db.migrated after the shell and workspace records commit successfully.

This design has direct operational consequences:

Consequence Detail
No login required The app opens directly — there are no ntkDeploy cloud accounts or credentials.
Data is per-workstation and per-workspace Each administrator still has a local installation, but one ntkDeploy shell can now hold multiple isolated workspace databases for different organizations or environments.
Workspace switches replace the active runtime Switching workspaces swaps the active database path, repositories, services, and artifact root so records from one workspace do not bleed into another.
Offline capable You can create and edit profiles without network access. Deployment and policy operations require intranet connectivity to UNC shares and the Policy Manager endpoint.
Backup is your responsibility Back up the shell database plus the workspace database files you care about, or use the workspace bundle export flow for a full active-workspace snapshot.

Database Schema

The shell database contains the following primary tables:

Table Purpose
workspaces Workspace identity, display metadata, and last-selected timestamps
workspace_settings Workspace-scoped conductor and policy server settings keyed by workspace ID
shell_settings Shell-scoped settings such as theme mode, deployment defaults, artifact base directory, and the last selected workspace

Each workspace database contains the following primary tables:

Table Purpose
profiles Profile metadata — name, environment, department, priority, target platform
profile_versions Versioned settings JSON per profile
mobile_profile_versions Mobile profile metadata, stable profileId, and validation status per profile
device_groups Deployment target groups
device_group_paths Individual target paths within a device group — UNC or local absolute paths — with pathType
assignments Links between profile versions and device groups
rollout_events Per-device deployment outcome records
audit_log_entries Append-only change and action history
provider_instances Cloud provider instance configurations
app_settings Workspace-local app settings such as artifact retention days

App Boot Sequence

Every time ntkDeploy starts, the following sequence runs before any UI appears:

main() → bootstrap()
           │
           ├─ Attach FlutterError handler (logs errors to console)
           ├─ Install AppBlocObserver (logs BLoC state changes with secret redaction)
       ├─ ServiceLocator.instance.initializeShell()
       │     ├─ Open ShellDatabase (`ntkdeploy_shell.db`)
       │     ├─ Instantiate shell repositories
       │     └─ Resolve workspace paths
       ├─ WorkspaceStartupResolver.resolve()
       │     ├─ Use existing shell workspace selection when present
       │     ├─ Otherwise migrate legacy `ntkdeploy.db` into the default workspace
       │     │  and archive the old file as `ntkdeploy.db.migrated` after commit
       │     └─ Otherwise create a fresh default workspace
       ├─ ServiceLocator.instance.initializeWorkspaceSession(...)
       │     ├─ Open `workspaces/{workspaceId}/ntkdeploy.db`
       │     ├─ Instantiate workspace repositories (Profile, Provider,
       │     │  Assignment, Audit, ...)
       │     ├─ Initialise SchemaRegistry (registers all profile schemas)
       │     ├─ Instantiate workspace-scoped services (ConfigBuildService,
       │     │  DeploymentService, MobileProfileBuilder, MobileDeliveryService, ...)
       │     └─ Leave PolicyApiClient / PolicyRepository null until the active
       │        workspace has valid policy settings
           └─ runApp(App())
                 └─ AppShell (navigation, environment sidebar, global search)

The Service Locator is still a singleton, but it now owns two scopes: a long-lived shell scope and a replaceable active workspace scope. The widget tree is only constructed after the active workspace session initializes successfully. Policy server connectivity is polled only after the active workspace has valid policy settings.

When the user switches workspaces, WorkspaceCubit updates the selected workspace and WorkspaceSessionScope activates the new session before rebuilding its subtree. That activation disposes the old workspace database connection, opens the new workspace database, and rebuilds workspace-scoped repositories and services so subsequent reads come from the newly selected workspace only.


Schema-Driven Profile Editing

Profile forms in ntkDeploy are generated at runtime from registered Schema definitions rather than being hard-coded widgets. This means:

  1. The Schema Registry maps a profile type identifier (for example, "appconfig-v1") to a schema definition that declares all fields, their types, validation rules, and display labels.
  2. When you open the Create or Edit Profile form, the UI reads the active schema and renders the appropriate field widgets automatically.
  3. As you edit, each change is validated against the schema rules. The live JSON preview reflects exactly what the resulting configuration JSON will contain.
  4. A Profile Version is only marked valid when all schema rules pass. Only valid versions can be used for deployment.

This architecture means new profile types can be added to the registry without changing any form UI code.


Config Build Pipeline

When you run a deployment, the following pipeline executes before any file is written to the network:

Profile Version (valid settings JSON)
        │
        ▼
 ConfigBuildService
   ├─ Merges settings JSON
   ├─ Resolves Provider credentials → embeds under "cloudProviders"
   ├─ Requests Policy Snapshot → embeds snapshot reference + payload
   └─ Produces Artifact JSON
        │
        ▼
 DeploymentService
   ├─ Backs up existing config at target path (UNC or local)
   └─ Writes Artifact JSON to target path
        │
        ▼
 Rollout Controller / Repository
   └─ Records RolloutEvent (succeeded / failed) per device path
        │
        ▼
 AuditRepository
   └─ Appends AuditLogEntry (actor, action, entity, timestamp)

Important: Deployment artifacts include resolved Provider credentials. Treat artifact JSON files as sensitive and restrict read access on the SMB share accordingly.


Mobile Profile Build Pipeline

When a profile's Target Platform is Mobile or Both, the mobile pipeline runs in addition to or instead of the desktop pipeline:

Profile Version (valid settings JSON)
        │
        ▼
 MobileProfileBuilder
   ├─ Reads conductorAddress from SettingsRepository
   ├─ Looks up existing profileId from MobileProfileVersions
   │    (creates new UUID on first build; reuses on subsequent builds)
   ├─ Maps desktop providers → ntkMobile vault format
   │    · AmazonS3  → S3
   │    · MinIO     → S3_COMPATIBLE (forcePathStyle: true)
   │    · Wasabi    → S3_COMPATIBLE
   │    · iDriveE2  → S3_COMPATIBLE
   │    · OneDrive  → ONEDRIVE
   │    · DropBox   → DROPBOX
   │    · GoogleDrive → GDRIVE
   │    · NetworkShare → excluded (warning emitted)
   ├─ Maps vault settings (encryption, compression, sync, zero-trust)
   ├─ Preserves ABAC attributes as AND-of-OR CNF per vault
   └─ Injects conductorAddress (omits field if not configured)
        │
        ▼
 MobileProfileValidator
   └─ Validates payload against profile-schema-v1 constraints
        (vault count 1–50, vault name ≤ 100 chars, etc.)
        │
        ▼
 NtkProfileCrypto
   ├─ Serialises payload as UTF-8 JSON
   ├─ Rejects payload > 256 KiB
   ├─ Derives 256-bit key: PBKDF2WithHmacSHA256 (210,000 iterations, 16-byte salt)
   ├─ Encrypts: AES/GCM/NoPadding (12-byte IV, 128-bit auth tag)
   └─ Writes binary envelope (formatVersion 0x02)
        │
        ▼
 MobileDeliveryService
   ├─ Managed deploy: writes {targetPath}\profiles\{profileId}.ntkprofile
   │    (supports UNC paths and local absolute paths)
   └─ File export: saves via system save dialog
        │
        ▼
 AuditRepository
   └─ Appends mobile audit events (mobile_profile_build_succeeded, mobile_profile_deploy_succeeded, …)

Note: PBKDF2 key derivation runs on an isolate (compute()) to avoid blocking the UI. Derivation takes approximately 2–5 seconds. A progress indicator is shown in the deployment wizard during this step.


Deployment Path Model

ntkDeploy delivers configurations by writing files directly to target paths — either Windows network shares via SMB or local absolute paths (including USB drives). The DeploymentPathValidationService classifies and validates each path before any write occurs.

UNC/SMB paths

  1. Each Device Group can hold one or more \\server\share\path UNC addresses that point to directories on SMB shares accessible from the administrator's workstation.
  2. The Deployment Service authenticates using the workstation's current Windows credentials (pass-through authentication) — no separate deployment credentials are stored in ntkDeploy.
  3. Before writing, the service backs up any existing configuration file at the target path.
  4. The built Artifact is written to the target path.
  5. ntkDrive on each managed device reads the updated file the next time it polls its configuration path.

Local absolute paths

Device groups also accept local absolute Windows paths (C:\folder, D:\usb\configs). These are useful for:

  • Deploying to USB drives or removable media for transport to air-gapped or isolated environments.
  • Writing to a local staging directory before distributing via other means.
  • Deploying mobile .ntkprofile files to a mounted USB device for manual import on ntkMobile.

The same backup, write, and rollout event behavior applies to local paths as to UNC paths.

Path reachability can be verified proactively using the Test Connectivity action in the Device Groups screen before initiating deployment.


Deployment Verification: Preflight, Connectivity Gate, and Snapshots

Before any artifact is written to the network, ntkDeploy enforces a multi-layer verification sequence:

Check What it verifies Gate behaviour
Connectivity Gate Policy Manager /capabilities and /readyz both respond with required flags set Blocks deployment if either fails
Ownership Mappings Every UNC path in the target device group has a deviceKey → Peer ID mapping Blocks deployment if any path is unassigned
Preflight API call preflightBulkVerify returns a clean plan with no missing-plan actions Blocks deployment if actions are outstanding (operator must confirm)
Snapshot retrieval snapshotResolve + snapshotGet return a deterministic snapshot Blocks deployment if snapshot cannot be obtained

All four checks must pass before the deployment wizard advances to the final deploy step. This fail-closed design ensures that no partially-verified configuration reaches devices.


Feature Modules

The app is organized into feature modules, each responsible for a distinct area of functionality:

Module Responsibility
shell App navigation, environment sidebar, global search, header policy status badge
dashboard Statistics overview, quick actions, recent activity feed
profiles Schema-driven profile creation, editing, versioning, import/export, priority reordering; mobile target platform selector and preview
device_groups Device group management, UNC and local path configuration, connectivity testing, ownership assignment
assignments Deployment wizard, assignment creation, rollout monitoring; mobile deployment steps (password, preview, delivery method)
rollout Rollout status tracking per assignment
policy Policy Manager integration, ABAC policies, people management, enrollment queue
audit Audit log viewer with filtering and export
settings Application settings — conductor address, server endpoints, cert/key paths, UI theme

Next Steps