Skip to content

Security: donphi/dropbox_proton

Security

SECURITY.md

Security model

Credentials

Dropbox bearer tokens are accepted only through the configured environment variable or its _FILE secret-file companion. Token values are never included in subprocess arguments, TOML, manifests, reports, or command records. Runtime logging redacts the active token and bearer authorization headers.

rclone reads its externally mounted configuration. The appliance never invokes rclone config show. Restrict that mount to read-only mode and permission it for the container UID only.

Proton authentication is performed interactively by the official proton-drive auth login. The container explicitly selects the official CLI's pass credential backend with PROTON_DRIVE_CREDENTIALS_STORE=pass. Its authenticated session is GPG-encrypted in the externally mounted password store; the corresponding dedicated private key is externally mounted from the GPG home. The non-interactive key has no passphrase, so confidentiality depends on mode 0700, per-migration isolation, and encrypted host storage for both mounts. Never pass a Proton password in Compose environment, TOML, shell arguments, or a migration command.

Rotate or revoke source credentials after the administrative migration process is complete.

Container permissions

The image runs as a non-root UID/GID. Its root filesystem is read-only in the provided Compose definition, all Linux capabilities are dropped, no-new-privileges is enabled, and process, memory, CPU, temporary-storage, and log growth are bounded. Only the following locations need writes:

  • /data/archive
  • /data/runs
  • /config/proton
  • /config/password-store
  • /config/gnupg
  • /tmp

The migration TOML, Dropbox token file, and rclone config mount read-only. Dedicated encrypted per-customer directories prevent cross-customer state reuse. Do not share archive/run volumes, Proton state, GPG homes, rclone configs, or token files across customer containers.

Logs and reports

Run logs intentionally contain object paths, provider object identifiers, sizes, hashes, timestamps, and safe provider errors. These may be sensitive customer metadata even without file contents. Protect the entire runs volume, encrypt it at rest, and apply a documented retention policy.

Provider errors are truncated and redacted. Operators must still review new provider CLI/API versions for changed error formats before updating the toolchain lock.

Integrity and dependency controls

The Docker build downloads rclone and Proton Drive CLI only from their official release locations and verifies pinned publisher checksums. Runtime preflight checks exact Python, requests, rclone, and Proton CLI versions against config/toolchain.lock.toml.

Important manifests are streamed to .partial, flushed, fsynced, and atomically renamed. Their size and SHA-256 are stored in SQLite. Downstream phases reject stale dependency artifacts.

Dropbox and Proton identifiers are observed from provider responses and compared exactly before work proceeds. Completed phases are reusable only while their config hash, dependency phase-run ID, artifacts, toolchain lock, identity anchors, and snapshot chain remain current.

Mutation and deletion

Planning is the default for recovery merge, metadata restoration, conflict normalization, Proton upload, P210 local catch-up, and P230 catch-up upload. --apply and the corresponding configuration permission are both required for those mutations. The initial download phase also requires --apply; it uses no-overwrite semantics and surrounds the copy with fresh source-drift checks. Dropbox must be frozen for that P20 capture and again for all of P200-P250.

Local recovery and normalization use no-overwrite/exclusive destination semantics. Different-content objects are never collapsed. Identical duplicates remain in run-scoped quarantine.

The Proton provider exposes list, download, folder creation, and upload operations. It does not expose trash, delete, or empty-trash. Only skip and rename baseline file-conflict strategies are accepted; replace is always rejected. The P230 catch-up path may explicitly request create-new-revision only for a same-path modification classified and approved by P220. It never uses Proton's replace strategy. The exact pinned CLI must be live-qualified to prove that this operation preserves the node UID, does not move the prior node to trash, retains a retrievable prior revision, and exposes the new active bytes for verification.

P210 moves superseded local bytes into run-scoped retained evidence before installing a new version. A Dropbox delete or rename never triggers a Proton delete, move, replacement, or trash operation. Old Proton nodes are preserved and reported as SOURCE_SUPERSEDED; P250 carries deleted and renamed source objects as review items.

Round-trip verification temporarily downloads destination bytes into the encrypted run volume, records durable hashes, and removes staged bytes only after the verification record is durable.

P240 may carry prior byte evidence only when Proton UID, CLI path, active revision fingerprint, and expected SHA-256 remain unchanged. Otherwise it downloads and independently hashes the active file. It also takes a complete fresh Proton inventory and requires Dropbox to remain quiescent for the configured interval.

There is no Dropbox deletion implementation. P120 is a baseline report and explicitly is not disconnect-ready. Only a passing P250 cutover report can state disconnect readiness, which remains evidence for a separate manual administrative decision rather than a provider deletion action.

Reporting vulnerabilities

Do not attach customer manifests, tokens, credential stores, or raw run logs to an issue. Provide a minimal synthetic reproduction and the locked tool versions. Revoke any credential that may have been exposed before sharing diagnostics.

There aren't any published security advisories