I’ve been building a small open-source TypeScript toolkit called Tenant Evidence Kit for private, multi-tenant evidence workflows on Supabase.
The project started from a very specific problem:
How do you attach photos, documents, or other evidence to a business object without making files public, leaking tenant data, or duplicating authorization logic across the application?
The toolkit keeps that infrastructure deliberately small and domain-agnostic.
It currently provides:
- private Supabase Storage;
- evidence metadata separated from file bytes;
- tenant isolation with Row Level Security;
- short-lived signed URLs;
- compensating cleanup when metadata persistence fails;
- reference migrations for tenant membership and evidence authorization.
But the interesting part of the latest release was not the original implementation.
It was the review loop.
A community review found real problems
I shared the project with the Supabase community and received a detailed security review.
The feedback raised several important questions:
- roles existed, but authorization was still too close to flat membership;
- evidence deletion needed a more explicit privilege boundary;
- the lack of UPDATE support needed to be intentional rather than accidental;
- RLS assumptions around
service_role, table owners andBYPASSRLSneeded to be documented; - authorization needed behavioral tests, not only static SQL assertions.
That feedback was good enough that I didn’t want to treat it as a documentation exercise.
I turned it into an implementation task.
Using Codex as the implementation loop
Instead of asking Codex something broad like:
“Improve the security.”
I gave it a tightly scoped issue with explicit acceptance criteria.
The workflow became:
community review → scoped issue → Codex implementation → human review → correction pass → CI → release
The first implementation was useful, but the review still found problems.
For example, it initially changed existing INSERT behavior and modified only the original migration, which would not safely upgrade installations that had already applied it.
So the task went back for another pass.
That second pass produced the version I actually wanted to ship.
What changed in v0.1.3
Tenant Evidence Kit v0.1.3 now includes:
- operation-specific evidence permissions;
- evidence deletion restricted to
ownerandadmin; - existing read/create behavior preserved for active members;
- evidence metadata explicitly append-only;
- a separate
0002_authorization_hardening.sqlmigration for existing installations; - real Supabase/pgTAP authorization tests;
- CI coverage for database authorization;
- explicit documentation of the RLS execution boundary, including
service_role, table owners andBYPASSRLS.
Storage and Postgres now use the same permission model for evidence operations.
The goal was not to build a large authorization framework.
It was to make the existing security boundary more explicit, testable and upgrade-safe.
One thing I learned
The most useful part of using an agent here was not code generation.
It was giving the agent a reviewable engineering boundary.
A vague request like “make this more secure” leaves too much room for interpretation.
A task like:
- preserve current read/create behavior;
- restrict sensitive deletion;
- add an upgrade migration;
- prove the authorization model with behavioral tests;
- document the RLS bypass boundary;
is much easier to evaluate.
The human review step still mattered.
A lot.
Links
GitHub:
https://github.com/oitydob-crypto/tenant-evidence-kit
npm:
https://www.npmjs.com/package/tenant-evidence-kit
Current release: v0.1.3
I’d be interested to hear how other developers are structuring agent tasks when the input is external technical review rather than a normal feature request.
Top comments (0)