Melange v0.7.3
Melange v0.7.3 adds the new melange init command for interactive project scaffolding, fixes four bugs where list_objects and list_users returned incorrect results, and adds several improvements to melange doctor including table index recommendations, orphaned tuple detection, and a fix for multi-table view parsing.
melange migrate to pick up the list function fixes. Run melange doctor to check for orphaned tuples and missing indexes.Highlights
melange init — Interactive Project Scaffolding
New command to bootstrap a melange project with a single command:
melange init # interactive wizard
melange init -y # accept all defaultsThe wizard detects your project type (Go module or Node.js package), then scaffolds:
melange/config.yaml— configuration file with schema path, database URL, and client code generation settingsmelange/schema.fga— starter OpenFGA schema from one of four templates:org-rbac— organization/team/repository hierarchy with role-based access (default)doc-sharing— document/folder sharing with viewer/editor rolesminimal— single type with one relationnone— empty schema
- Runtime dependency — automatically runs
go getornpm install(supports npm, pnpm, yarn, and bun)
Use --no-install to skip dependency installation, or pass --schema, --db, --template, --runtime, and other flags to override defaults without prompting.
Configuration discovery has also been updated: melange now finds melange/config.yaml in addition to the existing melange.yaml at the project root (backwards compatible).
Bug Fixes
list_objects Returned Results Through Non-Recursive Parent Chains
Fixed a bug (#34) where list_objects incorrectly granted access on child objects for relations that don’t use recursive parent lookups. For example, given a folder_viewer: [user] relation (no from parent clause), a user assigned folder_viewer on a parent folder would incorrectly appear as having access to all child folders.
check_permission was unaffected — only list functions exhibited this behavior.
Thanks to @jtbeach for reporting and fixing this.
list_objects Over-Propagated When Recursive and Non-Recursive Relations Share a Permission
A follow-up to the fix above. When a permission combines a recursive relation (e.g., viewer from parent) with a non-recursive one (e.g., editor: [user]) that also satisfies the permission, list_objects could still incorrectly propagate the non-recursive relation’s results through the parent chain. For example, a user directly assigned editor on a folder would incorrectly appear as having viewer access on all child folders.
list_objects and list_users Ignored Exclusions on Userset Lookups
Relations using exclusions with userset patterns (e.g., active_member: member but not blocked where access comes through group#member) were not filtering out excluded subjects. This meant list_objects could return objects a user should have been blocked from, and list_users could return users who should have been excluded.
list_users Returned Incomplete Results for Multi-Path TTU Relations
When a permission can be reached through multiple parent relations — either via role hierarchy (e.g., viewer is satisfied by admin, editor, and viewer roles, each linked through a different parent) or via a union of parent lookups (e.g., contributor: member from team or staff from department) — list_users only walked the first parent path. This caused missing results when access was granted through any of the other paths.
check_permission was unaffected — only list_users exhibited this behavior.
melange doctor Multi-Table View Parsing Fix
Fixed a bug (#35) where melange doctor incorrectly parsed melange_tuples views that join multiple tables. A FROM sites, organization clause was reported as source table sites, (with a trailing comma), and the second table was dropped entirely. This also produced invalid CREATE INDEX suggestions.
The view parser now handles:
- Comma-separated cross joins (single and multi-line)
- Explicit JOINs (
JOIN,LEFT JOIN, etc.) - PostgreSQL’s
ONLYkeyword - Quoted identifiers (
"Schema"."Table")
Thanks to @sgsfak for reporting this.
Improvements
melange doctor — Table Index Recommendations
Previously, performance checks only ran when melange_tuples was a view. Now melange doctor also checks for recommended indexes when melange_tuples is a regular table, based on the query patterns melange generates:
- check_lookup —
(object_type, object_id, relation, subject_type, subject_id)forcheck_permissionandlist_subjects - list_objects —
(object_type, relation, subject_type, subject_id, object_id)forlist_accessible_objects
Severity scales by table size: warning for small tables, critical for tables with 10k+ rows.
melange doctor — Orphaned Tuple Detection
melange doctor now comprehensively validates all tuples against the schema model, replacing the previous sampling-based check that only inspected 100 (object_type, relation) pairs. Four categories of orphaned data are now detected with affected tuple counts:
- Unknown object types —
object_typevalues not defined in the schema - Unknown relations — relations not defined on their object type
- Unknown subject types —
subject_typevalues not defined in the schema - Invalid subject type assignments — subject types not allowed by the relation definition (e.g.,
organizationused as subject for a relation that only accepts[user])
Keeping melange_tuples lean matters for query performance. These checks help surface stale references after schema changes so you can clean up waste.
Testing & Maintenance
- Removed over 1,000 lines of dead code (#33)
- Added Codecov integration for continuous coverage tracking (#32)
- Added 22 new test cases covering real-world authorization patterns including layered role chains, org/team/repo hierarchies, SaaS entitlement gating, and role-binding intermediaries
Contributors
Thanks to the contributors who made this release possible:
- @jtbeach — fixed
list_objectsreturning results through non-recursive parent chains (#34) - @sgsfak — reported multi-table view parsing bug in
melange doctor(#35)
Migration Notes
From v0.7.2
No breaking changes. Upgrade and run migrations to pick up the list function fixes:
melange migrateNew projects can now use melange init to get started:
melange init
melange migrateTry It Out
# Install / upgrade CLI
brew install pthm/melange/melange
# Apply migrations
melange migrate
# Go runtime
go get github.com/pthm/melange/melange@v0.7.3
# TypeScript runtime
npm install @pthm/melangeFeedback
We welcome feedback and bug reports. Please open an issue with questions or feature requests.
