Skip to content
Open
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
114 changes: 104 additions & 10 deletions Cargo.lock

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

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ azure_storage = "0.20"
azure_storage_blobs = "0.20"
google-cloud-storage = "0.22"

# HTTP (for OAuth + REST backends like OneDrive / Google Drive)
reqwest = { version = "0.12", default-features = false, features = ["json", "stream", "rustls-tls"] }
url = "2"
urlencoding = "2"
webbrowser = "1"

# Vault SDKs
azure_security_keyvault_secrets = "0.10"
azure_identity = "0.31"
Expand Down
82 changes: 82 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,88 @@ addr = "enigma-2.enigma:9000"
| S3-compatible | `S3Compatible`, `minio`, `rustfs`, `garage` | Requires `endpoint_url`, `path_style = true` |
| Azure Blob Storage | `Azure` | `bucket` = container name |
| Google Cloud Storage | `Gcs` | Uses Application Default Credentials |
| Microsoft OneDrive | `Onedrive` | OAuth2 device code — see [OneDrive setup](#onedrive-setup) |
| Google Drive | `Gdrive` | OAuth2 device code — see [Google Drive setup](#google-drive-setup) |

### OneDrive setup

OneDrive uses OAuth2 (device code flow). The app stores chunks in a dedicated, app-isolated folder at `/Apps/Enigma/` — it has no access to the rest of your OneDrive.

**One-time app registration (~5 minutes):**

1. Sign in to [Microsoft Entra ID admin center](https://portal.azure.com/).
2. **App registrations → New registration**.
3. Name: `enigma-backup` (anything). Supported account types: **"Accounts in any organizational directory and personal Microsoft accounts"**.
4. Leave "Redirect URI" blank — device code flow does not use a redirect.
5. Click **Register**. Copy the **Application (client) ID** that appears.
6. In the new app: **Authentication** tab → "Allow public client flows" → **Yes** → Save.
7. **API permissions** → **Add a permission** → Microsoft Graph → **Delegated permissions** →
- `Files.ReadWrite.AppFolder`
- `offline_access`

**One-time login (~30 seconds):**

```bash
enigma auth login onedrive --client-id <YOUR_CLIENT_ID>
```

The CLI prints a URL and an 8-character code. Open the URL in any browser, paste the code, sign in to your Microsoft account, click **Yes** to grant access. Tokens are then saved AES-256-GCM-encrypted in `<config_dir>/oauth_tokens.enc` (using your Enigma passphrase) and Enigma can use them indefinitely (refresh tokens are valid for ~90 days of inactivity).

**Use it:**

```toml
# Add to enigma.toml
[[providers]]
name = "my-onedrive"
type = "onedrive"
bucket = "" # unused for OneDrive
weight = 1
```

Then `enigma backup ./photos` and chunks go to `https://onedrive.live.com/?id=Apps/Enigma`.

### Google Drive setup

Google Drive also uses OAuth2 (device code flow), scope `drive.file` — the app can only see files it creates. Chunks live in a single folder named `enigma-chunks` at the user's Drive root.

**One-time app registration (~5 minutes):**

1. Open [Google Cloud Console](https://console.cloud.google.com/), create a new project (e.g. `enigma-backup`).
2. **APIs & Services → Library** → enable **Google Drive API**.
3. **APIs & Services → OAuth consent screen** → User Type: **External** → fill the minimum fields → Save (Test users: add your own Gmail).
4. **APIs & Services → Credentials → Create credentials → OAuth client ID** → Application type: **TVs and Limited Input devices**.
5. Copy the **Client ID** and **Client secret**. (Google requires a client secret in device flow even for "public" desktop clients.)

**One-time login (~30 seconds):**

```bash
enigma auth login gdrive --client-id <ID> --client-secret <SECRET>
```

Same UX as OneDrive — open the URL on any device, enter the code, grant access. Tokens saved encrypted; valid as long as the refresh token works (~6 months of inactivity for Google).

**Use it:**

```toml
[[providers]]
name = "my-gdrive"
type = "gdrive"
bucket = "" # unused for Google Drive
weight = 1
```

### OAuth token management

| Command | What it does |
|---------|--------------|
| `enigma auth login onedrive --client-id <id>` | Run the device code flow for OneDrive |
| `enigma auth login gdrive --client-id <id> --client-secret <s>` | Run the device code flow for Google Drive |
| `enigma auth status` | Show which providers have stored tokens, expiry, scope |
| `enigma auth logout <provider>` | Delete stored tokens for a provider |

The encrypted token store lives at `<config_dir>/oauth_tokens.enc`. It is unlocked with your Enigma passphrase — same one as the keystore.



### Environment Variables

Expand Down
5 changes: 4 additions & 1 deletion crates/enigma-cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,15 @@ glob = "0.3"
rpassword = "5"
hex.workspace = true
futures.workspace = true
webbrowser = { workspace = true, optional = true }

# OpenSSL (vendored for cross-compilation)
openssl = { workspace = true, optional = true }

[features]
default = []
default = ["browser-open"]
# Try to open the user's default browser during `enigma auth login` device flow.
browser-open = ["dep:webbrowser"]
vendored-openssl = ["dep:openssl"]
azure-keyvault = ["enigma-keys/azure-keyvault"]
gcp-secretmanager = ["enigma-keys/gcp-secretmanager"]
Expand Down
Loading
Loading