{"id":38919956,"url":"https://github.com/pthm/melange","last_synced_at":"2026-04-05T05:04:13.757Z","repository":{"id":331746454,"uuid":"1127071770","full_name":"pthm/melange","owner":"pthm","description":"OpenFGA-to-PostgreSQL authorization compiler. Generates specialized SQL functions from .fga schemas that query your existing tables. Zero sync, always consistent.","archived":false,"fork":false,"pushed_at":"2026-03-26T05:53:28.000Z","size":3332,"stargazers_count":59,"open_issues_count":4,"forks_count":7,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-03T14:06:03.656Z","etag":null,"topics":["authorization","database","fga","fine-grained-authorization","openfga","permissions","postgresql","rbac","rebac","zanzibar"],"latest_commit_sha":null,"homepage":"https://melange.sh/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pthm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-03T05:42:40.000Z","updated_at":"2026-03-29T16:37:04.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pthm/melange","commit_stats":null,"previous_names":["pthm/melange"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/pthm/melange","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pthm%2Fmelange","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pthm%2Fmelange/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pthm%2Fmelange/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pthm%2Fmelange/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pthm","download_url":"https://codeload.github.com/pthm/melange/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pthm%2Fmelange/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31424932,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T02:22:46.605Z","status":"ssl_error","status_checked_at":"2026-04-05T02:22:33.263Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authorization","database","fga","fine-grained-authorization","openfga","permissions","postgresql","rbac","rebac","zanzibar"],"created_at":"2026-01-17T15:32:40.888Z","updated_at":"2026-04-05T05:04:13.751Z","avatar_url":"https://github.com/pthm.png","language":"Go","readme":"# Melange\n\n![GitHub License](https://img.shields.io/github/license/pthm/melange)\n![GitHub Release](https://img.shields.io/github/v/release/pthm/melange)\n[![Go Reference](https://pkg.go.dev/badge/github.com/pthm/melange.svg)](https://pkg.go.dev/github.com/pthm/melange)\n[![Go Report Card](https://goreportcard.com/badge/github.com/pthm/melange)](https://goreportcard.com/report/github.com/pthm/melange)\n[![codecov](https://codecov.io/gh/pthm/melange/graph/badge.svg)](https://codecov.io/gh/pthm/melange)\n[![Matrix](https://img.shields.io/badge/Matrix-Join%20Chat-green?logo=matrix)](https://matrix.to/#/#melange:matrix.org)\n\n\u003cimg align=\"right\" width=\"300\" src=\"assets/mascot.png\"\u003e\n\n**An OpenFGA-to-PostgreSQL authorization compiler.**\n\nMelange compiles [OpenFGA](https://openfga.dev) authorization schemas into specialized PL/pgSQL functions that run directly in your PostgreSQL database. Like [Protocol Buffers](https://protobuf.dev/) compiles `.proto` files into serialization code, Melange compiles `.fga` files into optimized SQL functions for [Zanzibar](https://research.google/pubs/pub48190/)-style relationship-based access control.\n\nThe generated functions query a `melange_tuples` view you define over your existing domain tables—no separate tuple storage or synchronization required.\n\n## Why Melange?\n\nTraditional authorization systems require syncing your application data to a separate service. Melange takes a different approach: **it's a compiler, not a runtime service**.\n\n### How it works\n\n**Compile time** — When you run `melange migrate`, the compiler:\n\n- Parses your OpenFGA schema\n- Analyzes relation patterns (direct, union, exclusion, etc.)\n- Computes transitive closures for role hierarchies\n- Generates specialized SQL functions for each relation\n- Installs the functions into PostgreSQL\n\n**Runtime** — Permission checks are simple SQL function calls:\n\n- `check_permission()` executes the generated functions\n- Functions query a `melange_tuples` view you define over your domain tables\n- PostgreSQL's query planner optimizes the specialized functions\n\nThis compilation model gives you:\n\n- **Always in sync** — Permissions query your tables directly, no replication lag\n- **Transaction-aware** — Permission checks see uncommitted changes in the same transaction\n- **Language-agnostic** — Use from any language that can call SQL (Go, TypeScript, Python, Ruby, etc.)\n- **Optional runtime libraries** — Convenience clients for Go and TypeScript, or use raw SQL\n- **Single query** — Role hierarchies resolved at compile time, no recursive lookups at runtime\n\nInspired by [OpenFGA](https://openfga.dev) and built on ideas from [pgFGA](https://github.com/rover-app/pgfga).\n\n---\n\n\u003e [!NOTE]\n\u003e **📚 Full Documentation**\n\u003e Visit **[melange.sh](https://melange.sh)** for comprehensive guides, API reference, and examples.\n\n---\n\n## Installation\n\n### CLI\n\n**Homebrew (macOS and Linux):**\n\n```bash\nbrew install pthm/tap/melange\n```\n\n**Go install:**\n\n```bash\ngo install github.com/pthm/melange/cmd/melange@latest\n```\n\n**Pre-built binaries:**\nDownload from [GitHub Releases](https://github.com/pthm/melange/releases) (macOS binaries are code-signed)\n\n**Updating:**\n\n```bash\n# Homebrew\nbrew upgrade melange\n\n# Go install\ngo install github.com/pthm/melange/cmd/melange@latest\n```\n\nMelange automatically checks for updates and notifies you when a new version is available. Use `--no-update-check` to disable.\n\n### Optional: Go Runtime Library\n\nIf you want to use the Go convenience library instead of raw SQL:\n\n```bash\ngo get github.com/pthm/melange/melange\n```\n\nThe runtime module has zero external dependencies (Go stdlib only).\n\n## Quick Start\n\n### 1. Define Your Schema\n\nCreate a schema file (`schema.fga`) using the OpenFGA DSL:\n\n```\nmodel\n  schema 1.1\n\ntype user\n\ntype repository\n  relations\n    define owner: [user]\n    define reader: [user] or owner\n    define can_read: reader\n```\n\n### 2. Compile Schema into SQL Functions\n\nRun the migration to generate specialized PL/pgSQL functions:\n\n```bash\nmelange migrate --db postgres://localhost/mydb --schemas-dir ./schemas/\n```\n\nThis generates optimized SQL functions like `check_permission()`, `list_objects()`, and specialized check functions for each relation.\n\n### 3. Define Your Tuples View\n\nCreate a `melange_tuples` view that exposes your authorization data:\n\n```sql\nCREATE VIEW melange_tuples AS\nSELECT\n  'user' AS subject_type,\n  user_id::text AS subject_id,\n  'owner' AS relation,\n  'repository' AS object_type,\n  repo_id::text AS object_id\nFROM repository_owners\nUNION ALL\nSELECT 'user', user_id::text, 'reader', 'repository', repo_id::text\nFROM repository_readers;\n```\n\n### 4. Check Permissions\n\n**With Go runtime (optional):**\n\n```go\nimport \"github.com/pthm/melange/melange\"\n\nchecker := melange.NewChecker(db)\ndecision, err := checker.Check(ctx,\n    melange.Object{Type: \"user\", ID: \"alice\"},\n    \"can_read\",\n    melange.Object{Type: \"repository\", ID: \"my-repo\"},\n)\nif !decision.Allowed {\n    return ErrForbidden\n}\n```\n\n**Or use raw SQL from any language:**\n\n```sql\nSELECT check_permission(\n  'user', 'alice',\n  'can_read',\n  'repository', 'my-repo'\n);\n-- Returns: true/false\n```\n\n### 5. (Optional) Generate Type-Safe Client Code\n\nFor better type safety, generate constants and constructors:\n\n```bash\nmelange generate client --runtime go --schema schema.fga --output ./authz/\n```\n\n```go\nimport \"yourapp/authz\"\n\nchecker := melange.NewChecker(db)\ndecision, err := checker.Check(ctx,\n    authz.User(\"alice\"),\n    authz.RelCanRead,\n    authz.Repository(\"my-repo\"),\n)\n```\n\n## CLI Reference\n\n```\nmelange - PostgreSQL Fine-Grained Authorization\n\nCommands:\n  generate client  Generate type-safe client code from schema\n  migrate          Apply schema to database\n  validate         Validate schema syntax\n  status           Show current schema status\n  doctor           Run health checks on authorization infrastructure\n```\n\n### Generate Client Code\n\n```bash\n# Generate Go code\nmelange generate client --runtime go --schema schema.fga --output ./authz/\n\n# With custom package name\nmelange generate client --runtime go --schema schema.fga --output ./authz/ --package myauthz\n\n# With int64 IDs instead of strings\nmelange generate client --runtime go --schema schema.fga --output ./authz/ --id-type int64\n\n# Only generate permission relations (can_*)\nmelange generate client --runtime go --schema schema.fga --output ./authz/ --filter can_\n```\n\nSupported runtimes: `go` (TypeScript coming soon)\n\n### Apply Schema to Database\n\n```bash\n# Apply schema\nmelange migrate --db postgres://localhost/mydb --schemas-dir ./schemas/\n\n# Dry run (show SQL without applying)\nmelange migrate --db postgres://localhost/mydb --schemas-dir ./schemas/ --dry-run\n\n# Force re-apply even if unchanged\nmelange migrate --db postgres://localhost/mydb --schemas-dir ./schemas/ --force\n```\n\n### Validate Schema\n\n```bash\nmelange validate --schema schema.fga\n```\n\n### Check Status\n\n```bash\nmelange status --db postgres://localhost/mydb\n```\n\n### Health Check\n\n```bash\nmelange doctor --db postgres://localhost/mydb --verbose\n```\n\n---\n\n## Using from Any Language\n\nMelange generates standard PostgreSQL functions, so you can use it from **any language** that can execute SQL:\n\n```python\n# Python\ncursor.execute(\n    \"SELECT check_permission(%s, %s, %s, %s, %s)\",\n    ('user', 'alice', 'can_read', 'repository', 'my-repo')\n)\n```\n\n```ruby\n# Ruby\nDB.fetch(\n  \"SELECT check_permission(?, ?, ?, ?, ?)\",\n  'user', 'alice', 'can_read', 'repository', 'my-repo'\n).first\n```\n\n```typescript\n// TypeScript (with pg or any SQL client)\nconst result = await db.query(\"SELECT check_permission($1, $2, $3, $4, $5)\", [\n  \"user\",\n  \"alice\",\n  \"can_read\",\n  \"repository\",\n  \"my-repo\",\n]);\n```\n\n### Optional Runtime Libraries\n\nFor convenience, Melange provides type-safe runtime clients:\n\n| Language   | Runtime Package                   | CLI Flag               | Status      |\n| ---------- | --------------------------------- | ---------------------- | ----------- |\n| Go         | `github.com/pthm/melange/melange` | `--runtime go`         | Implemented |\n| TypeScript | `@pthm/melange`                   | `--runtime typescript` | Planned     |\n\nThese libraries provide a nicer API but are completely optional. See [`clients/`](clients/) for language-specific implementations.\n\n---\n\n## Contributing\n\nContributions are welcome! Melange is still evolving and feedback, bug reports, and improvements are greatly appreciated.\n\n### Chat\n\nIf you have questions, want to discuss ideas, or need help getting started, join the Matrix room:\n\n[![Matrix](https://img.shields.io/matrix/melange:matrix.org?label=Matrix%20Chat\u0026logo=matrix)](https://matrix.to/#/#melange:matrix.org)\n\nMatrix is the best place for:\n- general discussion about the project\n- design ideas or architecture questions\n- quick help getting set up\n\n### Issues\n\nFor **bug reports, feature requests, or design discussions**, please open an issue:\n\nhttps://github.com/pthm/melange/issues\n\nWhen reporting a bug, please include:\n- steps to reproduce\n- expected vs actual behavior\n- relevant logs or error messages\n- environment details if applicable\n\n### Pull Requests\n\nCode contributions are very welcome.\n\n1. **Fork the repository** and clone locally\n2. **Create a branch** for your changes\n3. **Run tests** with `just test`\n4. **Submit a pull request** with a clear description\n\nPlease ensure your code:\n\n- Passes all existing tests\n- Includes tests for new functionality\n- Follows the existing code style\n\nFor larger changes or new features, it's often helpful to **open an issue or start a discussion on Matrix first** so we can align on the approach.\n\n---\n\n## Resources\n\n- **[Documentation](https://melange.sh)** — Guides, API reference, and examples\n- **[OpenFGA](https://openfga.dev)** — The authorization model Melange implements\n- **[Zanzibar Paper](https://research.google/pubs/pub48190/)** — Google's original authorization system\n- **[pgFGA](https://github.com/rover-app/pgfga)** — PostgreSQL FGA implementation that inspired this project\n\n---\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n","funding_links":[],"categories":["\u003ca name=\"Go\"\u003e\u003c/a\u003eGo"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpthm%2Fmelange","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpthm%2Fmelange","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpthm%2Fmelange/lists"}