# WebDAV / S3 Custom Storage Configuration

When configuring Cloud Sync, you can choose to store sync data in your own cloud infrastructure (such as self-hosted WebDAV or third-party S3-compatible object storage) for full control over data residency and privacy.

In this mode, your clips are **end-to-end encrypted on-device with a key you hold** before they reach your storage, so the bucket/container only ever holds ciphertext. Octoclip's servers never receive your storage credentials, your encryption key, or your clip content. You are solely responsible for the availability, retention, and security of your storage bucket.

## Supported options

| Option | Typical implementation | Best for |
|------|------|------|
| WebDAV | Self-hosted WebDAV or third-party WebDAV service | Fast onboarding with lower ops complexity |
| S3-compatible storage | Amazon S3, MinIO, or other cloud object storage | Scalable setups with fine-grained IAM policies |

## Core fields

| Field | Type | Required | Description |
|------|------|:--------:|------|
| `provider` | `string` | Yes | Backend type, such as `webdav` or `s3` |
| `endpoint` | `string` | Yes | Service endpoint URL |
| `bucket` | `string` | No | Target bucket/container name (S3 flows) |
| `username` | `string` | No | Account (WebDAV) or Access Key ID (S3) |
| `password` | `string` | No | Password (WebDAV) or Secret Access Key (S3) |
| `pathPrefix` | `string` | No | Namespace prefix for sync objects |
| Encryption Key | `string` | Yes (in-app) | The end-to-end encryption key. You set it **in the app (under the "Encryption Key" field)**; it is stored in your device keychain and is **never written to this config file**. Every device must use the **same** value to decrypt. |

## Setup flow

:::steps
:::step{title="Choose and back up an encryption key"}

Pick the end-to-end encryption key you will use, and save it in a password manager. You will need to enter the **exact same** key on every device; without it, content cannot be decrypted by peer devices.

:::
:::step{title="Prepare credentials and permissions"}

Confirm endpoint reachability and read/write policy readiness. For S3, the access key needs at least `s3:PutObject`, `s3:GetObject`, `s3:DeleteObject`, and `s3:ListBucket` permissions on the target bucket. For WebDAV, verify the URL responds to a HEAD request.

:::
:::step{title="Fill parameters in app settings"}

In Octoclip's Cloud Sync settings, enter the required parameters based on your provider, along with your local encryption key.

:::
:::step{title="Run connection test"}

Verify test object read/write before enabling production sync. **Success:** the app reports `"Connection Successful"` or `"Test Passed"`; you can then enable sync.
:::
:::

## Example

The example below contains only the storage fields — the encryption key is set securely in the app and never appears in this file. Replace the angle-bracket values with your own credentials (these are placeholders, not real values).

```json title="storage.config.json"
{
  "provider": "s3",
  "endpoint": "https://s3.example.com",
  "bucket": "octoclip-sync",
  "pathPrefix": "prod/user-a/",
  "username": "<your-access-key-id>",
  "password": "<your-secret-access-key>"
}
```

> [!DANGER] Keep credentials and keys out of repos
> Never commit credential-bearing config files to public repositories, and never paste your encryption key into a shared channel. Enter them directly into the application settings.

## Common issues

:::accordion
:::item{label="Why does connection test fail?"}

Check endpoint reachability, credential validity, and write permission policies in your storage provider console.

:::
:::item{label="How should I handle multi-device conflicts?"}

Cloud Sync aims for eventual consistency. If conflicts occur due to sync latency, the local clipboard history remains your source of truth. You can re-copy or restore from a local backup if needed.

:::
:::item{label="Clips arrive but show as unreadable / fail to appear"}

Verify every device uses the **same encryption key**. A mismatched key prevents decryption even when the connection and storage config are correct. Mismatched decryption will fail silently without active errors.
:::
:::

## Related docs

:::cards{cols=2}
:::card{title="Cloud Sync" icon="lucide.cloud" href="/features/cloud-sync"}
Understand cloud sync mechanism and configuration flows.

:::
:::card{title="Privacy and Security" icon="lucide.shield" href="/advanced/privacy-security"}
Apply stronger handling for secrets and sensitive clips.
:::
:::
