Edge security
The cloud gateway checks connector credentials, hardware identity, fixed workspace, active service authority, assigned work centers, and configured IP restrictions. These controls do not secure every local interface automatically.
Local network boundary
Both local listeners are disabled by default. Enabling either requires a private EDGE_LOCAL_PRINCIPALS_FILE. Each machine has a separate random token (at least 32 characters), a unique id, explicit workCenterIds, and only the actions it needs: read, production, station-progress, scrap, status. There is no wildcard scope. Rotate a machine token independently and restart the service to apply changes.
REST requires PLC_REST_ENABLED=true, PLC_TLS_CERT, and PLC_TLS_KEY. It binds PLC_SERVER_HOST=127.0.0.1 on port 3005 unless explicitly changed. Use a trusted HTTPS certificate and Authorization: Bearer <machine-token> on every route, including health. Browser-origin requests are rejected and no permissive CORS header is emitted. A literal loopback plaintext listener is available only with both NODE_ENV=development and EDGE_ALLOW_INSECURE_LOOPBACK=true; it still requires authentication.
Inbound OPC UA requires OPCUA_SERVER_ENABLED=true, OPCUA_SERVER_CERT, and OPCUA_SERVER_KEY. It binds OPCUA_SERVER_HOST=127.0.0.1 on port 4841 with /UA/EnneaEdge. Only SignAndEncrypt with Basic256Sha256 is offered; anonymous sessions are disabled. Use the machine id as username and its token as password. Provision and trust the client application certificate in OPCUA_TRUST_DIR/server, and trust the Edge certificate on the PLC. Unknown certificates are rejected, not automatically accepted. Outbound PLC connections use the separate OPCUA_TRUST_DIR/client trust store and require the same encrypted mode/policy.
Reads are limited to the intersection of the local principal's work centers and the current cloud cache. Writes require an allowed action and work center, a cached order assigned to that work center, finite integer quantities from 0 through 1,000,000, and an exact station relationship where applicable. REST JSON bodies are limited to 16 KiB. Every write requires a unique 16–128-character requestId (letters, digits, underscore or hyphen) and timestamp in Unix milliseconds, within five minutes of the Edge clock. OPC UA report methods append those two arguments. Keep clocks synchronized. Replay receipts and buffered events commit in one SQLite transaction; a repeated ID returns 409 on REST / a bad method result on OPC UA, including after restart. These controls do not claim exactly-once cloud execution.
Limits apply per machine: 600 requests/minute, 120 writes/minute and a 10-write one-second burst. REST also has a 1,200 requests/minute aggregate ceiling. Respect 429/bad method status and retain the original request identity while reconciling uncertain results. Keep host/network firewalls restricted to approved PLCs; do not expose either listener to the public internet.
Cloud access uses the deployment's HTTPS and WebSocket origins. Permit only agreed routes between host, cloud, PLCs, and configured printers. Printer TCP destinations can issue physical jobs; limit network and assignment authority accordingly.
Identity and secrets
The runtime's hardware ID is currently a generated persisted identifier. It is not a tamper-proof hardware fingerprint. Treat the private state file and API key as credentials. Copying state to another host can copy its identity; replacements need a deliberate provisioning procedure.
State defaults to ~/.ennea/edge or an explicit EDGE_STATE_DIR. The runtime enforces service-owned private directories (0700), regular unlinked files (0600), atomic configuration replacement and equivalent Windows ACLs for the service identity, SYSTEM and Administrators. Symbolic links/reparse points and hard-linked state files are rejected. Existing cache/log permissions are tightened before opening them. Restrict .env, certificate keys, edge-config.json, SQLite files, and logs to the service account and authorized administrators. Store them on protected storage and include them in the deployment's encryption/backup policy. The runtime does not automatically encrypt its local state merely because cloud traffic uses TLS.
Remove initial registration tokens after registration. Do not put keys, tokens, state files, or raw manufacturing payloads in tickets or public examples. Keep backups protected to the same standard.
Least privilege and revocation
Assign only the required work centers and service capabilities. Registration creates pending access; an administrator must approve and provision it. Production reporting, issue reporting, and label printing have different authorities.
For a compromised or retired host, revoke the connector and relevant service authority. Rotate credentials through the authorized connector controls and install the new key securely. Preserve or quarantine buffered work for reconciliation before deleting state. A configuration change cannot recall commands already sent to a PLC or printer.
Upgrade existing installations
- Stop the service cleanly and preserve an encrypted backup of its identity, SQLite database and pending events. Do not re-register or discard pending work.
- Create a dedicated service-owned state directory. Move the existing
edge-config.json,data/, andlogs/together into it; setEDGE_STATE_DIRto its canonical path. Remove obsolete relativeDATA_DIR/LOG_DIRoverrides or point them at the migrated directories. A legacy working-directory state file causes startup to stop with a migration message rather than silently creating another identity. - Provision machine principals in a private JSON file. Example shape:
[{"id":"plc-a","token":"<random-secret-at-least-32-characters>","workCenterIds":["WC-A"],"actions":["read","production"]}]. Replace the placeholder locally; never commit tokens. SetEDGE_LOCAL_PRINCIPALS_FILEto that file. - Provision TLS/OPC UA certificates and peer trust, update PLC clients to send credentials plus request IDs/timestamps, and explicitly enable only required listeners. Migrate outbound mappings from
None/Sign/obsolete policies toSignAndEncrypt/Basic256Sha256; invalid or insecure settings now fail closed. HTTPS/WSS cloud redirects are not followed. - Start with a dedicated service account. Verify denied anonymous/wrong-scope requests, a read-only authorized request, trusted certificate behavior, then one authorized report and its cloud outcome. If old host permissions exposed reusable credentials, rotate them through approved provisioning controls.
- Build a separate artifact on each target OS/architecture with
pnpm --filter @ennea/edge-runtime package:runtime. The archive includes Node 24 and a tested native SQLite binding; verify its checksum/manifest and start throughstart.shorstart.cmd. Node 18/pkg executables are retired. Apply the release signing process before distribution.
Windows ACL enforcement requires permission to set the service account's state ACL. Startup fails if it cannot establish the restricted ACL. Validate the Windows service identity and filesystem ACLs on the target Windows host before commissioning; POSIX tests do not establish Windows deployment readiness.
Upgrade and recovery
Use an agreed package version, retain persistent state, and validate cloud and PLC behavior after updates. Confirm recovery from a representative disconnect and check pending/dead-letter work. Buffering is not an unlimited data-loss guarantee.
See Installation, API reference, and Troubleshooting.