From e38081145c45a3a96db46da43f5fb4f5cebc24a5 Mon Sep 17 00:00:00 2001 From: Cheese Date: Tue, 15 Sep 2026 16:59:24 -0400 Subject: [PATCH] docs: add TiDB Cloud Filesystem product documentation --- TOC-tidb-cloud-filesystem.md | 26 +++ ai/_index.md | 2 +- tidb-cloud-filesystem/_index.md | 74 ++++++++ .../filesystem-authorization.md | 104 +++++++++++ .../filesystem-branches-checkpoints.md | 164 ++++++++++++++++++ .../filesystem-mount-docker.md | 129 ++++++++++++++ .../filesystem-mount-linux.md | 82 +++++++++ .../filesystem-mount-macos.md | 82 +++++++++ tidb-cloud-filesystem/filesystem-mount.md | 98 +++++++++++ .../filesystem-quick-start.md | 127 ++++++++++++++ tidb-cloud-filesystem/filesystem-sharing.md | 113 ++++++++++++ 11 files changed, 1000 insertions(+), 1 deletion(-) create mode 100644 TOC-tidb-cloud-filesystem.md create mode 100644 tidb-cloud-filesystem/_index.md create mode 100644 tidb-cloud-filesystem/filesystem-authorization.md create mode 100644 tidb-cloud-filesystem/filesystem-branches-checkpoints.md create mode 100644 tidb-cloud-filesystem/filesystem-mount-docker.md create mode 100644 tidb-cloud-filesystem/filesystem-mount-linux.md create mode 100644 tidb-cloud-filesystem/filesystem-mount-macos.md create mode 100644 tidb-cloud-filesystem/filesystem-mount.md create mode 100644 tidb-cloud-filesystem/filesystem-quick-start.md create mode 100644 tidb-cloud-filesystem/filesystem-sharing.md diff --git a/TOC-tidb-cloud-filesystem.md b/TOC-tidb-cloud-filesystem.md new file mode 100644 index 0000000000000..2b6014848677d --- /dev/null +++ b/TOC-tidb-cloud-filesystem.md @@ -0,0 +1,26 @@ + + + +# Table of Contents + +## Getting Started + +- [Introduction](/tidb-cloud-filesystem/_index.md) +- [Quick Start](/tidb-cloud-filesystem/filesystem-quick-start.md) +- Mounting Locally + - [Overview](/tidb-cloud-filesystem/filesystem-mount.md) + - [Linux](/tidb-cloud-filesystem/filesystem-mount-linux.md) + - [macOS](/tidb-cloud-filesystem/filesystem-mount-macos.md) + - [Docker and Docker Compose](/tidb-cloud-filesystem/filesystem-mount-docker.md) + +## Concepts + +- [Authorization](/tidb-cloud-filesystem/filesystem-authorization.md) +- [Sharing Filesystems](/tidb-cloud-filesystem/filesystem-sharing.md) +- [Branches and Checkpoints](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md) + +## Reference + +- [Filesystem CLI Commands](/ai/ti/reference/ti-filesystem.md) +- [Regions and Limitations](/ai/ti/reference/ti-regions-security-and-limitations.md) +- [Troubleshooting](/ai/ti/reference/ti-troubleshooting.md) diff --git a/ai/_index.md b/ai/_index.md index 78b4767293763..ebbd5e69eee72 100644 --- a/ai/_index.md +++ b/ai/_index.md @@ -8,7 +8,7 @@ summary: Build AI applications and agent workflows with TiDB using SQL, integrat TiDB provides data and workspace capabilities for building AI applications and running AI agent workflows. - For application development, you can use SQL or [Python SDK for TiDB AI (`pytidb`)](https://github.com/pingcap/pytidb) with structured data, vector search, full-text search, hybrid search, and AI-powered retrieval. -- For AI agents and automation, you can use [TiDB Cloud CLI (`ti`)](https://github.com/tidbcloud/ti-cli) to manage TiDB Cloud Starter instances and SQL workflows, and use TiDB Cloud Filesystems as persistent, shared storage across local machines, CI jobs, and ephemeral agent sandboxes. Filesystems also support mounted workspaces, Git workflows, journals, and delegated secrets. +- For AI agents and automation, you can use [TiDB Cloud CLI (`ti`)](https://github.com/tidbcloud/ti-cli) to manage TiDB Cloud Starter instances and SQL workflows, and use [TiDB Cloud Filesystems](/tidb-cloud-filesystem/_index.md) as persistent, shared storage across local machines, CI jobs, and ephemeral agent sandboxes. Filesystems also support mounted workspaces, Git workflows, journals, and delegated secrets. ## Get started diff --git a/tidb-cloud-filesystem/_index.md b/tidb-cloud-filesystem/_index.md new file mode 100644 index 0000000000000..a053fbea6f69c --- /dev/null +++ b/tidb-cloud-filesystem/_index.md @@ -0,0 +1,74 @@ +--- +title: TiDB Cloud Filesystem +summary: Learn how TiDB Cloud Filesystem keeps agent files available across sessions, shares workspaces, and isolates changes with layers. +--- + +# TiDB Cloud Filesystem + +TiDB Cloud Filesystem is persistent, shared file storage for applications and AI agents. Keep a workspace in the cloud, access it from different machines, and retain its files after a sandbox or process ends. + +Use the TiDB Cloud Command Line Interface (`ti`) to create a Filesystem, upload and download files, or mount a remote directory for tools that work with local paths. You do not need to provision or manage a separate database to get started. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Keep work beyond one session + +An agent might collect source documents in one sandbox, generate a report in another, and hand the result to a person on a laptop. Files stored only on the sandbox's local disk disappear when that environment is removed. Repeatedly exporting and importing archives also creates separate copies that can drift apart. + +With a Filesystem, these participants use the same remote files. A new environment needs an access token and the Filesystem's region code, not the creator's TiDB Cloud API keys or local configuration directory. + +- **Continue a task in another environment.** Mount the existing workspace instead of recreating its input files. +- **Share results with a reviewer.** Give the reviewer a read-only scoped token for a report directory. +- **Compare parallel approaches.** Fork layers for independent drafts, create checkpoints, and commit a selected result to the shared base. + +## Work with files through the CLI or a mount + +The CLI provides two ways to use the same remote Filesystem: + +- **Direct file commands:** upload, download, list, read, and search files with `ti fs`. These commands do not require FUSE or a mount. +- **Local mounts:** expose remote files at a local directory so existing tools can use commands such as `cat`, `cp`, and `ls`. Linux uses FUSE. macOS uses WebDAV by default and can use macFUSE for layer and checkpoint mounts. + +For example, after selecting a Filesystem and supplying its token: + +```bash +# Read a remote file without mounting it. +ti fs read-file --path /workspace/report.md +``` + +Or mount the workspace on macOS or Linux: + +```bash +# Give local tools a directory backed by the remote workspace. +mkdir -p "$HOME/workspace" +ti fs mount-file-system --remote-path /workspace --mount-path "$HOME/workspace" +cat "$HOME/workspace/report.md" +``` + +## Control sharing and changes + +- [Authorization](/tidb-cloud-filesystem/filesystem-authorization.md) distinguishes resource-management credentials from owner and scoped Filesystem tokens. +- [Sharing Filesystems](/tidb-cloud-filesystem/filesystem-sharing.md) explains how participants access one remote workspace without sharing account credentials. +- [Branches and Checkpoints](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md) explains layers, saved history points, and publishing changes to the base Filesystem. + +## Before you begin + +Choose how to access the Filesystem: + +- **Create and manage a Filesystem:** obtain a TiDB Cloud API public key and private key from the [API Keys page](https://tidbcloud.com/org-settings/api-keys), then run `ti configure`. Follow the [Quick Start](/tidb-cloud-filesystem/filesystem-quick-start.md) to create a Filesystem and write your first file. +- **Use an existing Filesystem:** if someone has supplied an FS token, set `TI_FS_TOKEN` and `TI_REGION_CODE`. You do not need TiDB Cloud API keys or `ti configure` to access files within the token's permissions. Follow [Mounting Locally](/tidb-cloud-filesystem/filesystem-mount.md#use-a-token-without-configuring-a-profile). + +See [Authorization](/tidb-cloud-filesystem/filesystem-authorization.md) for the differences between API keys, owner tokens, and scoped tokens. An FS token does not grant permission to create or delete a Filesystem through the CLI. + +Choose a supported Filesystem region: `aws-us-east-1`, `aws-ap-southeast-1`, `aws-us-west-2`, or `alicloud-ap-southeast-1`. Keep compute close to that region when possible to reduce network latency. + +Mount support depends on the operating system and its permissions. Windows supports direct file commands but not native mounting through `ti`. WebDAV does not support layer or checkpoint mounts. Buffered writes must reach the service before you remove an environment; a successful local write alone is not a durability guarantee. + +These guides focus on file storage and access. TiDB Cloud Filesystem does not provision an agent's compute environment. A layer is not a security sandbox, and checkpoints do not snapshot the entire live base Filesystem. + +## What's next + +- [Create a Filesystem and write your first file](/tidb-cloud-filesystem/filesystem-quick-start.md). +- [Mount an existing Filesystem locally](/tidb-cloud-filesystem/filesystem-mount.md). +- [Try the interactive agent sandbox lab](https://labs.tidb.io/labs/demo_901). diff --git a/tidb-cloud-filesystem/filesystem-authorization.md b/tidb-cloud-filesystem/filesystem-authorization.md new file mode 100644 index 0000000000000..a1ae7f4152ab6 --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-authorization.md @@ -0,0 +1,104 @@ +--- +title: TiDB Cloud Filesystem Authorization +summary: Choose TiDB Cloud API keys, owner tokens, or scoped tokens to separate Filesystem administration from application data access. +--- + +# TiDB Cloud Filesystem Authorization + +The person who creates a Filesystem and the agent that uses its files do not need the same credentials. Keep account-level management on a trusted machine and give each application only the Filesystem access it needs. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Choose the credential type + +### TiDB Cloud API keys + +A TiDB Cloud public/private API key pair authorizes resource-management operations according to the account's permissions. Use it to create, list, describe, and delete Filesystems, generate owner tokens, and configure Filesystem AI providers. + +Configure the keys with `ti configure`, or provide `TIDB_CLOUD_PUBLIC_KEY` and `TIDB_CLOUD_PRIVATE_KEY` together. They are not FS tokens and do not directly replace the token used by a mount. + +### Owner FS tokens + +An owner token grants broad access within one Filesystem, including reading, writing, and deleting files. It can issue scoped tokens, list token metadata, and revoke tokens in that Filesystem. It can enable or disable scoped tokens, but enabling or disabling owner tokens requires TiDB Cloud API keys. It is a high-privilege secret, not a read-only mount credential. + +An owner FS token is not interchangeable with TiDB Cloud API keys: it cannot create or delete the Filesystem resource or generate another owner token through `ti`. In particular, deleting a file and deleting its Filesystem are different permissions. + +Filesystem creation returns an owner token and stores it locally for the creating profile. To generate another owner token, use `ti fs generate-file-system-token` with TiDB Cloud API keys. + +### Scoped FS tokens + +A scoped token limits access to specified path prefixes and operations. The supported operations are `read`, `list`, `search`, `write`, and `delete`. The service enforces these permissions, including when requests arrive through a mount. + +- A reporting agent might need `read,list` for `/inputs` and `read,list,write` for `/reports`. +- A reviewer might need only `read,list` for `/reports`. +- `search` also requires `read` on the scope. + +Scoped tokens cannot generate child tokens or manage token inventory. A scoped token can refresh itself while valid; refresh does not turn it into an owner token or broaden its permissions. + +## Delegate access to an agent + +On a trusted machine with a locally stored owner token, select the Filesystem and generate a limited token: + +```bash +# Capture the one-time token response without printing the secret. +SCOPED_TOKEN="$(ti fs generate-file-system-scoped-token \ + --file-system-id "" \ + --subject report-agent \ + --ttl 24h \ + --allow /workspace:read,list,write \ + --query fs_token --output text)" +``` + +Transfer `SCOPED_TOKEN` through a secret manager. In the agent's environment, inject it as `TI_FS_TOKEN` and provide the Filesystem's region: + +```bash +# In the agent environment, these values normally come from secret injection. +export TI_FS_TOKEN="" +export TI_REGION_CODE="aws-us-east-1" +ti fs list-files --path /workspace +``` + +The remote `/workspace` directory must already exist. For a mount, select the allowed subtree with `--remote-path /workspace`. Mounting the root `/` is not appropriate for a token that has access only to `/workspace`. + +## Understand local selection + +One Filesystem can have multiple remote tokens, but one CLI profile stores at most one selected local token for that Filesystem. Local state is a credential selection, not the authoritative remote token inventory. + +- `--fs-token` takes precedence over `TI_FS_TOKEN` for token-based operations. +- Without an explicit token, data-access commands use the locally stored credential for `--file-system-id` or `TI_FS_FILE_SYSTEM_ID`. +- An explicit token contains the Filesystem ID. A clean environment therefore needs only `TI_FS_TOKEN` and `TI_REGION_CODE` for data access. +- Generating a token does not select it locally unless you pass `--store-locally`. Replacing the local selection does not revoke the previous remote token. + +For token list, enable, disable, and delete commands, an explicitly supplied owner token selects bearer authentication; otherwise the CLI uses TiDB Cloud API keys and requires a Filesystem ID. A scoped token does not gain administrative capability merely because account keys also exist in the profile. + +## Rotate and revoke credentials + +List token metadata to identify the token you want to manage: + +```bash +# Use TiDB Cloud API keys when no explicit FS token is present. +ti fs list-file-system-tokens --file-system-id "" --output text +``` + +The list does not return token plaintext. Preserve newly generated or refreshed tokens in a secret manager. If you lose an owner token, generate a replacement using TiDB Cloud API keys; do not expect to recover the original secret by listing tokens. + +To retire a token, stop its consumers and use its token ID: + +```bash +# Revoke only the retired token, not the Filesystem itself. +ti fs delete-file-system-token --file-system-id "" --token-id "" +``` + +Token changes can take time to propagate through authorization caches. Rotate by distributing and validating a replacement before retiring the old token. Do not treat disabling an owner token as an implicit replacement for reviewing and revoking previously issued scoped tokens. + +> **Warning:** +> +> Stop writes and unmount consumers before refreshing, disabling, or deleting their token. The CLI checks known local mounts but cannot discover every remote machine using the secret. Token refresh is non-idempotent: if the request might have succeeded but the response was lost, do not blindly retry it with the old token. + +## What's next + +- [Share one Filesystem with multiple machines](/tidb-cloud-filesystem/filesystem-sharing.md). +- [Look up token management commands](/ai/ti/guides/manage-filesystem-tokens.md). +- [Mount a token-scoped directory](/tidb-cloud-filesystem/filesystem-mount.md). diff --git a/tidb-cloud-filesystem/filesystem-branches-checkpoints.md b/tidb-cloud-filesystem/filesystem-branches-checkpoints.md new file mode 100644 index 0000000000000..29bf09021cd79 --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-branches-checkpoints.md @@ -0,0 +1,164 @@ +--- +title: TiDB Cloud Filesystem Branches and Checkpoints +summary: Use Filesystem layers to compare parallel agent drafts, checkpoint progress, inspect history, and publish a selected result. +--- + +# TiDB Cloud Filesystem Branches and Checkpoints + +When two agents explore different answers, they should not overwrite each other's drafts. A Filesystem layer gives each agent a writable view over a base directory. Fork layers to work in parallel, record checkpoints for review, and commit a selected result to the shared base. + +The CLI calls these objects **layers**, not Git branches. All commands in this guide use `ti fs`; no Git repository is required. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Understand the model + +- **Base Filesystem:** the live shared files read by ordinary file commands and mounts without a layer selector. +- **Layer:** a set of changes over a base path. Its writes do not change the base until committed. +- **Fork:** a child layer that pins the parent's layer history at its current tip or a specified checkpoint. The child's later writes are independent of the parent's later layer changes. +- **Checkpoint:** a named point in one layer's durable history. It does not flush another client's pending writes or publish changes to the base. +- **Commit:** apply the layer's effective changes to the base Filesystem. This is not the same as a Git commit. + +> **Warning:** +> +> A fork or checkpoint pins layer history, not the entire base Filesystem. Paths resolved from the live base can still reflect later base changes. Layers are neither full Filesystem snapshots nor authorization boundaries. Do not use them as a substitute for backups or scoped tokens. + +## Prepare a parallel review + +This example has two agents write alternative reports, then publishes one result. It uses new filenames for successive drafts and avoids modifying the same file across checkpoints. + +Before running it: + +- Install `ti` v0.2.4 or later and select a Filesystem with an owner token as described in [Mounting Locally](/tidb-cloud-filesystem/filesystem-mount.md#select-a-filesystem). +- Use Linux with FUSE3 or macOS with macFUSE. WebDAV cannot mount layers or checkpoints. +- Use the same terminal for the shell variables below. Do not run other writers against this example's base path. + +```bash +# Isolate this run from existing work and earlier examples. +RUN_ID="$(date +%s)" +REMOTE_ROOT="/layer-demo-$RUN_ID" +LOCAL_ROOT="$HOME/layer-demo-$RUN_ID" +ti fs create-directory --path "$REMOTE_ROOT" +ti fs create-directory --path "$REMOTE_ROOT/reports" +mkdir -p "$LOCAL_ROOT/brief" "$LOCAL_ROOT/analyst" "$LOCAL_ROOT/review" +``` + +## Create a seed and fork two drafts + +```bash +# Create the seed layer and retain its immutable ID. +BASE_LAYER_ID="$(ti fs create-layer \ + --base-root-path "$REMOTE_ROOT" \ + --layer-name "seed-$RUN_ID" \ + --query layer_id --output text)" + +# Direct layer upload avoids a pending local mount write. +printf 'Compare two approaches to the same research question.\n' | ti fs copy-file \ + --from-stdin --to-remote "$REMOTE_ROOT/input.txt" \ + --layer-id "$BASE_LAYER_ID" + +SEED_ID="$(ti fs create-layer-checkpoint \ + --layer-id "$BASE_LAYER_ID" \ + --checkpoint-id "seed-$RUN_ID" \ + --label workspace-seed --query checkpoint_id --output text)" +``` + +Fork both drafts before committing the seed: + +```bash +# Both children start from the same parent checkpoint. +BRIEF_ID="$(ti fs fork-layer \ + --parent-layer-ref "$BASE_LAYER_ID" \ + --layer-name "brief-$RUN_ID" --checkpoint-id "$SEED_ID" \ + --query layer_id --output text)" +ANALYST_ID="$(ti fs fork-layer \ + --parent-layer-ref "$BASE_LAYER_ID" \ + --layer-name "analyst-$RUN_ID" --checkpoint-id "$SEED_ID" \ + --query layer_id --output text)" +ti fs list-layer-chain --layer-ref "$ANALYST_ID" + +# Publish the shared input before the children start writing new reports. +ti fs commit-layer --layer-id "$BASE_LAYER_ID" +``` + +The children retain their pinned parent history. Creating the shared directories in the base and committing the seed first also avoids having each child publish inherited directory creation as part of its own report. + +## Write the alternatives + +```bash +# Give each agent its own writable FUSE mount. +ti fs mount-file-system --driver fuse --remote-path "$REMOTE_ROOT" \ + --mount-path "$LOCAL_ROOT/brief" --layer-ref "$BRIEF_ID" +ti fs mount-file-system --driver fuse --remote-path "$REMOTE_ROOT" \ + --mount-path "$LOCAL_ROOT/analyst" --layer-ref "$ANALYST_ID" + +printf 'A concise recommendation.\n' > "$LOCAL_ROOT/brief/reports/brief.txt" +printf 'An evidence-led first draft.\n' > "$LOCAL_ROOT/analyst/reports/analyst-v1.txt" + +# Make the first analyst draft durable before checkpointing it. +ti fs drain-file-system --mount-path "$LOCAL_ROOT/analyst" --timeout 30s +V1_ID="$(ti fs create-layer-checkpoint \ + --layer-id "$ANALYST_ID" --checkpoint-id "v1-$RUN_ID" \ + --label first-draft --query checkpoint_id --output text)" +``` + +The two mounts contain different reports. Neither report is published in the base yet. Do not mount the same writable layer at multiple paths concurrently. + +## Review a historical checkpoint + +```bash +# Keep revisions in different files for this preview workflow. +printf 'A second draft with additional evidence.\n' > "$LOCAL_ROOT/analyst/reports/analyst-v2.txt" +ti fs drain-file-system --mount-path "$LOCAL_ROOT/analyst" --timeout 30s +ti fs create-layer-checkpoint --layer-id "$ANALYST_ID" \ + --checkpoint-id "v2-$RUN_ID" --label second-draft + +# Mount the earlier checkpoint read-only alongside the current writable tip. +ti fs mount-file-system --driver fuse --remote-path "$REMOTE_ROOT" \ + --mount-path "$LOCAL_ROOT/review" \ + --layer-ref "$ANALYST_ID" --checkpoint-id "$V1_ID" +ls "$LOCAL_ROOT/review/reports" +ls "$LOCAL_ROOT/analyst/reports" +ti fs diff-layer --layer-id "$ANALYST_ID" +``` + +The historical view includes `analyst-v1.txt` but not the later `analyst-v2.txt`. The writable tip includes both. `diff-layer` reports layer changes; it is not a Git-style line-by-line patch. + +To continue writing from a checkpoint, create a new child with `ti fs fork-layer --parent-layer-ref --checkpoint-id --layer-name ` while the parent remains forkable. A checkpoint mount itself is read-only. `rollback-layer` discards a layer; it does not reset that layer to a selected checkpoint. + +## Publish the selected result + +Stop all writers and unmount the example mounts before changing layer lifecycle state: + +```bash +# Flush writes and release both writable and historical mounts. +ti fs unmount-file-system --mount-path "$LOCAL_ROOT/review" +ti fs drain-file-system --mount-path "$LOCAL_ROOT/brief" --timeout 30s +ti fs unmount-file-system --mount-path "$LOCAL_ROOT/brief" +ti fs drain-file-system --mount-path "$LOCAL_ROOT/analyst" --timeout 30s +ti fs unmount-file-system --mount-path "$LOCAL_ROOT/analyst" + +# Abandon the rejected draft and publish the selected layer to the base. +ti fs delete-layer --layer-ref "$BRIEF_ID" +ti fs commit-layer --layer-id "$ANALYST_ID" +ti fs read-file --path "$REMOTE_ROOT/reports/analyst-v2.txt" +``` + +Committing publishes all effective changes in the selected layer, including both analyst draft files in this example. It does not select a single file automatically. Deleting a layer logically abandons it; it does not guarantee immediate physical removal of history still pinned by descendants. + +## Preview boundaries + +- Use immutable layer IDs in automation. Names are not guaranteed to be unique. +- Run a successful FUSE drain before a checkpoint of mounted writes. A checkpoint cannot capture data still buffered only on another machine. +- Recursive `ti fs copy-file --recursive` cannot be combined with `--layer-id`. To populate a layer with a directory tree, copy through its writable FUSE mount. +- Plain `ti fs read-file` and `ti fs list-files` read the base, not an uncommitted layer. Use a layer mount to inspect its files. +- Commit can fail on conflicting base changes. Retain the layer and inspect the conflict; do not automatically delete and recreate it or assume a transactional multi-file merge. +- Repeated changes to layer-created files and inherited metadata can have preview limitations. This example deliberately uses separate revision files and publishes the seed before child work. Test your own workflow before relying on more complex edit histories. +- Layer commit is not a merge into its parent, and the CLI does not provide Git-style merge, rebase, or an in-place reset to a checkpoint. + +## What's next + +- [Control which participants can read and write](/tidb-cloud-filesystem/filesystem-authorization.md). +- [Review the layer command reference](/ai/ti/reference/ti-filesystem.md). diff --git a/tidb-cloud-filesystem/filesystem-mount-docker.md b/tidb-cloud-filesystem/filesystem-mount-docker.md new file mode 100644 index 0000000000000..01b9f322bf33e --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-mount-docker.md @@ -0,0 +1,129 @@ +--- +title: Mount TiDB Cloud Filesystem in Docker +summary: Configure Docker or Docker Compose with a FUSE device, mount permissions, and a Filesystem token to use persistent remote files. +--- + +# Mount TiDB Cloud Filesystem in Docker + +A container needs both FUSE userspace tools and permission to use the Linux host's FUSE device. Installing `fuse3` inside an otherwise restricted container is not sufficient. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Prerequisites + +- A Linux Docker host with an accessible `/dev/fuse` device. +- An FS token for the existing Filesystem and its region code. +- Permission to start a container with the device and capabilities below. + +These examples target a Linux Docker host. Do not assume Docker Desktop's VM or a managed sandbox exposes the same device and security controls. If mounting is unavailable, use direct `ti fs` file commands instead. + +> **Warning:** +> +> `SYS_ADMIN` grants broad privileges, and `apparmor=unconfined` disables the container's AppArmor profile. Use these settings only in an environment whose security policy permits them. A scoped FS token limits remote data access but does not restore container isolation. Do not grant these privileges to untrusted agent code without an appropriate isolation boundary. + +## Start with Docker + +On the host, provide the token through your secret manager and set the matching region: + +```bash +# Do not put a real token in a Dockerfile or commit it to source control. +export TI_FS_TOKEN="" +export TI_REGION_CODE="aws-us-east-1" +``` + +Start an interactive container: + +```bash +# Expose FUSE and the permissions needed to create the mount. +docker run --rm -it \ + --device /dev/fuse \ + --cap-add SYS_ADMIN \ + --security-opt apparmor=unconfined \ + --env TI_FS_TOKEN \ + --env TI_REGION_CODE \ + ubuntu:24.04 bash +``` + +The device option exposes `/dev/fuse`; `SYS_ADMIN` permits the mount operation; the security option removes AppArmor restrictions that could otherwise reject it. A host's other security controls can still prohibit mounting. + +Continue with [Install and mount inside the container](/tidb-cloud-filesystem/filesystem-mount-docker.md#install-and-mount-inside-the-container). + +## Start with Docker Compose + +As an alternative to `docker run`, use the following `compose.yaml`. It reads the same two environment variables from the host: + +```yaml +services: + agent: + image: ubuntu:24.04 + command: ["sleep", "infinity"] + devices: + - /dev/fuse:/dev/fuse + cap_add: + - SYS_ADMIN + security_opt: + - apparmor=unconfined + environment: + TI_FS_TOKEN: ${TI_FS_TOKEN:?Set TI_FS_TOKEN} + TI_REGION_CODE: ${TI_REGION_CODE:?Set TI_REGION_CODE} +``` + +```bash +# Start the container, then open its shell. +docker compose up -d +docker compose exec agent bash +``` + +## Install and mount inside the container + +Run these commands inside the container. This Ubuntu image starts as root, so no `sudo` is needed for package installation: + +```bash +# Install HTTPS download support and the FUSE3 mount helper. +apt-get update +apt-get install -y --no-install-recommends ca-certificates curl fuse3 +``` + +Install the CLI: + +```bash +# The installer includes the Filesystem mount runtime. +curl -fsSL https://github.com/tidbcloud/ti-cli/releases/latest/download/install.sh | sh -s -- --yes +``` + +After installation, prepare the current shell and mount: + +```bash +# The token identifies the Filesystem; no profile configuration is needed. +export PATH="$HOME/.ti/bin:$PATH" +mkdir -p "$HOME/workspace" +ti fs mount-file-system --mount-path "$HOME/workspace" --driver fuse +ls "$HOME/workspace" +``` + +For a token restricted to a subtree, add the matching `--remote-path`, for example `/workspace`. Add `--read-only` for a read-only token. Keep the application and mount under the same OS user. If your application image uses a non-root user, install dependencies while building the image and mount as the application user at runtime. + +## Stop the container safely + +Stop application writes, close files, and unmount inside the container: + +```bash +# Wait for a successful unmount before destroying the container. +ti fs unmount-file-system --mount-path "$HOME/workspace" && exit +``` + +The `docker run --rm` container is removed after its shell exits. For Compose, run the following on the host only after the unmount succeeds: + +```bash +# Remove the container after the mount has stopped cleanly. +docker compose down +``` + +The remote Filesystem remains available. Removing the container before pending writes reach the service can lose those writes; an automatic container timeout is not a graceful unmount. + +## What's next + +- [Share data with the next sandbox](/tidb-cloud-filesystem/filesystem-sharing.md). +- [Restrict tokens to the required paths and operations](/tidb-cloud-filesystem/filesystem-authorization.md). diff --git a/tidb-cloud-filesystem/filesystem-mount-linux.md b/tidb-cloud-filesystem/filesystem-mount-linux.md new file mode 100644 index 0000000000000..74bfaa0bbe48a --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-mount-linux.md @@ -0,0 +1,82 @@ +--- +title: Mount TiDB Cloud Filesystem on Linux +summary: Set up FUSE3 on Linux, mount a TiDB Cloud Filesystem as the application user, and troubleshoot mount permission errors. +--- + +# Mount TiDB Cloud Filesystem on Linux + +Linux mounts use FUSE to route local filesystem operations to TiDB Cloud Filesystem. Applications can use the mounted directory without adopting a storage SDK. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Prerequisites + +- Install `ti` and select a Filesystem using [a local credential or an FS token](/tidb-cloud-filesystem/filesystem-mount.md#select-a-filesystem). +- Use a Linux host with FUSE support. For a container, follow [Docker and Docker Compose](/tidb-cloud-filesystem/filesystem-mount-docker.md) instead. +- Run the mount and application as the same OS user. + +## Install FUSE3 + +On Ubuntu or Debian: + +```bash +# Install the mount helper; this administrative step might require sudo. +sudo apt-get update +sudo apt-get install -y --no-install-recommends fuse3 +``` + +Check the helper and device: + +```bash +# Both the helper and the kernel device must be available. +command -v fusermount3 +ls -l /dev/fuse +``` + +On another distribution, install its FUSE3 package. If `/dev/fuse` is missing or inaccessible, have the host administrator enable FUSE and grant the mounting user access. Installing a library alone does not provide a usable mount environment. + +## Mount and verify + +Use an empty directory under your home directory: + +```bash +# Keep the mount owned and used by the current OS user. +mkdir -p "$HOME/workspace" +ti fs mount-file-system --mount-path "$HOME/workspace" --driver fuse +``` + +With a writable token, write a test file and confirm it has reached the remote Filesystem: + +```bash +# Use a unique filename so the test does not overwrite an existing file. +TEST_FILE="mount-check-$(date +%s).txt" +printf 'Hello from Linux\n' > "$HOME/workspace/$TEST_FILE" +ti fs drain-file-system --mount-path "$HOME/workspace" --timeout 30s +ti fs read-file --path "/$TEST_FILE" +``` + +This example mounts the remote root `/`. If you mounted a subtree, include that remote prefix in the `read-file` path. + +When finished, stop writers and unmount: + +```bash +# Stop the mount without deleting the remote Filesystem. +ti fs unmount-file-system --mount-path "$HOME/workspace" +``` + +## Diagnose permission errors + +If `fusermount3` reports `Permission denied`, check the local mount path, `/dev/fuse` access, and the host's security policy. This error is not necessarily a TiDB Cloud credential failure. + +Ubuntu 26.04 can apply an AppArmor profile to `fusermount3` that allows paths under home directories but rejects a top-level path such as `/workspace`. Becoming root or running `chown` on `/workspace` does not bypass that policy. Prefer `$HOME/workspace`; if the application requires another path, ask the administrator to update the narrow AppArmor rule described in [Ubuntu mount-path restrictions](/ai/ti/guides/mount-filesystem.md#ubuntu-2604-mount-paths). + +A root-created FUSE mount is also not automatically usable by an application running as a different user. Mount as the user that will run the application rather than trying to repair access with `chown` afterward. + +For startup failures, inspect the diagnostic log path shown by the CLI. Do not repeatedly start mounts at the same path without checking whether a previous mount is still present. + +## What's next + +- [Use layers and checkpoints](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md). +- [Share files with another machine](/tidb-cloud-filesystem/filesystem-sharing.md). diff --git a/tidb-cloud-filesystem/filesystem-mount-macos.md b/tidb-cloud-filesystem/filesystem-mount-macos.md new file mode 100644 index 0000000000000..1d7aad6b81317 --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-mount-macos.md @@ -0,0 +1,82 @@ +--- +title: Mount TiDB Cloud Filesystem on macOS +summary: Mount a TiDB Cloud Filesystem with macOS WebDAV, or choose macFUSE when your workflow needs layers and historical checkpoints. +--- + +# Mount TiDB Cloud Filesystem on macOS + +On macOS, `ti` uses WebDAV by default, so you can start with a local directory without installing FUSE. Install macFUSE and explicitly select the FUSE driver when you need layer mounts, checkpoint mounts, or the FUSE drain operation. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Prerequisites + +Install `ti` and select a Filesystem using [a local credential or an FS token](/tidb-cloud-filesystem/filesystem-mount.md#select-a-filesystem). Use a writable owner or scoped token for the write examples below. + +## Mount with the default WebDAV driver + +```bash +# Mount under your home directory, not at a root-level path such as /workspace. +mkdir -p "$HOME/workspace" +ti fs mount-file-system --mount-path "$HOME/workspace" +``` + +The successful result identifies the `webdav` driver. You can explicitly request the same mode with `--driver webdav`. + +```bash +# Verify a write through the local mount. +TEST_FILE="mount-check-$(date +%s).txt" +printf 'Hello from macOS\n' > "$HOME/workspace/$TEST_FILE" +cat "$HOME/workspace/$TEST_FILE" +``` + +Before a handoff or shutdown, close application files and unmount: + +```bash +# WebDAV has no drain command; finish file operations and unmount normally. +ti fs unmount-file-system --mount-path "$HOME/workspace" +ti fs read-file --path "/$TEST_FILE" +``` + +The final command reads from the remote service, independently of the mount. WebDAV and FUSE are different filesystem interfaces; do not assume WebDAV has every FUSE or POSIX capability. + +## Use macFUSE for layers and checkpoints + +Install [macFUSE](https://macfuse.github.io/) and complete the installation and security approvals required for your macOS version. Installing `ti` does not install macFUSE. Follow the macFUSE installation guidance for your system; do not assume every macFUSE backend is supported by the bundled Filesystem runtime. + +Unmount an existing WebDAV mount before reusing its directory with FUSE: + +```bash +# Select FUSE explicitly after installing macFUSE. +ti fs mount-file-system --mount-path "$HOME/workspace" --driver fuse +``` + +To keep a FUSE mount online while waiting for pending writes to reach the service: + +```bash +# Use this durability barrier before a layer checkpoint or cross-machine handoff. +ti fs drain-file-system --mount-path "$HOME/workspace" --timeout 30s +``` + +For writable layer and read-only checkpoint examples, see [Branches and Checkpoints](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md). They cannot run through WebDAV. + +When finished with the FUSE mount, stop writers and unmount it: + +```bash +# Release the mount after pending writes have been flushed. +ti fs unmount-file-system --mount-path "$HOME/workspace" +``` + +## Troubleshoot startup + +- Use an empty directory you can write to, such as `$HOME/workspace`. A root-level path might not be writable on macOS. +- For FUSE, verify that macFUSE installation and required approvals are complete. +- If startup fails, inspect the diagnostic log path in the CLI error. The top-level background-process error does not by itself identify the cause. +- If unmount fails, keep the process, local cache, and machine available until you resolve the failure and verify remote data. + +## What's next + +- [Understand mount lifecycle and durability](/tidb-cloud-filesystem/filesystem-mount.md#finish-safely). +- [Share a read-only workspace](/tidb-cloud-filesystem/filesystem-sharing.md). diff --git a/tidb-cloud-filesystem/filesystem-mount.md b/tidb-cloud-filesystem/filesystem-mount.md new file mode 100644 index 0000000000000..4a0eedacbc212 --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-mount.md @@ -0,0 +1,98 @@ +--- +title: Mount TiDB Cloud Filesystem Locally +summary: Select a Filesystem and mount driver, access remote files from a local directory, and stop a mount without losing pending writes. +--- + +# Mount TiDB Cloud Filesystem Locally + +A mount makes remote files available at a local directory. Use it when your editor, application, or agent expects filesystem paths instead of file-transfer commands. The remote Filesystem persists independently of the mount process. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Choose your environment + +- [Linux](/tidb-cloud-filesystem/filesystem-mount-linux.md): use FUSE3 and an accessible `/dev/fuse` device. +- [macOS](/tidb-cloud-filesystem/filesystem-mount-macos.md): use the default WebDAV driver, or install macFUSE and explicitly select FUSE for layers and checkpoints. +- [Docker and Docker Compose](/tidb-cloud-filesystem/filesystem-mount-docker.md): expose the Linux host's FUSE device and allow mounting inside the container. + +Native Windows mounting is not supported by `ti`. Use direct commands such as `ti fs copy-file`, `ti fs read-file`, and `ti fs list-files` instead. + +## Select a Filesystem + +### Use a locally stored token + +After creating a Filesystem with the CLI, select its ID: + +```bash +# Select the Filesystem whose token is already stored locally. +export TI_FS_FILE_SYSTEM_ID="" +``` + +The CLI uses the selected resource's stored token and region information. You can pass `--file-system-id` on each command instead. There is no default Filesystem selected merely because only one resource exists. + +### Use a token without configuring a profile + +On a machine with `ti` installed, provide the token through a secret manager or the environment: + +```bash +# Inject these values from your secret manager in automation. +export TI_FS_TOKEN="" +export TI_REGION_CODE="aws-us-east-1" +``` + +Set the region to where this Filesystem was created. `ti` derives the Filesystem ID from the token; neither `ti configure` nor `TI_FS_FILE_SYSTEM_ID` is required. A supplied ID must match the token. If your shell already has an ID for another Filesystem, clear it before using the token-only workflow. + +Use an owner token for full Filesystem access, or a scoped token with the operations required by the application. For a token restricted to `/workspace`, mount that subtree rather than `/`. See [Authorization](/tidb-cloud-filesystem/filesystem-authorization.md). + +## Mount and use the files + +After installing the platform dependencies, mount the selected Filesystem: + +```bash +# Use an empty directory owned by the user who will access the mount. +mkdir -p "$HOME/workspace" +ti fs mount-file-system --mount-path "$HOME/workspace" +``` + +The command waits for readiness and returns a structured result with `status: mounted`. A background companion process keeps the mount alive. Closing the terminal does not unmount it, but terminating that process or the machine interrupts access. + +To expose only one remote directory, pass `--remote-path /workspace`. To make a mount read-only, add `--read-only`. These are client-side mount settings, not substitutes for a scoped token's server-enforced permissions. + +```bash +# These are ordinary local filesystem commands, not CLI subcommands. +ls "$HOME/workspace" +printf 'Written through the mount\n' > "$HOME/workspace/mounted.txt" +cat "$HOME/workspace/mounted.txt" +``` + +The write example requires a writable mount and token. Use the same OS user for mounting and file access; changing a directory's ownership does not grant another user access through an existing FUSE mount. + +## Finish safely + +Stop applications writing to the mount and close their files. If you need pending writes to reach the service while keeping a FUSE mount online, such as before creating a checkpoint or handing work to another machine, drain it: + +```bash +# FUSE only: wait for pending remote writes without unmounting. +ti fs drain-file-system --mount-path "$HOME/workspace" --timeout 30s +``` + +When finished, unmount: + +```bash +# Graceful unmount flushes pending FUSE work before stopping the mount. +ti fs unmount-file-system --mount-path "$HOME/workspace" +``` + +An explicit drain is not required before every normal unmount. WebDAV does not support drain: close application files and complete a normal unmount before a handoff. Drain and unmount use the local mount locator and do not require you to provide the region or token again. The running mount still needs valid credentials to finish remote work. + +> **Warning:** +> +> Do not destroy a sandbox, stop its mount process, or delete its local cache after a drain or unmount error. Pending writes might exist only on that machine. Resolve the error and verify remote data before removing the environment. Unmounting does not delete the remote Filesystem. + +## What's next + +- [Share a Filesystem across environments](/tidb-cloud-filesystem/filesystem-sharing.md). +- [Mount a layer or historical checkpoint](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md). +- [Look up mount options](/ai/ti/reference/ti-fs-mount-file-system.md). diff --git a/tidb-cloud-filesystem/filesystem-quick-start.md b/tidb-cloud-filesystem/filesystem-quick-start.md new file mode 100644 index 0000000000000..6bb8ec93a308f --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-quick-start.md @@ -0,0 +1,127 @@ +--- +title: Get Started with TiDB Cloud Filesystem +summary: Create a TiDB Cloud Filesystem with the CLI, write and read a file, and keep the workspace available for another session. +--- + +# Get Started with TiDB Cloud Filesystem + +Create a workspace when your application's or agent's files need to outlive the machine that produces them. This quick start writes and reads a remote file without requiring a mount. You can mount the same Filesystem afterward. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## Prerequisites + +Obtain a TiDB Cloud API public key and private key from the [API Keys page](https://tidbcloud.com/org-settings/api-keys). The keys must have permission to create a Filesystem in your organization. + +If someone has already supplied you with an FS token, skip resource creation and follow [Mounting Locally](/tidb-cloud-filesystem/filesystem-mount.md#use-a-token-without-configuring-a-profile). + +## Step 1. Install the CLI + + + +
+ +Run the installer: + +```bash +# Install the CLI and its bundled Filesystem runtime. +curl -fsSL https://github.com/tidbcloud/ti-cli/releases/latest/download/install.sh | sh -s -- --yes +``` + +After installation, add the binary directory to your current shell: + +```bash +# Make the installed CLI available in this terminal. +export PATH="$HOME/.ti/bin:$PATH" +ti --version +``` + +Add the same `export PATH` line to your shell profile to use `ti` in future terminals. + +
+ +
+ +Run the installer: + +```powershell +# Download and run the PowerShell installer. +$script = "$env:TEMP\install-ti.ps1" +Invoke-WebRequest https://github.com/tidbcloud/ti-cli/releases/latest/download/install.ps1 -OutFile $script +powershell -ExecutionPolicy Bypass -File $script -Yes +``` + +After installation, add the binary directory to your current session: + +```powershell +# Make the installed CLI available in this PowerShell session. +$env:Path = "$HOME\.ti\bin;$env:Path" +ti --version +``` + +Add `$HOME\.ti\bin` to your user `PATH` for future sessions. Windows supports the direct file commands in this quick start, but not native Filesystem mounts through `ti`. + +
+
+ +For other installation and upgrade details, see [Install, Configure, and Update TiDB Cloud CLI](/ai/ti/reference/ti-install-configure-update.md). + +## Step 2. Configure access + +```shell +# Follow the prompts to save your API keys and default region. +ti configure +``` + +Choose one of these Filesystem regions: + +- `aws-us-east-1` +- `aws-ap-southeast-1` +- `aws-us-west-2` +- `alicloud-ap-southeast-1` + +Configuration saves the inputs locally. Your first remote command verifies the credentials with the service. + +## Step 3. Create the Filesystem + +```shell +# Wait until the new Filesystem's root is readable. +ti fs create-file-system --display-name my-workspace --wait +``` + +Copy the returned `file_system_id` for the next step. The CLI stores this Filesystem's token locally, so you do not need to export a token. Treat the returned `fs_token` as a secret; do not paste the output into a public issue or log. + +Display names help identify resources but are not unique selectors. Subsequent commands use the ID. A failed wait does not automatically delete the created Filesystem; inspect the reported resource before creating another one. If creation reports a free-plan quota error, follow its billing link to add a payment method. + +## Step 4. Write and read a file + +Replace `` with the ID returned by creation: + +```shell +# Store a file in the remote workspace. +echo "Hello from my workspace" | ti fs copy-file --file-system-id "" --from-stdin --to-remote /hello.txt +``` + +```shell +# Read the same file from the service. +ti fs read-file --file-system-id "" --path /hello.txt +``` + +The read returns `Hello from my workspace`. The file remains available after you close the terminal. There is no local mount to keep running for this workflow. + +## What's next + +- [Mount the Filesystem](/tidb-cloud-filesystem/filesystem-mount.md) to use it through a local directory. +- [Share the workspace](/tidb-cloud-filesystem/filesystem-sharing.md) with another machine or agent. +- [Use layers and checkpoints](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md) to review changes before publishing them. + +When you no longer need this tutorial Filesystem, delete it using your TiDB Cloud API credentials: + +```shell +# Permanently request deletion of only the tutorial resource. +ti fs delete-file-system --file-system-id "" +``` + +Deletion removes the remote resource and its data, not just a local registration. The command reports `deleting` when the asynchronous request is accepted. diff --git a/tidb-cloud-filesystem/filesystem-sharing.md b/tidb-cloud-filesystem/filesystem-sharing.md new file mode 100644 index 0000000000000..712ea6d485dbe --- /dev/null +++ b/tidb-cloud-filesystem/filesystem-sharing.md @@ -0,0 +1,113 @@ +--- +title: Share TiDB Cloud Filesystems +summary: Share a remote workspace across machines and sandboxes with separate access tokens, and hand off files after writes reach the service. +--- + +# Share TiDB Cloud Filesystems + +Sharing a Filesystem gives participants access to the same remote namespace, not independent copies. For example, an agent can produce a report in a sandbox and a reviewer can open that report from a laptop without downloading and redistributing an archive for every revision. + +> **Note:** +> +> TiDB Cloud Filesystem is currently in public preview. Its features and interfaces are subject to change without notice. + +## What each participant needs + +The trusted machine uses TiDB Cloud API keys to create the Filesystem. Other participants need `ti`, an FS token, and the Filesystem region. They do not need a copy of `~/.ti/`, account API keys, or their own Filesystem resource. + +Use separate tokens so you can retire one participant's access without changing every participant's credentials. Choose a scoped token for a restricted task; an owner token grants broad Filesystem access. See [Authorization](/tidb-cloud-filesystem/filesystem-authorization.md). + +## Prepare the workspace on machine A + +With `ti` installed and configured, create a Filesystem or use an existing one. This example creates a new resource: + +```bash +# Retain the ID; the creator's token is stored locally by the CLI. +FILE_SYSTEM_ID="$(ti fs create-file-system \ + --display-name shared-reports --wait \ + --query file_system_id --output text)" +``` + +Create a directory and publish the first report: + +```bash +# Write through the direct file interface, without a local mount. +ti fs create-directory --file-system-id "$FILE_SYSTEM_ID" --path /reports +printf 'The first report is ready for review.\n' | ti fs copy-file \ + --file-system-id "$FILE_SYSTEM_ID" \ + --from-stdin --to-remote /reports/summary.txt +``` + +Issue a read-only token for the reviewer: + +```bash +# Keep this value in a secret manager, not in a shared log. +REVIEW_TOKEN="$(ti fs generate-file-system-scoped-token \ + --file-system-id "$FILE_SYSTEM_ID" \ + --subject reviewer --ttl 24h \ + --allow /reports:read,list \ + --query fs_token --output text)" +``` + +Deliver `REVIEW_TOKEN` and the Filesystem's region code securely to machine B. Retain the Filesystem ID on machine A for administration. The token expires after the requested lifetime; a saved environment variable does not extend it. + +## Open the report on machine B + +Inject the reviewer's token and matching region into the environment: + +```bash +# No ti configure is needed on the receiving machine. +export TI_FS_TOKEN="" +export TI_REGION_CODE="" +ti fs read-file --path /reports/summary.txt +``` + +On macOS or Linux with the [mount dependencies](/tidb-cloud-filesystem/filesystem-mount.md#choose-your-environment), expose the allowed directory locally: + +```bash +# Mount only the scope allowed by the reviewer token. +mkdir -p "$HOME/reports" +ti fs mount-file-system \ + --remote-path /reports \ + --mount-path "$HOME/reports" \ + --read-only +cat "$HOME/reports/summary.txt" +``` + +The remote `/reports` prefix becomes the local mount root, so the local file is `$HOME/reports/summary.txt`, not `$HOME/reports/reports/summary.txt`. + +The token enforces read-only access at the service. `--read-only` also tells the local mount to reject writes; using that flag with an owner token alone would not restrict the owner's other API or CLI access. + +## Hand off new data safely + +A successful write to a FUSE-mounted file might still be buffered on the producing machine. Before telling the reviewer that a revision is ready, stop the application's writes and drain its FUSE mount, or unmount it successfully. For WebDAV, close application files and finish a normal unmount. See [Finish safely](/tidb-cloud-filesystem/filesystem-mount.md#finish-safely). + +Use a direct remote read to verify a handoff independently of another mount's cache. Existing open handles and client caches can retain older content; do not assume every reader instantly sees each local write. + +Coordinate writers to the same path. Shared storage is not a distributed lock or an automatic merge system. Use separate paths or [layers](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md) for independent drafts, and publish only after review. + +## End access without deleting the workspace + +On machine B, stop readers and unmount: + +```bash +# Remove the local mount, not the shared remote data. +ti fs unmount-file-system --mount-path "$HOME/reports" +unset TI_FS_TOKEN TI_REGION_CODE +``` + +On machine A, identify and revoke the reviewer's token when no longer needed: + +```bash +# Find the reviewer token ID in the metadata, then revoke that token only. +ti fs list-file-system-tokens --file-system-id "$FILE_SYSTEM_ID" --output text +ti fs delete-file-system-token \ + --file-system-id "$FILE_SYSTEM_ID" --token-id "" +``` + +Do not delete the Filesystem to disconnect one participant: resource deletion affects everyone and removes the shared data. + +## What's next + +- [Use branches to compare independent drafts](/tidb-cloud-filesystem/filesystem-branches-checkpoints.md). +- [Run the agent sandbox example](/ai/ti/guides/ti-agent-sandbox-example.md).