Skip to content

guides

Intended Documentation

Edge-Verifier Operator Guide (Roadmap)

The planned deployment, monitoring, key-rotation, and failure-mode model for the Intended edge verifier. The verifier binary is not yet shipped — today the cloud round-trip is the verifier.

RoadmapSource: codeValidated: 2026-06-07

Edge-Verifier Operator Guide (Roadmap)#

Audience: plant operations / IT teams planning to deploy and maintain the Intended edge verifier in production cells.

Roadmap — the edge verifier binary is not shipped

The Rust edge-verifier binary is not in the repository today. This guide documents the operating model the binary is intended to deliver so you can plan deployment, monitoring, and change-control ahead of GA. Everything below describing local sub-50ms verification, offline JWKS caching, local audit buffering, and tamper detection is forward-looking specification, not current behavior. What is real today is described in What works today.

What the edge verifier will be#

A single signed binary that:

  1. Verifies Authority Tokens locally with sub-50ms latency.
  2. Maintains a JWKS cache and a token-revocation list synced from GET /v1/physical/revocations.
  3. Buffers audit events locally and uploads in compressed batches.
  4. Operates for a bounded window fully offline.
  5. Detects local tamper attempts (file modification, time rollback) and fails closed.

Planned distribution: Linux x86_64, ARM64, ARMv7; container image and static binary; reproducible build with attestation.

Deployment topology (planned)#

One verifier per cell or per robot:

OptionWhen to use
Per-robot (verifier on each robot's controller PC)Highest isolation; one robot's outage doesn't affect others. Most edge CPU. Recommended.
Per-cell (one verifier for several robots over local network)Resource-constrained cells. Single point of failure within the cell — make the safe-default conservative.
Per-lineDiscouraged; network blast radius too wide. Non-safety telemetry only.

The verifier should be reachable from the controller over a sub-1ms local link (loopback or dedicated VLAN). Do not run it across the WAN from the robot it serves.

Configuration (planned shape)#

A single config file (/etc/intended/verifier.toml):

toml
[verifier]
bound_actor_identity   = "cobot-east-3"      # IEEE 802.1AR DevID
trusted_issuers        = ["https://api.intended.so"]
expected_audience      = "intended-edge-verifier"   # MUST match what the issuer mints
policy_allowlist_path  = "/etc/intended/policy-allowlist.json"
listen_addr            = "127.0.0.1:7400"

[jwks]
cache_path             = "/var/lib/intended/jwks.cache"
refresh_interval_secs  = 3600
max_offline_secs       = 86400

[revocations]
sync_endpoint          = "https://api.intended.so/v1/physical/revocations"
sync_interval_secs     = 5

[time]
source                 = "ptp"               # "ptp" | "ntp" | "system" (system is dev-only)

expected_audience

Tokens mint aud: "intended-edge-verifier". Set expected_audience to that exact value. The sample verifier in the intended-ros2 package defaults to intended-edge, which would reject every valid token.

policy_allowlist is the set of OI codes a verifier may enforce — defense-in-depth against a mis-issued token. A token citing an OI code outside the list is rejected even with a valid signature.

Provisioning identity (planned)#

Each verifier binds to one robot's identity:

  1. Provision an IEEE 802.1AR IDevID in the robot's TPM at manufacture.
  2. The verifier reads the IDevID at startup as bound_actor_identity.
  3. Only tokens issued against this identity are accepted.

Without IDevID hardware, the verifier accepts a manually-configured identifier — but the safety case can no longer claim hardware-anchored identity binding.

Operations (planned)#

Health metrics (Prometheus) the binary is expected to expose include verification counts by outcome, verification-latency histogram, JWKS cache age, audit-buffer depth, audit-upload failures, time-source offset, and revocation-sync status. Recommended alerts: stale JWKS, growing audit gap, p99 verification latency, and time-source drift (fail closed on the last).

Roll out a new binary version in stages — canary cell, then one safety-critical cell for ≥7 days with no false-rejects in the audit log, then a staggered fleet rollout. The binary requires a process restart to update; schedule restarts in maintenance windows. Audit-relevant config changes (issuer trust list, allowlist) must go through your change-control process.

Key rotation (planned)#

The cloud signals rotation by adding new kid values to JWKS; as long as the refresh interval is honored, rotation is invisible to the controller. If rotation occurs during an offline window, in-flight tokens are honored to their expiresAtMs, then the verifier rejects until JWKS refresh succeeds — fail-closed on unverifiable tokens.

For emergency revocation, the cloud records a revocation that the verifier picks up on its next /v1/physical/revocations sync. Offline verifiers cannot honor revocation until they reconnect — which is why the offline budget is bounded.

Failure modes (planned)#

FailureVerifier response
Process crashsystemd restarts; controller treats verification as denied while down.
Local disk full (audit buffer)Fail closed for new tokens; in-flight tokens honored to expiry.
Time-source drift / lossFail closed — cannot trust expiry checks without trustworthy time.
Cloud unreachable within offline budgetServe with cached JWKS; buffer audit locally; revocation cannot propagate.
Cloud unreachable past offline budgetFail closed for new tokens.
Tamper detectedWrite a tamper event, refuse all tokens, exit; recovery requires verified reinstall.

What works today#

Until the binary ships, the cloud is the verifier:

  • POST /v1/physical/authority-tokens signs and decides in one round trip (~80–250ms typical/p99).
  • Acceptable for non-RT planning loops; not acceptable for ms-critical control loops.
  • Revocation is already real: publish with POST /v1/physical/authority-tokens/{jti}/revoke, and any client can poll GET /v1/physical/revocations?since= to stay current.
  • The signer's public key is at /.well-known/jwks.json. In dev/sandbox it is an ephemeral per-process keypair (rotates on restart); a KMS-backed signer path exists for a stable key.

When the binary ships, migration is intended to be configuration-only: install the binary, point the controller at 127.0.0.1:7400 instead of the cloud URL. The token wire format and claims do not change — they are the contract in Rust safety-critical firmware.

See also#

Edge-Verifier Operator Guide (Roadmap) | Intended