Repository navigation
feat(function-resolution): claim-scoped default bucket resolver - #144
Conversation
|
I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".
|
|
Review complete. 🟠 1 high · 🟡 1 medium 💬 Inline comments (1)
📍 Findings outside the diff (1) — 🟡 1 medium — defects on lines GitHub can't attach comments to🟡 Medium — New request-lane membership gates have zero test coverage · default-bucket.test.ts:93–192 · // packages/function-resolution/__tests__/default-bucket.test.ts
93 it('resolves the database default without anyone naming a bucket', async () => {
94 const [row] = await pg.any(
95 `SELECT bucket_id, resolved_key, bucket_type, physical_name, owner_database_id
96 FROM function_resolution.frame_default_bucket($1, 'database', $1, false)`,
97 [TENANT_DB]
98 );
99 expect(row).toEqual({
100 bucket_id: ids.default,
101 resolved_key: 'default',
102 bucket_type: 'private',
103 physical_name: 'phys-default',
104 owner_database_id: TENANT_DB,The rewritten 🧹 Nitpicks (1) — 🟢 1 low
This PR splits default-bucket resolution into two paths: a frame-side helper pinned to JWT claims, and a request-lane resolver that validates entity scope keys and SPRT membership (failing closed with
Reviewed commit: 6529ebe |
There was a problem hiding this comment.
Renames resolve_default_bucket to frame_default_bucket and re-adds a 4-arg request-lane resolve_default_bucket that enforces scope-key and membership checks before delegating.
Key findings
- 🟠 Reused plan change name breaks existing-database upgrades — pgpm.plan:88
- 🟡 New request-lane membership gates have zero test coverage — default-bucket.test.ts:93
|
Re the test-coverage note on |
Summary
Adds a claim-scoped default bucket resolver to
function-resolution.function_resolution.resolve_default_bucket(uuid, text, uuid, boolean, text)is renamedframe_default_bucket(same body, same grants).function_resolution.resolve_default_bucket(scope text, entity_id uuid, public_access boolean, bucket_key text DEFAULT NULL): takes the database fromjwt_private.require_database_id(), checks the caller's membership at the storage scope, then callsframe_default_bucket. Granted toauthenticated.bucket_matches.sql/resolve_staging_bucket.sql;default-bucket.test.tscallsframe_default_bucket.Plan change edited in place (no new migration).
EXECUTE grants, main vs this branch
has_function_privilege(role, oid, 'EXECUTE')over all non-trigger functions infunction_resolution(82 on main, 83 here), function-resolution deployed into two fresh databases:No other function changes.
Local checks
pnpm testinpackages/function-resolution: 11 suites, 156 tests passpgpm test-packages --full-cycle: all modules passLink to Devin session: https://app.devin.ai/sessions/b0f74849b4834e3ba5892e2e13b22e88
Open in Devin Desktop: https://app.devin.ai/desktop/session/b0f74849b4834e3ba5892e2e13b22e88?variant=devin
Requested by: @pyramation