From ebb11f19c20cfa66b0b9ae355b15e41217139fe0 Mon Sep 17 00:00:00 2001 From: Edouard Vanbelle Date: Tue, 14 Jul 2026 12:21:51 +0200 Subject: [PATCH] doc(webdav): login is via app password --- docs/config/authentication.md | 27 +++++++++++++++++++ docs/guide/caldav-carddav.md | 20 ++++++++++++-- docs/guide/dav-client-setup.md | 37 +++++++++++++++++++++++--- docs/guide/webdav.md | 48 ++++++++++++++++++++++++++-------- 4 files changed, 116 insertions(+), 16 deletions(-) diff --git a/docs/config/authentication.md b/docs/config/authentication.md index 971fdb06..8d3e20eb 100644 --- a/docs/config/authentication.md +++ b/docs/config/authentication.md @@ -176,9 +176,36 @@ The `error_type` field on 4xx responses lets frontends render specific UX. Codes | `RegistrationDomainNotAllowed` | 403 | Email domain outside `OXICLOUD_REGISTRATION_ALLOWED_EMAIL_DOMAINS` | | `AccountLocked` | 429 | Too many failed login attempts for (account, IP) — see rate-limit config | +## DAV clients (WebDAV / CalDAV / CardDAV): app passwords only + +DAV surfaces at `/webdav/`, `/caldav/`, and `/carddav/` accept HTTP +Basic Auth **only against app passwords** — the user's regular account +password is refused on those paths. This is intentional and cannot be +switched off. + +Reasons: + +- **Uniformity across account types.** Magic-link-only accounts (email- + only signup) and OIDC-linked accounts have no local password to send + over Basic Auth. App passwords are the one credential shape that + works for every account type. +- **Revocable and scoped.** An app password can be revoked + individually without touching the account password. Losing a phone + or rotating a client only affects that client. +- **Bounded blast radius on phishing / leak.** A leaked account + password grants web login (which the SPA can gate with 2FA / step-up + in future); an app password grants only the DAV surface it was + minted for. + +**User workflow:** in the OxiCloud web UI, *Profile → App Passwords → +Create*, name it, copy the token shown once, and use `username + +token` in the DAV client. See +[DAV Client Setup](/guide/dav-client-setup#before-you-start-get-an-app-password). + ## Security Model - Local passwords hashed with Argon2id +- DAV surfaces (WebDAV / CalDAV / CardDAV) accept **app passwords only** — the account password is refused on `/webdav/`, `/caldav/`, `/carddav/` by design (see above) - Access control is role-based (`admin` and `user`) - Refresh tokens support session renewal without forcing frequent re-login - Login endpoint uses anti-enumeration response shapes — bad-username and bad-password return the same 403 diff --git a/docs/guide/caldav-carddav.md b/docs/guide/caldav-carddav.md index a72b1196..edae15c9 100644 --- a/docs/guide/caldav-carddav.md +++ b/docs/guide/caldav-carddav.md @@ -2,6 +2,22 @@ OxiCloud provides built-in CalDAV (calendar) and CardDAV (contacts) servers — no extra apps or plugins needed. +## Authentication + +CalDAV and CardDAV clients authenticate with an **app password**, not +your regular OxiCloud account password. Your account password is +refused on `/caldav/` and `/carddav/` (same as `/webdav/`). This is by +design — app passwords are the only credential shape that works +uniformly across all account types (password, magic-link-only, OIDC). + +**Generate one:** in OxiCloud web UI, go to **Profile → App Passwords**, +click *Create*, name it (e.g. "Thunderbird calendar"), and copy the +token shown once. Use your username + that token in every DAV client +below. + +See [DAV Client Setup](./dav-client-setup#before-you-start-get-an-app-password) +for full details. + ## CalDAV (Calendars) ### Endpoint @@ -58,7 +74,7 @@ Typical resource shapes: 2. Right-click → **New Calendar** → **On the Network** 3. Format: **CalDAV** 4. URL: `https://your-server:8086/caldav/` -5. Enter your OxiCloud credentials +5. Enter your OxiCloud username and an [app password](#authentication) — the account password is refused --- @@ -114,7 +130,7 @@ Typical resource shapes: 1. Install [DAVx⁵](https://www.davx5.com/) from F-Droid or Play Store 2. Add account → **Login with URL and user name** 3. Base URL: `https://your-server:8086/` -4. Enter your OxiCloud credentials +4. Enter your OxiCloud username and an [app password](#authentication) — the account password is refused 5. DAVx⁵ auto-discovers both CalDAV and CardDAV endpoints ::: info diff --git a/docs/guide/dav-client-setup.md b/docs/guide/dav-client-setup.md index a4214857..a23f7eac 100644 --- a/docs/guide/dav-client-setup.md +++ b/docs/guide/dav-client-setup.md @@ -2,6 +2,28 @@ This page collects platform-specific connection steps for OxiCloud's WebDAV, CalDAV, and CardDAV endpoints. +## Before you start: get an app password + +Every DAV client — WebDAV, CalDAV, CardDAV — authenticates with an +**app password**, not your regular OxiCloud account password. Your +account password is deliberately refused on `/webdav/`, `/caldav/`, and +`/carddav/`. This applies whether you signed up with a password, use +magic-link login, or authenticate via SSO/OIDC — app passwords are the +only credential shape that works uniformly across all account types. + +**Generate one:** + +1. Open OxiCloud in your browser and sign in as usual. +2. Go to **Profile → App Passwords**. +3. Click **Create**, give it a memorable name (e.g. "Thunderbird laptop", + "iPhone contacts"), and copy the token shown once. +4. Use your username + that token as the credentials in every DAV client + below. + +You can revoke a single app password without touching your account +password — useful if you lose a device or want to rotate the credential +in one specific client. + ## Connection Summary | Use case | URL | @@ -17,7 +39,9 @@ This page collects platform-specific connection steps for OxiCloud's WebDAV, Cal 1. Open File Explorer 2. Right-click This PC and choose Add a network location or Map network drive 3. Enter `https://your-oxicloud-server/webdav/` -4. Provide your OxiCloud username and password +4. Provide your OxiCloud username and an **app password** (see + [above](#before-you-start-get-an-app-password) — your regular account + password will be rejected) If Windows refuses the connection, check the `WebClient` service and verify these registry values under `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters`: @@ -29,7 +53,8 @@ If Windows refuses the connection, check the `WebClient` service and verify thes 1. Open Finder 2. Choose Go -> Connect to Server or press Cmd+K 3. Enter `https://your-oxicloud-server/webdav/` -4. Sign in with your OxiCloud credentials +4. Sign in with your OxiCloud username and an **app password** (see + [above](#before-you-start-get-an-app-password)) ### Linux @@ -85,12 +110,18 @@ Use a CardDAV-capable synchronizer and configure the remote address book endpoin ### WebDAV +- **401 Unauthorized on every request?** Almost always the wrong + credential shape. Use an app password from *Profile → App Passwords* + — the account password is refused deliberately (see + [Before you start](#before-you-start-get-an-app-password) above). - Make sure the URL includes `/webdav/` - Use HTTPS in production -- Recheck credentials and the WebClient service on Windows +- Recheck the WebClient service on Windows ### CalDAV and CardDAV +- **401 Unauthorized?** Same rule as WebDAV — use an app password, not + your account password. - Use the full `/caldav` or `/carddav` base path - Verify the calendar or address book identifier when the client asks for one - If sync works on one client and not another, compare the exact URLs being used diff --git a/docs/guide/webdav.md b/docs/guide/webdav.md index f77caf1f..e59bf4cd 100644 --- a/docs/guide/webdav.md +++ b/docs/guide/webdav.md @@ -13,11 +13,28 @@ https://your-server:8086/webdav/ HTTP Basic Authentication: ``` -Authorization: Basic base64(username:password) +Authorization: Basic base64(username:app_password) ``` -::: tip -Always use HTTPS in production — Basic auth sends credentials in every request. +::: warning Use an app password, NOT your account password +DAV clients authenticate with an **app password** — a distinct, revocable, +scoped credential. Your regular OxiCloud account password (used in the +web login) will always be refused on `/webdav/`, `/caldav/`, and +`/carddav/`. + +Why: app passwords are the only credential that works uniformly across +all account types (password, magic-link-only, OIDC-linked), and they can +be revoked individually without touching your account password. + +**Generate an app password:** open OxiCloud in your browser, go to +**Profile → App Passwords**, click *Create*, name it (e.g. "Thunderbird +laptop"), and copy the token shown once. Use your username + that token +in every DAV client. +::: + +::: tip HTTPS +Always use HTTPS in production — Basic auth sends credentials in every +request. ::: ## Supported Methods @@ -56,7 +73,7 @@ Successful directory listings return `207 Multi-Status`. ```http GET /webdav/projects/document.pdf HTTP/1.1 -Authorization: Basic base64(username:password) +Authorization: Basic base64(username:app_password) ``` ### Upload or replace a file @@ -99,39 +116,43 @@ DELETE /webdav/projects/document.pdf HTTP/1.1 1. Open **This PC** → **Map network drive** 2. Enter: `https://your-server:8086/webdav/` 3. Check **Connect using different credentials** -4. Enter your OxiCloud username and password +4. Enter your OxiCloud username and an [app password](#authentication) ### macOS Finder 1. **Go** → **Connect to Server** (⌘K) 2. Enter: `https://your-server:8086/webdav/` -3. Enter credentials when prompted +3. Enter your OxiCloud username and an [app password](#authentication) ### Linux (Nautilus / Files) 1. Open Files → **Other Locations** 2. In the address bar, type: `davs://your-server:8086/webdav/` -3. Enter credentials +3. Enter your OxiCloud username and an [app password](#authentication) ### Linux (Dolphin / KDE) 1. In the address bar, type: `webdavs://your-server:8086/webdav/` +2. Enter your OxiCloud username and an [app password](#authentication) ### Command Line (curl) +`user:apppw` below means your OxiCloud username + the app-password token +you generated in *Profile → App Passwords* (not your account password). + ```bash # List root directory -curl -u user:pass -X PROPFIND https://your-server:8086/webdav/ \ +curl -u user:apppw -X PROPFIND https://your-server:8086/webdav/ \ -H "Depth: 1" # Download a file -curl -u user:pass https://your-server:8086/webdav/document.pdf -o document.pdf +curl -u user:apppw https://your-server:8086/webdav/document.pdf -o document.pdf # Upload a file -curl -u user:pass -T localfile.txt https://your-server:8086/webdav/remotefile.txt +curl -u user:apppw -T localfile.txt https://your-server:8086/webdav/remotefile.txt # Create a folder -curl -u user:pass -X MKCOL https://your-server:8086/webdav/new-folder/ +curl -u user:apppw -X MKCOL https://your-server:8086/webdav/new-folder/ ``` ## Streaming PROPFIND @@ -146,6 +167,11 @@ OxiCloud streams PROPFIND responses, so listing directories with thousands of fi ## Troubleshooting +- **401 Unauthorized on every request?** You're almost certainly using + your account password instead of an app password. Open OxiCloud in + your browser → *Profile* → *App Passwords* → *Create*, then use the + token shown once (with your username) in your client. See + [Authentication](#authentication) above. - Always use the `/webdav/` base path - Prefer HTTPS because WebDAV uses Basic Authentication - On Windows, make sure the `WebClient` service is enabled