Skip to content

Device Management Toolkit Architecture Deep Dive

Ganesh Raikhelkar edited this page Aug 19, 2026 · 23 revisions

A comprehensive technical guide covering microservice deployment, device lifecycle, CIRA connectivity, command execution flows, WSMAN protocol, and E2E TLS activation.

Table of Contents

  1. Deployment Models & Component Overview
  2. System Overview & Deployment Architecture
  3. Microservice Roles & Responsibilities
  4. How RPC Operates Internally on the Device
  5. RPC-Go to RPS Communication
  6. Device Lifecycle: Activation to Remote Manageability
  7. CIRA Connection: Establishment & Maintenance
  8. MPS Router: Scaled Deployment & Connection Routing
  9. Command Execution: API Request to Device Action
  10. WSMAN Protocol
  11. APF Protocol Overview
  12. KVM, SOL & IDER: Redirection Features
  13. Data Storage: Vault vs Database
  14. Production Integration Guide
  15. Security Architecture
  16. Appendix: Port & Protocol Reference

1. Deployment Models & Component Overview

DMT provides two deployment models: a cloud deployment (current, production-ready) and an enterprise on-premises deployment (work in progress).

  • Cloud Deployment — the v2 branch of the deployment repo. Microservice-based, Docker Compose orchestrated, designed for remote management of distributed AMT devices over the internet.
  • Enterprise Deployment — On-premises focused, uses two standalone binaries: Console (server) and RPC-Go in local mode. No cloud infrastructure needed — communicates with AMT directly on the LAN.

1.1 Deployment Models

flowchart TB

    DMT["Device Management Toolkit"]

    DMT --> Cloud["Cloud Deployment"]
    DMT --> Enterprise["Enterprise Deployment"]
Loading

1.2 Cloud Deployment (v2 — Current)

flowchart TB

    Cloud["Cloud Deployment - v2 (Current Deployment)"]

    Cloud --> MPSRouter["MPS Router"]
    Cloud --> MPS["MPS"]
    Cloud --> RPS["RPS"]
    Cloud --> RPC["RPC-Go"]

    Cloud --> SWUI["Sample Web UI"]
    Cloud --> EA["Enterprise Assistant"]

    SWUI --> UITAngular["UI Toolkit Angular"]
    UITAngular --> UIT["UI Toolkit"]

    MPS --> WSMAN["WSMAN-Messages"]
    RPS --> WSMAN

    RPC --> GoWSMAN["Go-WSMAN-Messages"]
Loading
Component Repo Role
MPS mps Management Presence Server — maintains CIRA connections, REST API, WebSocket relay
RPS rps Remote Provisioning Server — activates devices, applies profiles
MPS Router mps-router Device-affinity TCP proxy for horizontal MPS scaling
RPC-Go rpc-go Agent on managed device — communicates with AMT via MEI
Sample Web UI sample-web-ui Angular reference management console
Enterprise Assistant Assists with enterprise integration workflows
UI Toolkit Angular ui-toolkit-angular Reusable KVM/SOL/IDER Angular components
UI Toolkit ui-toolkit Core rendering logic (framework-agnostic)
WSMAN-Messages wsman-messages TypeScript SOAP/XML message construction for AMT
Go-WSMAN-Messages go-wsman-messages Go WSMAN message construction + transport + digest auth

1.3 Enterprise Deployment (On-Premises — Work in Progress)

flowchart TB

    Enterprise["Enterprise Deployment"]

    Enterprise --> Console["Console"]
    Enterprise --> RPC["RPC-Go"]

    Enterprise --> SWUI["Sample Web UI"]
    Enterprise --> EA["Enterprise Assistant"]

    SWUI --> UITAngular["UI Toolkit Angular"]
    UITAngular --> UIT["UI Toolkit"]

    Console --> GoWSMAN["Go-WSMAN-Messages"]
    RPC --> GoWSMAN
Loading

The enterprise model replaces MPS/RPS/Router with a single Console binary (Go) that manages devices directly on the LAN. No CIRA tunnel needed — Console communicates with AMT over local WSMAN (ports 16992/16993) using go-wsman-messages.

2. System Overview & Deployment Architecture

2.1 Component Map

DMT Cloud deployment is composed of the following core microservices, deployable via Kubernetes (EKS, AKS) for production or Docker Compose for quick setups:

graph TB
    subgraph External["External Network"]
        Client[API Client / Browser]
    end

    subgraph Device["Client Machine (vPro/ISM)"]
        RPC["RPC-Go<br/>(OS Layer)"]
        AMT["Intel AMT<br/>(Firmware Layer)"]
    end

    subgraph Cloud["Cloud Services"]
        Kong["Kong API Gateway<br/>:443 HTTPS<br/>JWT · CORS · TLS termination"]

        subgraph Core["Core Services"]
            MPS["MPS<br/>Management Presence Server<br/>:4433 CIRA (TLS+APF)<br/>:3000 REST API + WS Relay"]
            RPS["RPS<br/>Remote Provisioning Server<br/>:8081 REST API<br/>:8080 WebSocket (activation)"]
            Router["MPS Router<br/>:8003<br/>Device-affinity TCP proxy"]
        end

        subgraph Backing["Backing Services (3rd Party)"]
            PG["PostgreSQL :5432<br/>rpsdb + mpsdb"]
            Vault["Vault :8200<br/>Secrets & Certs"]
        end

        WebUI["Sample Web UI<br/>nginx :80"]
    end

    RPC -->|"LMS (APF) :16992/16993"| AMT
    Client -->|HTTPS :443| Kong
    RPC -->|"WSS :443 /activate"| Kong
    AMT -->|"TLS :4433 (CIRA)"| Kong
    Kong -->|/mps/*| Router
    Kong -->|/mps/login, /mps/ws/*| MPS
    Kong -->|/rps/*| RPS
    Kong -->|/activate, /deactivate| RPS
    Kong -->|/| WebUI
    Kong -->|":4433 TCP passthrough"| MPS
    Router -->|Route to correct instance| MPS
    RPS -->|POST /api/v1/devices| MPS
    RPS --> PG
    RPS --> Vault
    MPS --> PG
    MPS --> Vault

    %% DMT-owned components - Blue
    style MPS fill:#1565C0,color:#fff
    style RPS fill:#1976D2,color:#fff
    style Router fill:#1E88E5,color:#fff
    style WebUI fill:#2196F3,color:#fff
    style RPC fill:#42A5F5,color:#fff

    %% 3rd party / external - Gray
    style Kong fill:#616161,color:#fff
    style PG fill:#616161,color:#fff
    style Vault fill:#616161,color:#fff
    style Client fill:#616161,color:#fff
    style AMT fill:#616161,color:#fff

    %% Device context
    style Device fill:#EEEEEE,color:#000
    style Cloud fill:#ffffff,color:#000,stroke:#1565C0
    style Core fill:#E3F2FD,color:#000
    style Backing fill:#FAFAFA,color:#000
    style External fill:#FAFAFA,color:#000
Loading

2.2 Inter-Service Communication

graph LR
    Client[Client / Browser] -->|":443 HTTPS"| Kong
    RPC[RPC-Go] -.->|":443 WSS /activate"| Kong
    AMT[Intel AMT] ==>|":4433 TLS (CIRA)"| Kong

    Kong -->|":8003 HTTP"| Router[MPS Router]
    Kong -->|":3000 HTTP"| MPS
    Kong -->|":8081 HTTP"| RPS
    Kong -->|":80 HTTP"| WebUI[Sample Web UI]
    Kong ==>|":4433 TCP passthrough"| MPS
    Router -->|":3000 HTTP"| MPS
    RPS -->|":3000 HTTP"| MPS
    MPS --> PG[PostgreSQL :5432]
    RPS --> PG
    MPS --> Vault[Vault :8200]
    RPS --> Vault

    style MPS fill:#1565C0,color:#fff
    style RPS fill:#1976D2,color:#fff
    style Router fill:#1E88E5,color:#fff
    style WebUI fill:#2196F3,color:#fff
    style RPC fill:#42A5F5,color:#fff
    style Kong fill:#616161,color:#fff
    style PG fill:#616161,color:#fff
    style Vault fill:#616161,color:#fff
    style Client fill:#616161,color:#fff
    style AMT fill:#616161,color:#fff
Loading

External → Cloud

Port Protocol From To Purpose
443 HTTPS Client / Browser Kong All API calls, WebSocket relay, UI — Kong terminates TLS
443 WSS RPC-Go (OS) Kong → RPS :8080 Activation/deactivation via /activate, /deactivateKong terminates TLS
4433 TLS + APF Intel AMT (firmware) Kong → MPS Persistent CIRA connection — Kong passes TCP through, MPS handles TLS

API Gateway → Services

Port Protocol From To Purpose
4433 TCP passthrough Kong MPS Forward CIRA TLS connections as-is — MPS handles TLS termination
8003 HTTP Kong MPS Router Route device-specific API requests to correct MPS instance
3000 HTTP Kong MPS Auth endpoints (/mps/login), WebSocket relay (/mps/ws/*)
8081 HTTP Kong RPS Profile/config management API (/rps/*)
8080 HTTP/WS Kong RPS Activation/deactivation WebSocket — routed from /activate, /deactivate on :443
80 HTTP Kong Sample Web UI Serve Angular SPA

Service ↔ Service

Port Protocol From To Purpose
3000 HTTP MPS Router MPS Forward device-affinity routed requests
3000 HTTP RPS MPS Register device after activation (POST /api/v1/devices)

Services → Infrastructure Dependencies

Port Protocol From To Purpose
5432 TCP MPS PostgreSQL Device inventory, connection state (mpsdb)
5432 TCP RPS PostgreSQL Profiles, CIRA configs, domains (rpsdb)
8200 HTTP MPS Vault Device MPS passwords, AMT credentials
8200 HTTP RPS Vault Provisioning certs, device passwords

Device (On-Box)

Port Protocol From To Purpose
443 WSS RPC-Go Kong (cloud) Outbound activation/deactivation connection to cloud
16992/16993 APF (LMS) RPC-Go Intel AMT (firmware) Local MEI communication on the client machine

2.3 Database Layout

Two separate PostgreSQL databases share the same server:

Database Owner Key Tables
rpsdb RPS profiles, ciraconfigs, domains, wirelessconfigs, ieee8021xconfigs, proxyconfigs
mpsdb MPS, MPS Router devices (GUID, status, mpsInstance, tags, tenantId, lastSeen, deviceInfo)

3. Microservice Roles & Responsibilities

3.1 RPS — Remote Provisioning Server

Purpose: Activates (provisions) AMT devices and applies configuration profiles.

Capability Details
Activation CCM (Client Control Mode) and ACM (Admin Control Mode)
Configuration CIRA, TLS, WiFi, 802.1x, proxy, KVM/SOL/IDER features
Deactivation Unprovision devices remotely
Maintenance Sync clock, hostname, IP, password rotation, device info
Profile Management CRUD for AMT profiles, CIRA configs, domains, wireless profiles
Device Registration After activation, RPS calls POST /api/v1/devices on MPS to add the device

Runtime behavior: RPS runs an Express REST API (port 8081) for profile management and a WebSocket server (port 8080) for RPC client connections. The activation logic is driven by XState v5 state machines that orchestrate dozens of WSMAN calls against the device.

Key interaction with MPS:

  • Fetches MPS root CA certificate from Vault (path MPSCerts) for CIRA configuration
  • Adds the device to MPS via POST /api/v1/devices (sends GUID, hostname, mpsusername, tags, tenantId, deviceInfo)
  • Checks tenant access on already-activated devices via GET /api/v1/devices/{uuid}

3.2 MPS — Management Presence Server

Purpose: Maintains persistent connections to AMT devices and provides the management API.

Capability Details
CIRA Connections Accepts and manages persistent TLS connections from devices via APF protocol
REST API Power control, feature management, certificates, audit/event logs, hardware info
WebSocket Relay Bridges browser WebSocket connections to AMT redirection channels (KVM/SOL/IDER)
Device Inventory Tracks connection status, last seen timestamps, device metadata in PostgreSQL
Multi-Instance Supports horizontal scaling via MPS Router for connection routing

Two servers in one process:

Server Port Clients
MPS Server 4433 AMT devices (CIRA over TLS)
Web Server 3000 API clients, Web UI, MPS Router

3.3 MPS Router

Purpose: Routes API requests to the correct MPS instance in multi-instance deployments. See Section 8 for the detailed scaling mechanism.

4. How RPC Operates Internally on the Device

4.1 Architecture on the Device

RPC-Go is a command-line tool (or shared library) that runs on the managed device. In remote mode, it acts as a transparent byte bridge — one WSS connection to the cloud, one TCP connection to AMT via LMS. It decodes base64 payloads from JSON messages and forwards the raw bytes to LMS. In local mode, it constructs WSMAN messages itself using go-wsman-messages and sends them to AMT via the same LMS or LME paths.

graph TB
    subgraph Cloud["Cloud"]
        Kong["Kong :443"]
        RPS["RPS :8080"]
    end

    subgraph Device["Managed Device (OS)"]
        subgraph RPC["RPC-Go Process"]
            CLI["CLI Parser<br/>(cobra)"]
            Exec["Command Executor<br/>activate / deactivate /<br/>configure / maintenance / amtinfo"]

            subgraph RemoteMode["Remote Mode (-u wss://...)"]
                WS["WebSocket Client<br/>(gorilla/websocket)"]
                Decode["Decode base64 payload<br/>to raw bytes"]
            end

            subgraph LocalMode["Local Mode (-local)"]
                WSMANLib["go-wsman-messages<br/>(HTTP/SOAP client,<br/>constructs WSMAN XML)"]
            end

            subgraph LMLayer["Local Management Interface"]
                LMS_Conn["LMS Connection<br/>(TCP socket to LMS daemon)<br/>preferred"]
                LME_Conn["LME Connection<br/>(APF over MEI)<br/>fallback when LMS not running"]
            end

            PTHI_Cmd["PTHI Commands<br/>(binary: UUID, version,<br/>cert hashes, control mode)"]
        end

        LMS["Intel LMS Daemon<br/>(separate system service)<br/>TCP listener on localhost"]
        HECI["HECI / MEI Driver<br/>(kernel)"]
    end

    subgraph ME["Intel Management Engine (Hardware)"]
        AMT["Intel AMT Firmware<br/>:16992 · :16993 (WSMAN)<br/>:16994 (KVM) · :16995 (SOL) · :16996 (IDER)"]
    end

    %% Cloud connections
    WS <-->|"JSON over WSS"| Kong
    Kong <-->|"JSON over WS"| RPS

    %% CLI flow
    CLI --> Exec
    Exec --> RemoteMode
    Exec --> LocalMode
    Exec --> PTHI_Cmd

    %% Remote mode: decode then forward
    WS -->|"base64 payload<br/>from JSON"| Decode
    Decode -->|"raw bytes"| LMLayer

    %% Local mode: WSMAN HTTP to LMS or LME
    WSMANLib -->|"HTTP POST<br/>/wsman"| LMLayer

    %% LM connections
    LMS_Conn -->|"TCP"| LMS
    LME_Conn -->|"APF bytes"| HECI

    %% PTHI (common to both modes, direct to driver)
    PTHI_Cmd -->|"IOCTL"| HECI

    %% LMS daemon to ME
    LMS --> HECI

    %% ME
    HECI --> AMT

    %% Styling
    style RPC fill:#FAFAF0,color:#000
    style ME fill:#616161,color:#fff
    style Cloud fill:#FAFAF0,color:#000
    style LMS fill:#616161,color:#fff
Loading

Key points:

  • In remote mode, rpc-go maintains two simultaneous connections: WSS to cloud (left) and TCP to LMS (right). It decodes base64 from JSON messages and forwards raw bytes to LMS, and base64-encodes LMS responses back into JSON for the cloud.
  • In local mode, rpc-go constructs WSMAN HTTP/SOAP messages using go-wsman-messages and sends them to LMS over HTTP, or directly via LME/MEI if LMS isn't running.
  • PTHI commands are common to both modes — used at startup to gather device info (UUID, version, cert hashes, control mode). They call the HECI/MEI driver directly.
  • LMS (Intel Local Management Service) is a separate OS daemon — not part of rpc-go. It provides the TCP socket interface on localhost that proxies into AMT firmware.
  • LME (via MEI) is the fallback path when LMS is not installed or not running. RPC-Go speaks APF protocol directly over the HECI driver.

4.2 Hardware Interface Stack

Layer Interface Protocol Purpose
HECI pkg/heci/ IOCTLs to MEI device Raw byte transport to Management Engine
PTHI pkg/pthi/ Binary commands over HECI AMT host commands (UUID, version, control mode, cert hashes, unprovision)
WSMAN go-wsman-messages HTTP/SOAP over LMS or LME Full AMT configuration (activation, CIRA, TLS, WiFi, etc.)

Three MEI client GUIDs are used:

Client GUID Purpose
PTHI {12F80028-...} Primary provisioning commands
LME {6733A4DB-...} Local Manageability Engine (APF protocol for WSMAN)
Watchdog {05B79A6F-...} AMT operational state, TLS enforcement check

5. RPC-Go to RPS Communication

5.1 Connection & Security Model

RPC-Go connects to RPS over a secure WebSocket (WSS) through Kong on port 443. The connection path is:

RPC-Go → WSS :443 → Kong (TLS termination) → WS :8080 → RPS

Authentication model: The RPC-Go to RPS WebSocket connection itself does not carry API key or mutual TLS credentials. ISVs are expected to authenticate the device through their own agent before initiating the RPC-Go activation flow. The ISV agent establishes trust and authorization first, then connects RPC-Go to RPS over the already-authenticated session.

TLS certificate verification (-n flag):

Flag Behavior Use Case
Without -n RPC-Go verifies Kong's TLS certificate against system trust store Production — ISV provides a valid certificate on Kong
With -n RPC-Go skips certificate verification (InsecureSkipVerify=true) Reference/dev setup — Kong uses a self-signed certificate

Note for ISVs: The reference deployment uses -n because Kong ships with a self-signed certificate. In production, replace Kong's certificate with your own CA-signed certificate and remove the -n flag. See Kong documentation for configuring custom certificates.

5.2 ACM Activation with E2E TLS (AMT 11–18, --tls-tunnel)

The entire ACM activation is a single /activate WebSocket session. The device cannot be activated directly to ACM — it must first be activated to CCM, then TLS certificates are added to AMT (which enables TLS and makes AMT listen on :16993), then rpc-go switches to port 16993 for E2E TLS communication, and finally ACM elevation occurs over the encrypted channel.

sequenceDiagram
    autonumber

    box Client Machine
        participant AMT as AMT<br/>LMS :16992
        participant RPC as RPC-Go<br/>Byte-forwarding proxy
    end

    box Cloud
        participant Kong as Kong<br/>API Gateway :443
        participant RPS as RPS<br/>:8080
    end

    Note over RPC,Kong: RPC-Go to Kong is JSON over WSS
    Note over Kong,RPS: Kong to RPS is JSON (WSS terminated at Kong)
    Note over AMT,RPC: RPC-Go to AMT is non-TLS (via LMS on port 16992)

    RPC->>Kong: JSON activate message over WSS (with --tls-tunnel)
    Kong->>RPS: Forward JSON activate message

    Note left of RPS: method=activate
    Note left of RPS: payload.tlsTunnel=true
    Note left of RPS: payload.profile=acm

    RPS->>RPS: Resolve ACM profile, start XState machine

    Note over AMT,RPS: Phase 1 — CCM Activation (non-TLS :16992)

    loop WSMAN round-trips over non-TLS LMS :16992
        RPS->>Kong: JSON {method:"wsman", payload: base64(WSMAN)}
        Kong->>RPC: Forward JSON over WSS
        RPC->>AMT: Decode base64, forward to LMS :16992
        AMT-->>RPC: WSMAN response
        RPC-->>Kong: JSON {method:"response", payload: base64(response)} over WSS
        Kong-->>RPS: Forward JSON
    end

    Note over RPS: CCM activation complete

    Note over AMT,RPS: Phase 2 — Add TLS Certs to AMT (still over non-TLS :16992)

    loop Add TLS certificates and enable TLS via WSMAN
        RPS->>Kong: JSON {method:"wsman", payload: base64(TLS cert WSMAN)}
        Kong->>RPC: Forward JSON over WSS
        RPC->>AMT: Decode base64, forward to LMS :16992
        AMT-->>RPC: WSMAN response
        RPC-->>Kong: JSON {method:"response", payload: base64(response)} over WSS
        Kong-->>RPS: Forward JSON
    end

    Note over AMT: TLS configured. AMT now listens on :16993.

    Note over AMT,RPS: Phase 3 — Port Switch (rpc-go switches to :16993)

    RPS->>Kong: JSON {method:"port_switch", payload:{port:"16993"}}
    Kong->>RPC: Forward JSON over WSS
    RPC->>RPC: Reconnect LMS to port 16993
    RPC-->>Kong: JSON {method:"port_switch_ack"} over WSS
    Kong-->>RPS: Forward JSON

    Note over AMT,RPS: Phase 4 — E2E TLS Handshake + ACM Activation

    RPS->>Kong: JSON {method:"tls_data", payload: base64(TLS ClientHello)}
    Kong->>RPC: Forward JSON over WSS
    RPC->>AMT: Decode base64, forward TLS bytes to LMS :16993
    AMT-->>RPC: TLS ServerHello + handshake
    RPC-->>Kong: JSON {method:"tls_data", payload: base64(TLS response)} over WSS
    Kong-->>RPS: Forward JSON

    Note over AMT,RPS: E2E TLS tunnel established (RPS ↔ AMT)

    loop ACM activation WSMAN over E2E TLS
        RPS->>Kong: JSON {method:"tls_data", payload: base64(encrypted WSMAN)}
        Kong->>RPC: Forward JSON over WSS
        RPC->>AMT: Decode base64, forward encrypted bytes to LMS :16993
        AMT-->>RPC: Encrypted WSMAN response
        RPC-->>Kong: JSON {method:"tls_data", payload: base64(response)} over WSS
        Kong-->>RPS: Forward JSON
    end

    Note over RPS: ACM activation complete
Loading

AMT version behavior:

AMT Version --tls-tunnel Flag Behavior
11–18 Not provided All WSMAN over non-TLS LMS :16992. CCM-only activation.
11–18 Provided CCM over :16992 → add TLS certs over :16992 → port switch to :16993 → E2E TLS → ACM
19+ Not needed AMT enforces TLS — TLS tunnel is used automatically regardless of flag

Deprecation notice: With RPC-Go v3 (planned before end of 2025), --tls-tunnel will be enabled by default and non-TLS local connections will be deprecated.

5.3 ACM Activation with E2E TLS (AMT 19+)

AMT 19+ devices enforce TLS on port 16993 — there is no non-TLS 16992 endpoint. The activation uses a multi-phase approach: CCM first (over a TLS tunnel), then TLS certificate provisioning, and finally ACM upgrade (over a new TLS tunnel with the provisioned cert).

RPC-Go supports end-to-end TLS where RPS performs the actual TLS handshake directly with AMT firmware, and RPC-Go acts as a transparent byte relay — it doesn't do any TLS processing.

E2E TLS Architecture

graph RL
    subgraph Cloud
        RPS["RPS Service<br/>tls.TLSSocket<br/>(encrypt/decrypt)"]
        Kong["Kong<br/>WSS TLS termination"]
    end

    subgraph Device["Client Machine"]
        AMT["Intel AMT 19<br/>TLS server :16993"]
        LMS["LMS<br/>Local AMT interface"]
        RPC["rpc-go<br/>WebSocket client<br/>Byte-forwarding proxy<br/>(no TLS processing)"]
    end

    RPS -->|"JSON tls_data<br/>over WS"| Kong
    Kong -->|"JSON tls_data<br/>over WSS"| RPC
    RPC -->|"Decode base64<br/>raw TLS bytes"| LMS
    LMS -->|"Forward to<br/>port 16993"| AMT

    AMT -->|"TLS bytes"| LMS
    LMS -->|"Raw bytes"| RPC
    RPC -->|"base64 encode<br/>JSON tls_data"| Kong
    Kong -->|"Forward WS"| RPS

    style RPS fill:#0068B5,color:#fff
    style AMT fill:#6c3483,color:#fff
    style RPC fill:#B43232,color:#fff
Loading

Key insight: Kong, rpc-go, and LMS forward payload bytes but cannot decrypt the WSMAN HTTP/XML content. The TLS tunnel is truly end-to-end between RPS and AMT.

Complete Activation Sequence

sequenceDiagram
    autonumber

    box Client Machine
        participant AMT as Intel AMT 19<br/>TLS server
        participant LMS as LMS<br/>Local AMT interface
        participant RPC as rpc-go<br/>WebSocket client<br/>Byte-forwarding proxy
    end

    box Cloud
        participant Kong as API Gateway<br/>Kong<br/>WSS TLS termination
        participant RPS as RPS Service<br/>TLS client
        participant Vault as Vault<br/>Secrets and Certs
        participant DB as DB<br/>Non-secret config
    end

    Note over AMT,RPC: AMT, LMS, and rpc-go are on the client machine.
    Note over Kong,DB: Kong, RPS, Vault, and DB are running in the cloud.
    Note over AMT,LMS: AMT 19 local TLS path uses 16993 only. 16992 is not used in this flow.
    Note over RPC,RPS: All tunnel traffic uses JSON tls_data messages. The payload field carries base64 encoded TLS bytes.

    RPC->>Kong: Open WSS connection
    Note left of Kong: Kong presents WebSocket TLS cert
    Kong-->>RPC: Complete WSS TLS handshake

    Kong->>RPS: Forward WebSocket connection to RPS
    Note left of Kong: Kong terminates WSS TLS and forwards WS traffic to RPS

    RPC->>Kong: JSON activate message over WSS
    Kong->>RPS: Forward JSON activate message over WS

    Note right of RPS: method=activate
    Note right of RPS: protocolVersion=4.0.0
    Note right of RPS: payload.ver=19.0.5
    Note right of RPS: payload.uuid=device uuid
    Note right of RPS: payload.tlsEnforced=true
    Note right of RPS: payload.profile=acm

    RPS->>DB: Read AMT profile and CIRA config
    DB-->>RPS: Profile, TLS mode, non-secret config

    RPS->>Vault: Read AMT and MEBx password
    Vault-->>RPS: Secrets

    RPS->>RPS: tlsEnforced=true. Enable TLS tunnel mode.

    Note over AMT,RPS: Phase 1: Pre-activation TLS validation uses Intel ODCA trust only.

    RPS->>Kong: JSON tls_data over WS. payload=base64 TLS ClientHello bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 TLS ClientHello bytes

    RPC->>LMS: Decode base64 payload and forward raw TLS bytes
    LMS->>AMT: Forward TLS bytes to 16993

    AMT-->>LMS: TLS ServerHello and AMT ODCA cert chain
    LMS-->>RPC: Forward TLS bytes
    RPC-->>Kong: JSON tls_data over WSS. payload=base64 TLS response bytes
    Kong-->>RPS: JSON tls_data over WS. payload=base64 TLS response bytes

    RPS->>RPS: Capture and parse AMT cert chain from TLS handshake

    RPS->>RPS: Validate ODCA chain
    Note right of RPS: 1. Ensure peer certificate chain exists
    Note right of RPS: 2. Check validity period for every cert in chain
    Note right of RPS: 3. Verify each cert is signed by the next cert in chain
    Note right of RPS: 4. Load trusted Intel ODCA root certificates
    Note right of RPS: 5. Verify top cert fingerprint matches trusted ODCA root
    Note right of RPS: 6. Or verify top cert is signed by trusted ODCA root
    Note right of RPS: 7. Skip EKU validation intentionally

    Note over RPS: CRL and revocation checking are not implemented.

    RPS->>RPS: Complete TLS handshake. TLS tunnel established.

    Note over AMT,RPS: WSMAN HTTP/XML is encrypted inside RPS to AMT TLS.
    Note over LMS,Kong: Kong, rpc-go, and LMS forward payload bytes but cannot decrypt HTTPS/XML.

    RPS->>Kong: JSON tls_data over WS. payload=base64 encrypted WSMAN TLS bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 encrypted WSMAN TLS bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes to 16993
    AMT-->>LMS: HTTP 401 challenge inside encrypted TLS
    LMS-->>RPC: Forward encrypted TLS response bytes
    RPC-->>Kong: JSON tls_data over WSS. payload=base64 encrypted TLS response bytes
    Kong-->>RPS: JSON tls_data over WS. payload=base64 encrypted TLS response bytes

    RPS->>RPS: Close and reset tunnel after 401

    RPS->>Kong: JSON tls_data over WS. payload=base64 new TLS tunnel bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 new TLS tunnel bytes
    RPC->>LMS: Decode base64 payload and forward TLS bytes
    LMS->>AMT: Forward TLS bytes to 16993
    AMT-->>RPS: TLS established again through Kong, rpc-go, and LMS

    RPS->>Kong: JSON tls_data over WS. payload=base64 WSMAN digest auth bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 WSMAN digest auth bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: AMT_GeneralSettings response over TLS

    RPS->>Kong: JSON tls_data over WS. payload=base64 WSMAN Setup bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 WSMAN Setup bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: SetupResponse ReturnValue=0

    RPS->>Kong: JSON tls_data over WS. payload=base64 WSMAN CommitChanges bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 WSMAN CommitChanges bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: CommitChangesResponse ReturnValue=0

    Note over AMT,RPS: Device is now activated in CCM.

    Note over AMT,RPS: Phase 2: TLS cert provisioning (over E2E TLS)

    RPS->>Kong: JSON tls_data over WS. payload=base64 TLS handshake bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 TLS handshake bytes
    RPC->>LMS: Decode base64 payload and forward TLS bytes
    LMS->>AMT: Forward TLS bytes to 16993
    AMT-->>RPS: TLS handshake using temporary self-signed AMT cert

    RPS->>RPS: Temporarily allow self-signed AMT cert only during post-CCM transition.

    RPS->>Vault: Fetch MPS root key and MPS root cert
    Vault-->>RPS: MPS root key and MPS root cert

    RPS->>Kong: JSON tls_data over WS. payload=base64 Enumerate AMT_PublicPrivateKeyPair bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 Enumerate AMT_PublicPrivateKeyPair bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: Existing AMT key pair inventory

    RPS->>Kong: JSON tls_data over WS. payload=base64 GenerateKeyPair bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 GenerateKeyPair bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Generate key pair internally
    AMT-->>RPS: Public key returned

    Note over AMT: Private key never leaves AMT.

    RPS->>RPS: Generate AMT TLS leaf cert signed by MPS root CA using AMT-generated public key.

    RPS->>Kong: JSON tls_data over WS. payload=base64 Add MPS root cert bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 Add MPS root cert bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: ReturnValue=0

    RPS->>Kong: JSON tls_data over WS. payload=base64 AddCertificate bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 AddCertificate bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: ReturnValue=0

    RPS->>Kong: JSON tls_data over WS. payload=base64 Associate cert with AMT key bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 Associate cert with AMT key bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Bind cert to internal private key
    AMT-->>RPS: ReturnValue=0

    RPS->>Kong: JSON tls_data over WS. payload=base64 Configure AMT local TLS bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 Configure AMT local TLS bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: ReturnValue=0

    RPS->>Vault: Store AMT TLS leaf cert for future verification
    Vault-->>RPS: Stored

    RPS->>RPS: Wait for AMT TLS rollover

    Note over AMT,RPS: Phase 3: ACM activation (over E2E TLS with new cert)

    RPS->>Kong: JSON tls_data over WS. payload=base64 TLS handshake bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 TLS handshake bytes
    RPC->>LMS: Decode base64 payload and forward TLS bytes
    LMS->>AMT: Forward TLS bytes to 16993
    AMT-->>RPS: TLS handshake using AMT TLS cert signed by MPS root

    RPS->>RPS: Validate AMT leaf cert
    Note right of RPS: 1. Check AMT leaf cert validity period
    Note right of RPS: 2. Load configured MPS root CA
    Note right of RPS: 3. Verify AMT leaf signature using MPS root public key
    Note right of RPS: 4. Validate issuer relationship with MPS root
    Note right of RPS: 5. Allow issuer formatting mismatch if signature is valid

    Note over RPS: CRL and revocation checking are not implemented.

    RPS->>Kong: JSON tls_data over WS. payload=base64 ACM activation WSMAN bytes
    Kong->>RPC: JSON tls_data over WSS. payload=base64 ACM activation WSMAN bytes
    RPC->>LMS: Decode base64 payload and forward encrypted TLS bytes
    LMS->>AMT: Forward encrypted TLS bytes
    AMT-->>RPS: ACM activation WSMAN responses over TLS
Loading

5.4 Basic Activation Flow (CCM, no TLS tunnel)

For simple CCM activation without --tls-tunnel:

sequenceDiagram
    autonumber

    box Client Machine
        participant AMT as AMT<br/>LMS :16992
        participant RPC as RPC-Go
    end

    box Cloud
        participant Kong as Kong<br/>API Gateway :443
        participant RPS as RPS<br/>:8080
    end

    Note over RPC: Gather from MEI:<br/>UUID, version, SKU,<br/>cert hashes, control mode

    RPC->>Kong: JSON activate message over WSS
    Kong->>RPS: Forward JSON activate message

    Note left of RPS: Resolve profile,<br/>start XState machine

    loop WSMAN round-trips (dozens)
        RPS->>Kong: JSON {method:"wsman", payload: base64(WSMAN)}
        Kong->>RPC: Forward JSON over WSS
        RPC->>AMT: Decode base64, forward to LMS :16992
        AMT-->>RPC: WSMAN response
        RPC-->>Kong: JSON {method:"response", payload: base64(response)} over WSS
        Kong-->>RPS: Forward JSON
    end

    RPS->>Kong: JSON {method:"success"}
    Kong->>RPC: Forward JSON over WSS
    RPC->>Kong: WebSocket Close
Loading

5.5 WebSocket Message Structure

Envelope (all messages):

{
  "method": "activation",
  "apiKey": "",
  "appVersion": "v2.50.6",
  "protocolVersion": "4.0.0",
  "status": "ok",
  "message": "",
  "fqdn": "",
  "payload": "<base64-encoded or JSON string>",
  "tenantId": ""
}

Initial activation payload (decoded from payload field):

{
  "ver": "16.1.2",
  "build": "1234",
  "sku": "16392",
  "features": "AMT Pro",
  "uuid": "4c4c4544-0042-3210-8030-b4c04f564433",
  "username": "",
  "password": "",
  "currentMode": 0,
  "hostname": "DEVICE-01",
  "fqdn": "device-01.corp.local",
  "client": "RPC",
  "certHashes": ["e7685634...", "a4310d50..."],
  "ipConfiguration": { "ipAddress": "192.168.1.100" },
  "hostnameInfo": { "dnsSuffix": "corp.local" },
  "tlsEnforced": false,
  "tlsTunnel": false
}

5.6 WebSocket Message Methods

Method Direction Purpose
activation RPC → RPS Initial request to activate device (includes device payload)
deactivation RPC → RPS Request to unprovision device
maintenance RPC → RPS Sync clock, change password, update hostname, etc.
response RPC → RPS WSMAN HTTP response from AMT (base64-encoded)
wsman RPS → RPC WSMAN HTTP request to forward to AMT (base64-encoded)
success RPS → RPC Operation completed successfully
error RPS → RPC Operation failed with error message
tls_data Both Raw TLS bytes for E2E TLS tunnel (base64)
port_switch RPS → RPC Instruct RPC to reconnect LMS to different port (16992→16993)
port_switch_ack RPC → RPS Confirm port switch completed
connection_reset RPC → RPS LMS connection died, RPS should re-establish state

5.7 RPC as Proxy vs Orchestrator

Mode Flag Deployment How It Works
Remote Mode -u wss://... Cloud deployment RPC is a transparent byte proxy. RPS orchestrates everything — sends WSMAN commands, RPC forwards them to AMT via LMS, sends responses back. RPC does zero protocol interpretation.
Local Mode -local Enterprise / on-prem RPC is the orchestrator. It directly constructs WSMAN calls using go-wsman-messages, sends them to AMT via LMS/LME, and handles the activation flow locally without RPS.

5.8 TLS Provisioning Decision Tree

This flowchart shows how RPS decides the TLS path based on device state and AMT version:

flowchart TD
    Start([AMT Provisioning]) --> ModeCheck{Device Mode?}

    %% ============================================================
    %% PATH 1: Already Activated (ACM/CCM)
    %% ============================================================
    ModeCheck -->|Activated - ACM / CCM| TLSConfigured{TLS already<br>configured?}

    %% TLS not configured
    TLSConfigured -->|No| GenCert[RPS generates cert<br>from MPS root and<br>adds it to AMT]
    GenCert --> Done1[Connect on port 16993<br>RPS: amt_post_tls_reject = true]

    %% TLS already configured
    TLSConfigured -->|Yes| GetCerts[Get AMT_PublicKeyCertificate<br>and AMT_TLSCredentialsContext]
    GetCerts --> IdentifyCert[Identify cert AMT<br>is currently using]
    IdentifyCert --> SignedByMPS{Cert signed by<br>MPS Root?}

    SignedByMPS -->|Yes| Reuse[Switch to port 16993<br>and reconfigure]
    Reuse --> Done2[RPS: amt_post_tls_reject = true<br>MPS root cert is trusted]

    SignedByMPS -->|No| RegenCert[RPS generates new cert<br>from MPS root and<br>configures it in AMT]
    RegenCert --> Done3[Connect on port 16993<br>RPS: amt_post_tls_reject = true]

    %% ============================================================
    %% PATH 2: Pre-Provisioning
    %% ============================================================
    ModeCheck -->|Not Activated| PreProv{AMT Version?}

    %% AMT 19+
    PreProv -->|19+| ODCA[ODCA cert present<br>and validatable]
    ODCA --> Act19[Activates to CCM<br>over e2e TLS on port 16993<br>RPS: amt_pre_tls_reject = true]
    Act19 -->|Post-Activation| Self19[AMT generates its own<br>self-signed cert]
    Self19 --> DMT19[RPS adds DMT self-signed cert<br>to AMT]
    DMT19 --> RPS19[RPS: amt_post_tls_reject = true<br>RPS owns the DMT root cert]

    %% AMT 18 and below
    PreProv -->|18 and below| TLSCheck{--tls-tunnel<br>flag set?}

    TLSCheck -->|Yes| NoODCA[No ODCA cert available]
    NoODCA --> Act18TLS[Activates to CCM<br>over non-TLS port 16992]
    Act18TLS -->|Post-Activation| VersionCheck2{AMT Version?}

    VersionCheck2 -->|16 - 18| Self16[AMT generates its own<br>self-signed cert]
    Self16 --> DMT16[RPS adds DMT self-signed cert<br>to AMT]
    DMT16 --> RPS16[RPS: amt_post_tls_reject = true<br>RPS owns the DMT root cert]

    VersionCheck2 -->|15 and below| DMT[RPS generates DMT<br>self-signed cert and<br>adds it to AMT]
    DMT --> RPS15[RPS: amt_post_tls_reject = true<br>RPS owns the DMT root cert]

    TLSCheck -->|No| Act18Plain[Activates to CCM<br>over non-TLS port 16992]
    Act18Plain -->|Post-Activation| NoTLS[No certs used or added<br>remains on port 16992]
    NoTLS --> RPS18Plain[Both RPS TLS configs<br>not applicable]

    %% Styling
    classDef version19 fill:#2563eb,stroke:#1e40af,color:#fff
    classDef version18tls fill:#7c3aed,stroke:#5b21b6,color:#fff
    classDef version15 fill:#0891b2,stroke:#0e7490,color:#fff
    classDef version18plain fill:#64748b,stroke:#475569,color:#fff
    classDef decision fill:#f59e0b,stroke:#d97706,color:#000
    classDef rps fill:#dc2626,stroke:#b91c1c,color:#fff
    classDef rpsok fill:#16a34a,stroke:#15803d,color:#fff
    classDef acm fill:#0d9488,stroke:#0f766e,color:#fff
    classDef query fill:#6366f1,stroke:#4f46e5,color:#fff

    class ODCA,Self19 version19
    class Act19 rpsok
    class NoODCA,Act18TLS,Self16 version18tls
    class DMT,DMT16,DMT19 version15
    class Act18Plain,NoTLS version18plain
    class ModeCheck,TLSConfigured,SignedByMPS,PreProv,TLSCheck,VersionCheck2 decision
    class RPS18Plain rps
    class RPS15,RPS19,RPS16,Done1,Done2,Done3 rpsok
    class GenCert,RegenCert acm
    class GetCerts,IdentifyCert query
    class Reuse query
Loading

5.9 Key E2E TLS Concepts

Concept Details
OnDie CA (ODCA) AMT's factory-installed certificate chain. RPS validates against Intel ODCA root certificates during Phase 1 to verify it's talking to genuine AMT firmware. CRL/revocation checking is not implemented.
Self-signed transition After CCM activation, AMT may temporarily present a self-signed cert. RPS temporarily allows this only during the post-CCM transition window.
Private key isolation When RPS calls GenerateKeyPair(), AMT generates the key pair internally. The private key never leaves AMT. RPS only receives the public key to sign.
Cert binding RPS signs a leaf cert using MPS root CA + AMT's public key, then calls AddCertificate and associates it with the internal private key. AMT then uses this cert for TLS.
amt_pre_tls_reject RPS config that controls whether to reject untrusted certs before activation (Phase 1). Set true for AMT 19+ (ODCA validation).
amt_post_tls_reject RPS config that controls whether to reject untrusted certs after activation (Phase 2+). Set true when RPS owns the MPS root cert used to sign the AMT leaf.
CCM-then-ACM AMT 19+ requires CCM activation first over the TLS tunnel, then TLS cert provisioning, then ACM upgrade. ACM requires cert chain injection which needs the device to be in at least CCM.
RPC-Go as transparent relay RPC-Go does zero TLS processing. It passes raw bytes between the WebSocket and local TCP. The TLS handshake is truly end-to-end between RPS and AMT.

6. Device Lifecycle: Activation to Remote Manageability

6.1 ACM Activation Prerequisites

# Requirement Details
1 Wired LAN connection Device connected via ethernet, receiving IP from DHCP
2 DHCP Option 15 DNS Suffix / domain must be configured on the DHCP server
3 Provisioning certificate Purchased from a supported CA vendor. CN must match DNS suffix from DHCP Option 15
4 Intel MEI driver Linux: upstreamed to kernel. Windows: installer available

Why DHCP Option 15? AMT firmware reads the domain suffix from DHCP Option 15 and verifies it matches the CN on the provisioning certificate. This is the zero-touch trust anchor.

flowchart LR
    DHCP["DHCP Server<br/>Option 15: corp.local"] -->|"DNS suffix"| AMT["AMT Firmware"]
    ProvCert["Provisioning Cert<br/>CN: corp.local"] -->|"uploaded to"| RPS
    AMT -->|"Verifies CN matches<br/>DHCP Option 15"| Match{Match?}
    Match -->|Yes| ACM["ACM Activation Proceeds"]
    Match -->|No| Fail["Activation Rejected"]

    style Match fill:#FFA000,color:#000
    style ACM fill:#2E7D32,color:#fff
    style Fail fill:#C62828,color:#fff
Loading

Wi-Fi: DNS suffix must be manually configured in MEBx, negating zero-touch. Uncommon in practice.

6.2 Lifecycle Phases

stateDiagram-v2
    [*] --> Unprovisioned: Factory state
    Unprovisioned --> Activating: RPC connects to RPS
    Activating --> Provisioned: Activation + CIRA configured
    Provisioned --> Managed: AMT CIRA connects to MPS
    Managed --> Operational: Ready for management

    state Activating {
        [*] --> ProfileResolution
        ProfileResolution --> WSMANActivation: ACM or CCM
        WSMANActivation --> SaveCredentials: To Vault
        SaveCredentials --> RegisterDevice: POST /api/v1/devices to MPS
        RegisterDevice --> ConfigureCIRA: WSMAN AddMPS, PolicyRules
        ConfigureCIRA --> [*]
    }
Loading

6.3 Step-by-Step: What Happens Behind Each Phase

Phase 1: Pre-Activation Setup

Before any device can be activated, an administrator must configure:

  1. AMT Profile (in RPS via API or Web UI) — Defines activation mode (ACM/CCM), random password generation, TLS mode, features (KVM/SOL/IDER), CIRA config name, WiFi profiles
  2. CIRA Configuration (in RPS) — MPS server address, port (4433), authentication method, MPS root certificate
  3. Domain (for ACM only, in RPS) — DNS suffix that matches the device's network, plus the provisioning certificate (PFX) that chains to a root hash trusted by AMT

Phase 2: Activation (RPC <-> RPS)

This is the most complex phase. The XState state machine in RPS orchestrates the following:

sequenceDiagram
    autonumber
    participant RPS as RPS
    participant AMT as AMT (via RPC relay)

    Note over RPS,AMT: ACM Activation Flow
    RPS->>AMT: AMT_GeneralSettings.Get()
    AMT-->>RPS: DigestRealm, hostname

    RPS->>AMT: IPS_HostBasedSetupService.Get()
    AMT-->>RPS: ConfigurationNonce, allowedControlModes

    loop For each cert in provisioning chain
        RPS->>AMT: AddNextCertInChain(cert[i])
        AMT-->>RPS: ReturnValue=0
    end

    RPS->>AMT: AdminSetup(passwordHash, nonce, signature)
    AMT-->>RPS: ReturnValue=0

    RPS->>AMT: SetMEBXPassword(hash)
    AMT-->>RPS: ReturnValue=0

    Note over RPS,AMT: Device activated in ACM
Loading

ACM vs CCM Comparison:

Aspect CCM (Client Control Mode) ACM (Admin Control Mode)
Provisioning Cert Not required Required (must match AMT trusted root hash)
User Consent Required for KVM/SOL Can be disabled
MEBx Password Not set Set during activation
Features Limited Full control
Certificate Chain Not injected Injected via AddNextCertInChain
Signature Not used SHA-256 signed with provisioning cert private key

Phase 3: Post-Activation Configuration

After successful activation, RPS applies the profile configuration:

sequenceDiagram
    autonumber
    participant RPS
    participant Vault
    participant MPS
    participant AMT as AMT (via RPC relay)

    RPS->>Vault: Save AMT_PASSWORD, MEBX_PASSWORD
    RPS->>Vault: Save MPS_PASSWORD

    RPS->>MPS: POST /api/v1/devices<br/>(GUID, hostname, mpsusername, tags, tenantId, deviceInfo)
    MPS-->>RPS: 201 Created

    RPS->>AMT: Network config (EthernetPortSettings, WiFi)
    RPS->>AMT: Feature config (RedirectionService, OptInService)
    RPS->>AMT: CIRA config (AddTrustedRootCert, AddMPS, PolicyRules)

    RPS->>RPC: Success message
    Note over RPS: WebSocket closed. Activation complete.
Loading

Note: The POST /api/v1/devices call to MPS is how RPS registers the device. This creates the device record in the mpsdb.devices table so MPS knows about the device before it connects via CIRA.

Phase 4: First CIRA Connection

After RPC completes and CIRA is configured, AMT firmware autonomously initiates an outbound TLS connection to MPS (see Section 7).


7. CIRA Connection: Establishment & Maintenance

7.1 What is CIRA?

CIRA (Client-Initiated Remote Access) is an Intel AMT feature where the device's AMT firmware establishes an outbound TLS connection to a Management Presence Server. This eliminates the need for inbound firewall rules — the device "calls home" to the cloud.

7.2 CIRA Configuration (Done During Activation)

The CIRA state machine in RPS configures AMT firmware with these WSMAN calls (in order):

Step WSMAN Call Purpose
1 AMT_PublicKeyManagementService.AddTrustedRootCertificate(mpsRootCert) Install MPS server's root CA so AMT trusts the TLS connection
2 Save MPS password to Vault devices/{uuid}/MPS_PASSWORD
3 POST /api/v1/devices to MPS Add/register the device in MPS database
4 AMT_RemoteAccessService.AddMPS(server, port, username, password) Register MPS server address/credentials in AMT firmware
5 AMT_RemoteAccessService.AddRemoteAccessPolicyRule(trigger=2) Periodic connection policy (connect on schedule)
6 AMT_RemoteAccessService.AddRemoteAccessPolicyRule(trigger=0) User-initiated connection policy
7 AMT_RemoteAccessPolicyAppliesToMPS.Put() Bind policies to MPS (type=Both)
8 AMT_EnvironmentDetectionSettingData.Put() Set detection domain (prevents CIRA on corporate LAN)
9 AMT_UserInitiatedConnectionService.RequestStateChange(32771) Enable all CIRA connection types

7.3 CIRA Connection Establishment

After configuration, AMT firmware handles the connection autonomously:

sequenceDiagram
    autonumber
    participant AMT as AMT Firmware
    participant MPS as MPS Server (:4433)
    participant Vault
    participant DB as PostgreSQL

    AMT->>MPS: TLS ClientHello
    MPS-->>AMT: TLS ServerHello + MPS TLS Certificate
    AMT->>MPS: TLS Finished (verifies cert against installed MPS root CA)
    MPS-->>AMT: TLS Finished

    Note over AMT,MPS: TLS Tunnel Established

    AMT->>MPS: APF PROTOCOL_VERSION (includes SystemId = device UUID)
    MPS-->>AMT: APF PROTOCOL_VERSION

    AMT->>MPS: APF SERVICE_REQUEST("auth")
    MPS-->>AMT: APF SERVICE_ACCEPT("auth")

    AMT->>MPS: APF USERAUTH_REQUEST (username + password)
    MPS->>Vault: Verify: devices/{uuid}/MPS_PASSWORD
    Vault-->>MPS: Stored password
    MPS->>MPS: Verify password match + username matches DB
    MPS->>DB: UPDATE devices SET mpsInstance=this, connectionStatus=true, lastConnected=now()
    MPS-->>AMT: APF USERAUTH_SUCCESS

    Note over AMT,MPS: CIRA Session Active

    AMT->>MPS: APF GLOBAL_REQUEST (bind ports 16992, 16994, 16995, 16996)
    MPS-->>AMT: APF REQUEST_SUCCESS

    Note over AMT,MPS: Device Ready for Remote Management
Loading

7.4 Connection Maintenance

CIRA connections are in-memory only — each connection lives as a ConnectedDevice object in a Record<string, ConnectedDevice> map inside the MPS process. There is no persistent connection state on disk. If the MPS process restarts, all connections are lost and devices must reconnect. The database only tracks metadata about the connection (which instance owns it, last seen timestamp, connection status) for routing and monitoring purposes — it does not store the actual socket or session.

This means:

  • Scaling requires sticky routing (MPS Router) because the connection object only exists in one MPS instance's memory
  • Process crashes cause all connected devices on that instance to appear disconnected until AMT firmware re-establishes CIRA
  • Graceful shutdown (SIGINT/SIGTERM) triggers clearInstanceStatus() which nulls out mpsInstance and sets connectionStatus=false for all devices owned by that instance
Mechanism Details
In-memory storage Each authenticated CIRA connection is stored as a ConnectedDevice object (holds the TLS socket, AMT credentials, HTTP handler, rate limiter) in a process-level devices map keyed by device GUID.
Keepalive AMT sends APF: KEEPALIVE_REQUEST every ~30 seconds (CIRA_KEEPALIVE_INTERVAL). MPS replies with KEEPALIVE_REPLY and updates lastSeen timestamp in DB.
Idle Timeout MPS sets socket.setTimeout(90s) (CIRA_MAX_IDLE_TIME). If no data received within 90 seconds, socket is closed and the device record is cleaned up.
DB metadata sync On connect: sets connectionStatus=true, mpsInstance=<instance_name>, lastConnected=now(). On keepalive: updates lastSeen. On disconnect: sets connectionStatus=false, mpsInstance=null, lastDisconnected=now().
Duplicate connection handling If a device connects while an existing connection exists (same GUID), MPS closes the old socket first (ciraSocket.end()), cleans up the old record, then stores the new connection.
Reconnection If connection drops, AMT firmware automatically reconnects based on the CIRA periodic policy. This is handled entirely by the ME firmware — no OS/RPC involvement needed.
Environment Detection AMT checks if it's on the corporate network (by DNS suffix). If detected, CIRA connection is not established (device is already locally reachable).
Graceful shutdown On SIGINT/SIGTERM/exit, MPS calls db.devices.clearInstanceStatus(instance_name) which sets mpsInstance=null and connectionStatus=false for all devices owned by this instance.

8. MPS Router: Scaled Deployment & Connection Routing

8.1 The Problem

In a scaled deployment, you run multiple MPS instances. Each AMT device connects via CIRA to exactly one MPS instance, and that connection is held in-memory as a ConnectedDevice object. When an API request arrives for a device, it must be routed to the specific MPS instance holding that device's CIRA connection.

8.2 How Device-to-Instance Mapping Works

sequenceDiagram
    autonumber
    participant Client as API Client
    participant Router as MPS Router :8003
    participant DB as PostgreSQL<br/>(mpsdb.devices)
    participant MPS1 as MPS Instance "mps.1"
    participant MPS2 as MPS Instance "mps.2"

    Note over MPS1: In-memory CIRA connections:<br/>device-guid-123<br/>device-guid-456
    Note over MPS2: In-memory CIRA connections:<br/>device-guid-789<br/>device-guid-012

    Client->>Router: GET /api/v1/amt/power/state/device-guid-123
    Router->>Router: Parse GUID from URL (regex)
    Router->>DB: SELECT mpsinstance FROM devices WHERE guid='device-guid-123'
    DB-->>Router: mpsinstance = "mps.1"
    Router->>MPS1: TCP proxy to mps.1:3000
    MPS1-->>Router: Response (device is connected here)
    Router-->>Client: 200 OK {powerstate: ...}
Loading

8.3 Step-by-Step: How a Request Gets Routed

Step 1: Device connects to an MPS instance via CIRA

When a device's CIRA connection is authenticated, MPS calls handleDeviceConnect() which:

// mps/src/server/mpsserver.ts
async handleDeviceConnect(guid: string): Promise<void> {
    const device = await this.db.devices.getById(guid)
    device.connectionStatus = true
    device.mpsInstance = Environment.Config.instance_name  // e.g., "mps.1"
    device.lastConnected = new Date()
    await this.db.devices.update(device)
}

The instance_name comes from the MPS_INSTANCE_NAME environment variable. In Docker Swarm, this is set to {{.Task.Name}} which auto-expands to a unique name like mps.1, mps.2, etc. If not in Swarm, it defaults to "mps".

Step 2: API request arrives at MPS Router

MPS Router is a raw TCP proxy. On each incoming connection:

// mps-router/internal/proxy/proxy.go
guid := s.parseGuid(string(b))          // Extract GUID from URL using regex
if guid != "" {
    instance := s.DB.Query(guid)         // SELECT mpsinstance FROM devices WHERE guid = $1
    if instance != "" {
        parts := strings.Split(destination, ":")
        parts[0] = instance              // Replace hostname with MPS instance name
        destination = parts[0] + ":" + parts[1]
    }
}
dst, err = net.Dial("tcp", destination)  // Connect to the correct MPS instance

Step 3: Request is proxied to the correct MPS instance

The Router dials a raw TCP connection to the resolved MPS instance (e.g., mps.1:3000) and bidirectionally copies all bytes. It does NOT interpret HTTP — it's a transparent TCP proxy.

Step 4: Cleanup on disconnect

When a device disconnects or an MPS instance shuts down:

  • handleDeviceDisconnect() clears connectionStatus and mpsInstance in the DB
  • SIGINT/SIGTERM handlers clean up all device records owned by that instance
  • Next CIRA reconnect from the device may land on a different MPS instance

8.4 What Happens If an MPS Instance Goes Down?

  1. The mpsInstance field in the DB still points to the dead instance
  2. MPS Router queries DB, gets the dead instance name, and tries to connect — connection fails
  3. The SIGTERM handler on the dying instance should have cleared the mpsInstance field
  4. If ungraceful shutdown, stale entries remain until the device reconnects to a healthy instance
  5. When the device's CIRA reconnect lands on a new instance, handleDeviceConnect() updates mpsInstance to the new instance name

9. Command Execution: API Request to Device Action

9.1 Where WSMAN XML Is Built

When an API request like "Power Off" arrives, the WSMAN XML message is constructed inside MPS using the @device-management-toolkit/wsman-messages library. Here's the exact code path:

API Request: POST /api/v1/amt/power/action/{guid}  {action: 8}
    │
    ▼
Express Route Handler: powerAction.ts
    │ req.deviceAction.sendPowerAction(8)
    ▼
DeviceAction class (src/amt/DeviceAction.ts)
    │ this.cim = new CIM.Messages()     // <── wsman-messages library
    │ this.amt = new AMT.Messages()
    │ this.ips = new IPS.Messages()
    │
    │ xmlRequestBody = this.cim.PowerManagementService
    │     .RequestPowerStateChange(powerState, managedElement)
    │
    │ // This produces SOAP XML like:
    │ // <s:Envelope>
    │ //   <s:Header>
    │ //     <a:Action>RequestPowerStateChange</a:Action>
    │ //     <w:ResourceURI>CIM_PowerManagementService</w:ResourceURI>
    │ //   </s:Header>
    │ //   <s:Body>
    │ //     <PowerState>8</PowerState>
    │ //   </s:Body>
    │ // </s:Envelope>
    ▼
CIRAHandler.Send(socket, xmlRequestBody)
    │ Rate limited: max 3 concurrent, 250ms min interval
    ▼
HttpHandler.wrapIt(xml)
    │ Wraps SOAP XML in HTTP POST request:
    │   POST /wsman HTTP/1.1
    │   Authorization: Digest username=admin, ...
    │   Content-Type: application/soap+xml; charset=UTF-8
    │   <SOAP XML body>
    ▼
CIRAChannel.writeData(httpBytes)
    │ Sends via APF CHANNEL_DATA frame on the CIRA connection
    │ APF frame: [type=94][channelId][dataLength][httpBytes]
    ▼
AMT Firmware (port 16992 through CIRA tunnel)
    │ Receives HTTP POST on /wsman
    │ Digest auth challenge → MPS retries with credentials
    │ Processes WSMAN command
    │ Returns SOAP response via CHANNEL_DATA
    ▼
Response flows back: AMT → APF CHANNEL_DATA → CIRAHandler → DeviceAction → Express → Kong → Client

9.2 Full Power Action Sequence

sequenceDiagram
    autonumber
    participant Client as API Client
    participant Kong as Kong :443
    participant Router as MPS Router :8003
    participant DB as PostgreSQL
    participant MPS as MPS :3000
    participant AMT as AMT Device<br/>(via CIRA)

    Client->>Kong: POST /mps/api/v1/amt/power/action/{guid}<br/>{action: 8}
    Kong->>Kong: JWT validation, strip /mps prefix
    Kong->>Router: Forward to MPS Router
    Router->>DB: SELECT mpsinstance FROM devices WHERE guid={guid}
    DB-->>Router: mpsinstance = "mps.1"
    Router->>MPS: TCP proxy to mps.1:3000

    MPS->>MPS: Verify JWT, check CIRA connection in memory
    MPS->>MPS: DeviceAction builds WSMAN XML<br/>(using wsman-messages library)
    MPS->>MPS: CIRAHandler wraps in HTTP POST /wsman
    MPS->>AMT: APF CHANNEL_OPEN (port 16992)
    AMT-->>MPS: APF CHANNEL_OPEN_CONFIRMATION
    MPS->>AMT: APF CHANNEL_DATA (HTTP + WSMAN XML)
    AMT-->>MPS: APF CHANNEL_DATA (HTTP 401 Digest challenge)
    MPS->>AMT: APF CHANNEL_DATA (HTTP + Digest auth + WSMAN)
    AMT-->>MPS: APF CHANNEL_DATA (HTTP 200 + SOAP response)
    MPS-->>Router: 200 {ReturnValue: 0, ReturnValueStr: "SUCCESS"}
    Router-->>Kong: Forward response
    Kong-->>Client: 200 OK
Loading

9.3 KVM/SOL/IDER Redirection Flow

For interactive sessions, MPS uses WebSocket relay — no WSMAN involved, just raw byte streaming:

sequenceDiagram
    autonumber
    participant Browser
    participant MPS as MPS Web Server :3000
    participant AMT as AMT Device<br/>(via CIRA channel)

    Browser->>MPS: GET /api/v1/authorize/redirection/{guid}
    MPS-->>Browser: Short-lived JWT (scoped to device + expiry)

    Browser->>MPS: WebSocket Upgrade<br/>/relay/webrelay.ashx?host={guid}&port=16994&mode=kvm<br/>Sec-WebSocket-Protocol: {short-lived-JWT}
    MPS->>MPS: Verify JWT (host claim matches, not expired)
    MPS->>AMT: APF CHANNEL_OPEN (port 16994)
    AMT-->>MPS: APF CHANNEL_OPEN_CONFIRMATION

    loop Bidirectional raw byte relay
        Browser->>MPS: WebSocket binary frame (RFB/VNC data)
        MPS->>AMT: APF CHANNEL_DATA
        AMT-->>MPS: APF CHANNEL_DATA
        MPS-->>Browser: WebSocket binary frame
    end
Loading

10. WSMAN Protocol

10.1 What is WSMAN?

WS-Management (WSMAN) is a SOAP-based protocol used by Intel AMT for device management. Every management action (power control, feature toggle, certificate operation, etc.) is performed via WSMAN requests.

10.2 Message Structure

<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope
  xmlns:s="http://www.w3.org/2003/05/soap-envelope"
  xmlns:a="http://schemas.xmlsoap.org/ws/2004/08/addressing"
  xmlns:w="http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd">

  <s:Header>
    <a:Action>http://schemas.xmlsoap.org/ws/2004/09/transfer/Get</a:Action>
    <a:To>http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous</a:To>
    <w:ResourceURI>
      http://intel.com/wbem/wscim/1/amt-schema/1/AMT_GeneralSettings
    </w:ResourceURI>
    <a:MessageID>uuid:unique-id-here</a:MessageID>
  </s:Header>

  <s:Body>
    <!-- Operation-specific content -->
  </s:Body>
</s:Envelope>

10.3 Transport

Context Transport
MPS → AMT (remote via CIRA) HTTP POST tunneled through APF CHANNEL_DATA on port 16992
RPC → AMT (local) HTTP POST to localhost:16992/wsman or :16993/wsman (TLS)
Authentication HTTP Digest authentication (username: admin, password: AMT admin password)

10.4 DMT WSMAN Libraries

Library Language Package Used By Scope
wsman-messages TypeScript @device-management-toolkit/wsman-messages MPS, RPS Message construction only
go-wsman-messages Go github.com/device-management-toolkit/go-wsman-messages/v2 RPC-Go Message construction + transport + digest auth

In MPS, the DeviceAction class instantiates message builders:

this.cim = new CIM.Messages()  // CIM class messages
this.amt = new AMT.Messages()  // AMT class messages
this.ips = new IPS.Messages()  // IPS class messages

These build the SOAP XML string, which is then wrapped in an HTTP POST request by HttpHandler and sent through the CIRA channel.

10.5 WSMAN Classes

The DMT codebase implements 80+ WSMAN classes across three namespaces. These are implemented in wsman-messages (TypeScript) and go-wsman-messages (Go).

AMT Classes (Provisioning, Security & Remote Access)

Class Purpose
AMT_GeneralSettings Hostname, digest realm, network settings
AMT_SetupAndConfigurationService Provisioning mode, unprovision, commit changes
AMT_AuthorizationService User/ACL authorization management
AMT_TimeSynchronizationService Time sync between OS and AMT
AMT_PublicKeyCertificate Public key certificate store
AMT_PublicKeyManagementService Add/remove certificates and keys
AMT_PublicPrivateKeyPair RSA key pair store
AMT_TLSSettingData TLS configuration (mutual auth, ports)
AMT_TLSCredentialContext Certificate-to-TLS-setting association
AMT_TLSProtocolEndpointCollection TLS endpoint collection
AMT_RemoteAccessService Register MPS, add CIRA policies
AMT_RemoteAccessPolicyRule CIRA policy rules (periodic, alert, etc.)
AMT_RemoteAccessPolicyAppliesToMPS Policy-to-MPS association
AMT_ManagementPresenceRemoteSAP MPS server connection endpoint
AMT_MPSUsernamePassword MPS connection credentials
AMT_RemoteAccessCapabilities Remote access capability info
AMT_UserInitiatedConnectionService User-initiated CIRA connection
AMT_EnvironmentDetectionSettingData Domain detection settings (corporate vs. remote)
AMT_RedirectionService KVM/SOL/IDER enable/disable
AMT_BootSettingData Boot configuration settings
AMT_BootCapabilities Boot capability enumeration
AMT_EthernetPortSettings Wired/wireless NIC configuration
AMT_WiFiPortConfigurationService WiFi profile configuration
AMT_8021XProfile 802.1x authentication profile
AMT_8021xCredentialContext 802.1x credential context
AMT_AlarmClockService Alarm clock/wake timer management
AMT_AuditLog Security audit log access
AMT_MessageLog AMT message log
AMT_SystemPowerScheme Power scheme management
AMT_KerberosSettingData Kerberos authentication settings

CIM Classes (Hardware, Power & System Info)

Class Purpose
CIM_PowerManagementService Power on/off/reset/cycle
CIM_PowerManagementCapabilities Supported power states
CIM_AssociatedPowerManagementService Power service association
CIM_SoftwareIdentity AMT firmware version
CIM_ComputerSystemPackage Computer-to-chassis association
CIM_Processor CPU info
CIM_PhysicalMemory RAM module info
CIM_MediaAccessDevice Storage device info
CIM_Card System board info
CIM_Chassis Chassis/enclosure info
CIM_Chip Chipset info
CIM_PhysicalPackage Physical package container
CIM_Battery Battery status
CIM_Fan Fan/cooling info
CIM_Sensor Hardware sensor readings
CIM_BIOSElement BIOS information
CIM_BootConfigSetting Boot configuration
CIM_BootService Boot service operations
CIM_BootSourceSetting Boot source/device setting
CIM_EthernetPort Ethernet port hardware info
CIM_KVMRedirectionSAP KVM redirection service access point
CIM_RedirectionService Redirection service status
CIM_IEEE8021xSettings 802.1x authentication settings
CIM_WiFiEndpoint WiFi endpoint status
CIM_WiFiEndpointSettings WiFi profile settings
CIM_WiFiPort WiFi port hardware info
CIM_WiFiPortCapabilities WiFi port capabilities
CIM_CredentialContext Credential context association
CIM_ConcreteDependency Concrete dependency association
CIM_ServiceAvailableToElement Service-to-element association

IPS Classes (Intel Platform-Specific)

Class Purpose
IPS_HostBasedSetupService Host-based activation (Setup, AdminSetup)
IPS_OptInService User consent configuration
IPS_KVMRedirectionSettingData KVM settings (consent, port)
IPS_AlarmClockOccurrence Individual alarm occurrence instance
IPS_HostIPSettings Host IP configuration
IPS_IEEE8021xSettings IPS-specific 802.1x settings
IPS_8021xCredentialContext IPS 802.1x credential context
IPS_IPv6PortSettings IPv6 port configuration
IPS_HTTPProxyService HTTP proxy service management
IPS_HTTPProxyAccessPoint HTTP proxy access point
IPS_LANEndpoint LAN endpoint status
IPS_PowerManagementService OS power saving state
IPS_ProvisioningRecordLog Provisioning record log
IPS_ScreenSettingData Screen/display settings
IPS_SecIOService Secure IO service
IPS_HostBootReason Host boot reason information

11. APF Protocol Overview

11.1 What is APF?

APF (AMT Port Forwarding Protocol) is the multiplexing protocol used inside the CIRA TLS tunnel. Based on SSH's channel architecture, it allows multiple logical channels over a single TCP connection.

Reference: Intel AMT Port Forwarding Protocol Reference Manual

11.2 APF Message Types

Code Name Direction Purpose
192 PROTOCOL_VERSION Both Version negotiation, carries SystemId (device UUID)
5/6 SERVICE_REQUEST/ACCEPT Both Authentication service negotiation
50/52 USERAUTH_REQUEST/SUCCESS Both Username + password authentication
80/81 GLOBAL_REQUEST/SUCCESS Both Bind port forwarding (tcpip-forward)
90/91 CHANNEL_OPEN/CONFIRMATION Both Open channel to specific AMT port
94 CHANNEL_DATA Both Data transfer on channel (carries HTTP+WSMAN)
93 CHANNEL_WINDOW_ADJUST Both Flow control (sliding window)
97 CHANNEL_CLOSE Both Close channel
208/209 KEEPALIVE_REQUEST/REPLY Both Connection heartbeat

11.3 Channel Multiplexing

Multiple AMT services are accessed through different channels on the same CIRA connection:

graph LR
    subgraph CIRA["CIRA TLS Connection (single TCP socket)"]
        CH0["Channel 0<br/>Port 16992<br/>WSMAN commands"]
        CH1["Channel 1<br/>Port 16994<br/>KVM (RFB/VNC)"]
        CH2["Channel 2<br/>Port 16995<br/>SOL (serial)"]
        CH3["Channel 3<br/>Port 16996<br/>IDER (boot media)"]
    end

    MPS["MPS Server"] --> CH0
    MPS --> CH1
    MPS --> CH2
    MPS --> CH3

    CH0 --> AMT_WSMAN["AMT WSMAN<br/>HTTP POST /wsman<br/>Digest auth + SOAP XML<br/>(built by wsman-messages)"]
    CH1 --> AMT_KVM["AMT KVM<br/>Raw RFB/VNC bytes"]
    CH2 --> AMT_SOL["AMT SOL<br/>Raw serial bytes"]
    CH3 --> AMT_IDER["AMT IDER<br/>Raw IDE bytes"]

    style CIRA fill:#1a2744,color:#fff
    style MPS fill:#0068B5,color:#fff
Loading

12. KVM, SOL & IDER: Redirection Features

AMT provides three redirection features that allow remote operators to interact with a device as if physically present. These all use the Intel AMT Redirection Protocol over dedicated ports, proxied through MPS via WebSocket.

12.1 Feature Summary

Feature Full Name Protocol AMT Port Purpose
KVM Keyboard, Video, Mouse RFB 3.8 (VNC) 16994 Remote desktop — view screen, control keyboard and mouse
SOL Serial Over LAN Serial terminal 16994 Remote serial console — BIOS setup, OS install, recovery
IDER IDE Redirection USB-R (storage redirection) 16994 Mount ISO/floppy images to boot from remotely

All three features connect to AMT port 16994 (the redirection port). The Intel AMT Redirection Protocol handles session setup, authentication, and multiplexing between the three services.

Reference: RFB Protocol 3.8 (RFC 6143)

12.2 Connection Flow

The browser does not connect directly to the AMT device. Instead, MPS acts as a relay — the browser opens a WebSocket to MPS, and MPS bridges it to the device's CIRA channel:

sequenceDiagram
    participant Browser as Browser<br/>(ui-toolkit)
    participant MPS as MPS<br/>(WebSocket relay)
    participant AMT as AMT Device<br/>(port 16994)

    Browser->>MPS: WebSocket UPGRADE<br/>/relay/webrelay.ashx?host={uuid}&port=16994&mode=kvm
    MPS->>MPS: Verify JWT token
    MPS->>MPS: Look up device in connected devices map
    MPS->>AMT: Open CIRA channel to port 16994

    Note over Browser,AMT: AMT Redirection Protocol Handshake
    Browser->>MPS: StartRedirectionSession (0x10)<br/>+ protocol type (SOL/KVM/IDER)
    MPS->>AMT: Forward bytes
    AMT->>MPS: StartRedirectionSessionReply (0x11)
    MPS->>Browser: Forward bytes

    Note over Browser,AMT: Digest Authentication (handled by MPS interceptor)
    AMT->>MPS: AuthenticateSession (challenge)
    MPS->>MPS: RedirectInterceptor injects<br/>device credentials from Vault
    MPS->>AMT: AuthenticateSession (response)
    AMT->>MPS: AuthenticateSessionReply (success)
    MPS->>Browser: Forward success

    Note over Browser,AMT: Protocol-specific data flows directly
    Browser->>AMT: RFB / SOL / IDER data (relayed through MPS)
    AMT->>Browser: Screen updates / serial output / disk reads (relayed through MPS)
Loading

Key detail: The browser never handles AMT credentials. MPS's RedirectInterceptor intercepts the authentication challenge and responds with the device password from Vault, then passes the success back to the browser. After authentication, MPS enters "direct relay mode" — it just forwards bytes in both directions.

12.3 KVM (Remote Desktop)

KVM uses the RFB (Remote Framebuffer) protocol version 3.8 — the same protocol used by VNC. After the AMT redirection handshake and authentication, the connection transitions into standard RFB:

RFB Handshake:

  1. AMT sends RFB 003.008\n (server version)
  2. Client responds RFB 003.008\n (client version)
  3. Security negotiation (type "None" — already authenticated via redirection)
  4. Server init — sends framebuffer dimensions, pixel format, desktop name

Data flow after handshake:

  • Server → Client: Framebuffer updates (Raw or ZRLE encoding)
  • Client → Server: Key events, pointer (mouse) events, framebuffer update requests

Encoding support:

Encoding ID Description
Raw 0 Uncompressed pixel data (simple, higher bandwidth)
ZRLE 16 Zlib-compressed Run-Length Encoding (lower bandwidth)
Desktop Size -223 Pseudo-encoding for screen resize notification

12.4 SOL (Remote Serial Console)

SOL provides access to the device's serial port over the network. After the AMT redirection handshake, raw serial data flows in both directions:

  • AMT → Browser: Serial output bytes (ASCII, translated to Unicode for display)
  • Browser → AMT: Keyboard input bytes

The terminal is rendered using xterm.js in the browser. The TerminalDataProcessor handles character encoding translation (extended ASCII → Unicode) before passing data to xterm.

Use cases:

  • BIOS/UEFI configuration before OS boots
  • OS installation (text-mode installers)
  • System recovery when OS is unresponsive
  • Headless server management

12.5 IDER (Remote Boot Media)

IDER allows mounting local ISO or floppy disk images to the remote device as virtual USB storage. The device sees these as physically attached drives and can boot from them.

Protocol flow after handshake:

  1. Client sends OPEN_SESSION with timeout and heartbeat parameters
  2. AMT responds with firmware version, buffer sizes, protocol info
  3. Client sends DISABLE_ENABLE_FEATURES to register virtual floppy and/or CD-ROM
  4. AMT issues COMMAND_WRITTEN requests (SCSI-like commands: READ, MODE_SENSE, etc.)
  5. Client reads sectors from the local file and sends DATA_FROM_HOST responses

Command types handled:

Command Purpose
OPEN_SESSION / CLOSE Session lifecycle
KEEPALIVE_PING / PONG Connection heartbeat
RESET_OCCURRED Device reset notification
COMMAND_WRITTEN SCSI read/write/inquiry from AMT
DATA_FROM_HOST Sector data sent to AMT
HEARTBEAT Periodic heartbeat

Use cases:

  • Remote OS installation from ISO
  • Boot into diagnostic/recovery tools
  • Firmware update from bootable media

12.6 Implementation Architecture

The implementation is split across three packages:

graph TB
    subgraph Core["ui-toolkit (core library)"]
        Redirector["AMTRedirector<br/>WebSocket connection,<br/>AMT redirection protocol,<br/>digest auth handshake"]
        KvmRedir["AMTKvmDataRedirector<br/>extends AMTRedirector<br/>for KVM data routing"]
        Desktop["AMTDesktop<br/>Canvas rendering,<br/>RFB framebuffer updates,<br/>mouse/keyboard encoding"]
        RFB["RFBStateProcessors/<br/>Handshake, SecurityOptions,<br/>ServerInit, Encoding"]
        Terminal["AmtTerminal<br/>Serial data handling,<br/>ASCII-to-Unicode mapping"]
        TermProc["TerminalDataProcessor<br/>Processes serial bytes<br/>for xterm.js display"]
        IDER["AMTIDER<br/>IDE redirection protocol,<br/>sector read/write handling"]
        IDERProc["IDERDataProcessor<br/>SCSI command interpretation,<br/>file I/O coordination"]
    end

    subgraph React["ui-toolkit-react"]
        RKVM["KVM component<br/>(canvas + mouse/keyboard)"]
        RSOL["Sol component<br/>(xterm.js terminal)"]
        RIDER["IDER component<br/>(headless, file mount)"]
    end

    subgraph Angular["ui-toolkit-angular"]
        AKVM["KVMComponent<br/>(canvas + mouse/keyboard)"]
        ASOL["SolComponent<br/>(xterm.js terminal)"]
        AIDER["IderComponent<br/>(headless, file mount)"]
    end

    RKVM --> KvmRedir
    RKVM --> Desktop
    RSOL --> Redirector
    RSOL --> Terminal
    RSOL --> TermProc
    RIDER --> Redirector
    RIDER --> IDER

    AKVM --> KvmRedir
    AKVM --> Desktop
    ASOL --> Redirector
    ASOL --> Terminal
    ASOL --> TermProc
    AIDER --> Redirector
    AIDER --> IDER

    KvmRedir --> Redirector
    Desktop --> RFB
    IDER --> IDERProc

    style Core fill:#E3F2FD,color:#000
    style React fill:#E8F5E9,color:#000
    style Angular fill:#FFF3E0,color:#000
Loading

Package roles:

Package Role
ui-toolkit Core protocol implementations — framework-agnostic TypeScript classes that handle WebSocket connections, AMT redirection protocol, RFB rendering, serial processing, and IDER disk I/O
ui-toolkit-react React components (KVM, Sol, IDER) that wrap the core classes with React lifecycle, state management, and JSX rendering
ui-toolkit-angular Angular components (KVMComponent, SolComponent, IderComponent) that wrap the core classes with Angular lifecycle hooks, signals, and templates

12.7 WebSocket URL Format

The browser connects to MPS using this WebSocket URL pattern:

wss://{mps-server}/relay/webrelay.ashx?p=2&host={device-uuid}&port=16994&tls=0&tls1only=0&mode={kvm|sol|ider}
Parameter Value Purpose
p 2 Indicates redirection session (vs. other relay types)
host Device UUID Identifies which connected device to relay to
port 16994 AMT redirection port
tls 0 or 1 Whether to use TLS on the CIRA channel to AMT
tls1only 0 or 1 Restrict to TLS 1.0 only
mode kvm, sol, or ider Which redirection service (used for connection tracking)

The JWT auth token is passed as the WebSocket subprotocol during the upgrade handshake.

13. Data Storage: Vault vs Database

13.1 What Goes Where

Data Type Storage Path / Table Why
AMT admin password Vault devices/{uuid}/AMT_PASSWORD Secret - never stored in DB
AMT MEBx password Vault devices/{uuid}/MEBX_PASSWORD Secret - ACM only
MPS device password Vault devices/{uuid}/MPS_PASSWORD Secret - used for CIRA auth
TLS issued certificate Vault devices/{uuid}/TLS_ISSUED_CERTIFICATE Sensitive key material
Provisioning cert (ACM) Vault certs/{domainName}/CERT + CERT_PASSWORD PFX with private key
MPS root CA keys Vault MPSCerts/root_key, root_ca Root signing key
Profile passwords Vault profiles/{profileName}/AMT_PASSWORD Template secret
CIRA config passwords Vault CIRAConfigs/{configName}/MPS_PASSWORD Template secret
Device inventory PostgreSQL (mpsdb) devices table Non-secret metadata: GUID, hostname, status, mpsInstance, tags, tenantId, lastSeen, deviceInfo
AMT Profiles PostgreSQL (rpsdb) profiles table Non-secret config: activation mode, features, TLS mode, CIRA config reference
CIRA Configurations PostgreSQL (rpsdb) ciraconfigs table Non-secret config: MPS address, port, auth method, root cert
Domains PostgreSQL (rpsdb) domains table Domain suffix, cert storage format, expiration (cert itself in Vault)
Wireless configs PostgreSQL (rpsdb) wirelessconfigs table SSID, auth method, encryption
802.1x configs PostgreSQL (rpsdb) ieee8021xconfigs table EAP type, CA cert references

13.2 Design Principle

Secrets (passwords, private keys, certificates with keys) go to Vault. Everything else goes to PostgreSQL.

This separation ensures:

  • Secrets are never exposed in database dumps or backups
  • Vault provides access auditing, rotation, and encryption at rest
  • PostgreSQL handles relational queries (device filtering, profile lookups, joins)
  • In production, Vault should use proper authentication (AppRole, Kubernetes auth) instead of dev tokens

14. Production Integration Guide

DMT is designed as a toolkit for ISVs to integrate into their existing platforms — not as a standalone production system. The reference docker-compose.yml, sample configurations, and Sample Web UI are provided to demonstrate how the components work together and to accelerate development. ISVs are expected to leverage their existing infrastructure (container orchestration, databases, secret stores, API gateways, identity providers) and deploy DMT services into their existing clusters. You are the expert on your production environment — the guidance below identifies integration points, not prescriptions.

14.1 Infrastructure Replacements

The docker-compose reference deployment includes supporting services (PostgreSQL, Vault, Kong) for convenience. In production, replace these with your existing enterprise equivalents:

Reference Component Production Replacement Configuration
PostgreSQL Your existing cloud-hosted database service (Azure SQL, AWS RDS, Cloud SQL, etc.) Configure MPS_DB_* and RPS_DB_* environment variables to point to your database. MPS and RPS use standard PostgreSQL-compatible connections.
Vault Your existing key vault service (Azure Key Vault, AWS Secrets Manager, HashiCorp Vault Enterprise, etc.) Configure the SECRETS_PATH environment variable and implement the ISecretManagerService interface for your provider.
Kong Your existing API gateway (Azure API Management, AWS API Gateway, Nginx, Envoy, etc.) Route /mps/ and /rps/ prefixes to the respective services. Apply JWT validation and rate limiting at your gateway layer.
Docker Compose Your existing container orchestration (Kubernetes, ECS, AKS, EKS, GKE, Nomad, etc.) Deploy MPS, RPS, and MPS-Router as containers/pods in your cluster. See Kubernetes deployment guide. The kubernetes/charts/ directory provides Helm chart references.

14.2 Authentication & Authorization

DMT's reference deployment uses Kong JWT for API authentication. In production, integrate with your existing identity provider:

  • API Authentication: Configure your API gateway or middleware to validate tokens from your IdP (Active Directory, Okta, Auth0, Keycloak, etc.) on all MPS and RPS API routes
  • Authorization/RBAC: Implement role-based access control at your middleware or gateway layer — DMT APIs accept authorized requests and do not enforce roles internally

14.3 Multi-Tenancy

If deploying in a multi-tenant environment:

  1. Custom middleware — Add a middleware layer (or modify the existing one) that extracts the tenantId from your authenticated user context and injects it into every request to MPS and RPS
  2. Tenant isolation — MPS and RPS use tenantId to scope all database queries and Vault paths, ensuring tenants cannot access each other's devices or configurations
  3. Build custom image — Add your modified middleware file to the MPS/RPS Docker images at build time

14.4 RPC-Go Integration

RPC-Go is designed to be embedded into your existing device management agent:

  • As a shared library (DLL/.so) — Build RPC-Go as a C-shared library (go build -buildmode=c-shared -o rpc.dll ./cmd/rpc on Windows, or librpc.so on Linux) and integrate it into agents written in any language via FFI. See the RPC-Go shared library build instructions and the .NET integration sample for a working example.
  • Agent distribution — Bundle the rpc binary (or shared library) with your agent installer and invoke it during device onboarding workflows

Authentication model: The RPC-Go to RPS WebSocket connection itself does not carry API key or mutual TLS credentials. ISVs are expected to authenticate the device through their own agent before initiating the RPC-Go activation flow. The ISV agent establishes trust and authorization first, then connects RPC-Go to RPS over the already-authenticated session.

note: The RPS /activate, /deactivate, and /maintenance WebSocket paths are reachable without authentication in the reference deployment. ISVs must lock down these endpoints at the API gateway or network layer — restrict access so that only your trusted agent (running on managed devices) can reach RPS over WebSocket. Without this, any client with network access to RPS could initiate activation or deactivation flows.

14.5 UI Integration

The Sample Web UI is a reference implementation and demo — not intended for direct production use. For production, embed the DMT ui-toolkit components into your existing management console:

Component Framework What It Provides
ui-toolkit-react React KVM, SOL, and IDER viewer components
ui-toolkit-angular Angular KVM, SOL, and IDER viewer components

These are production-grade, tested components that handle the MPS WebSocket connections, rendering, and input forwarding. Embed them in your console alongside your existing device management UI, authentication, and RBAC layers.

graph TB
    subgraph YourApp["Your Production Console"]
        Auth["Your Auth & RBAC Layer"]
        BizLogic["Your Business Logic &<br/>Workflow Orchestration"]
        UIToolkit["DMT ui-toolkit<br/>(KVM/SOL/IDER components)<br/>Angular or React"]
        APIs["Your API Gateway / Middleware"]
    end

    Auth --> BizLogic
    BizLogic --> UIToolkit
    UIToolkit --> APIs
    APIs --> MPS["MPS"]
    APIs --> RPS["RPS"]

    style YourApp fill:#f0f5fa,color:#000
    style UIToolkit fill:#0068B5,color:#fff
    style APIs fill:#008080,color:#fff
Loading

14.6 Deployment Topology

Deploy DMT services as pods/containers in your existing cluster rather than standing up a separate environment:

graph TB
    subgraph Cluster["Your Existing Kubernetes Cluster"]
        subgraph DMTNamespace["dmt namespace"]
            MPS["MPS Pod"]
            RPS["RPS Pod"]
            Router["MPS-Router Pod<br/>(if scaled)"]
        end

        subgraph ExistingInfra["Your Existing Infrastructure"]
            GW["API Gateway"]
            DB["Database Service"]
            KV["Key Vault"]
            IdP["Identity Provider"]
        end
    end

    GW --> MPS
    GW --> RPS
    MPS --> DB
    RPS --> DB
    MPS --> KV
    RPS --> KV
    GW --> IdP

    style DMTNamespace fill:#E3F2FD,color:#000
    style ExistingInfra fill:#F5F5F5,color:#000
Loading

14.7 Summary Checklist

Integration Point Action
Container orchestration Deploy MPS, RPS, MPS-Router in your existing cluster
Database Point MPS/RPS at your managed database service
Secrets Configure MPS/RPS to use your key vault
API Gateway Route DMT API paths through your existing gateway
Authentication Validate tokens from your IdP on DMT API routes
Multi-tenancy Inject tenantId from authenticated context into requests
RPC-Go Integrate into your device agent (subprocess or library)
UI Embed ui-toolkit-react or ui-toolkit-angular in your console

15. Security Architecture

15.1 Authentication Layers

Layer Mechanism Details
API Clients → Kong JWT (Bearer token) Signed with shared jwt_secret, expiration enforced
Kong → MPS/RPS Internal network No additional auth (trusted Docker network)
AMT Device → MPS TLS + APF USERAUTH Device authenticates with username + password (verified against Vault)
RPC → RPS Not authenticated WebSocket connection with no API key or mutual TLS
MPS → AMT HTTP Digest Auth Over CIRA channel, credentials from Vault
Services → Vault Vault Token Dev token for development, AppRole/Kubernetes auth for production
Services → PostgreSQL Username/Password Via connection string

15.2 TLS Certificates

The system uses four certificates for different purposes:

flowchart TB
    subgraph Vault["Vault (MPSCerts)"]
        VRoot["C3: MPS Root CA + key"]
        VLeaf["C3: MPS Server TLS Certificate"]
    end

    subgraph RPSDomain["RPS Domain Configuration"]
        ProvPFX["C2: Provisioning PFX + private key"]
    end

    subgraph AMTDevice["AMT Firmware"]
        AMTTrust["C3: Trusted MPS Root CA"]
        AMTE2E["C4: AMT Device TLS Certificate"]
        AMTProvTrust["C2: Trusted provisioning CA hash"]
    end

    User["User/Admin"] -.->|"uploads C2"| ProvPFX
    User -.->|"uploads C3"| VRoot
    MPS -->|"loads C3"| VLeaf
    RPS -.->|"reads C2"| ProvPFX
    RPS -.->|"checks C2 trust"| AMTProvTrust
    RPS -.->|"reads C3"| VRoot
    RPS -.->|"installs C3"| AMTTrust
    RPS -->|"issues C4"| AMTE2E
    MPS -->|"presents C3"| AMTTrust
    MPS -->|"validates C4"| AMTE2E
Loading

Certificate 1: Kong TLS Certificate (port 443)

Aspect Details
Purpose Presented to clients on :443 (browsers, RPC-Go)
Certificate Source Self-signed in the reference deployment (why -n is needed)
Production Certificate Source ISV replaces it with a CA-signed certificate through Kong configuration

Certificate 2: Provisioning Certificate (ACM only)

Aspect Details
Purpose Required only for ACM activation
Certificate Source Purchased from a supported CA (Comodo, DigiCert, Entrust, GoDaddy)
Requirement CN must match DHCP Option 15 DNS suffix
Storage Location Uploaded to RPS as part of Domain configuration (PFX format)
Usage RPS injects cert chain into AMT via AddNextCertInChain, signs activation with private key

Certificate 3: MPS Server TLS Certificate (port 4433, CIRA)

Aspect Details
Purpose Presented by MPS to AMT devices on :4433
Certificate Source User creates the MPS Root CA and MPS Server TLS Certificate, then uploads both to Vault at MPSCerts
Requirement Required when AMT devices use CIRA to connect to MPS on port 4433
Storage Location Vault MPSCerts: root_key, mps_tls_config.cert, mps_tls_config.key, web_tls_config.ca
Runtime Behavior MPS reads the certificate material on startup. If the user has not created and uploaded the MPS Root CA and MPS Server TLS Certificate to Vault, MPS generates a self-signed fallback set.
Trust Establishment During activation, RPS adds the MPS Root CA to AMT with AddTrustedRootCertificate
Usage MPS presents this certificate during the AMT-to-MPS CIRA TLS handshake

Certificate 4: AMT Device TLS Certificate (port 16993)

Aspect Details
Purpose Enables E2E TLS between MPS and the AMT device for management communication on port 16993
Certificate Source RPS creates it during the TLS provisioning phase from an AMT-generated key pair and certificate signing request
Requirement Required only when the profile and AMT platform enable E2E TLS between MPS and the AMT device
Signing Authority MPS Root CA private key from Vault
Provisioning Flow RPS creates an AMT Device TLS Certificate (CN=AMT-{hostname}), signs it with the MPS Root CA, adds it to AMT with AddCertificate, then creates a TLSCredentialContext
Usage AMT presents this certificate to MPS during E2E TLS management connections on port 16993

16. Appendix: Port & Protocol Reference

16.1 Cloud Services

Service Port Protocol Direction Purpose
Kong 443 HTTPS Inbound API gateway, TLS termination
MPS CIRA 4433 TLS+APF Inbound (devices) Persistent device connections
MPS Web 3000 HTTP/WS Internal REST API + WebSocket relay
MPS Router 8003 HTTP Internal Device-affinity routing
RPS REST 8081 HTTP Internal Profile management API
RPS WebSocket 8080 WS Inbound (RPC) Activation/deactivation
PostgreSQL 5432 TCP Internal Shared database
Vault 8200 HTTP Internal Secrets management
Web UI 80 HTTP Internal (via Kong) Management console

16.2 AMT Device Ports (tunneled through CIRA or accessed locally)

Port Protocol Service Used By
16992 HTTP WSMAN (non-TLS) Management commands (AMT < 19)
16993 HTTPS WSMAN (TLS) Management commands (TLS enforced, AMT 19+)
16994 TCP KVM Remote desktop (RFB/VNC)
16995 TCP SOL Serial Over LAN
16996 TCP IDER IDE Redirection (boot media)

Glossary

Term Definition
AMT Intel Active Management Technology — hardware-based remote management built into Intel vPro platforms
CIRA Client-Initiated Remote Access — AMT feature where the device establishes an outbound connection to a management server
APF AMT Port Forwarding Protocol — multiplexing protocol inside CIRA TLS tunnel (SSH-like channels)
WSMAN WS-Management — SOAP/XML-based management protocol used by AMT
MEI Management Engine Interface — OS driver interface to Intel Management Engine
HECI Host Embedded Controller Interface — hardware interface to ME (accessed via MEI driver)
PTHI Platform/Topology Host Interface — binary command protocol for AMT host operations
LMS Local Manageability Service — OS service that provides TCP socket access to AMT firmware
LME Local Manageability Engine — direct MEI access using APF protocol (fallback when LMS unavailable)
CCM Client Control Mode — activation mode that doesn't require provisioning certificates (limited features)
ACM Admin Control Mode — full-featured activation requiring provisioning certificates
KVM Keyboard Video Mouse — remote desktop access to AMT-managed device
SOL Serial Over LAN — remote serial console access
IDER IDE Redirection — remote boot media mounting
RPC Remote Provisioning Client — agent installed on managed devices
RPS Remote Provisioning Server — cloud service for device activation
MPS Management Presence Server — cloud service maintaining device connections
MEBx Management Engine BIOS Extension — BIOS-level AMT configuration interface
LSA Local System Account — AMT-provided credentials for local WSMAN access
ODCA On-Die Certificate Authority — factory-installed certificate authority in AMT firmware, used for initial TLS verification of genuine Intel hardware
E2E TLS End-to-End TLS — RPS performs TLS handshake directly with AMT through RPC-Go as a byte relay

References

Resource Link
DMT Documentation https://device-management-toolkit.github.io/docs/2.36/
MPS REST API https://device-management-toolkit.github.io/docs/2.36/APIs/indexMPS/
RPS REST API https://device-management-toolkit.github.io/docs/2.36/APIs/indexRPS/
Kubernetes Deployment Guide https://device-management-toolkit.github.io/docs/2.36/Tutorials/Scaling/Kubernetes/deployingk8s/
RFB Protocol 3.8 (RFC 6143) https://datatracker.ietf.org/doc/html/rfc6143
Intel AMT Port Forwarding Protocol https://software.intel.com/sites/manageability/AMT_Implementation_and_Reference_Guide/HTMLDocuments/MPSDocuments/Intel%20AMT%20Port%20Forwarding%20Protocol%20Reference%20Manual.pdf

Clone this wiki locally