feat(storage): tenant-safe config read + bucket type/isPublic provisioning#1311
Open
yyyyaaa wants to merge 1 commit into
Open
feat(storage): tenant-safe config read + bucket type/isPublic provisioning#1311yyyyaaa wants to merge 1 commit into
yyyyaaa wants to merge 1 commit into
Conversation
…oning graphile-presigned-url-plugin reads storage config via the resolve_storage_modules SECURITY DEFINER accessor. The direct storage_module select returns 0 rows under tenant RLS, so this is required for the presigned mutation to resolve bucket/file table names on every upload. graphile-bucket-provisioner-plugin's provisionBucket gains type/isPublic and ensures the bucket row + S3 access type stay consistent; reuses @constructive-io/bucket-provisioner for S3 ops.
NorOldBurden
approved these changes
Jun 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The graphile-plugin half of the storage-uploads work. Pairs with constructive-db PR (resolve_storage_modules accessor) and dashboard PR #235 (client seam + provisioning preset).
graphile-presigned-url-plugin— RLS-safe storage config read.storage-module-cache.tsnow reads a tenant's storage config throughmetaschema_modules_public.resolve_storage_modules($database_id)(the SECURITY DEFINER accessor) instead of a directSELECT … FROM storage_module, which RLS blocks for a tenant role (returns 0 rows). Without this, the presigned mutation can't resolve the bucket/config for the calling database.graphile-bucket-provisioner-plugin—type/isPublicon provision.provisionBucketacceptstypeandisPublic; when the bucket row doesn't yet exist it ensures the row + S3 bucket with a consistent access type (ensureType = requestedType || (isPublic ? 'public' : 'private')),ON CONFLICTno-op if it does. Reuses@constructive-io/bucket-provisionerfor the actual S3 ops (no reimplementation).Why
Provisioned tenant databases expose storage on the data API (see the constructive-db + dashboard PRs), but the presigned plugin couldn't read the per-tenant storage config under RLS, and bucket provisioning didn't carry the public/private intent. These two changes close that.
Validation
Deployed to the hub backend and verified end-to-end: a freshly provisioned database uploaded a file from the dashboard data grid → the presigned plugin resolved storage config via
resolve_storage_modules→ presigned PUT to MinIO returned 200 →app_filesrow + user-table reference persisted. (CI builds the plugins; the worktree itself isn't installed locally.)Notes
plugin.test.tsuses jest globals (the package's configured runner) — editor "cannot find name jest" warnings are pre-existing type-resolution noise, not introduced here.