reviews/current/objective-20260909T223027Z/openai__gpt-6-astra.md
On this page

Independent Pi/OpenRouter review: openai/gpt-6-astra

Source: a10323dede4413fbf295916b8ad12e3dbad7514e. Status: completed.

Independent security assessment

I would not rely on this deployment for sensitive content under the stated objective. The implementation has meaningful confidentiality protections, but it does not support an unqualified claim that intermediaries cannot infer contents before approximately one week.

My main conclusions are:

Scope and method

This is a static review of the supplied frozen source at a10323dede4413fbf295916b8ad12e3dbad7514e. I executed no tests, builds, benchmarks, or network requests. Every reproduction sketch below is unexecuted. Documentation and test assertions were treated as claims, not proof.

The deployed entry point is attested-relay-enclavesrc/v2_main.rs (crates/enclave/Cargo.toml:11–13; build/Dockerfile.graviton5:32–35). Consequently:


Property verdicts

Property Verdict Basis
No pre-release inference of request/response contents VIOLATED Distinguishable candidate contents can be identified through traffic and audit-ciphertext lengths; hostname-carried secrets reach DNS.
Client-to-enclave content encryption and endpoint authentication SUPPORTED CONDITIONALLY Fresh Nitro nonce, exact PCR0, AWS-rooted signature, and actual TLS-peer SPKI are checked before sending the target request. Requires correct verifier/TLS implementations and an independently accepted pin.
Confidentiality from arbitrary upstream TLS terminators VIOLATED The relay sends ordinary HTTPS. An in-scope intermediary holding the destination’s valid TLS credentials sees plaintext.
Resistance to upstream redirection by a malicious resolver/parent alone SUPPORTED CONDITIONALLY TLS verifies the original hostname, not merely the returned IP or ECH public name. Requires sound WebPKI authentication.
No practical early epoch-key recovery through application APIs INSUFFICIENT EVIDENCE for a comprehensive guarantee No such exploit is demonstrated here; the native implementation and full execution environment remain unreviewed.
Seven serial segments despite seven-worker generation SUPPORTED CONDITIONALLY Independent private seeds and authenticated wraps serialize the solver; generation knows all seeds. Requires secret seeds/endpoints, correct FFI/native evaluation, and secure KDF/AEAD composition.
No early sharing of a completed future puzzle through normal publication paths SUPPORTED CONDITIONALLY Future material stays in enclave memory until the previous publication deadline; no generation-progress export is called.
No old-puzzle reactivation through delayed/replayed host ACKs SUPPORTED CONDITIONALLY Lifetime is anchored before puzzle disclosure, is not reset on ACK, and activation rechecks expiry.
No key/puzzle reuse on ordinary restart SUPPORTED CONDITIONALLY Fresh boot signer/TLS key and fresh NSM-generated puzzle material; no restore/import path shown.
Full seven-day delay from every request VIOLATED Daily epoch reuse consumes up to a day of the remaining puzzle work before a request arrives.
Approximately one week against unrestricted solver hardware INSUFFICIENT EVIDENCE Fixed iteration count and reference calibration are not a lower bound on adversarial elapsed time.
Expired epochs reject new requests SUPPORTED CONDITIONALLY Fresh NSM time and monotonic expiry are both checked. Depends on functioning runtime/kernel/NSM integration.
Strict wall-clock erasure of all keys and plaintext copies VIOLATED as a blanket erasure property Plaintext copies are not comprehensively zeroized; timeout and destructor coverage do not establish erasure of all library/native/compiler copies.
Successful response implies genuinely public, retained artifacts VIOLATED A malicious parent can acknowledge without storing or serving anything.
Recovery without the enclave after artifacts survive SUPPORTED CONDITIONALLY Public solver and record decryptor need no later enclave participation; native correctness and sufficient computation remain conditions.
Individual records prove historical enclave origin after key release VIOLATED without a previously trusted receipt Anyone with the released symmetric key can create another valid record under the original signed puzzle.
Authentication of archived puzzle identity/parameters SUPPORTED CONDITIONALLY Archive verification binds content hashes, Nitro-attested signer, signature, and work parameters. It does not authenticate publication time or archive completeness.

1. Byte and key flow across the trust boundaries

Request path

  1. Trusted client environment: Relay.get() parses the target URL and constructs /f/https/<authority>/<path>?<query> (python/.../client.py:167–177).
  2. Before sending that target, the client opens an inner TLS 1.3 connection and requests a fresh nonce-bound attestation (client.py:42–60,143–165).
  3. The outer GET transport carries:
    • session ID, sequence, ACK and send controls;
    • base64url-encoded TLS bytes, not the target URL in plaintext
      (transport.py:122–149,167–174).
  4. The parent/front end can read, replace, replay, truncate, and delay these outer values. It does not thereby obtain inner TLS plaintext.
  5. The enclave terminates inner TLS and parses the target URL (v2_main.rs:180–195; v2_proxy.rs:53–77).
  6. The outbound request is newly constructed as:
    • GET plus target path/query;
    • Host;
    • Accept-Encoding: identity;
    • User-Agent: attested-relay/2;
    • empty body
      (v2_proxy.rs:169–173).

Caller cookies, Authorization headers, arbitrary headers, and request bodies are not forwarded. This limits supported functionality but also blocks several cross-client chosen-header attacks.

DNS and upstream path

There is no additional end-to-origin encryption inside upstream HTTPS.

Response and audit path

Private key path


2. Concrete findings and limitations

F1 — Pre-release content inference from lengths and destination disclosure

Verdict: VIOLATED — content-inference confidentiality.
Impact: Candidate identification, potentially revealing the entire request or response when the candidate set is known. This is not general-purpose decryption or epoch-key recovery.

Code

Attacker capability and trace

A parent/front end records TLS flight sizes and artifact sizes. A colluding client makes its own requests to candidate resources and builds fingerprints.

For example:

  1. Two equal-length URLs on the same honest destination return different known documents.
  2. One document is 1 KiB; the other is 64 KiB.
  3. The victim requests one of them.
  4. The parent observes the outbound/inbound TLS lengths and the encrypted audit record.
  5. The ciphertext’s decoded length is exactly the CBOR plaintext length plus the AEAD tag; hex serialization exposes that length directly.
  6. The attacker identifies the document, and therefore the request choice and response contents, before any puzzle is solved.

Random nonces prevent ciphertext equality comparison, but do not hide lengths. The archive also preserves a high-resolution content-length signal beyond transient traffic observation.

Separately, a URL such as https://<secret>.example.org/... discloses that secret to the resolver. Suppressing ECH can expose the same hostname to the parent. Calling the hostname “metadata” does not make the encoded secret cease to be content.

Minimal reproduction — unexecuted

Serve two deterministic, differently sized documents at equal-length paths under the same HTTPS hostname. Submit victim requests in randomized order. Classify them using only captured TLS record lengths and public .record.json ciphertext lengths.

A second fixture can put a unique test secret in a wildcard-certified hostname and record the DoH query received by a controlled resolver.

Limits

This does not demonstrate recovery of arbitrary equal-length, unpredictable plaintext. The inference accuracy depends on the candidate set and observable behavior. Nevertheless, it directly contradicts a broad “cannot infer contents” claim.


F2 — Cloudflare or another destination TLS intermediary can see plaintext immediately

Verdict: VIOLATED for destinations whose TLS terminates at an in-scope intermediary.

Code

Attacker capability and trace

Cloudflare operates the HTTPS endpoint for a destination domain and has valid credentials for that domain:

  1. The client sends an authenticated inner-TLS request to the enclave.
  2. The enclave connects to the destination’s Cloudflare TLS endpoint.
  3. Certificate verification succeeds legitimately.
  4. Cloudflare decrypts the outbound request and handles the response.
  5. Cloudflare shares them with the operator immediately.

No TLS or RandomX primitive is broken.

Minimal reproduction — unexecuted

Use a staging hostname whose valid HTTPS endpoint is a logging reverse proxy in front of a separate origin. Relay a request containing a canary query and return a canary response. Verify that the reverse proxy records both before any audit recovery.

Required clarification

If the owner defines the destination’s CDN/TLS terminator as part of the intended destination exception, this particular exposure is accepted rather than a violation. But then the service does not provide confidentiality from Cloudflare for Cloudflare-terminated destinations.

A malicious recursive resolver alone does not have this power merely by returning an attacker IP: the attacker still needs acceptable credentials for the original hostname. The implementation therefore also depends on a trustworthy upstream authentication system, not just cryptographic algorithm strength.


F3 — Daily key reuse gives publication-relative, not per-request, delay

Verdict: VIOLATED for a full seven days after each request; hardware-independent timing has INSUFFICIENT EVIDENCE.

Code

Attacker capability and trace

A solver starts immediately when the parent first receives the puzzle, then shares its progress or recovered key:

  1. Puzzle becomes available at (t_p).
  2. Solver continuously evaluates the chain.
  3. A victim request arrives near the end of the 24-hour epoch.
  4. The service correctly encrypts that request under the same epoch key.
  5. Approximately one day of work has already been completed.

The configured count is:

[ 7 \times 43{,}768{,}124 = 306{,}376{,}868 ]

dependent RandomX calls. Using the claimed reference rate only as an illustrative calibration, that is about seven days from initial disclosure. A request near expiry has about six days remaining, slightly less measured from its eventual response/capture completion.

More generally:

[ \text{remaining delay} \approx \text{adversarial solve duration} - \text{puzzle age at request}. ]

If an allowed implementation/hardware combination solves the puzzle within the serving epoch, the code has no separate gate detecting that the puzzle is already solved. It will continue accepting requests until normal expiry.

Minimal reproduction — unexecuted

Use reduced-work parameters, solve from first puzzle disclosure, and send another request late in that epoch. Demonstrate that its release time is the same as the earlier record’s, not one additional puzzle duration after its own arrival.

For the production timing claim, benchmark the actual dependent-chain loop on plausible optimized solver implementations and hardware—not aggregate mining throughput.

Limits

I have not demonstrated a particular production solver achieving a faster rate. The strong RandomX assumption rules out the stated cryptanalytic shortcut; it does not establish a minimum elapsed duration, prevent faster evaluation, or require solvers to use the enclave’s hardware.


F4 — An ACK can be fabricated without public storage or retention

Verdict: VIOLATED — acknowledged-publication and retention guarantee.
Classification: Availability/retention; not inherently an early plaintext-recovery attack.

Code

Attacker capability and trace

A malicious parent replaces the record sink:

  1. Receive the puzzle, bundle, or record.
  2. Optionally retain a private copy.
  3. Return OK\n without writing or publishing it.
  4. The enclave activates or returns the response.
  5. Public readers receive no artifact.

The host can also kill the enclave after the upstream has received a GET but before any complete record exists.

The honest daemon’s sync_all() and no-overwrite logic are useful against ordinary faults, but the adversary controls whether that daemon runs.

Minimal reproduction — unexecuted

Replace the sink with a bounded frame reader that returns OK\n and discards all bytes. Confirm that an epoch activates and a successful response includes artifact names while the public artifact endpoint returns nothing.

For the kill window, terminate a test enclave after the upstream acknowledges receiving a request but before the response completes.

Confidentiality relevance

A parent can privately start solving before honest public solvers receive the puzzle. However, the expiration anchor prevents an arbitrarily long hidden head start followed by a newly rebased serving lifetime; see the blocked attacks below.


F5 — Plaintext and intermediate erasure is incomplete

Verdict: VIOLATED for comprehensive erasure; INSUFFICIENT EVIDENCE for external recovery from the residue.

Code

Trace and impact

A sensitive response is copied into capture storage, base64/JSON/CBOR representations, and the returned response buffer. Only the final serialized CBOR buffer is explicitly wrapped in Zeroizing. Dropping the other ordinary containers does not establish that their allocations are wiped.

Private RandomX intermediates also cross a native implementation boundary and ordinary return-value storage. The supplied code does not establish whether native scratchpads, JIT state, temporary registers, or compiler-generated copies are cleared.

This increases the consequences of a later enclave memory-disclosure defect. It does not by itself let parent root read protected enclave RAM.

Minimal reproduction — unexecuted

In an instrumented development build, use a unique plaintext canary and inspect process memory/allocator frees after request completion. Audit native VM destruction and compiler output for private-chain intermediates. Such testing can demonstrate residue; absence of a canary in one test is not a proof of erasure.

Lease qualification

The 30-second fetch timeout and 30-second publication timeout bound normal asynchronous waits (v2_proxy.rs:90–107). They are not a hard real-time deadline on synchronous CBOR serialization, encryption, an NSM ioctl, scheduler starvation, or a stalled native call.

The expiration watchdog removes the global epoch reference, but existing request leases retain the key until their work exits. Response buffers may remain after the epoch key lease is dropped.


F6 — Released epoch keys allow creation of valid-looking historical records

Verdict: VIOLATED — post-release record provenance without prior trusted receipts.
Classification: Authenticity after release, not early confidentiality.

Code

Attacker capability and trace

After legitimately solving a puzzle:

  1. Keep the original signed manifest unchanged.
  2. Choose fabricated audit plaintext and an existing or new sequence number.
  3. Run encrypt_record() with the recovered epoch key.
  4. Publish the resulting record under its correct content-addressed filename.
  5. The normal decryptor accepts it.

A digest newly supplied by a malicious archive does not distinguish this object from an original enclave-produced object.

Minimal reproduction — unexecuted

Solve a short-work puzzle, then use the library to encrypt fabricated CBOR under its key and the original manifest. Confirm successful decryption and commitment verification without possession of the service signing key.

Additional historical limit

The signed manifest contains no publication timestamp (lib.rs:28–40). Archived evidence binds the signer and parameters, but can be paired with another matching puzzle from that signer’s lifetime. The archive API correctly does not establish when that particular puzzle first became public.

A client’s independently retained, authenticated response header containing the original record digest can protect that particular object against later substitution. Relay.get() returns headers but does not automatically establish durable external custody of such a receipt.


3. Strongest reasons important attacks are blocked

These are conditional guarantees, not proofs of complete implementation security.

G1 — Attestation substitution does not authenticate an attacker’s TLS endpoint

Code: client.py:143–164; verify.py:52–107,110–142.

The client verifies:

The target request is sent afterward on that same InnerTLS object.

A front end can relay a challenge to a genuine enclave, but a document binding the genuine enclave key does not authenticate the front end’s different TLS key. Replaying historical evidence fails the fresh nonce/live checks.

Unexecuted test: Present an attacker TLS certificate while forwarding only the nonce challenge to a real enclave. Expect SPKI rejection before any /f/https/… request. Also replay a previously accepted document under a fresh challenge.

Limits: PCR authenticity does not establish source safety. The verifier accepts any positive iteration count within its broad bound; the exact accepted production count and epoch behavior depend on the independently accepted measurement, not an independent client minimum-duration policy.

G2 — Seven generation workers do not imply seven independent public solver jobs

Code: timelock/src/lib.rs:238–284,312–387,473–495.

Generation knows all seven random seeds and computes the seven chains concurrently. A public solver initially knows only seed 1. The endpoint of segment (i), through HKDF and authenticated decryption, reveals seed (i+1); segment 7 reveals the independently random epoch key.

The loop inputs bind epoch, segment, iteration and previous state. There is no visible XOR-mask cancellation, plaintext seed reuse, or public table of generation endpoints.

Unexecuted test: Instrument a short-work generation and independent solver to compare every chain boundary, and attempt to start segment 2 using only published fields. Exercise cross-segment and cross-epoch wrap substitution.

Limits: Besides exact dependent evaluation, the wrapping argument needs the unreleased endpoints to provide adequate unpredictable key material to HKDF. A statement only about the cost of computing an exact chain result is not, by itself, a complete compositional security proof. No concrete failure of that property is established here.

G3 — Delayed host messages cannot renew an exposed puzzle’s lifetime

Code: v2_epoch.rs:76–101,130–146; v2_proxy.rs:81–87; attest.rs:84–95.

The critical ordering is sound in the visible source:

  1. Publish attestation evidence, which contains no puzzle seed.
  2. Set monotonic and NSM activation anchors.
  3. Send the puzzle.
  4. Wait for puzzle/bundle ACKs.
  5. Recheck both expiry conditions before activation.

Retries do not reset those anchors. A 60-second outer activation timeout also limits normal publication waits.

The future-publication deadline is retained independently of the active key’s global reference. The watchdog erasing an old key does not authorize early publication of the future puzzle.

Unexecuted test: Delay puzzle ACK past its anchored lifetime; it must never become ready. Repeat with delayed bundle ACK, failed ACK/retry, NSM failure, and a successor generated before the previous deadline.

Limits: Tokio timeouts are cooperative, and this argument depends on the local NSM/kernel time integration. It does not establish a week-long solver duration.

G4 — Restart and external checkpoints do not provide a production puzzle-import path

Code: v2_main.rs:155,169–176; v2_epoch.rs:104–125,148–149; timelock/src/lib.rs:458–495.

An ordinary restart discards active state and creates fresh signing, TLS, seed and epoch-key material. Even a repeated numerical epoch would not reproduce the random dataset, seeds, and key.

Checkpoint import exists in the standalone solver, not the production enclave lifecycle. Its unkeyed checksum is only corruption detection. A malicious checkpoint can claim advanced coordinates, but random state must still authenticate the wrap and yield the committed final key.

Unexecuted test: Restart repeatedly and compare signers, manifests and key commitments. Feed a solver a checkpoint with recomputed checksum and false final coordinates; require wrap/commitment failure. Instrument production dispatch to confirm no external input reaches solve() or supplies generation seeds.

Limits: A genuine advanced checkpoint is equivalent to work already performed and can be shared. A leaked private later-segment seed or endpoint would reduce remaining work without violating RandomX.

G5 — Chosen requests do not visibly become key or plaintext-decryption oracles

Code: v2_proxy.rs:53–59,76–107,127–158,169–173; timelock/src/lib.rs:73–115.

Other clients can select URLs and obtain known responses and corresponding ciphertexts, but:

Importantly, sequence is authenticated context, not the XChaCha nonce. Actual nonce uniqueness is probabilistic through OS-generated 192-bit random nonces (lib.rs:103–105). The sequence-exhaustion test alone does not prove nonce uniqueness.

DNS changes and ECH fallback retain hostname certificate verification. Redirects are restricted again to public HTTPS/443. A malicious parent can disregard the requested IP, but must still defeat endpoint authentication to impersonate an unrelated destination.

Unexecuted test: Collect many chosen-plaintext records, mutate context/nonce/ciphertext fields, and test cross-puzzle substitution. Redirect to private addresses, HTTP, and wrong-certificate public endpoints. Require rejection without target-content logs.


4. Unresolved questions and missing evidence

Native RandomX and FFI — INSUFFICIENT EVIDENCE

The Rust binding has useful ownership properties:

But unsafe impl Sync and native calls rely on facts not established by the header. I cannot assess concurrent mutation, native memory safety, actual ARM JIT behavior, scratchpad cleanup, exception handling, or whether all flag combinations implement the intended algorithm correctly.

Please supply the complete frozen vendor/randomx tree, SHA256SUMS, CMake configuration and actual compile flags—especially VM/cache/dataset code, AArch64 JIT/assembly, memory allocation/protection, and hash implementations.

Requested tests — unexecuted: Independent full/light/interpreter/JIT cross-checks; sanitizer-supported native testing; concurrent VM creation/use/destruction; allocation-failure paths; intermediate-state checks against an independently implemented reference.

A measured native defect remains a defect. Conversely, native code’s presence alone is not evidence of an exploitable vulnerability.

Kernel, bootstrap, entropy, clock and isolation plumbing — INSUFFICIENT EVIDENCE

Direct NSM entropy with no production fallback is a strong design choice (attest.rs:43–61). The custom GetRandom decoder bounds responses and uses zeroizing storage (attest.rs:216–247).

However, the two-step reseed argument specifically depends on the kernel’s CRNG implementation and configuration (attest.rs:198–214,251–269). That kernel source and bootstrap are absent.

Please supply:

Upstream rustls uses its normal time source rather than the explicit NSM admission timestamp (net.rs:57–63). I need the bootstrap/timekeeping evidence to assess certificate validity under the permitted parent capabilities. This is an unresolved dependency, not a demonstrated expired-certificate bypass.

Requested tests — unexecuted: Entropy-failure injection, per-CPU/NUMA CRNG reseed validation against source, startup clock manipulation within realistic parent capabilities, NSM failure during rollover, and dump/residue inspection.

Side channels — INSUFFICIENT EVIDENCE

RandomX evaluates secret-dependent chains for long periods alongside request handling. The supplied source does not establish isolation from all relevant cache, scheduling, contention, JIT, or other side channels.

I have not identified a concrete parent-observable channel that recovers private chain states from this snapshot. Nor does the strong RandomX assumption exclude such an implementation leak.

Needed evidence: The actual Nitro/CPU isolation configuration and a capability-specific analysis of what the parent can observe or influence. Testing should target private seeds and intermediates, not merely total calibration time.

Whole-process bounds and exceptional paths — INSUFFICIENT EVIDENCE

There are sensible connection, request, body, DNS, and publication bounds. Nevertheless:

Relevant code: v2_main.rs:182–195; v2_proxy.rs:42–49,98–119,167–168,197; dns.rs:194–197; workspace Cargo.toml:44–46.

These warrant resource-lifetime and exceptional-path review. I am not claiming a demonstrated OOM-to-key-leak or secret-bearing panic.

Requested tests — unexecuted: Slow readers with maximum responses, repeated disconnects, cancellation at each fetch stage, allocation faults, and reachable panic-path/log capture under the actual enclave memory allocation.

Build-to-measurement and operational deployment — INSUFFICIENT EVIDENCE

The Dockerfile fixes useful inputs and copies only the v2 executable into the enclave image. That does not establish the actual deployed image, native correctness, or public archive operations.

The supplied CI workflow delegates crucial behavior to omitted scripts, and the documentation describes a separately pinned CI revision. I cannot independently validate that chain from the README and expected PCR JSON.

Please supply the exact pinned CI scripts/revision, EIF/kernel tooling inputs, Python dependency lock, and archive/solver deployment source. For operational claims, provide full-duration generation, rollover and independent recovery evidence, while recognizing that those observations still cannot prove an adversarial timing lower bound.


5. Bottom line on A and B

A. Can an in-scope adversary recover or infer contents early?

Yes, content inference is supported by concrete code paths. Distinct candidate requests/responses can be identified through unpadded lengths and destination behavior. Hostname-carried content reaches DNS. An in-scope upstream TLS terminator receives plaintext immediately.

For arbitrary unpredictable contents sent to an independently authenticated, non-adversarial destination TLS endpoint, the visible application design provides substantial protection against ordinary parent/front-end interception. I did not find a demonstrated generic plaintext-decryption bypass on that path.

B. Can an adversary obtain early decryption capability or cause use of a pre-solved puzzle?

No practical early key-extraction or stale-puzzle-injection exploit is demonstrated by the supplied application code. The hidden-seed wrapping structure, fresh generation, no-import lifecycle, pre-disclosure expiry anchor, independent expiry checks, and peer-bound attestation are meaningful barriers.

But the broader guarantee remains unsupported:

Recommendation: Do not describe this as week-long content confidentiality against the stated colluding adversaries. A defensible narrower description is: attested encrypted relay transport with public audit recovery after a fixed amount of conditionally sequential work, subject to traffic-analysis leakage, upstream TLS endpoint trust, daily-epoch aging, surviving artifacts, and unresolved implementation-security dependencies.