Install
Install PrivacyFence.
PrivacyFence runs as Docker containers. Answer a few questions to get the commands for your setup: who uses it, whether it comes with a presentation tool and a data lake, how people sign in, which apps connect the services, and what sits in front of it.
Your setup
Pick your setup.
Your commands
What to run.
The suite, for one person on this computer
curl -fsSL https://github.com/privacyfence/privacyfence-suite/releases/latest/download/install.sh | sh -s -- localhost --start
cd privacyfence-localhost
docker compose logs privacyfence | grep "Setup code"
Then open http://localhost:8765, enter the code and set up your passkey. Peek is at http://localhost:7700 and Grist at http://localhost:8484. Needs Docker Engine 24 or later with Compose 2.24 or later.
PrivacyFence alone, for one person on this computer
docker run --rm -p 127.0.0.1:8765:8765 \
-v pf-data:/var/lib/privacyfence-org/.privacyfence \
ghcr.io/privacyfence/privacyfence-org:latest
The log prints Setup code: XXXX-XXXX. Open http://localhost:8765/login to set up your passkey. Open http://localhost:8765, not http://127.0.0.1:8765: the passkey belongs to localhost.
Running it on this computer, in the Docker guide.
The suite with Caddy and your identity provider
curl -fsSL https://github.com/privacyfence/privacyfence-suite/releases/latest/download/install.sh | sh -s -- caddy-idp
- Register one confidential OIDC client with your identity provider, for PrivacyFence only, with the redirect URIs
https://<PF_HOSTNAME>/oauth/idp/callback,/oauth/idp/login-callbackand/oauth/stepup/callback. - Fill in the host names, the identity provider and the admins in
.env. If your identity provider sends noemail_verifiedclaim (Microsoft Entra ID, for example), also setIDP_TRUST_UNVERIFIED_EMAIL=true; without it, those users cannot sign in at Peek and Grist. - Put the client secret in the secret file the README names.
- Start it with
docker compose up -d. - Sign in as an admin and add a passkey.
Needs three DNS names pointing at the server (PrivacyFence, Peek and Grist), ports 80 and 443 reachable from the internet, and Docker Engine 24 or later with Compose 2.24 or later. The suite's README has the details.
The suite with Caddy and the built-in Google sign-in
curl -fsSL https://github.com/privacyfence/privacyfence-suite/releases/latest/download/install.sh | sh -s -- caddy-google
- Edit
.env: the three host names,ADMIN_EMAILS,ALLOWED_DOMAINandGRIST_ADMIN_EMAIL. - Start it with
docker compose up -d. - Publish the
_privacyfence-relayDNS TXT records printed bydocker compose exec privacyfence privacyfence-app --relay-dns-records. - Sign in with a Google Workspace account.
Needs three DNS names pointing at the server (PrivacyFence, Peek and Grist), ports 80 and 443 reachable from the internet, and Docker Engine 24 or later with Compose 2.24 or later. The suite's README has the details.
The suite behind your nginx, with the built-in Google sign-in
curl -fsSL https://github.com/privacyfence/privacyfence-suite/releases/latest/download/install.sh | sh -s -- nginx-google
- Edit
.env: the three host names,ADMIN_EMAILS,ALLOWED_DOMAINandGRIST_ADMIN_EMAIL. - Set up the host's nginx from the suite's nginx README.
- Start it with
docker compose up -d. - Publish the
_privacyfence-relayDNS TXT records printed bydocker compose exec privacyfence privacyfence-app --relay-dns-records.
Needs Linux with rootful Docker, nginx 1.25.1 or later, and a certificate for the three names. Docker Desktop and rootless Docker do not work; use Caddy there.
No ready-made suite configuration for this combination
The suite ships Caddy with your identity provider, and Caddy or nginx with the built-in Google sign-in. With your identity provider behind nginx or another proxy, either use the Caddy configuration, or install PrivacyFence alone behind your proxy and connect Peek and Grist to it.
See the suite's configurations, reverse proxy and TLS in the organization guide, and signing Peek and Grist in through PrivacyFence.
PrivacyFence alone, with Caddy
Point a public host name at the Docker host and open TCP 443 (and 80 if you can). With the built-in Google sign-in or built-in apps, TCP 443 must be reachable from the whole internet. If the DNS is on Cloudflare, set the record to DNS only.
Register one OIDC client with your identity provider, with the redirect URIs https://<host>/oauth/idp/callback, /oauth/idp/login-callback and /oauth/stepup/callback.
Make the deploy folder:
sudo install -d -o root -g root -m 0750 /opt/privacyfence-org
cd /opt/privacyfence-org
Fetch the deploy files. Replace vX.Y.Z with the release you run.
sudo curl -fsSLO https://raw.githubusercontent.com/privacyfence/privacyfence/vX.Y.Z/deploy/docker/compose.yaml
sudo curl -fsSLO https://raw.githubusercontent.com/privacyfence/privacyfence/vX.Y.Z/deploy/docker/Caddyfile
sudo curl -fsSL -o privacyfence.env https://raw.githubusercontent.com/privacyfence/privacyfence/vX.Y.Z/deploy/docker/privacyfence.env.example
sudo curl -fsSL -o .env https://raw.githubusercontent.com/privacyfence/privacyfence/vX.Y.Z/deploy/docker/env.example
Then fill in privacyfence.env:
PRIVACYFENCE_IDP_ISSUER=https://login.example.com
PRIVACYFENCE_IDP_CLIENT_ID=
PRIVACYFENCE_IDP_CLIENT_SECRET_FILE=/run/secrets/idp_client_secret
[email protected],[email protected]
sudo install -m 0400 -o 10001 -g 10001 /dev/null idp_client_secret
sudo sh -c 'cat > idp_client_secret' # paste the secret, then press Ctrl-D
Then uncomment the secrets: lines in compose.yaml, under the service and at the bottom.
Comment out the PRIVACYFENCE_IDP_ISSUER and PRIVACYFENCE_IDP_CLIENT_ID lines at the top of privacyfence.env: the built-in Google sign-in refuses to start next to any PRIVACYFENCE_IDP_* setting. Then set:
PRIVACYFENCE_IDP=builtin-google
[email protected],[email protected]
PRIVACYFENCE_ALLOWED_DOMAINS=example.com
Set PF_HOSTNAME and PRIVACYFENCE_IMAGE_TAG in .env, then start it:
sudo docker compose up -d
Sign in as an admin and add a passkey. Quick start, in the Docker guide.
PrivacyFence alone, behind nginx or another proxy
PrivacyFence's Docker files bring Caddy. Behind nginx or another reverse proxy, install PrivacyFence from PyPI and run it with systemd as the organization deployment guide describes; its reverse proxy section has a Caddy and an nginx example.
See the organization deployment guide and its reverse proxy and TLS section.
Good to know
Before you start.
Single-user mode is no protection against an AI agent that can run docker on that computer: whoever can run docker can read the setup code from the log or open the data volume. Run it under a separate account with rootless Docker or in a virtual machine, or use an organization server.
Single-user mode, in Security and compliance.
PrivacyFence ships its own apps for Google, Slack, Salesforce, Atlassian and Miro, so an organization server connects them with nothing to register. An organization may register its own app with any of them instead and upload it on the Admin page; its own apps never touch the relay.
The relay at oauth.privacyfence.eu forwards the browser's sign-in redirect (a one-time authorization code and the state) to your server. It never sees a token, keeps no logs and stores no code: your server exchanges the code with the provider itself.
Until Google verifies PrivacyFence's Google app, people see Google's unverified-app screen, and the app is limited to 100 users across all installs; an organization that needs neither registers its own Google app.
Slack and Miro send no PKCE, so with the built-in app their one-time sign-in code passes through the relay without it; an organization's own app avoids this.
The server needs a public https:// address reachable on TCP 443 from the whole internet, and outbound HTTPS to oauth.privacyfence.eu.
Built-in apps through the relay, in the organization guide, and the relay terms.
Register an app with each provider, sign its client ID and secret as a connector config, and upload it on Admin → Services. Your own apps use your server's own redirect addresses and never touch the relay.
Signed connector configs, in the organization guide.
The built-in Google sign-in admits only verified Google Workspace accounts in your allowed domains. Nobody from a domain signs in until you publish the DNS TXT record _privacyfence-relay.<domain> that the server prints. Every sign-in goes through oauth.privacyfence.eu.
Built-in Google sign-in, in the organization guide.
Administrators run the server from the Admin page: which services are offered and which app each uses, who may sign in, step-up, scoped tokens, audit forwarding and the install-wide privacy filter. Every change that alters what the server does asks for a passkey and is recorded in the audit log. The server address, the identity provider and the admins are set in the environment, not on the page.
The Admin page, in the organization guide.
What gets installed
The images.
ghcr.io/privacyfence/privacyfence-org- With the suite,
ghcr.io/privacyfence/peek,ghcr.io/privacyfence/grist-core(PrivacyFence's grist-core fork) andghcr.io/privacyfence/grist-provisioner - In the Caddy configurations (suite and standalone),
caddy - With the suite,
alpine, for the one-shot setup container that generates the secrets
The suite pins every image except PrivacyFence, which follows latest; its .env holds the tags.
Verify
Check what you download.
The suite's verified path:
base=https://github.com/privacyfence/privacyfence-suite/releases/latest/download
curl -fsSLO $base/install.sh && curl -fsSLO $base/SHA256SUMS
sha256sum -c --ignore-missing SHA256SUMS # prints "install.sh: OK"
gh attestation verify install.sh --repo privacyfence/privacyfence-suite
sh install.sh caddy-google
Then check the image: gh attestation verify oci://ghcr.io/privacyfence/privacyfence-org:X.Y.Z --owner privacyfence