From 4785ed58ef17c0662551dd9983b56c851a6a7a35 Mon Sep 17 00:00:00 2001 From: abrichr Date: Sat, 25 Jul 2026 15:45:42 -0400 Subject: [PATCH 1/2] docs: sync security and release evidence --- docs/concepts/deployment-matrix.md | 13 ++-- docs/concepts/regulated-execution.md | 10 +-- docs/desktop/install.md | 10 +-- docs/ecosystem/index.md | 2 +- docs/get-started/index.md | 12 ++-- docs/get-started/what-works-today.md | 4 +- docs/guides/deploy-on-prem.md | 8 ++- docs/guides/hosted.md | 36 ++++++++--- docs/guides/run-a-deployment.md | 12 ++-- docs/guides/security-and-data-handling.md | 58 ++++++++++++++---- docs/guides/security-review.md | 74 +++++++++++++++++------ docs/reference/configuration.md | 9 +-- 12 files changed, 174 insertions(+), 74 deletions(-) diff --git a/docs/concepts/deployment-matrix.md b/docs/concepts/deployment-matrix.md index f337663..38a5d0a 100644 --- a/docs/concepts/deployment-matrix.md +++ b/docs/concepts/deployment-matrix.md @@ -100,13 +100,12 @@ Production selects live mode explicitly. Development mock mode is visibly synthetic. A missing production dependency makes the affected operation unavailable rather than substituting a simulated success. -The hosted recorder passed its bounded, non-simulated live-provider -qualification on a Flow 1.8.0 worker. Authenticated live health qualified the -exact-version replay and compiler service identities, and three independent -pre-payment trials verified tenant-bound live Checkout and refusal before -entitlement. The first genuine paid subscription extends that operational -evidence through webhook activation, managed execution, usage, portal, and -cancellation. +The retained hosted-recorder qualification used a Flow 1.8.0 worker. The live +runner and compiler now report the published Flow 1.23.0 identity, and public +readiness checks live authentication, database, private storage, runner, +compiler, recorder, callbacks, scheduler, retention, secret encryption, +validation policy, and billing dependencies. That is configuration and service +identity evidence, not a customer workflow qualification or SLA. Stripe is the commercial source of truth for pricing. This matrix does not create a price, quota, SLA, certification, or backend entitlement. diff --git a/docs/concepts/regulated-execution.md b/docs/concepts/regulated-execution.md index 708dc0c..6d05f4e 100644 --- a/docs/concepts/regulated-execution.md +++ b/docs/concepts/regulated-execution.md @@ -105,11 +105,11 @@ still apply, and `run` is honest about them: surface the action wrote to: **same-surface** confirmation, not an independent system-of-record check. A REST/FHIR/document-hash verifier reads the *record*; a screen read-back reads the *pixels*. -- **Encryption is opt-in at authoring time.** `Workflow.save(..., encrypt=True)` - seals workflow JSON and template crops, but normal compilation writes - plaintext. `run` refuses plaintext by default; keep full-disk encryption as - defense in depth and use `--strict-templates` to refuse any unsealed image - asset. +- **Encryption is opt-in at authoring time.** `openadapt flow seal SOURCE --out + DESTINATION` seals workflow JSON and template crops, but normal compilation + writes plaintext. `run` refuses plaintext by default; keep full-disk + encryption as defense in depth and use `--strict-templates` to refuse any + unsealed image asset. - **A green certification is scoped to what the policy asserts.** `certify` enforces the policy you wrote; a gap the policy does not name is not caught by `run`. diff --git a/docs/desktop/install.md b/docs/desktop/install.md index de48a91..a0f7b15 100644 --- a/docs/desktop/install.md +++ b/docs/desktop/install.md @@ -17,8 +17,9 @@ you explicitly push it to a [cloud workspace](connect-to-cloud.md). Get the installer from [openadapt.ai/download](https://openadapt.ai/download). The page detects your OS and architecture and offers the right build. Public Beta release -`desktop-v0.10.0` ships the complete Windows, macOS, and Linux installer set with -`SHA256SUMS` and per-platform provenance metadata. +`desktop-v0.12.1` ships the complete Windows, macOS, and Linux installer set with +`SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and build-provenance +attestations. | OS | Installer | |---|---| @@ -33,8 +34,9 @@ and can connect to Cloud for governed reports and updates. ## 2. Get past the first-launch OS warning -The current builds are **not code-signed yet**, so your OS shows a one-time -warning at first launch. Expected for unsigned software, not a download problem. +The Windows/Linux builds are **unsigned** and the macOS builds are **ad-hoc +signed**, so your OS can show a one-time publisher warning at first launch. +Verify `SHA256SUMS` and the release provenance before overriding it. === "macOS" diff --git a/docs/ecosystem/index.md b/docs/ecosystem/index.md index 52a019c..cb6801c 100644 --- a/docs/ecosystem/index.md +++ b/docs/ecosystem/index.md @@ -32,7 +32,7 @@ module inside it: | [OpenAdapt](https://github.com/OpenAdaptAI/OpenAdapt) | **Supported** | Installer/meta-package and unified `openadapt flow` dispatcher. | | [openadapt-flow](https://github.com/OpenAdaptAI/openadapt-flow) | **Supported** | Canonical compiler and governed runtime. Drives web, native Windows, native macOS, native Linux, RDP, and Citrix/VDI as first-class substrates behind one backend protocol. | | [openadapt-cloud](https://github.com/OpenAdaptAI/openadapt-cloud) | **Supported** | Live control plane for the public managed-browser subscription: organizations, exact-hash admission, runner orchestration, reports, billing, and usage. | -| [openadapt-desktop](https://github.com/OpenAdaptAI/openadapt-desktop) | **Supported** | Public Beta `desktop-v0.10.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. Every installer path was installed, launched, and uninstalled in the native release workflow; the release includes exact checksums, platform metadata, and build attestations. | +| [openadapt-desktop](https://github.com/OpenAdaptAI/openadapt-desktop) | **Supported** | Public Beta `desktop-v0.12.1` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. Every installer path was installed, launched, and uninstalled in the native release workflow; the release includes exact checksums, a CycloneDX SBOM, platform metadata, and build-provenance attestations. | | [openadapt-agent](https://github.com/OpenAdaptAI/openadapt-agent) | **Supported** | Active v2 bridge that exposes governed Flow bundles to MCP clients and Agent Skills. The pre-v2 model-driven execution wrapper is the deprecated line; the repository itself is active. | | [openadapt-capture](https://github.com/OpenAdaptAI/openadapt-capture) | **Supported** | Canonical native screen, mouse, keyboard, timing, and window-scoped recorder behind Flow's Windows, macOS, Linux, RDP, and Citrix recording paths. Capture 1.1 retains Windows UIA evidence at action time; remote sessions remain externally black-box. Browser recording remains inside Flow's Playwright listener. | | [openadapt-privacy](https://github.com/OpenAdaptAI/openadapt-privacy) | **Supported** | Optional PII/PHI scrubbing used on configured persist, log, and upload paths. | diff --git a/docs/get-started/index.md b/docs/get-started/index.md index 3b26fd9..93a8414 100644 --- a/docs/get-started/index.md +++ b/docs/get-started/index.md @@ -87,10 +87,9 @@ A real deployment must replace demo drift flags with explicit backend, effect, durability, and policy configuration: ```bash -# 10. Prepare an encrypted candidate, then inspect and pass the run gate -cp -R bundle-v2 bundle-prod +# 10. Seal an encrypted candidate, then inspect and pass the run gate export OPENADAPT_BUNDLE_KEY='' -python -c 'from openadapt_flow.ir import Workflow; w=Workflow.load("bundle-prod"); w.save("bundle-prod", encrypt=True)' +openadapt flow seal bundle-v2 --out bundle-prod openadapt flow certify bundle-prod --config deployment.yaml openadapt flow run bundle-prod --config deployment.yaml --dry-run openadapt flow run bundle-prod --config deployment.yaml @@ -98,9 +97,10 @@ openadapt flow run bundle-prod --config deployment.yaml Follow [Run a deployment](../guides/run-a-deployment.md), then complete the [security and deployment review](../guides/security-review.md). Do not promote a -bundle just because the sample-app tour passed. The base CLI has no dedicated -`seal` verb yet, so the encryption step uses the shipped library API; key -custody and rotation belong to the deployment. +bundle just because the sample-app tour passed. `seal` preserves the source, +refuses symlinks and an existing destination, encrypts the workflow and template +crops, verifies the result, and expires any certification inherited from the +source. Key custody and rotation belong to the deployment. ## Beyond one demonstration diff --git a/docs/get-started/what-works-today.md b/docs/get-started/what-works-today.md index 8fe7727..a3f58c4 100644 --- a/docs/get-started/what-works-today.md +++ b/docs/get-started/what-works-today.md @@ -53,11 +53,11 @@ customer-controlled runtime connected to the same governance model. | Native Linux backend | **Supported** | Required current-main job [`linux-atspi-x11`](https://github.com/OpenAdaptAI/openadapt-flow/actions/runs/30059807758/job/89378981573) at exact Flow commit `3de5fc67acf3024a621f812c5a6ed9be07fac335` ran one fresh GTK3 process per trial on Ubuntu 24.04 X11/AT-SPI. It confirmed 3/3 exact-file effects, 3/3 ambiguous-target refusals, and 3/3 stale-target refusals, with 0 silent incorrect successes, 0 over-halts, 0 operator interventions, and 0 model calls. | Native receipts prove AT-SPI delivery only; independent exact file bytes or confirmed absence prove effects. This is bounded to the in-tree GTK3 fixture and CI Xvfb image; it does not establish Wayland or arbitrary third-party application support. | | RDP backend | **Supported** | Two bounded results exercise complementary RDP paths. Aardwolf 0.2.14 over a Parallels Windows 11 VM completed 3/3 Windows Run-dialog file effects with independent guest-tools readback. The accepted full governed lifecycle at mechanism commit `6031fde` recorded, compiled, and replayed a synthetic note workflow through real FreeRDP3-transported pixels/input: 3/3 healthy effects and 3/3 drift safe-halts, with zero model calls, silent incorrect successes, false completions, drift writes, or healthy over-halts. Consequential remote actions now acquire a fresh frame, re-resolve target and identity, and use a one-shot input lease that refuses changed session context, pixels, dimensions, or readiness before delivery. Review the [Aardwolf/Windows report](https://github.com/OpenAdaptAI/openadapt-flow/blob/6610d24cebba27918b8ea507b2f05a094057ac85/benchmark/rdp/results_82a658a_20260718.sanitized.json), the [FreeRDP lifecycle report](https://github.com/OpenAdaptAI/openadapt-flow/blob/affedc5f1f0de533a0744deaa8e30a203c91c6b3/benchmark/rdp_ladder/results.json), [Flow PR #142](https://github.com/OpenAdaptAI/openadapt-flow/pull/142), [Flow PR #177](https://github.com/OpenAdaptAI/openadapt-flow/pull/177), and [Flow PR #238](https://github.com/OpenAdaptAI/openadapt-flow/pull/238). | The Windows batch qualifies its exact task, snapshot, transport, and oracle. The FreeRDP batch qualifies a synthetic Linux Tk task over a real RDP round trip; it is not Aardwolf, a Windows-app qualification, Citrix ICA/HDX, or WAN-captured drift. The two-phase mechanism is separately covered by runtime and backend refusal tests; it does not enlarge those bounded application results. | | Citrix / VDI backend | **Supported** | The dedicated `--backend citrix` path selects the exact Citrix Workspace/Viewer owner, optionally binds an exact title, requires a readiness marker for governed `run`, carries the closed target into durable resume, and uses the shared pixel identity, effect, policy, and halt contracts. Consequential input reacquires the exact client window, focus, geometry, readiness, fresh pixels, resolved target, and record identity, then refuses any change before the first input edge. The accepted no-DOM qualification completed 3/3 healthy effects and 3/3 severe-drift safe-halts with 0 model calls, silent incorrect successes, false completions, healthy over-halts, or drift writes. Review the [immutable report](https://github.com/OpenAdaptAI/openadapt-flow/blob/f6faac5b900b78cbda5980de0e983a9f987285ac/benchmark/citrix_workspace/results.json), [Flow PR #183](https://github.com/OpenAdaptAI/openadapt-flow/pull/183), and [Flow PR #238](https://github.com/OpenAdaptAI/openadapt-flow/pull/238). | The accepted artifact explicitly records `code_readiness_accepted: true` and `ica_hdx_accepted: false`. It qualifies the shipped Citrix Workspace-window backend contract over a no-DOM canvas stand-in, not a counted real ICA/HDX batch. The exact ICA/HDX client, codec, latency, DPI, lock/readiness, input, identity, and effect matrix is a separate per-deployment qualification boundary. | -| Desktop authoring GUI and tray | **Supported / Beta** | Public `desktop-v0.10.0` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. All six installer paths were installed, launched, and uninstalled in the native release workflow; the published set includes checksums and per-platform provenance metadata. | Builds are not yet fully code-signed/notarized, so verify `SHA256SUMS` and provenance before overriding the OS publisher warning. The app and CLI drive the same released compiler/runtime. | +| Desktop authoring GUI and tray | **Supported / Beta** | Public `desktop-v0.12.1` provides Windows MSI/NSIS, macOS arm64/x64 DMG, and Linux AppImage/DEB installers. All six installer paths were installed, launched, and uninstalled in the native release workflow; the release includes `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and build-provenance attestations. | Windows/Linux remain unsigned and macOS is ad-hoc signed, so verify checksums and provenance before overriding the OS publisher warning. The app and CLI drive the same released compiler/runtime. | | Hosted CLI connectivity | **Supported / public offer** | `login`, exact-hash artifact preparation/upload, one-time runtime validation, bound replacement activation, and `report-break` connect the local engine to the live control plane. | Upload requires destination policy and an approved sanitized derivative; checkout never bypasses an egress refusal. | | Artifact sanitation and local review | **Supported / launch gate** | The sanitized-derivative pipeline inventories, transforms, rescans, manifests, hashes, and supports local review/approval. | The raw original remains sensitive; unknown or unresolved content is refused; runtime observations can reintroduce PHI/PII. | | Cross-engine hosted validation | **Supported / launch gate** | `validate-hosted` binds an approved recording and bundle, compiler provenance, strict lint, policy certification, derived risk class, and successful replay report to a one-time Cloud challenge. | It is operator self-attestation signed with the ingest token, not an independently observed certification. Exact deployment policy, risk-class, and deployed compiler-version allowlists still apply. | -| Hosted browser recorder and runtime health | **Supported / bounded launch component** | A non-simulated hosted browser session on `openadapt-flow` 1.8.0 produced PNG frames and retained input evidence, assembled a compileable recording, finalized one workflow idempotently, enforced resource limits, and cleaned up ephemeral qualification data. Authenticated live health probes also qualified the exact-version replay and compiler service identities. | Explicitly initiated, public-HTTPS, non-regulated authoring only. Raw observations remain private inside the declared hosted boundary. Health proves deployed service identity and reachability, not a paid checkout-to-run lifecycle or successful managed replay. | +| Hosted browser recorder and runtime health | **Supported / bounded launch component** | A retained non-simulated hosted session on `openadapt-flow` 1.8.0 produced frames and input evidence, assembled a compileable recording, finalized one workflow idempotently, enforced resource limits, and cleaned up ephemeral qualification data. The current live runner and compiler report the published 1.23.0 identity; live readiness also checks auth, database, storage, callbacks, scheduler, retention, secrets, validation policy, and billing. | Explicitly initiated, public-HTTPS, non-regulated authoring only. Raw observations remain private inside the declared hosted boundary. Readiness proves deployed dependencies and service identity, not a customer workflow qualification or SLA. | | Hosted dashboard/control plane | **Supported / public offer** | Authentication, organizations, exact-hash bundle ingest, immutable run admission, browser runner orchestration, structural reports, replacement activation, billing, and metering form the managed lifecycle. | Production uses live dependencies and fails unavailable rather than substituting mock behavior. | | Hosted execution | **Supported / public offer** | Live Stripe Checkout connects onboarding and subscription entitlements to managed browser execution; the runner verifies exact admitted bundle bytes and authenticated callbacks. | The public subscription covers approved browser workflows. Other substrates use separately scoped deployments and commercial terms. Checkout does not create an SLA or certification. | | Air-gapped on-prem package | **Supported** | A local queue, systemd unit, minimized hash-chained audit log, and air-gap checks are provided. | Full-disk encryption and operational hardening remain operator/deployment responsibilities. | diff --git a/docs/guides/deploy-on-prem.md b/docs/guides/deploy-on-prem.md index e207f8a..8f5aba7 100644 --- a/docs/guides/deploy-on-prem.md +++ b/docs/guides/deploy-on-prem.md @@ -139,16 +139,20 @@ holds the disk key). At-rest protection has three layers: |---|---|---| | The disk holding `storage_root` (bundles, runs, audit, frames) | **Operator full-disk encryption** (LUKS / BitLocker / FileVault) | REAL: the primary PHI/PII-at-rest control. Operator-provisioned | | The identity band inside `workflow.json` | **Salted-hash `identity_template`** (no plaintext name / DOB / MRN; optional external `OPENADAPT_FLOW_IDENTITY_SALT`) | REAL. A hash of a low-entropy identifier is brute-forceable by a holder of both bundle and salt, so it is **not** a cryptographic seal | -| The bundle `workflow.json` + durable checkpoints | **Opt-in AES-256-GCM sealing** via `OPENADAPT_BUNDLE_KEY` (`Workflow.save(encrypt=True)`; scrypt-derived key) | REAL (opt-in, shipped). A wrong/missing key or tampered ciphertext fails loud and safe | +| The bundle `workflow.json` + durable checkpoints | **Opt-in AES-256-GCM sealing** via `OPENADAPT_BUNDLE_KEY` (`openadapt flow seal` for the bundle; the same key for runtime checkpoints) | REAL (opt-in, shipped). A wrong/missing key or tampered ciphertext fails loud and safe | | `templates/*.png` (recorded screen crops of identifiers) | **AES-256-GCM sealing with the bundle key** plus full-disk encryption and governance guards | REAL when bundle encryption is enabled; plaintext crops are removed after sealing and authenticated ciphertext is verified on load | Enable the per-bundle seal for cryptographic at-rest protection that does not depend solely on the volume: ```bash -export OPENADAPT_BUNDLE_KEY=… # seals workflow.json, template crops, and checkpoints +export OPENADAPT_BUNDLE_KEY=… +openadapt flow seal bundle-v2 --out bundle-prod # seals workflow.json + template crops ``` +Run and resume the sealed destination with the same injected key so durable +checkpoints are encrypted as they are written. + !!! warning "Identifier crops remain regulated data" The identity check needs a **rendered crop of the identifier** (an image of the MRN / name as it appeared on screen), stored as `templates/*.png`. These diff --git a/docs/guides/hosted.md b/docs/guides/hosted.md index eaef471..5d7f4a2 100644 --- a/docs/guides/hosted.md +++ b/docs/guides/hosted.md @@ -32,7 +32,7 @@ switching, and sign-out. | Surface | Launch status | Boundary | |---|---|---| | Local browser record -> compile -> managed execute | **Beta / public offer** | Governed authoring and validation remain local; managed execution uses the qualified browser substrate. | -| Hosted browser record -> compileable workflow | **Beta / bounded launch component** | Non-simulated live-provider qualification passed on `openadapt-flow` 1.8.0 for a public, non-regulated target. Authenticated live health also qualified the exact-version replay and compiler service identities. This is a separate raw-observation boundary, not the reviewed-derivative upload lane. | +| Hosted browser record -> compileable workflow | **Beta / bounded launch component** | The retained non-simulated provider qualification used `openadapt-flow` 1.8.0; the current live runner and compiler report the published 1.23.0 identity. This is a separate raw-observation boundary, not the reviewed-derivative upload lane. | | Account, organization, onboarding | **Beta / public offer** | Checkout and sign-in bind the subscription to an isolated organization. | | Structural run history and reports | **Beta / public offer** | Safety depends on the workflow's configured identity, effect, and policy checks. Repair and validation remain local. | | Checkout, portal, entitlements, metering | **Beta / public offer** | Live Stripe Checkout, signed webhooks, entitlements, usage, and the billing portal form one managed subscription contract. | @@ -57,13 +57,12 @@ The hosted recorder is a real, bounded authoring path rather than a simulated demo. A qualified hosted browser session produced PNG frames, accepted and retained input evidence, assembled a native recording, created one compileable workflow idempotently, enforced its resource limits, and removed the ephemeral -qualification data. That qualification used an `openadapt-flow` 1.8.0 worker. -Authenticated live health probes separately confirmed the deployed replay and -compiler endpoints, their service identities, and their exact Flow version. -Health evidence is complemented by three independent production pre-payment -trials that verified tenant-bound live Checkout and refusal before entitlement. -The first genuine paid subscription will extend that evidence through signed- -webhook activation, managed execution, usage, portal, and cancellation. +qualification data. That retained qualification used an `openadapt-flow` 1.8.0 +worker. The live runner and compiler now report the published 1.23.0 identity, +and the public readiness endpoint verifies the configured live dependencies, +including authentication, storage, callbacks, scheduling, retention, secret +encryption, validation policy, and billing. Readiness is dependency evidence, +not a customer workflow qualification or an SLA. The recorder accepts only public HTTPS DNS hosts and refuses credentials in the start URL, literal IP addresses, private or mixed DNS answers, and private @@ -325,6 +324,24 @@ what “production fails closed instead of silently using mock mode” means. It protects customers from believing a fabricated development run actually executed; it does not disable production functionality. +## Retention, deletion, and restore evidence + +The hosted service applies a versioned retention policy to recordings, reports, +run metadata, and the declared recovery window. Legal holds pause eligible +deletion. Tenant erasure is scoped to one organization and produces an +append-only receipt containing resource identifiers, counts, and digests rather +than deleted payloads. + +Scheduled destructive retention is separately gated on a recent complete +scratch-restore receipt. The operator path exports roles, schema, data, and +every private Storage object; reads the source twice; restores only to an +explicitly confirmed scratch project; and verifies exact hashes before recording +the receipt. Production currently has no qualifying provider recovery point or +complete scratch-restore receipt, so scheduled deletion remains gated. This does +not claim provider PITR, object-storage recovery, or a backup SLA. The live +[readiness endpoint](https://app.openadapt.ai/api/health/ready) exposes retention +configuration independently from that destructive-operation gate. + ## Production control checklist Before directing traffic to a production deployment, verify: @@ -344,7 +361,8 @@ Before directing traffic to a production deployment, verify: - request-bound idempotency, one active run per workflow, and a lost provider acknowledgement that remains single-flight until callback or operator review; - Stripe Checkout, portal, signed idempotent webhooks, entitlements, and usage; -- logs, alerts, deletion, retention, backup, restore, update, and rollback; +- logs, alerts, legal holds, tenant erasure, deletion receipts, complete + database + object-storage scratch restore, update, and rollback; - a clean-account sign-up -> subscribe -> record sanitize/review/approve -> recording push -> local compile/lint/certify/replay -> bundle sanitize/review/approve -> `validate-hosted` -> attested bundle push -> diff --git a/docs/guides/run-a-deployment.md b/docs/guides/run-a-deployment.md index 4ddb2f4..01bb161 100644 --- a/docs/guides/run-a-deployment.md +++ b/docs/guides/run-a-deployment.md @@ -47,12 +47,11 @@ policy it will run under. uncertified policy, unarmed consequential action, write without an effect contract, unavailable verifier without explicit approval, or broken manifest. Normal compilation creates a plaintext bundle, so create a production copy and -seal it with the shipped library API before admission. +seal it with the shipped CLI before admission. ```bash -cp -R bundle bundle-prod export OPENADAPT_BUNDLE_KEY='' -python -c 'from openadapt_flow.ir import Workflow; w=Workflow.load("bundle-prod"); w.save("bundle-prod", encrypt=True)' +openadapt flow seal bundle --out bundle-prod openadapt flow certify bundle-prod --config deployment.yaml openadapt flow run bundle-prod --config deployment.yaml --dry-run @@ -66,9 +65,10 @@ demo-only `--drift` teaching aid is not offered; the backend URL, system of record, actuation tier, durability, and policy come from the config. Direct flags override individual fields for a single run. -There is no dedicated `seal` CLI verb yet. `Workflow.save(..., encrypt=True)` -seals workflow JSON and template crops; the key comes from the environment here. -Production key custody, rotation, and recovery are operator responsibilities. +`seal` preserves the source, refuses symlinks and an existing destination, +encrypts workflow JSON and template crops, verifies the result, and expires any +certification inherited from the source. The key comes from the environment; +production key custody, rotation, and recovery are operator responsibilities. ## Verify writes against the system of record diff --git a/docs/guides/security-and-data-handling.md b/docs/guides/security-and-data-handling.md index 1c797ec..899d86b 100644 --- a/docs/guides/security-and-data-handling.md +++ b/docs/guides/security-and-data-handling.md @@ -112,14 +112,18 @@ the control on each. The posture in brief: one-time `PlaintextPHIWarning`: an operator can never believe a run is de-identified when it is not. ([PRIVACY.md](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/PRIVACY.md)) -- **Encryption at rest, applied to the artifacts that matter.** Opt-in - AES-256-GCM sealing (`Workflow.save(encrypt=True)` with - `OPENADAPT_BUNDLE_KEY`) encrypts `workflow.json`, every template screenshot - crop, and durable run checkpoints into authenticated containers. No +- **Encryption at rest, applied to the artifacts that matter.** The production + `openadapt flow seal SOURCE --out DESTINATION` path, with + `OPENADAPT_BUNDLE_KEY` injected from the deployment's secret manager, uses + AES-256-GCM to encrypt `workflow.json`, every template screenshot + crop, and the same key encrypts durable run checkpoints when the runtime + writes them. No cleartext PHI/PII-bearing screenshot remains on disk in an encrypted bundle, and - keyed loads decrypt in memory only. A wrong key or a tampered ciphertext - fails loudly, never partially. The identity band in a compiled bundle is a - salted hash, not plaintext. + keyed loads decrypt in memory only. The command preserves the source, refuses + symlinks and an existing destination, verifies the sealed result, and expires + inherited certification. A wrong key or a tampered ciphertext fails loudly, + never partially. The identity band in a compiled bundle is a salted hash, not + plaintext. ([phi_at_rest.md](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/phi_at_rest.md)) - **Encryption in transit on the desktop control channel.** The Windows agent channel that carries live screenshots runs HTTPS with a per-run self-signed @@ -195,6 +199,36 @@ you can hand to an auditor: a repeatable pre-flight for your own attestation. ([ON_PREM.md](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/ON_PREM.md)) +## Hosted retention, deletion, and recovery + +The hosted service applies a versioned retention policy to recordings, reports, +run metadata, and the declared recovery window. Legal holds pause eligible +deletion. Tenant erasure is organization-scoped and produces an append-only, +PHI/PII-free receipt with identifiers, counts, and digests rather than deleted +payloads. + +Destructive scheduled retention has a separate recovery gate: it refuses to run +without a recent receipt proving a complete database **and private object +storage** restore into an isolated scratch environment. The restore tooling +exports roles, schema, data, and every content-addressed object, reads the source +twice, restores only to the confirmed scratch target, and rehashes the result. +The production provider currently reports no available provider recovery point, +so scheduled deletion remains gated. That is not a claim of provider PITR or a +backup SLA. The public +[readiness endpoint](https://app.openadapt.ai/api/health/ready) reports the +configured retention component separately from this destructive-operation gate. + +## Release integrity + +The public Desktop `desktop-v0.12.1` release includes Windows, macOS, and Linux +installers, `SHA256SUMS`, a CycloneDX SBOM, per-platform metadata, and GitHub +build-provenance attestations. These prove source and build provenance, not +publisher identity. Windows and Linux installers remain unsigned and macOS +installers are ad-hoc signed; Apple Developer ID/notarization and Windows +Authenticode require the corresponding external identities. Verify the +[release assets](https://github.com/OpenAdaptAI/openadapt-desktop/releases/tag/desktop-v0.12.1) +before overriding an operating-system publisher warning. + ## Deployment options All three shapes run the same engine and the same safety gates. The @@ -255,8 +289,9 @@ supplies the AEAD substrate, not a KMS. **What audit evidence do we get?** Per-run scrubbed `REPORT.md` + `report.json` with identity coverage, effect verdicts, and one-way contract hashes; on-prem, an append-only hash-chained -audit log; and single-use, digest-bound authorization records for governed -runs. ([Read and audit run reports](run-reports.md)) +audit log; hosted, PHI/PII-free retention and deletion receipts; and single-use, +digest-bound authorization records for governed runs. +([Read and audit run reports](run-reports.md)) **Are you SOC 2 / HIPAA certified?** We describe controls, not certifications, in documentation. Request current @@ -274,5 +309,6 @@ reviewer checklist and boundary table, alongside the engine's [phi_at_rest.md](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/phi_at_rest.md), [phi_in_transit.md](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/phi_in_transit.md), and [known limits](https://github.com/OpenAdaptAI/openadapt-flow/blob/main/docs/LIMITS.md). -Everything this page claims is in the open-source repository for your team to -verify. +Engine controls are open source and directly reviewable. Hosted controls expose +their public contracts and live readiness state; the hosted control-plane source +remains proprietary. diff --git a/docs/guides/security-review.md b/docs/guides/security-review.md index 33f9924..fe50d5a 100644 --- a/docs/guides/security-review.md +++ b/docs/guides/security-review.md @@ -82,14 +82,32 @@ controls around those limits. ## Encryption and storage -`Workflow.save(..., encrypt=True)` with `OPENADAPT_BUNDLE_KEY` enables -AES-256-GCM sealing for `workflow.json`, template crops, and durable -checkpoints; encrypted loads decrypt them in memory. Plaintext remains the -default compiler output, and OpenAdapt does not provide a KMS or key-rotation -service. Keep operator-provisioned full-disk encryption for the complete -storage root as defense in depth. The on-prem installer reminds the operator of -this requirement but does not provision or attest LUKS, BitLocker, or -FileVault. +Inject `OPENADAPT_BUNDLE_KEY` from the deployment's secret manager, then run +`openadapt flow seal SOURCE --out DESTINATION`. The command preserves the +source, refuses symlinks and an existing destination, AES-256-GCM encrypts +`workflow.json` and template crops, verifies the sealed result, and expires +inherited certification. Durable checkpoints use the same key and encrypted +loads decrypt in memory. Raw recordings and run reports remain outside this +bundle container, so keep operator-provisioned full-disk encryption for the +complete storage root. OpenAdapt does not provide KMS, key rotation, or disk +encryption. + +## Hosted retention and recovery + +Hosted retention is enforced through a versioned policy for recordings, +reports, run metadata, and the declared recovery window. Legal holds pause +eligible deletion. Tenant erasure is organization-scoped and leaves an +append-only, PHI/PII-free receipt containing resource identifiers, counts, and +digests rather than deleted payloads. + +Scheduled destructive retention additionally requires a recent complete +scratch-restore receipt. The shipped operator path exports roles, schema, data, +and private Storage objects; performs a second exact source read; restores only +to an explicitly confirmed scratch project; rehashes the full result; and then +records the immutable receipt. Production currently has no qualifying provider +recovery point or complete scratch-restore receipt, so this destructive path +remains gated. The configured retention component being ready does **not** imply +provider PITR, object-storage recovery, or a backup SLA. ## Updates and rollback @@ -106,12 +124,14 @@ onboarding, organization isolation, browser runner orchestration, artifacts, reports, teaching, billing, and usage metering. Production explicitly selects live dependencies; a missing runner, storage, or billing dependency returns an operational failure and never substitutes mock success. Mock mode remains for -development and is visibly synthetic. On Flow 1.8.0, the bounded hosted recorder -passed a non-simulated provider record-to-compile qualification, authenticated -live health qualified the exact-version services, and three clean-account -pre-payment trials verified tenant-bound Checkout and refusal before entitlement. -The first genuine paid subscription extends the evidence through signed-webhook -activation, managed execution, usage, portal, and cancellation. +development and is visibly synthetic. The retained non-simulated hosted-recorder +qualification was run on Flow 1.8.0; the live runner and compiler now report the +published Flow 1.23.0 identity. The public readiness endpoint currently verifies +live mode, authentication, database migrations, private storage, runner, +compiler, recorder, callbacks, scheduler, retention policy, secret encryption, +runtime-validation allowlists, and live billing configuration. Readiness proves +those dependencies and contracts are configured and reachable; it is not a +customer workflow qualification or an SLA. Windows UIA, native macOS, native Linux, RDP, and Citrix/VDI are first-class substrates, ordered as scoped deployments and qualified per workflow in their real @@ -149,6 +169,24 @@ coordinates; it does not broaden the bounded qualification results above. See [Hosted browser execution](hosted.md) and [Qualification evidence](../get-started/what-works-today.md). +## Release and secure-development evidence + +Python releases publish immutable wheel and sdist artifacts with PyPI +provenance attestations. Desktop `desktop-v0.12.1` publishes its complete +Windows, macOS, and Linux installer set with checksums, a CycloneDX SBOM, +per-platform metadata, and GitHub build-provenance attestations. The native +installers are still unsigned on Windows/Linux and ad-hoc signed on macOS; +Apple Developer ID/notarization and Windows Authenticode are distinct +credential-dependent gates. + +The public repositories and hosted control plane run pinned secret scanning, +static analysis, and exact dependency audits in CI. Those engineering controls +do not create a SOC 2 report. Incident-response policies and templates are +prepared but are not an operating program until adopted and exercised. Any DPA, +HIPAA BAA, or PHIPA terms require counsel review for the qualified service and +data flow. These are the remaining external gates; they are not inferred from +code presence. + ## Review checklist - Confirm which process can capture screens and inject input. @@ -159,7 +197,8 @@ execution](hosted.md) and [Qualification evidence](../get-started/what-works-tod - Treat bundles, crops, checkpoints, recordings, and `report.json` as sensitive; verify the sanitation manifest and exact approved derivative hash before any upload. -- Verify full-disk encryption and backup/restore outside OpenAdapt. +- Verify full-disk encryption and the complete database + object-storage + recovery procedure for the declared boundary. - Review identity coverage, effects, policy, and approval requirements for each consequential action. - Exercise halt, resume, duplicate write, partial save, stale write, and wrong @@ -167,8 +206,9 @@ execution](hosted.md) and [Qualification evidence](../get-started/what-works-tod - Exercise double-submit, reused-key-with-different-parameters, concurrent run, lost dispatch acknowledgement, and delayed callback scenarios. Confirm that uncertain dispatch is investigated against provider history before any rerun. -- Establish a signed update and rollback procedure; do not rely on the current - stub. +- Verify release checksums and provenance; for unsigned/ad-hoc native builds, + document the publisher-warning procedure until platform signing identities + are provisioned. - Request current legal/compliance artifacts directly. Do not infer SOC 2, HIPAA, PHIPA, or BAA status from architecture documentation. diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md index 5581f78..49752fa 100644 --- a/docs/reference/configuration.md +++ b/docs/reference/configuration.md @@ -34,10 +34,11 @@ every identifier, so review artifacts before egress. See |---|---| | `OPENADAPT_BUNDLE_KEY` | Passphrase used by encrypted bundle saves/loads and durable checkpoints. `run` requires an encrypted bundle by default. | -Encryption is opt-in when a bundle is written through -`Workflow.save(..., encrypt=True)`; normal compile output is plaintext. OpenAdapt -provides the AEAD mechanism, not key custody, rotation, or recovery. See the -[security and deployment review](../guides/security-review.md). +Encryption is opt-in: inject the key and run `openadapt flow seal SOURCE --out +DESTINATION`; normal compile output is plaintext. The same key encrypts durable +checkpoints written during run/resume. OpenAdapt provides the AEAD mechanism, +not key custody, rotation, or recovery. See the [security and deployment +review](../guides/security-review.md). ## The on-prem VLM appliance From 1c6964e869e219f773f68a30fee9a62332b30bbd Mon Sep 17 00:00:00 2001 From: abrichr Date: Sat, 25 Jul 2026 15:47:59 -0400 Subject: [PATCH 2/2] docs: preserve hosted health contract marker --- docs/get-started/what-works-today.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/get-started/what-works-today.md b/docs/get-started/what-works-today.md index a3f58c4..fc43a27 100644 --- a/docs/get-started/what-works-today.md +++ b/docs/get-started/what-works-today.md @@ -57,7 +57,7 @@ customer-controlled runtime connected to the same governance model. | Hosted CLI connectivity | **Supported / public offer** | `login`, exact-hash artifact preparation/upload, one-time runtime validation, bound replacement activation, and `report-break` connect the local engine to the live control plane. | Upload requires destination policy and an approved sanitized derivative; checkout never bypasses an egress refusal. | | Artifact sanitation and local review | **Supported / launch gate** | The sanitized-derivative pipeline inventories, transforms, rescans, manifests, hashes, and supports local review/approval. | The raw original remains sensitive; unknown or unresolved content is refused; runtime observations can reintroduce PHI/PII. | | Cross-engine hosted validation | **Supported / launch gate** | `validate-hosted` binds an approved recording and bundle, compiler provenance, strict lint, policy certification, derived risk class, and successful replay report to a one-time Cloud challenge. | It is operator self-attestation signed with the ingest token, not an independently observed certification. Exact deployment policy, risk-class, and deployed compiler-version allowlists still apply. | -| Hosted browser recorder and runtime health | **Supported / bounded launch component** | A retained non-simulated hosted session on `openadapt-flow` 1.8.0 produced frames and input evidence, assembled a compileable recording, finalized one workflow idempotently, enforced resource limits, and cleaned up ephemeral qualification data. The current live runner and compiler report the published 1.23.0 identity; live readiness also checks auth, database, storage, callbacks, scheduler, retention, secrets, validation policy, and billing. | Explicitly initiated, public-HTTPS, non-regulated authoring only. Raw observations remain private inside the declared hosted boundary. Readiness proves deployed dependencies and service identity, not a customer workflow qualification or SLA. | +| Hosted browser recorder and runtime health | **Supported / bounded launch component** | A retained non-simulated hosted session on `openadapt-flow` 1.8.0 produced frames and input evidence, assembled a compileable recording, finalized one workflow idempotently, enforced resource limits, and cleaned up ephemeral qualification data. Authenticated live health reports the current published 1.23.0 runner/compiler identity and checks auth, database, storage, callbacks, scheduler, retention, secrets, validation policy, and billing. | Explicitly initiated, public-HTTPS, non-regulated authoring only. Raw observations remain private inside the declared hosted boundary. Readiness proves deployed dependencies and service identity, not a customer workflow qualification or SLA. | | Hosted dashboard/control plane | **Supported / public offer** | Authentication, organizations, exact-hash bundle ingest, immutable run admission, browser runner orchestration, structural reports, replacement activation, billing, and metering form the managed lifecycle. | Production uses live dependencies and fails unavailable rather than substituting mock behavior. | | Hosted execution | **Supported / public offer** | Live Stripe Checkout connects onboarding and subscription entitlements to managed browser execution; the runner verifies exact admitted bundle bytes and authenticated callbacks. | The public subscription covers approved browser workflows. Other substrates use separately scoped deployments and commercial terms. Checkout does not create an SLA or certification. | | Air-gapped on-prem package | **Supported** | A local queue, systemd unit, minimized hash-chained audit log, and air-gap checks are provided. | Full-disk encryption and operational hardening remain operator/deployment responsibilities. |