Melange v0.8.0
Melange v0.8.0 adds modular model support (fga.mod / Schema 1.2) for splitting schemas across multiple files, configurable database schema for installing melange objects into a custom PostgreSQL schema, and safe identifier truncation to handle PostgreSQL’s 63-byte name limit.
_no_wildcard to _nw). Running melange migrate will drop the old functions and install the new ones automatically. If you call specialized check or list functions directly (e.g., check_document_viewer_no_wildcard), you will need to update those references. If you only use the dispatcher functions (check_permission, list_accessible_objects, list_accessible_subjects), no changes are needed.Highlights
Modular Models (fga.mod / Schema 1.2)
Schemas can now be split across multiple .fga files using OpenFGA’s modular model format. Each module can define new types or extend existing ones. Melange merges them into a single schema at compile time.
Project structure:
project/
├── fga.mod
├── core.fga
├── tracker/
│ └── projects.fga
└── wiki/
└── spaces.fgafga.mod manifest:
schema: '1.2'
contents:
- core.fga
- tracker/projects.fga
- wiki/spaces.fgaModule files use module declarations and extend type:
module core
type user
type organization
relations
define member: [user]
define admin: [user]module tracker
extend type organization
relations
define can_create_project: admin
type project
relations
define organization: [organization]
define viewer: member from organizationAll CLI commands accept fga.mod paths. Pass --schema fga.mod where you previously passed --schema schema.fga:
melange validate --schema fga.mod
melange migrate --schema fga.mod
melange generate client --schema fga.mod --runtime go --output internal/authz
melange generate migration --schema fga.mod --output migrations/ --git-ref mainThe migrator computes content hashes across all module files for skip detection, so changes to any module file trigger a migration. Module validation (duplicate relations, undefined type extensions, schema version mismatches) is handled by the upstream OpenFGA library at parse time.
Configurable Database Schema
Melange objects can now be installed into a custom PostgreSQL schema instead of public, keeping authorization functions and tables separate from your application.
Configure via YAML, environment variable, or CLI flag:
# melange.yaml
database:
url: postgres://localhost/mydb
schema: authz# Environment variable
export MELANGE_DATABASE_SCHEMA=authz
# CLI flag (all commands)
melange migrate --db-schema authzObjects placed in the custom schema:
- All generated check and list functions
- The
melange_migrationstracking table - The
melange_tuplesview
Application tables stay where they are. The tuples view in the custom schema can query tables in any schema:
CREATE SCHEMA IF NOT EXISTS authz;
CREATE OR REPLACE VIEW authz.melange_tuples AS
SELECT 'user' AS subject_type, user_id::text AS subject_id,
role AS relation, 'organization' AS object_type,
organization_id::text AS object_id
FROM public.organization_members;Pass the schema to runtime clients:
checker := melange.NewChecker(db, melange.WithDatabaseSchema("authz"))const checker = new Checker({ db, databaseSchema: "authz" });You need to create the schema yourself before running melange migrate. Dry-run output includes the required CREATE SCHEMA as a commented hint.
Safe Identifier Truncation
PostgreSQL silently truncates identifiers longer than 63 bytes, which can cause collisions or runtime failures with long type or relation names. Melange now handles this.
Shorter function suffixes reduce baseline name length:
| Old suffix | New suffix | Savings |
|---|---|---|
_no_wildcard | _nw | 8 chars |
_subjects | _sub | 5 chars |
_objects | _obj | 4 chars |
When a generated function name would still exceed 63 bytes, the type and relation parts are truncated proportionally to their original lengths and an 8-character SHA-256 hash is appended to ensure uniqueness:
check_my_group_a_really_long_relation_name → (unchanged, under 63 bytes)
check_my_group_a_really_really_really_long_name → check_my_gro_a_really_really_re_d70fe023_nwNames under the limit are unchanged. No configuration required.
Improvements
Init Wizard: Migration Strategy Selection
melange init now asks whether to use the built-in migrator or versioned SQL file generation. Previously, users who wanted melange generate migration for use with external frameworks (golang-migrate, Atlas, Flyway) had to edit their config manually after init.
When “versioned” is selected, the wizard collects output directory, file format (split/single), and migration name suffix. CLI flags (--migration-strategy, --migration-output, etc.) support the non-interactive -y path.
Documentation Site
The documentation site has been restructured with a refreshed design, new product sections on the homepage, and updated dependencies.
What’s Changed Since v0.7.4
- Modular model support: fga.mod / Schema 1.2 parsing, migration, and code generation across all CLI commands
- Configurable database schema: install melange objects into a custom PostgreSQL schema via YAML, env var, or CLI flag
- Safe identifier truncation: shorter function suffixes and automatic truncation with hash for names exceeding 63 bytes
- Init wizard migration strategy: choose between built-in and versioned migration during project setup
- Schema qualification bug fixes: correct
DROP FUNCTIONstatements, consistent identifier quoting, per-schema validation - Documentation site refresh: restructured content, new homepage sections, updated design
- Dependency upgrades: all Go dependencies updated to latest versions
Migration Notes
From v0.7.4
Specialized SQL function names have changed (e.g., check_document_viewer_no_wildcard is now check_document_viewer_nw). Running melange migrate drops the old functions and installs the renamed ones:
melange migrateIf you call specialized functions directly, update your code to use the new names. Most users won’t need to do this, since the dispatcher functions (check_permission, list_accessible_objects, list_accessible_subjects) are the standard API and their names are unchanged.
If you use melange generate migration, regenerate your migration files to pick up the new function names.
To move melange objects out of public, create the target schema and update your config:
psql -c "CREATE SCHEMA authz;"# melange.yaml
database:
schema: authzmelange migrateTo convert an existing single-file schema to modular format, create an fga.mod manifest pointing to your module files and update the --schema path in your config or CLI commands.
Try It Out
# Install / upgrade CLI
brew install pthm/melange/melange
# Apply migrations
melange migrate
# Go runtime
go get github.com/pthm/melange/melange@v0.8.0
# TypeScript runtime
npm install @pthm/melangeFeedback
We welcome feedback and bug reports. Please open an issue with questions or feature requests.
