Skip to content

F5 masking, Gate 1 step 1: rules on confirmed findings, masked accounts - #214

Merged
SauravYadav12 merged 5 commits into
mainfrom
feat/f5-mask-step1
Nov 6, 2026
Merged

SauravYadav12 merged 5 commits into
mainfrom
feat/f5-mask-step1

Conversation

@SauravYadav12

Copy link
Copy Markdown
Collaborator

Masking (F5), Gate 1 step 1 (point 4.6, Enterprise; licence feature masking). Built to the agreed design (docs/FOX_F5_Masking_Design.md) and decisions 2–4. Decision 9 was not answered, so the recommendation stands: the cost is accepted and is said before a rule is set.

What it does

  • fox mask setup --branch b [--yes] previews, then:

    • makes the key at <state>/mask/default.key: 32 bytes, owner uid 999, mode 0400, in a 0700 folder;
    • mounts it read-only at /run/bb-mask, restarting the branch only if it must;
    • installs the shadow tables, triggers and views.
  • fox mask rule <[schema.]table.column> [--path $.a] [--rule hash|fake|partial|empty] [--off] [--yes] sets or takes off a rule.

    • It works only on a finding the personal-data scan made and a person confirmed.
    • The preview states the measured cost. Partial and empty cost nothing on writes. A hash or a fake costs about a fifth to a third fewer single-row writes, and a 10,000-row UPDATE takes about 3.6 times as long. A JSON path costs more.
    • Aadhaar can only be partial or empty, never hashed or faked.
  • fox mask account <email> [--off] --yes masks or unmasks an account. A masked account, on main and on branches it doesn't own:

    • reads the masks of marked tables and real values elsewhere;
    • cannot write marked tables;
    • has its failing statements logged without their text (log_min_error_statement = panic).

    Admins can't be masked. Admins and a branch's owner always see real values.

  • Console: a new Masking page, where every change goes through a dialog that shows its cost. API: /api/masking, admins only, documented in openapi.yaml. Every change is recorded in the security log.

Fixed on the way

  • Unmasking now finds the role by name in pg_roles. to_regrole parses an identifier, so it never finds an email.
  • Rules are read only where bb.mask_rules exists. A guarding CASE still fails when the query is planned.
  • fox uninstall now removes the key folder even though the server's user owns it. If removal fails, it falls back to sudo rm -rf, but only for the state dot-folder.

Limits (in the docs)

  • Only one-column primary keys are supported.
  • Array and quoted JSON paths are refused.
  • Masking stays on once set up.
  • A new schema needs setup to run again.
  • Key domains, rotation, lookup, audited reads and masked branches are steps 2–5.

Tests

All in the fox-test VM, on the final code:

  • make integration: 792/792. The new §11ai covers:
    • the key's owner, modes and read-only mount, and the key appearing in no logs;
    • rules refused before a finding is confirmed;
    • the cost preview, and a hash on Aadhaar refused;
    • each rule's mask as a masked account reads it, and joins on a hash;
    • the real table, the shadow and the hash function out of the account's reach;
    • writes refused;
    • the application's writes kept in sync;
    • admins and owners seeing real values;
    • rules taken off and accounts unmasked;
    • the security log.
  • integration-v2: 403/403.
  • integration-ui: 47/47, plus the upgrade test. The new masking.spec.ts covers a rule set after its cost, Aadhaar's choices, and an account masked and unmasked.
  • integration-f5: 57/57; integration-f1: 70/70; integration-f6: 71/71.
  • Web unit tests: 256/256.
  • Go unit tests in both editions, and go vet for macOS, Linux and Windows.
  • scripts/test_feature_checklist.sh: in step (113 features). The PDFs were re-rendered.

… accounts, live masks

fox mask setup|rule|account, /api/masking and the console's Masking page.
Rules (partial, hash, fake, empty) only on confirmed findings; Aadhaar
never hashed or faked; masks kept in shadow tables by statement triggers;
masked accounts in db_masked read masks and ordinary tables and cannot
write to marked tables; admins and a branch's owner see real values;
the cost is said before a rule is set (design, decision 9).
…on uninstall, test on main

A CASE guarding a missing table still fails when planned, so whether
bb.mask_rules and bb.pii_findings are there is asked first. Uninstall
deletes the state directory's masking-key folder with sudo, as only the
server's user may enter it. §11ai runs on main: an account reaches main
and its own branches, and is exempt on those.
…n email

Unmasking, and an owner's exemption, did nothing: to_regrole parses an
identifier, and an email is not one. The role is looked up in pg_roles.
@vercel

vercel Bot commented Nov 6, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
foxbyte-get Ready Ready Preview Nov 6, 2026 6:22am UTC

@SauravYadav12
SauravYadav12 merged commit 23da0b7 into main Nov 6, 2026
8 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Nov 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant