The Zero-Knowledge Proxy: Inside duplicati/oauth-handler

How an open-source backup engine solved the impossible problem of desktop OAuth without absorbing massive security liability.

7 min read • View on GitHub • More from duplicati

A heavy steel vault door with two widely separated keyholes, one operated by a robot and one by a human, representing the split-key architecture.
The split-key architecture ensures neither the proxy server nor the end user can access the stored data independently.
Key Takeaways

The Open-Source OAuth Trap

Building a local application that needs to talk to Google Drive or Microsoft Graph requires an OAuth Client Secret. If your application is open source, anyone can extract that secret from the codebase and impersonate your app to bypass rate limits or conduct phishing. Duplicati needed a centralized proxy to hold the secret, but the maintainers absolutely did not want the liability of storing thousands of user access tokens.

The Split-Key Architecture

The solution lies in a zero-knowledge cryptography pattern. When a user authenticates, the proxy receives the token from the provider. It then generates a random password, encrypts the token using AES-256 (Encrypt-then-MAC), and stores only the ciphertext in its Google Datastore. The proxy returns a composite string of the key ID and the password to the user. The centralized server literally cannot use the tokens it stores.

The zero-knowledge flow ensures the proxy retains zero liability for the localized tokens.

Bridging the Terminal Divide

Running a backup server on a headless Raspberry Pi makes web-based OAuth impossible. The proxy solves this with a headless polling mechanism. The system allows the CLI to poll a specific session ID while the user completes the web flow on their phone or laptop. This seamlessly passes the credentials back to the isolated terminal.

A close-up of a vintage computer terminal with a single glowing thread reaching out into the dark, symbolizing the FetchToken polling mechanism.
The FetchToken mechanism allows headless servers to patiently pull authorized credentials across the network.

The Burden of Centralization

Operating a centralized proxy works flawlessly until the cloud providers change their rules. Google recently began requiring expensive third-party security audits for applications requesting full Drive access. This policy change forced the Duplicati project to evolve. The old Python-based Google App Engine handler is slowly being superseded by a modern C# Dockerized server. Open-source users must now increasingly host their own OAuth infrastructure to bypass prohibitive centralized audit costs.

FeatureOriginal oauth-handler (GAE)Modern oauth-server (Docker)
InfrastructureGoogle App Engine (Python)Self-Hosted Docker (C#)
User SetupZero setup (Centralized)Requires custom Google Cloud Project
Provider ScopesRestricted to un-audited scopesUnrestricted (User assumes liability)