Security Architecture
SecureLink implements defense-in-depth across authentication, authorization, device identity, encrypted communication, and multi-tenant isolation. This page describes how these layers work together.
Authentication and Authorization
SecureLink separates authentication (verifying who you are) from authorization (determining what you can do):
- Keycloak handles authentication — it manages user credentials, login flows, and issues identity tokens
- VSN+ handles authorization — it issues session tokens containing the user's type, tenant, roles, and permissions
Token Exchange Flow
When a user logs into the Web UI, the following exchange occurs:
The VSN+ session token contains the full authorization context:
| Field | Description |
|---|---|
| userType | 1 = SuperAdmin, 2 = Tenant Admin, 3 = VPN User |
| tenantId | The tenant this user belongs to (null for SuperAdmin) |
| roles | Role names assigned to the user |
| permissions | Flattened list of permissions derived from roles |
| sessionId | Reference to the server-side session record |
This separation means Keycloak never needs to know about SecureLink's tenant model, roles, or permissions — it only verifies credentials.
Session Lifecycle
| Event | Action |
|---|---|
| Login | Keycloak JWT exchanged for VSN+ session token (default 8-hour expiry) |
| API call | VSN+ token verified on every request; tenant context extracted for data filtering |
| Refresh | Session token can be refreshed before expiry without re-authenticating with Keycloak |
| Logout | Session is revoked server-side; token becomes invalid immediately |
| Revocation | Admin revokes a user's sessions — next API call returns 401, forcing re-authentication |
Session Revocation Enforcement
When a VSN+ session token is revoked (either by the user via "Revoke All Active" or by an admin):
- The revoked token is definitively invalidated — it returns a 401 Unauthorized error
- The auth middleware does not fall back to Keycloak validation for revoked VSN+ tokens
- This ensures that session revocation is immediate and enforceable, even if the user's Keycloak session is still valid
- The user must re-authenticate through the full login flow (Keycloak credentials + token exchange) to obtain a new session
Keycloak Instance Separation
The platform uses two separate Keycloak instances with different purposes:
| Instance | Users | Purpose |
|---|---|---|
| Production Keycloak | Tenant admins, VPN users | Authentication for the SecureLink Web UI and API |
| Global VSA Keycloak | Multi-orchestrator administrators | Authentication for the Global VSA management plane |
These instances have separate realms, client configurations, and user directories. They do not share state.
Certificate Provisioning
Every edge device establishes its identity through X.509 certificates provisioned during the bootstrap process. These certificates enable mutual TLS (mTLS) authentication on all subsequent MQTT communication.
Provisioning Flow
The SecureLink Installer CLI provisions devices using a one-time deployment token over HTTPS:
- The installer claims the deployment token via the orchestrator's provision API. The token claim is atomic (
UPDATE ... SET status='claimed' WHERE status='active') to prevent double-use. - The API generates a signed X.509 certificate with the device GUID as the Common Name. The private key is returned unencrypted over the HTTPS connection (secured by TLS + token authentication).
- The installer saves certificates with restricted file permissions (root-owned, 0600). The private key never traverses an unencrypted channel.
- The device establishes an mTLS connection to the MQTT broker using the provisioned certificates.
Deployment Token
Deployment tokens follow the format NLZ-XXXX-XXXX-XXXX-XXXX using an unambiguous character set (excludes I, O, 0, 1 to avoid confusion). Each token is:
- Single-use — once claimed, it cannot be reused
- Time-limited — tokens expire if not used within the configured window
- Atomically claimed — database-level protection against race conditions
Certificate Storage on Edge
After provisioning, certificates are stored on the edge device:
| File | Purpose |
|---|---|
ca.crt | CA certificate — validates the broker's identity |
edge.crt | Device certificate — proves the edge's identity to the broker |
edge.key | Private key — restricted file permissions (0600), never transmitted after provisioning |
Mutual TLS (mTLS)
After bootstrap, all communication between edge devices and the MQTT broker uses mutual TLS:
- The broker presents its certificate, which the edge validates against the CA
- The edge presents its certificate, which the broker validates against the CA
- Both sides must prove their identity before the connection is established
This means:
- Unauthorized devices cannot connect to the MQTT broker
- Messages cannot be intercepted or tampered with in transit
- Each device's identity is cryptographically verified on every connection
Multi-Tenant Isolation
SecureLink enforces tenant isolation at multiple layers:
API Layer
Every API query is filtered by the authenticated user's tenant ID. A Tenant Admin can only see and modify resources belonging to their own tenant. SuperAdmins can access all tenants but must explicitly select a tenant context for most operations.
MQTT Layer
MTGE devices use per-tenant MQTT topics (VSR/{serial}/batch/{tenantId}), ensuring that configuration for one tenant is never delivered to another tenant's processing context on the device.
Data Plane Layer (MTGE)
On multi-tenant gateway edges, VRF (Virtual Routing and Forwarding) technology provides complete data plane isolation:
- Each tenant gets a separate VRF with its own routing table
- WireGuard tunnels, NAT rules, and ACLs are bound to the tenant's VRF
- Traffic cannot cross VRF boundaries unless explicitly configured (e.g., internet breakout)
Database Layer
All tenant-scoped tables include a tenant_id column. Drizzle ORM queries always include a tenant filter when operating on behalf of a Tenant Admin.
WireGuard Key Security
WireGuard tunnels use X25519 key pairs. Keys are:
- Generated using the Node.js native cryptography module
- Encrypted at rest in the database using AES-256-GCM (key derived via PBKDF2 from a per-key salt)
- Never logged — the API enforces that private keys are excluded from all logging output
- Transmitted only inside batch configuration — delivered over the mTLS-encrypted MQTT channel
IKEv2 Certificate Security
IKEv2 App VPN uses a separate certificate chain for StrongSwan:
- CA certificate and server certificate generated per-edge (or per-tenant for MTGEs)
- Client certificates issued per VPN user, bundled as PKCS#12 with a one-time password
- Certificate bundles encrypted in the database using AES-256-GCM with a static environment key (distinct from the PBKDF2 scheme used for WireGuard keys)
- Certificate Revocation List (CRL) maintained and distributed via batch configuration
Further Reading
- Platform Architecture — Component overview and communication paths
- Config Sync Pipeline — How configuration is delivered securely to devices
- MQTT Topic Reference — Topic structure and mTLS requirements