Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/os-approval.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: OS approval

on:
pull_request:
paths: ['crates/oauth-service/**', 'crates/shell/src/connected_review.rs', 'Cargo.toml', 'Cargo.lock', '.github/workflows/os-approval.yml']
push:
branches: [main]
paths: ['crates/oauth-service/**', 'crates/shell/src/connected_review.rs', 'Cargo.toml', 'Cargo.lock', '.github/workflows/os-approval.yml']
workflow_dispatch:

permissions:
contents: read

concurrency:
group: os-approval-${{ github.ref }}
cancel-in-progress: true

jobs:
windows:
runs-on: windows-2022
timeout-minutes: 45
steps:
- name: Preserve runtime patch bytes
run: git config --global core.autocrlf false
- uses: actions/checkout@v6
- uses: actions/setup-python@v6
with:
python-version: '3.12'
- uses: dtolnay/rust-toolchain@stable
- run: python tools/setup.py
- uses: Swatinem/rust-cache@v2
with:
shared-key: platform-accounts-windows
- name: Approval bindings and native adapter refusal tests
run: cargo test --locked -p octosense-oauth-service --features host --lib
- name: Actual Windows Hello availability without authentication
run: cargo test --locked -p octosense-oauth-service --features host native_windows_hello_availability_without_prompt -- --ignored --nocapture
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion crates/oauth-service/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ publish = false

[features]
default = []
host = ["dep:octosense-appstore", "dep:octosense-mail-service", "dep:keyring", "dep:makepad-widgets"]
host = ["dep:octosense-appstore", "dep:octosense-mail-service", "dep:keyring", "dep:makepad-widgets", "dep:dbus", "dep:webview2-windows", "dep:windows-future"]
# Native acceptance executables only; no environment/config switch in releases.
acceptance-fixtures = ["host"]

Expand All @@ -28,6 +28,9 @@ octosense-mail-service = { workspace = true, optional = true }

[target.'cfg(target_os = "windows")'.dependencies]
keyring = { version = "3", features = ["windows-native"], optional = true }
webview2-windows = { workspace = true, optional = true, features = ["Security_Credentials_UI", "Win32_System_WinRT", "Win32_System_Threading"] }
windows-future = { version = "=0.3.2", optional = true }

[target.'cfg(target_os = "linux")'.dependencies]
keyring = { version = "3", features = ["sync-secret-service", "crypto-rust", "vendored"], optional = true }
dbus = { version = "=0.9.12", features = ["vendored"], optional = true }
25 changes: 16 additions & 9 deletions crates/oauth-service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ to GitHub or Google, approves that app's scopes, and gets an app-bound connectio
There is no OctoSense account or central login backend. This implements the
shared-service part of [ADR 0010](../../docs/adr/0010-shared-oauth-and-connected-apps.md).

The separate Linux/Windows OS-authenticated write approval implementation and
its remaining native acceptance requirements are described in
[desktop write approval](../../docs/os-authenticated-approval.md). It does not
upgrade synthetic input to trusted physical input.

## Current delivery boundary

The Rust protocol, connectors, native review, account lifecycle and sample UI
Expand Down Expand Up @@ -39,11 +44,11 @@ editing, in a standalone test APK that left the regular Home in place
([OnePlus Notes check](../../tools/connected-e2e/evidence/notes-oneplus-20261006/README.md));
Inbox Assistant and Google Calendar have not run there.

| Platform | Provider authorization | Credential storage | Gmail send approval |
| Platform | Provider authorization | Credential storage | Native write approval |
| --- | --- | --- | --- |
| macOS | GitHub device flow; Google browser/PKCE loopback | Mail's platform Keychain adapter, separate OAuth namespace | Native pointer provenance; remote clicks refused; physical acceptance unverified |
| Windows | Same desktop flows; platform execution unverified | Windows Credential Manager; unverified on Windows | Unsupported: fails closed |
| Linux | Protocol tests and host compilation passed on Linux; browser login and GUI unverified | Secret Service; unlocked service required, no plaintext fallback; native vault test refused the locked/unavailable build-host store | Unsupported: fails closed |
| Windows | Desktop flows implemented; actual synthetic backend browser acceptance is pending | Native Windows Credential Manager persistence/reopen/logout tested | OS authentication adapter implemented; needs Windows Hello and build 22000+; user-positive write unverified |
| Linux | Synthetic backend registration/login, callback and two-app isolation passed with native host + real browser; see the exact source/lock limitation in the [receipt](../../tools/connected-e2e/evidence/linux-backend-native.json) | Real isolated Secret Service persistence/reopen/logout tested; no plaintext fallback | OS authentication adapter implemented; requires installed polkit policy and session agent; user-positive write unverified |
| Android | GitHub flow present but unverified; **Google connection refused until its native adapter is implemented** | Mail's Android platform vault, separate namespace | Existing physical-touch provenance; this sample unverified |

`desktop-v0.1.0-beta.2` is the first release with the connected-account
Expand Down Expand Up @@ -195,7 +200,8 @@ Call the declared operations with an active connection:

Both objects are arguments to `auth.backend.request`. GET operations execute on a
worker. POST/PUT/PATCH/DELETE open the same native immutable review used for
GitHub/Calendar; a physical activation is required, and scripts/agents cannot
GitHub/Calendar; physical approval on macOS/Android or fresh OS-authenticated approval
on Linux/Windows is required. Scripts/agents cannot
approve through `auth.backend.sheet.save`. Background mutations return a request
to open the app. Cancellation or expiry before approval performs no write. Once an
approved HTTP request begins, cancellation cannot promise to undo the server's
Expand Down Expand Up @@ -227,7 +233,7 @@ registration requires reconnecting; it cannot redirect an existing token.
Logout revokes the local handle before attempting remote logout and reports
the remote result separately. Embedded callbacks retain caller, state, expiry
and single-use checks. Android versions below 9 and iOS refuse embedded backend
login. Windows/Linux execution remains unverified.
login. Linux external-browser backend execution has a [native receipt](../../tools/connected-e2e/evidence/linux-backend-native.json); Windows browser/callback acceptance remains pending.

The synthetic backend uses real browser forms, HTTP code exchange and protected
requests. HTTP loopback is available only in the non-default acceptance build,
Expand Down Expand Up @@ -332,10 +338,11 @@ host.request("auth.connect", {
`github.review_save` freezes repository/branch/path/content/base SHA.
`gcalendar.review_save` freezes calendar/event/ETag; a stale ETag is a conflict,
not permission to overwrite. `gmail.draft.review` freezes the durable draft
revision, recipient and body. All three writes require a physical activation
of the native host review control, with native provenance checked on press and
release before the one-use capability crosses into the worker. Scripts,
agents, remote instrumentation and JSON flags cannot approve a save or send.
revision, recipient and body. macOS/Android require physical activation of the
native review control, checking provenance on press and release. Linux/Windows
require the distinct [OS-authenticated proof](../../docs/os-authenticated-approval.md).
Both routes consume a one-use capability; scripts, agents, remote clicks and JSON
flags cannot approve a save or send by themselves.
Dismissal cancels an unsubmitted review; a selected-account change is checked
again before writing. Unknown Gmail submission outcomes stay unknown and are
not retried blindly.
Expand Down
17 changes: 11 additions & 6 deletions crates/oauth-service/README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ OctoSense 为已安装应用保存服务商凭据。用户登录 GitHub 或 Goog
应用得到绑定自身身份的连接句柄。无需 OctoSense 账户或中心登录后台。
本服务实现 [ADR 0010](../../docs/adr/0010-shared-oauth-and-connected-apps.zh-CN.md) 的共享服务部分。

Linux/Windows 独立的 OS 认证写入审批实现及剩余原生验收要求,见
[桌面写入审批](../../docs/os-authenticated-approval.zh-CN.md)。它不会将合成输入
升级为可信的物理输入。

## 当前交付边界

Rust 授权协议、连接器、原生审批、账户生命周期和示例界面已实现。macOS 原生宿主与
Expand All @@ -32,8 +36,8 @@ Inbox Assistant 和 Google Calendar 尚未在该设备上运行。
| 平台 | 服务商授权 | 凭据保存 | Gmail 发信审批 |
| --- | --- | --- | --- |
| macOS | GitHub 设备授权;Google 浏览器/PKCE/回环回调 | 复用 Mail 的 Keychain 适配器,独立 OAuth 命名空间 | 原生鼠标来源校验;远程点击被拒绝,亲手点按未验证 |
| Windows | 同样的桌面流程,平台运行未验证 | Windows Credential Manager;未在 Windows 验证 | 不支持,明确拒绝 |
| Linux | 已在 Linux 通过协议测试和主机编译;浏览器登录和 GUI 未验证 | 需要解锁 Secret Service,不回退到明文;原生测试被构建主机未解锁/不可用的凭据库拒绝 | 不支持,明确拒绝 |
| Windows | 已实现桌面流程;真实合成后端浏览器验收待完成 | 原生 Windows Credential Manager 持久化、重开、退出已测试 | OS 认证适配器已实现;需要 Windows Hello 和 build 22000+;用户认证写入正向验收未验证 |
| Linux | 原生宿主与真实浏览器的合成后端注册/登录、回调、双应用隔离已通过;准确源码/锁文件限制见[记录](../../tools/connected-e2e/evidence/linux-backend-native.json) | 独立真实 Secret Service 的持久化、重开、退出已测试,不回退到明文 | OS 认证适配器已实现;需要已安装的 polkit 策略和会话认证 agent;用户认证写入正向验收未验证 |
| Android | GitHub 流程存在但未验证;**Google 原生适配器完成前拒绝连接** | Mail 的 Android 凭据库,独立命名空间 | 现有的亲手点按来源校验;本示例未验证 |

`desktop-v0.1.0-beta.2` 是第一个包含已连接账户服务(`auth`、`github`、`gmail`、`gcalendar`)的发布版本;
Expand Down Expand Up @@ -152,7 +156,7 @@ shell 通过 `host::set_backend_resolver` 提供经过摘要验证的 manifest `
```

GET 在工作线程执行;POST/PUT/PATCH/DELETE 复用 GitHub/Calendar 的原生不可变
审核界面,须通过真实输入确认。脚本和 agent 不能通过 `auth.backend.sheet.save`
审核界面;macOS/Android 要求物理输入确认,Linux/Windows 要求新的 OS 认证证据。脚本和 agent 不能通过 `auth.backend.sheet.save`
批准发送。后台写操作要求先打开应用。批准前取消或超时不会发送;已批准的 HTTP
请求一旦开始,取消不能承诺撤销服务端结果,错误也不会自动重试。

Expand All @@ -172,7 +176,7 @@ GET 在工作线程执行;POST/PUT/PATCH/DELETE 复用 GitHub/Calendar 的原
URL 凭据及 HTTP 重定向。宿主把保存的连接绑定到规范化注册,修改注册后必须
重新连接,不能把旧令牌发送到新端点。退出先撤销本地句柄,再尝试远程退出,
并单独报告远程结果。嵌入回调仍检查调用者、state、有效期及单次使用。
Android 9 以下与 iOS 拒绝嵌入后端登录;Windows/Linux 的运行尚未验证。
Android 9 以下与 iOS 拒绝嵌入后端登录。Linux 外部浏览器后端流程已有[原生记录](../../tools/connected-e2e/evidence/linux-backend-native.json),Windows 浏览器/回调验收仍待完成。

合成后端使用真实浏览器表单、HTTP 代码交换及受保护请求。HTTP 回环仅在非默认
验收构建中通过显式隔离注册开放,不是发行版本的配置开关。参阅
Expand Down Expand Up @@ -251,8 +255,9 @@ Google 为 `openid`、`email`、`profile`、`calendar.list`、`calendar.events`

GitHub 保存冻结仓库、分支、路径、内容及原 blob SHA。Calendar 保存冻结日历、事件和 ETag;
过期 ETag 会报冲突,不会静默覆盖。Gmail 原生审阅界面冻结持久化草稿版本、收件人及正文。
这三种写入都必须由用户亲手点按宿主原生审阅界面上的控件;按下与释放时分别检查原生输入来源,
然后才把一次性能力交给工作线程。脚本、Agent、远程测试及 JSON 标记不能批准保存或发送。
macOS/Android 要求用户亲手点按宿主原生审阅控件,按下与释放时分别检查输入来源。
Linux/Windows 使用独立的 [OS 认证证据](../../docs/os-authenticated-approval.zh-CN.md)。
两条路径都消费一次性能力;脚本、Agent、远程点击或 JSON 标记本身不能批准保存或发送。
关闭审阅界面会取消尚未提交的请求;写入前再次检查当前账户。结果不明的 Gmail 提交保持
不明状态,不会盲目重试。

Expand Down
Loading
Loading