Skip to content

Add source generator for strongly-typed OpenFGA model and relationships in the .NET SDK #137

@simongottschlag

Description

@simongottschlag

Checklist

Describe the problem you'd like to have solved

When using the .NET SDK, developers must currently work with raw strings for object types, relationships and tuples when constructing ClientCheckRequest and related payloads.
This leads to:

  • Lack of compile-time safety (typos or invalid relations are only caught at runtime)
  • Poor discoverability and DX (developers must remember the model definition manually)
  • Fragile integration when the OpenFGA model changes

For example, building a check request today requires writing things like "channel:abc", "reader", or "team:xyz" manually, even though this information exists in the OpenFGA model.

Describe the ideal solution

It would be ideal if the SDK provided an optional source generator (or similar tooling) that:

  • Parses an OpenFGA model file (DSL or JSON) at build time
  • Generates strongly-typed wrappers for each type in the model (User, Team, Channel, etc.)
  • Generates enum values or constants for valid relationships per type (Reader, ReadWriter, etc.)
  • Optionally generates typed helpers for tuples and ClientCheckRequest creation

Example of generated types:

var user = User.From("oid123");
var team = Team.From("team-1");
var channel = Channel.From("chan-42");

var check = ChannelChecks.Build(
    user,
    ChannelRelationship.Reader,
    channel,
    ChannelTuples.Parent(team, channel)
);

This gives developers full IntelliSense support and compile-time safety while maintaining parity with the underlying OpenFGA model.

Alternatives and current workarounds

I currently work around this by writing a custom source generator that:

  • Deserializes a model.transformed.json file embedded at build time
  • Emits classes and enums for all types and relationships
  • Generates small helper builders for tuples and check requests

While this approach works, it adds maintenance burden and fragments the ecosystem.
Having this functionality built into the official SDK would ensure consistency and encourage type-safe integrations across .NET applications.

References

No response

Additional context

  • Using .NET 9 and Roslyn incremental source generators
  • Model schema example:
model
  schema 1.1

type user

type team
  relations
    define reader: [user] or read_writer
    define read_writer: [user]

type channel
  relations
    define parent: [team]
    define reader: [user] or reader from parent
    define read_writer: [user] or read_writer from parent
  • The generated code makes ClientCheckRequest construction strongly typed and much easier to maintain:
var req = ChannelChecks.Build(
    User.From(oid),
    ChannelRelationship.Reader,
    Channel.From(channelId),
    ChannelTuples.Parent(Team.From(teamId), Channel.From(channelId))
);

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    Status

    Intake

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions