Security Architecture
Fly-by-Wire’s security posture starts from a single principle: every failure mode preserves the original rejection. The system is fail-closed by default, fail-closed by design, and fail-closed at every verification boundary.
Fail-Closed Design
Section titled “Fail-Closed Design”When the evaluation pipeline encounters an error — malformed input, expired license, stale metrics, unreachable coordinator, invalid token — the outcome is always rejection. There is no fallback to permissive behavior. There is no “best effort” pass.
This applies at every stage:
| Failure | Outcome |
|---|---|
| Invalid license | REJECT_LICENSE |
| Stale metric snapshot | REJECT_STALE_METRICS |
| Invalid metric signature | REJECT_INVALID_SIGNATURE |
| Override token verification failure | Original rejection preserved |
| Coordinator unreachable | Original rejection preserved |
| Token already redeemed | Original rejection preserved |
The failBehavior field in the deployment policy controls one exception: operators can configure fail_open for stale metrics during early integration. The base policy (signed by Ananke) determines whether this option is available. An operator can tighten fail_open to fail_closed but cannot reverse the direction.
Cryptographic Token Verification
Section titled “Cryptographic Token Verification”Override tokens use RSA-PSS signatures with SHA-256 hashing. Each token is signed by an operator’s private key, and the evaluation pipeline verifies it against the operator’s public key registered in the deployment policy.
The signing infrastructure:
| Property | Value |
|---|---|
| Algorithm | RSA-PSS |
| Hash function | SHA-256 |
| Key format | PKCS#8 PEM |
| Signature encoding | Base64url without padding |
The same RSA verification stack is shared with the license verification system, ensuring a single cryptographic implementation across the entire platform.
Request Binding
Section titled “Request Binding”Every override token is bound to the exact evaluation request it was issued for. The binding mechanism is a SHA-256 hash computed over a canonical form of the request.
The canonical form includes: envelope version, request ID, snapshot timestamp, metric signature, all metrics (sorted by key), action type, action target, action payload (deep-sorted recursively), and actor ID. The override token field is excluded from the hash — it cannot be part of the input to the hash it must contain.
The hash is computed deterministically: metrics are sorted via BTreeMap, payload keys are deep-sorted recursively, and the result is serialized to compact JSON before hashing. This ensures stability regardless of field ordering in the original request.
If the evaluation request changes in any way — a different metric value, a different timestamp, a different action — the hash changes, and the token fails verification with RequestHashMismatch.
Time Binding
Section titled “Time Binding”Every token has a time-to-live (TTL). The Coordinator sets the expiry when it signs the token: expiresAt = issuedAt + min(requestedTtl, maxTokenTtlMs). The maxTokenTtlMs is defined in the deployment policy and cannot be exceeded.
The evaluation pipeline rejects tokens past their expiresAt timestamp. A 30-second clock-skew tolerance is applied to account for clock drift between the Coordinator and the evaluating runtime.
Single-Use Enforcement
Section titled “Single-Use Enforcement”The Coordinator enforces single-use via an atomic database operation. When a token is redeemed, the Coordinator executes an atomic update that sets the redemption timestamp only if the token has not already been redeemed. If the update affects zero rows, the token was already consumed, and the response is REPLAY_DETECTED.
This is the authoritative defense against replay. The SubstrateSession also maintains an in-memory set of redeemed token IDs as a supplementary guard, but this does not survive process restarts.
Four Layers of Replay Protection
Section titled “Four Layers of Replay Protection”Token reuse is prevented by four independent mechanisms:
| Layer | Mechanism | Scope |
|---|---|---|
| Request binding | SHA-256 hash ties token to exact request | Prevents use against different requests |
| Time binding | Configurable TTL with hard expiry | Prevents use after the approval window closes |
| Coordinator redemption | Atomic single-use enforcement in SQLite | Prevents second use of the same token |
| In-session guard | In-memory token ID set | Best-effort supplement within a running session |
Each layer is independent. Even if one layer were bypassed, the remaining layers maintain protection.
Policy Signing
Section titled “Policy Signing”The deployment policy uses a two-layer design:
Base policy (Ananke-signed). The base policy is signed by Ananke Labs using RSA-PSS. It establishes minimum safety bounds: the minimum gamma floor, permitted enforcement modes, maximum metric staleness, whether metric signatures are required, and fail behavior. These bounds cannot be weakened by operators.
Operator overrides (tightening only). Operators can raise the gamma floor above the base minimum, restrict to a subset of permitted modes, reduce the staleness window, or tighten fail behavior from fail_open to fail_closed. Operators cannot lower the gamma floor below the base minimum, enable modes the base does not permit, or loosen staleness or fail behavior.
This asymmetric design means Ananke sets the safety floor and operators can only build upward from it. The policy resolution happens once at load time, not per-request.
Metric Signature Verification
Section titled “Metric Signature Verification”When requireMetricSignature is enabled in the deployment policy, every evaluation request must include an HMAC-SHA256 signature over the metric snapshot. The shared secret is configured out-of-band between the metric source and the evaluation runtime.
This ensures the metrics have not been modified between the source system and the evaluator. Without signature verification, an adversary with network access could alter metric values to produce a false PASS.
Metric signature verification is optional. The base policy controls whether operators must enable it.
License Verification
Section titled “License Verification”Every evaluation checks the runtime license before processing. The license verification confirms three things: the license has not expired, the machine fingerprint matches, and the domain is permitted. License verification uses the same RSA cryptographic infrastructure as token verification.
An invalid license produces REJECT_LICENSE — the pipeline does not proceed to metric evaluation. This is another expression of the fail-closed principle: the system does not evaluate without a valid trust anchor.
For the full token structure, verification chain, and failure reason catalog, see the HITL Override Protocol technical reference.