Skip to main content

PrivateBin

A minimalist, zero-knowledge encrypted paste service.

PrivateBin is a zero-knowledge pastebin where the server has no knowledge of pasted content. All encryption and decryption happens client-side in the browser using AES-256. Self-hosting ensures pastes are not stored on third-party servers, making it suitable for sharing sensitive configuration or code snippets.

Alternatives considered

Cloud Hosted

ToolOpen SourceFree TierMonthly Cost
PastebinNoLimitedFree / From $4.99/mo
GitHub GistsNoYesFree; requires GitHub account

Self Hosted

ToolOpen SourceFull FeaturesNotes
HastebinYesYesNo encryption, plaintext only

Installation

Architecture

  • Deployment: Single privatebin deployment in the privatebin namespace
  • Image: privatebin/nginx-fpm-alpine:2.0.3 (digest-pinned)
  • Storage: Longhorn PVC (privatebin-data) for paste storage; tmpfs volumes for tmp, var-run, var-tmp
  • Networking: ClusterIP service on port 80, HTTPRoute via public gateway

Security

  • Runs as runAsUser: 65534, runAsNonRoot: true, readOnlyRootFilesystem: true, allowPrivilegeEscalation: false, capabilities dropped
  • Zero-knowledge architecture — server never sees plaintext (client-side AES-256 encryption)
  • Longhorn PVC encrypted at rest; tmpfs mounts enforce read-only container filesystem

Updates

Managed by Renovate. Image is digest-pinned.

Data Management

  • PVC: privatebin-data (Longhorn-encrypted) for paste storage
  • Backups: No k8up schedule — pastes are ephemeral by design.

User Management

No user accounts or authentication. PrivateBin is anonymous by design.

Configuration Management

  • App configuration (expiry, format options, etc.) from ConfigMap (privatebin-config)
  • Longhorn encryption key from SOPS-encrypted secret

Administration

Usage

Paste text, code, or data into the web UI. Choose an expiration time and optional password. Share the generated link — only the URL fragment (containing the decryption key) allows decryption, and the server never sees it.

Cluster-specific deviations from the above live in the per-cluster README — see k8s/apps/talos/privatebin/README.md.

Cluster Deployment

PrivateBin — Talos cluster

Cluster-specific notes only. General product info, "why we use it", and alternatives live in docusaurus/docs/apps/privatebin.mdx.

Deviations from defaults

Defaults live in docusaurus/docs/apps/privatebin.mdx — document anything this cluster does differently here, with a one-line reason.

Kubernetes Metadata
  • Image: privatebin/nginx-fpm-alpine:2.0.4@sha256:96171f34dd07f6c655cb3a311de24c1e9bafd05307ea9b6d38443863f6b48153
Rendered manifests (kustomize build)
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
kustomize.toolkit.fluxcd.io/force: enabled
name: privatebin
namespace: privatebin
spec:
replicas: 1
selector:
matchLabels:
app: privatebin
ingress: public
strategy:
type: Recreate
template:
metadata:
labels:
app: privatebin
ingress: public
spec:
containers:
- image: privatebin/nginx-fpm-alpine:2.0.4@sha256:96171f34dd07f6c655cb3a311de24c1e9bafd05307ea9b6d38443863f6b48153
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 10
periodSeconds: 30
name: privatebin
ports:
- containerPort: 8080
name: http
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 256Mi
requests:
cpu: 50m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /srv/data
name: data
- mountPath: /srv/cfg/conf.php
name: config
readOnly: true
subPath: conf.php
- mountPath: /tmp
name: tmp
- mountPath: /var/run
name: var-run
- mountPath: /var/tmp
name: var-tmp
securityContext:
fsGroup: 65534
runAsGroup: 65534
runAsNonRoot: true
runAsUser: 65534
volumes:
- name: data
persistentVolumeClaim:
claimName: privatebin-data
- configMap:
name: privatebin-config
name: config
- emptyDir: {}
name: tmp
- emptyDir: {}
name: var-run
- emptyDir: {}
name: var-tmp