Skip to content

These pages describe PrivacyFence 6.3.0. Download it · What changed

privacyfence-sync

privacyfence-sync runs a data-sync recipe against PrivacyFence with no AI model involved, so a regular refresh costs no model tokens. A recipe reads from your connected services (Salesforce reports, Jira searches, Grist tables, Drive files), runs your own scripts on the files, writes the result back to Grist, and can publish an HTML dashboard on Peek.

Who it is for

You design the sync with Claude once: the Grist data model, the sources, the transforms, the dashboard. privacyfence-sync then repeats it on a schedule. It is an ordinary client of PrivacyFence, like Claude Code: every call goes through the gate, your rules and the audit log, and it holds none of your service credentials, cannot approve anything and cannot change rules. It declares an unattended session (see Unattended sessions), so a step that no rule covers fails at once instead of waiting for a card nobody will answer.

Install

Python 3.11 or newer, in its own virtual environment, together with anything your scripts import:

python3 -m venv ~/.venvs/privacyfence-sync
~/.venvs/privacyfence-sync/bin/pip install privacyfence-sync

It needs no PrivacyFence install of its own, so it works against an organization server from a computer that has none.

Connect

Local mode. Get your AI client token with privacyfence-app --print-mcp-token (or Copy AI Client Token in the companion app) and put it in the environment variable PRIVACYFENCE_TOKEN of the process that runs privacyfence-sync. A token is never accepted as a command-line argument; --token-env NAME names another variable. The server defaults to http://127.0.0.1:8765/mcp (--server, the recipe's server, or PRIVACYFENCE_MCP_URL).

Organization mode. Sign in once with privacyfence-sync login --server https://<host>/mcp. Runs use the stored sign-in as long as PRIVACYFENCE_TOKEN is not set. A sign-in lasts 30 days; after that a run exits with code 4 and you sign in again.

Unattended sessions must be allowed. Both modes need unattended_sessions.enabled in the organization bundle (build_org_bundle.py --enable-unattended-sessions, see the configuration reference). Without it a run stops before its first step.

The rules a recipe needs

Every step needs an auto-accept rule, because a scheduled run gets no cards. Create them in Settings → Auto-accept → Add a rule (each asks for your passkey): the report, Jira project, Drive folder, Grist document and Peek page the recipe touches, with the verbs its steps use. The export tools and a Peek page upload also need Let exports, downloads and page uploads carry personal data ticked on the recipe's scoped token if the data holds personal data (Letting personal data through).

To find a missing rule, run the recipe once with privacyfence-sync run recipe.yaml --attended: each uncovered step shows a card, and the card's Always allow button or Settings adds the rule. Then run it without --attended and no card should appear. Before scheduling, privacyfence-sync preflight reports with the token whether each step is in its scope and covered by a rule.

The recipe-writing plugin

The privacyfence-sync plugin gives Claude a skill that writes recipes, their scripts, dashboard templates and the list of rules for you, and ports an existing data-sync skill.

  • Claude Code: /plugin marketplace add privacyfence/privacyfence#stable, then /plugin install privacyfence-sync@privacyfence.
  • Claude Cowork: Plugins → Add → Add marketplace, and enter privacyfence/privacyfence#stable.
  • Claude Cowork and claude.ai, by file: download privacyfence-sync-plugin.zip from the latest release and upload it as a plugin.

#stable is a branch that each stable release moves to its own commit, so the marketplace follows the latest stable release. Without #stable it follows main, which can be newer than the privacyfence-sync you installed. For an exact version, use the release zip or #v<version>.

The recipe format

The recipe format, step types, script steps, dashboard templates, scheduling, exit codes and limits are in the privacyfence-sync README on GitHub. Why it is a separate client: ADR 0161.