---
name: Freeze Destructive Dropbox Operations
tags:
  - dropbox
  - freeze-destructive-ops
  - ingress
  - soc2
publishedAt: 2026-07-12
description: |
  # dropbox / freeze-destructive-ops

  **Direction:** ingress (`tool_pre_invoke`)
  **Default:** deny destructive tools, allow everything else
  **Package:** `dropbox.ingress.freeze_destructive_ops`

  ## What it does

  Freezes the irreversible and bulk-mutation Dropbox tools on the agent channel,
  regardless of path. At ingress it denies, by tool-name suffix:

  - **Deletion** — `Delete` (official `mcp.dropbox.com`), `safe_delete_item`
    (`dbx-mcp-server`), `dropbox_delete` (`ngs`). A prompt-injected or mistaken
    agent can use these to mass-delete files; Dropbox moves deletes to *Deleted
    files*, recoverable **only within the plan's retention window**, so a bulk
    agent delete can become permanent.
  - **Folder rewind** — `RestoreFolder` (official). Rewinds an entire folder to an
    earlier point in time, silently reverting every file in a shared tree.
  - **Revision resurrection** — `RestoreFileRevision` (official),
    `dropbox_restore_file` (`ngs`). Resurfaces content that was deliberately
    removed by restoring an older file revision.

  All other tools pass through unchanged. There is **no identity carve-out by
  default**: destructive storage actions belong to a human working in the Dropbox
  UI, not to an autonomous agent. `Move` (rename/relocate) is intentionally **not**
  frozen here — renames and moves are common and legitimate; scope them with the
  companion path-fencing and role-gate policies instead. The deny reasons tell the
  caller to perform the deletion or restore manually and note the retention-window
  caveat on deletes.

  ## Compliance alignment

  - **SOX §802 / 18 U.S.C. §1519** — anti-destruction/alteration of records: an
    agent cannot delete files or roll a folder/file back to an earlier state on the
    MCP path, supporting the record-preservation obligation for financial and audit
    evidence stored in Dropbox; **§802 / Rule 2-06** — supports retention and
    legal-hold posture by keeping agent-initiated deletion off evidence paths.
  - **SOC 2 PI1.5** — supports integrity of stored records by preventing
    agent-initiated destruction and silent rollback of stored content.
  - **HIPAA §164.312(c)** — integrity (anti-alteration/destruction of ePHI) on the
    agent channel; **§164.530(c)** — administrative safeguard limiting who can
    destroy or roll back records containing PHI.
  - **GDPR Art. 5(1)(d)** — accuracy: supports the anti-mass-corruption posture by
    stopping an errant or injected agent from bulk-erasing or silently rewinding
    personal-data records.

  ## Tool name matching

  Matches case-insensitively on `input.resource.name` as an exact name or by a
  `-`/`_`-separated suffix, so the policy tolerates any gateway server-name prefix
  (e.g. `dropbox-Delete`, `dbx-mcp-safe_delete_item`). The DTwo gateway prefixes
  tool names with the configured MCP server name, and that prefix is not
  standardized — suffix matching keeps the policy portable. Verify the exact names
  your gateway sends with the dump-input debug technique before relying on this in
  production.

  Frozen suffixes:

  - **Deletion:** `delete` (official `Delete`; also catches `dropbox_delete` via the
    `_delete` boundary), `safe_delete_item` (dbx), `dropbox_delete` (ngs, listed
    explicitly).
  - **Folder rewind:** `restorefolder` (official `RestoreFolder`).
  - **Revision resurrection:** `restorefilerevision` (official `RestoreFileRevision`),
    `dropbox_restore_file` (ngs).

  The read-only `ListRestoreEvents` tool (official) is deliberately **not** matched —
  it enumerates restore history and mutates nothing. `Move`, `Copy`, `CreateFolder`,
  `CreateFile`, share-link and file-request tools, and every read tool pass through.

  ## Argument shape

  This policy decides purely on the **tool name** — it inspects no arguments, so a
  call with missing, empty, or malformed `args` is still denied on name alone
  (fail-closed for destructive tools). Because Dropbox does not publish MCP JSON
  schemas, name-only matching also sidesteps the unverified argument-key problem
  entirely. `input.resource.name` is read via `object.get`, defaulting to `""`
  (which matches nothing) when absent.

  ## Examples

  ### Allowed — read tool, untouched

  ```jsonc
  {
    "input": {
      "action": "tool_pre_invoke",
      "resource": { "name": "dropbox-GetFileContent", "type": "tool" },
      "payload": { "name": "dropbox-GetFileContent", "args": { "path": "/Projects/roadmap.pdf" } }
    }
  }
  ```

  `allow = true`, no reason.

  ### Allowed — Move (rename/relocate is not frozen here)

  ```jsonc
  {
    "input": {
      "action": "tool_pre_invoke",
      "resource": { "name": "dropbox-Move", "type": "tool" },
      "payload": { "name": "dropbox-Move", "args": { "from_path": "/a/x.txt", "to_path": "/b/x.txt" } }
    }
  }
  ```

  `allow = true` — moves are gated by the path-fencing and role-gate policies, not frozen.

  ### Denied — file deletion

  ```jsonc
  {
    "input": {
      "action": "tool_pre_invoke",
      "resource": { "name": "dropbox-Delete", "type": "tool" },
      "payload": { "name": "dropbox-Delete", "args": { "path": "/Finance/2026/ledger.xlsx" } }
    }
  }
  ```

  `allow = false`, reason points to a manual delete in the Dropbox UI and the retention-window caveat.

  ### Denied — folder rewind

  ```jsonc
  {
    "input": {
      "action": "tool_pre_invoke",
      "resource": { "name": "dropbox-RestoreFolder", "type": "tool" },
      "payload": { "name": "dropbox-RestoreFolder", "args": { "path": "/Shared/Team", "rev": "2026-01-01T00:00:00Z" } }
    }
  }
  ```

  `allow = false`, reason explains folder rewind / revision restore is frozen on the agent channel.

  ## Composition

  Single-purpose: this policy only freezes destruction and rollback. Useful
  companions for Dropbox:

  - [`fence-sensitive-paths`](../fence-sensitive-paths/policy.md) — role-gates
    reads/listings/moves/copies/search of sensitive path prefixes (this policy leaves
    `Move`/`Copy` to it).
  - [`guard-share-links-external`](../guard-share-links-external/policy.md) — stops
    the exfiltration surface (public links, file requests) that destruction does not
    cover.
  - An egress PII/PHI redaction policy on `GetFileContent` / `download_file` and
    `Search` responses.

  ## Known limitations

  - **No identity carve-out.** Every caller is denied the frozen tools; there is no
    break-glass group by design. If your workflow needs an admin bypass, add an
    `allow if` branch gated on `input.subject.claims.groups` (read fail-closed via
    `object.get` chains) — see the sibling `box/freeze-destructive-ops` policy for
    that pattern. Group names would be placeholders to replace at import time.
  - **Community-server coverage is dialect-specific.** Only the tool names listed
    are matched. The `dbx-mcp-server` exposes only `safe_delete_item` (no restore
    tool) and `ngs` exposes `dropbox_delete` + `dropbox_restore_file`; folder rewind
    (`RestoreFolder`) exists **only** on the official server. If your fork names a
    delete/restore tool differently, add its suffix to `delete_suffixes` or
    `restore_suffixes` (the two arrays at the top of the Rego); confirm names with
    the dump-input technique against a live `tools/list`.
  - **Matching is a full-token suffix, not a substring.** A frozen suffix only fires
    when the tool name *ends* in it (as an exact name or after a `-`/`_` boundary),
    so a destructive tool with a trailing qualifier after the verb is **not** caught
    by the generic `delete` suffix — e.g. `delete_batch` (the Dropbox HTTP API has a
    real `/files/delete_batch`), `delete_file`, `delete_folder`, or `PermanentlyDelete`
    would pass through. This is deliberate — it keeps the generic `delete` token from
    over-matching benign names like `undelete` — but it means the suffix list is an
    allowlist of exact endings, **not** a semantic "anything that deletes" filter.
    None of the three dialects in scope expose such a tool today (official `Delete`,
    dbx `safe_delete_item`, ngs `dropbox_delete` are all matched); if a fork or a
    future server surfaces a batch/qualified variant, add its full suffix to
    `delete_suffixes`/`restore_suffixes`, or pair this policy with a
    `default-deny-unknown-tools` (PF-28) allowlist so drift fails closed instead of open.
  - **`Move` is intentionally out of scope.** A folder-level `Move` can restructure a
    shared tree, but renames/moves are routine, so they are left to the path-fencing
    and role-gate policies rather than frozen here. Attach those alongside this policy
    if you need move containment.
  - **Overwrites are not deletion.** Re-uploading over an existing file
    (`CreateFile` / `upload_file` / `dropbox_upload`) replaces content without a
    delete call and is **not** blocked here. Pair with an upload/version guard if you
    need overwrite protection; Dropbox keeps prior revisions, but the agent could then
    use a (blocked) restore tool to recover — hence freezing restore too.
  - **Name-only matching.** The policy does not inspect arguments, so it cannot
    distinguish, say, a single-file delete from a bulk one — all deletes are frozen.
    This is deliberate: agent-initiated deletion has no routine Cowork use.

  > **Compliance note.** This policy supports alignment with the cited framework controls **on the MCP path only**. No policy or bundle makes an organization compliant with any framework; web-UI, native-API, and in-app access are outside the gateway's reach by design. Validate against your own compliance program before relying on it.
direction: ingress
apps:
  - dropbox
industries: []
bundles:
  - soc2
experimental: true
schemaVersion: 1.0.0
minimumGatewayVersion: 1.0.0b24
---

```rego
package dropbox.ingress.freeze_destructive_ops

# Deny-by-default: only the explicit allow rule below permits the request.
default allow := false

# Destructive / bulk-mutation tool suffixes across the three Dropbox dialects.
# The gateway prefixes tool names with the configured MCP server name
# (separator not standardized), so we match the exact name or a `-`/`_`-
# separated suffix, case-insensitively, to stay portable.
delete_suffixes := [
    # Official mcp.dropbox.com `Delete`. Also catches ngs `dropbox_delete`
    # via the `_delete` boundary; listed there too for clarity.
    "delete",
    # dbx-mcp-server community soft-delete
    "safe_delete_item",
    # ngs community delete (also matched by `delete` above)
    "dropbox_delete",
]

# Folder rewind + file-revision resurrection. `RestoreFolder` rewinds a whole
# folder to a point in time; `RestoreFileRevision` / `dropbox_restore_file`
# resurface a previous revision of a single file.
restore_suffixes := [
    "restorefolder",
    "restorefilerevision",
    "dropbox_restore_file",
]

# Case-insensitive tool name; missing fields resolve to "" (never matches).
tool_name := lower(object.get(object.get(input, "resource", {}), "name", ""))

# Match the exact tool name, or a `-`/`_`-separated suffix so any gateway
# server-name prefix is tolerated (e.g. `dropbox-Delete`, `dbx-mcp-dropbox_delete`).
tool_matches(suffix) if tool_name == suffix

tool_matches(suffix) if endswith(tool_name, sprintf("-%s", [suffix]))

tool_matches(suffix) if endswith(tool_name, sprintf("_%s", [suffix]))

is_delete_tool if {
    some suffix in delete_suffixes
    tool_matches(suffix)
}

is_restore_tool if {
    some suffix in restore_suffixes
    tool_matches(suffix)
}

is_destructive_tool if is_delete_tool

is_destructive_tool if is_restore_tool

# Allow any tool that isn't on the frozen list. There is no identity carve-out.
allow if {
    not is_destructive_tool
}

reasons contains "Deleting Dropbox files through an agent is frozen. Delete the item yourself in the Dropbox web or desktop app so a human owns the decision. Deleted files are recoverable only within your plan's retention window, so a mistaken or bulk agent delete may be permanent. Contact your InfoSec team if this block is a false positive." if {
    is_delete_tool
}

reasons contains "Rewinding a Dropbox folder to an earlier point in time, or restoring a previous file revision, is frozen on the agent channel — it can silently revert an entire shared folder or resurface content that was deliberately removed. Perform the restore yourself in the Dropbox web app so a human owns the decision. Contact your InfoSec team if this block is a false positive." if {
    is_restore_tool
}

reason := joined if {
    count(reasons) > 0
    reason_list := sort([r | some r in reasons])
    joined := concat("; ", reason_list)
}
```
