Skip to content

PII Handling

Overview

Floh provides field-level encryption at rest for Personally Identifiable Information (PII) stored in user profiles. This ensures that PII is protected even if the database is compromised.

What Is Encrypted

Standard PII Fields

The following user profile columns are individually encrypted using AES-256-GCM:

  • phone_number
  • employee_id

Each value is stored in the format iv:authTag:ciphertext using the shared encryptValue utility from packages/server/src/shared/encryption.ts.

Custom PII Attributes

Profile attribute definitions can be marked as PII (is_pii = true). All PII-flagged custom attributes are:

  1. Serialized into a single JSON blob
  2. Encrypted as one AES-256-GCM ciphertext
  3. Stored in the pii_attributes text column on user_profile

Non-PII custom attributes remain as queryable, indexable plaintext JSONB in custom_attributes.

Encryption Key

PII encryption uses the same key as connector secrets and workflow variables:

  • Environment variable: CONNECTOR_ENCRYPTION_KEY (64-character hex string representing a 256-bit key)
  • Key rotation: supported via CONNECTOR_ENCRYPTION_KEY_PREVIOUS for gradual re-encryption

See Encryption Keys for key management details.

Access Control

Permission: user:read_pii

A dedicated permission controls PII visibility in API responses:

Has user:read_pii Behavior
Yes PII fields are decrypted and returned in plaintext
No PII fields return "********" (SECRET_MASK)

By default, only the admin role includes user:read_pii.

Audit Logging

Every API request that returns decrypted PII is logged via the AuditService:

  • Action: user.pii_accessed
  • Entity: user_profile
  • Entity ID: the user's ID
  • Actor: the requesting user's display name and ID
  • IP Address: the request origin

Workflow Context

Workflow variables have full access to profile data including PII fields (decrypted in-memory). Workflows are trusted execution contexts — PII is available through:

{{user.profile.phoneNumber}}
{{user.profile.employeeId}}
{{user.profile.customAttributes.<pii_field>}}

The profile_update step type can write to both PII and non-PII fields.

Logging Safety

PII values must never appear in logs. The existing logging safety rules apply:

  • Never log raw profile field values
  • Never log decrypted PII blob contents
  • Log only sanitized metadata (field names, user IDs, operation types)