Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Proposal: Google Drive Storage Backend

Status: future design. No implementation. The native backend is gated behind the userspace-driver authority gate, a userspace network stack, an outbound TLS client, an HTTP client, and the OAuth2 service – none of which exist yet. The browser-transport model is the near-term path and is already partially specified in storage-and-naming-proposal.md.

Summary

Let a Google-authenticated user use their own Google Drive as a capOS storage backend, exposed behind the same storage capabilities apps already use (Store / Namespace / Directory / File, and the AppData cap from docs/proposals/standard-app-capabilities-proposal.md). The user’s Drive – specifically the per-app appDataFolder space – becomes the backing for an app’s AppData cap, and selected user files become File caps minted through the powerbox.

There are two delivery models, and this proposal keeps them explicit because they have very different trust and readiness profiles:

  • Browser-transport (near-term): the user’s browser holds the Google OAuth session and does the TLS/HTTP to Drive; capOS never sees Google tokens and stores only encrypted capsules in appDataFolder. This is already sketched in storage-and-naming-proposal.md (“User-Owned Browser Transport”) and is feasible without a capOS network/TLS/OAuth stack.
  • Native backend (deep-future): a capOS userspace service holds the OAuth refresh token and performs outbound HTTPS to the Drive API itself. This is the more capable model and the more demanding one – it sits behind the full network/TLS/HTTP/OAuth dependency chain.

In both models, Drive sits behind a backend adapter, not pretended to be a set of first-class local object caps (see Trust Model).

Why Drive

  • The user already owns the storage and the quota; capOS does not provision a server.
  • The appDataFolder space is a near-exact fit for the per-app AppData cap: Google already provides per-app private storage invisible to the user and other apps under the narrow, non-sensitive drive.appdata scope.
  • Drive’s drive.file + Picker consent model maps onto the capOS powerbox, so user-selected files become capabilities without granting the all-files scope.
  • It is a concrete, widely-available validation of the storage caps’ backend-agnosticism that storage-and-naming-proposal.md already asserts (“Store service backed by virtio-blk, RAM, or network”).

Architecture

A userspace Drive storage service implements the standard storage cap interfaces and translates their methods into Drive REST calls:

app  --(File/Directory/Store/AppData cap)-->  Drive storage service
                                                |  uses
                                                v
                              DriveAccount cap (OAuth tokens)  -->  OAuthClient / AccessToken
                                                |                    (oidc-and-oauth2-proposal)
                                                v
                              OutboundHttpRequest  -->  TLS client  -->  userspace net stack
                              (networking)            (certificates-and-tls)
  • The service consumes, does not redefine the OAuth capabilities from oidc-and-oauth2-proposal.md (OAuthClient, AccessToken.authorize / attenuate, RefreshToken), passing each Drive request as the OutboundHttpRequest struct that AccessToken.authorize decorates with the bearer credential. The refresh token lives in the OAuth service; the Drive service holds a DriveAccount cap that exposes only the typed operations the user consented to.
  • It consumes the outbound TLS client from certificates-and-tls-proposal.md and the HTTP client / userspace network stack from networking-proposal.md Phase C.
  • It is the network analog of the virtio-blk-backed FS service in docs/proposals/storage-and-naming-proposal.md: same Directory/File/Store caps in front, a different backend behind.

Concept mapping (Drive -> capOS standard caps)

DrivecapOS standard cap (Proposal A)
appDataFolder space (drive.appdata)AppData cap backing
drive.file + Picker selectionpowerbox FilePicker returns a File cap
File idthe File cap handle
FolderDirectory cap
Roles (reader/writer)shareAs wrapper caps
ShortcutNamespace binding
Revisionscontent-addressed Store blobs + pointer
OAuth scopes(not modeled internally) method-narrowed DriveAccount

A key consequence: capOS does not model OAuth scopes internally. A DriveAccount cap exposes only the methods the user consented to; “read-only Drive access” is a DriveAccount whose wrapper omits write methods, not a drive.readonly scope string re-checked server-side.

Dependency stack and gating

A native Drive client backend needs, bottom-up:

LayerNeedcapOS state
NIC / virtio-netpacket I/Opartly present (virtio-net MSI-X + delivery); driver must move to userspace
TCPreliable streampresent (smoltcp, in-kernel/transitional); must move to a userspace net process
TLS 1.2/1.3confidentiality + server auth (X.509 chain, trust roots, AEAD/ECDHE)not implementedcertificates-and-tls-proposal.md is future design (rustls + webpki-roots planned); the hardest single piece
HTTP/1.1 or HTTP/2Drive REST transport (Google prefers HTTP/2)not implemented
JSONrequest/response + metadata; resumable upload state machinetractable (serde_json no-std)
OAuth2 token flowPKCE/device-flow handshake, refresh->access exchange, sealed refresh-token storagedesigned but unimplemented (oidc-and-oauth2-proposal.md)
Trusted wall-clocktoken expiry, cert validity, permission expirationTimeweak today; needed for TLS cert validity

The native backend is therefore gated on, in order: docs/backlog/hardware-boot-storage.md Task 5 (userspace-driver authority gate) -> networking-proposal.md Phase C (userspace net stack + NIC driver) -> certificates-and-tls-proposal.md (outbound TLS) -> an HTTP client -> oidc-and-oauth2-proposal.md (OAuth service). This is the same authority gate that blocks userspace networking generally; the Drive backend is one of its downstream consumers, not a way around it.

Delivery models

Browser-transport (near-term)

The user’s browser, already authenticated to Google, holds the OAuth session and performs the TLS/HTTP to Drive. capOS hands the browser an opaque, client-side-encrypted capsule to store in the app’s appDataFolder; capOS never sees Google tokens. This reuses the remote-session / browser-capability surface and the KMS envelope-encryption pattern in storage-and-naming-proposal.md (“User-Owned Browser Transport”). It is feasible before any capOS network/TLS/OAuth stack exists, and is the recommended first delivery. This proposal’s role here is to reconcile that existing section with the AppData/powerbox vocabulary, not to redefine it.

Native backend (deep-future)

A capOS Drive service holds the OAuth refresh token and does outbound HTTPS itself. For a headless/embedded OS the realistic OAuth flows are authorization-code + PKCE with a loopback redirect (http://127.0.0.1:port) when a same-host browser is reachable, otherwise the device flow (show URL + code on one device, poll for tokens). PKCE is non-negotiable – capOS has no trustworthy on-device confidential client secret. Token lifecycle: persist only the refresh token in a sealed cap (an AppData-style or credential_store secret), exchange for short-lived access tokens on demand, and treat the access token as an ephemeral bearer credential passed to the HTTP path, never persisted.

Trust model and honest mismatches

A Drive-backed File is not a true local object capability – it is a bearer credential to a remote, server-authoritative ACL. The authority lives on Google’s server, which re-checks it on every request against a mutable table. Consequences the design must respect:

  • No local revocation/attenuation guarantee. Dropping a local handle does not revoke access Google still grants; narrowing a DriveAccount wrapper does not change Google’s server-side scope. capOS can wrap Drive behind the adapter but cannot give a remote file the local revocation/attenuation semantics of a true cap.
  • Offline = non-functional. Unlike a local cap, a Drive-backed cap is dead without network.
  • Global mutable namespace / instant org-wide revoke are Drive server-authoritative features with no clean local-cap equivalent; they stay behind the adapter.
  • Quota is Drive’s per-user pool, not a per-cap budget; an app’s appDataFolder usage counts against the human’s Drive quota.

Therefore Drive is exposed strictly as a backend adapter that serves the storage caps with documented remote semantics, never as a drop-in for local object caps. Apps that need local revocation/attenuation/offline guarantees should use a local backend; apps that want the user’s Drive accept the remote semantics.

Phasing

  1. Reconcile + capsule model (near-term, browser-transport): align the existing “User-Owned Browser Transport” section of storage-and-naming-proposal.md with the AppData/powerbox vocabulary; define the encrypted-capsule format and the appDataFolder capsule lifecycle. No capOS network/TLS/OAuth dependency.
  2. OAuth service + outbound HTTPS prerequisites (deep-future): land the gated chain (userspace net stack, TLS, HTTP, OAuth service) per their own proposals. This proposal only consumes them.
  3. Native DriveAccount + Drive storage service (deep-future): implement the service that maps AppData/File/Directory/Store onto Drive REST using the OAuth/TLS/HTTP caps; prove an appDataFolder round-trip and a powerbox-picked file read in a QEMU smoke against a Drive API stand-in.
  4. Sharing bridge (future): map shareAs to Drive permissions where the remote semantics allow, with the bearer/clawback caveats flagged.

Relationship to existing proposals

  • docs/proposals/standard-app-capabilities-proposal.md – defines the AppData/powerbox/shareAs caps this backend serves.
  • docs/proposals/storage-and-naming-proposal.md – owns the storage caps, the “Managed Cloud Backing” and “User-Owned Browser Transport” sections (the near-term Drive path), and the backend-agnosticism this validates.
  • docs/proposals/oidc-and-oauth2-proposal.md – the OAuth token capabilities this backend consumes; the refresh token lives there.
  • docs/proposals/certificates-and-tls-proposal.md – the outbound TLS client.
  • docs/proposals/networking-proposal.md – Phase C userspace net stack + the HTTP client; the shared authority gate.
  • docs/research/{eros-capros-coyotos,plan9-inferno}.md – application-level persistence (vs transparent single-level store) and per-process namespaces (a Drive backend unioned into an app namespace alongside local storage).

Open questions

  • Is the encrypted-capsule (browser-transport) model sufficient for the first user-facing Drive feature, deferring the native backend until the network stack is real?
  • Where does the refresh token live – the OAuth service’s own sealed store, a credential_store extension, or a dedicated DriveAccount object?
  • Does the native backend target the Drive REST API directly, or go through a capOS-hosted proxy that holds the Google credentials (narrowing the on-device trust surface, at the cost of running a proxy)?
  • How are Drive’s server-side semantics (revocation, quota, mutable ACL) surfaced to apps so they are not surprised by a File cap that behaves unlike a local one?