Phronion

Security

Security at Phronion is architectural, not aspirational. This page describes how we handle encryption, data flows, authentication, governance, and infrastructure.

Principles

Server-blind by default

The server handles ciphertext only. Encryption keys are derived and held client-side. A server breach does not expose user content.

No ambient authority

Every action requires explicit authorisation. There are no implicit permissions, no shared admin credentials, and no privilege escalation paths by design.

Auditable state transitions

Subscriptions, entitlements, and access changes are driven by explicit state machines. Every transition is logged. No silent mutations.

Minimal data retention

We store what is necessary for the service to function. Stripe webhook payloads are stored with PII stripped. We do not build user profiles or behavioural models.

Encryption

Client-side encryption model

ARK-Journal entries are encrypted client-side before storage. The server stores ciphertext only. It does not hold the keys required to decrypt journal entries.

A Key Encryption Key (KEK) is derived from the user's recovery key using PBKDF2-SHA256 with 600,000 iterations. A random AES-GCM-256 Data Encryption Key (DEK) is generated client-side, wrapped with AES-KW using the KEK, and only the wrapped (encrypted) DEK is sent to the server. Raw keys are never transmitted.

Each entry is encrypted with a per-entry key derived via HKDF-SHA256 from the DEK. The full entry structure — blocks, formatting, images, tags, and mode — is encrypted as a single payload before storage.

Keys are not recoverable by Phronion. If a user loses their recovery key, their encrypted data cannot be decrypted. There is no password reset, no admin override, and no backdoor. This is by design.

Device linking

QR-based device pairing

Multi-device access uses a short-lived pairing flow. The primary device generates a 6-digit code (displayed as QR or entered manually) and an AES-256-GCM encrypted payload containing the wrapped DEK.

Pairing offers expire after 5 minutes and are single-use. Only one active offer is permitted per user. The encrypted payload uses a fresh 12-byte random nonce per offer and authenticated encryption with associated data.

Failed claim attempts are rate-limited to 10 per minute per user. Failed attempts are logged as security events.

Backup

Encrypted cloud backup

Encrypted backup protects the DEK with a user-chosen PIN. The PIN is never sent to the server. The client derives an encryption key using Argon2id (time cost 3, memory 64 MB, parallelism 4) with a 16-byte random salt, then encrypts the DEK with AES-256-GCM before upload.

The server stores only the encrypted blob and KDF parameters. All decryption is performed client-side.

Restore attempts are rate-limited. After 10 failed attempts, the backup is locked for 30 minutes. This is designed to resist online guessing with rate limiting and lockouts, not to make brute force mathematically impossible.

Sessions

Session management

Sessions are server-side database records, not stateless tokens. Each session has an independent lifetime (default 90 days) and can be individually revoked by the user at any time.

Session tokens are transported via httpOnly Secure SameSite=Lax cookies, or as Bearer tokens for non-browser clients. Every API request checks the session is not revoked and not expired.

Users can list all active sessions (with device information) and revoke any session. When an account is disabled by an administrator, all active sessions are revoked immediately.

Authentication

Identity and authentication

Phronion does not store passwords. Authentication is delegated to established identity providers (Google and Microsoft) via OAuth 2.0 / OpenID Connect. Tokens are validated server-side against provider JWKS endpoints with RS256 signature verification.

Local authentication (username/password) is available as an alternative. Passwords are hashed with bcrypt. Failed login attempts are tracked per credential with automatic lockout after 10 failures (10-minute lockout window).

Admin access requires explicit role assignment. Platform administration endpoints are protected by role-based access controls enforced at the API layer.

Governance

Platform administration and governance

A platform administrator can perform the following governance actions. Each action creates a structured audit record with the administrator identity, reason, legal reference, and a point-in-time snapshot of the target account:

  • Disable account — revokes all active sessions immediately
  • Re-enable account — restores a disabled account
  • Place legal hold — prevents self-service account deletion
  • Export encrypted data — produces a ZIP of ciphertext with a SHA-256 manifest hash

A platform administrator cannot:

  • Read journal entries — all content is encrypted with client-held keys
  • Decrypt backups — the backup PIN is never sent to the server
  • Bypass encryption — there is no admin decryption key, no override, and no backdoor

Encrypted exports return ciphertext only. Legal holds preserve encrypted data, not readable content. Account disablement does not grant content access.

Monitoring

Security alerting and audit trail

Threshold-based anomaly detection runs inline with authentication and administrative operations. Alerts are triggered by patterns including brute-force attempts, unusual account creation rates, authentication failure spikes, and abnormal administrative activity.

When a threshold is breached, the system emits alerts through multiple channels: structured log entries, database persistence for post-incident review, Prometheus counters for dashboarding, and email notification to the security contact.

Governance actions (account disable, legal hold, encrypted export) generate email notifications with structured subjects and tamper-evident detail including SHA-256 hashes for exports.

All administrative actions are recorded in a write-only audit log with actor identity, action, target, and timestamp.

Billing

Billing and payment

All payment processing is handled by Stripe. Phronion does not store, process, or have access to credit card numbers or payment credentials.

Stripe webhook events are verified using cryptographic signature validation before processing. Event deduplication uses transaction-safe database operations to prevent double processing.

Webhook payloads stored for audit purposes have personally identifiable information (email, name, phone, address) stripped before storage.

Threat model

What we protect against

Phronion is designed to protect against:

  • Server compromise revealing journal content
  • Platform operator access to user content
  • Credential stuffing and brute-force attacks
  • Stripe webhook forgery or replay

Phronion is not designed to protect against:

  • Compromise of your unlocked device
  • Malicious browser extensions with content script access
  • Screen recording or shoulder surfing
  • Loss of the recovery key (no recovery mechanism exists by design)

Infrastructure

Infrastructure

Phronion platforms run on dedicated infrastructure hosted by Hetzner in EU data centres. We do not use shared hosting or multi-tenant compute environments.

Database connections use TLS. Backups are encrypted. Access to production systems is restricted and logged.

We do not use client-side analytics, tracking pixels, or third-party scripts beyond the payment processor (Stripe). There is no Google Analytics, no Facebook pixel, no ad network integration.

Security model version: 2026.02 · Last updated: 14 February 2026