GitClub: Developing an end-to-end example for working with OpenFGA in .NET #287
Replies: 5 comments 4 replies
-
Hey @bytefish 👋🏻 Thanks for showing your demo! It looks like your on the right way, doing the Authorization checks as early as possible for each action. While I currently don't have an example repo with a .NET project available, I recently published a Google Drive style demo written in Next.js. The readme contains some more information about which OpenFGA checks are performed, and when we write new tuples to the OpenFGA Store. If there are some specific questions you might have, we'de be happy to answer them :) |
Beta Was this translation helpful? Give feedback.
-
@Sambego That’s a great showcase for OpenFGA! What a great project, it looks so clean in TypeScript. 👍 |
Beta Was this translation helpful? Give feedback.
-
@Sambego I have added an Outbox Pattern to show how to reach Eventual Consistency between OpenFGA and the Database. It is based on Postgres Logical Replication, because I want to avoid using Debezium (Kafka) as long as possible: I've also added Integration Tests to the application, where I am basically spinning up Docker Containers (manually) and create an OpenFGA Store using a fixed Store ID. Whenever a new tests starts, I am creating a fresh Store with the latest AuthorizationModel... so every tests runs with a new set of tuples: I would be really interested to understand, how I could improve the integration test setup, so tests could run in parallel for example. |
Beta Was this translation helpful? Give feedback.
-
Given its ASP.NET Core, you might be interested in my extensions for enforcing FGA checks within authorization middleware: https://github.com/Hawxy/Fga.Net. This package is being used by a number of OpenFGA users in production applications. |
Beta Was this translation helpful? Give feedback.
-
I am preparing an article on GitClub with OpenFGA, but I am not making any progress. I am reflecting about the implementation and I wonder, what’s the best practices. Putting something out there, that is problematic in the long run is harmful and wouldn’t be responsible. So in the GitClub example I have put all Authorization decisions a layer below the “Service Layer” (Controllers, Endpoints). All Authorization decisions happen in the “Business Logic Layer”, as my initial instinct was to put Authorization decisions as down as possible. While it doesn't apply to the specific GitClub example, there could be Transports such as gRPC, Reporting, Desktop Applications, something where a Controller oder HTTP Request Middleware doesn't cut it. Sharing the Authorization decisions in the "Business Logic Layer" seems to be useful to me. Now Fga.Net came up and I thought a lot about how to put it into the GitClub application, because the implementation looks so beautifully clean and smart. I understand, that Fga.Net enables me to use the Say I have a method, where a User wants to create a new Issue. Only a At the moment in the "Business Logic" (what a vague term, they are simply CRUD Services) I am authorizing it like this: public async Task<Issue> CreateIssueAsync(Issue issue, CurrentUser currentUser, CancellationToken cancellationToken)
{
_logger.TraceMethodEntry();
// Only Readers of the Repository are allowed to create issues:
bool isReadRepositoryAuthorized = await _aclService
.CheckUserObjectAsync<Repository>(currentUser.UserId, issue.RepositoryId, RepositoryRoleEnum.Reader, cancellationToken)
.ConfigureAwait(false);
if (!isReadRepositoryAuthorized)
{
throw new EntityUnauthorizedAccessException()
{
EntityName = nameof(Repository),
EntityId = issue.RepositoryId,
UserId = currentUser.UserId,
};
}
// ...
} Now I could move this check to the Controller using Fga.Net and end up with something like this: [FgaPropertyObject(Relations.Reader, nameof(Repository), nameof(Issue.RepositoryId))]
public async Task<IActionResult> PostIssue([FromServices] IssueService issueService, [FromServices] CurrentUser currentUser, [FromBody] Issue issue, CancellationToken cancellationToken) Yes the Route is debatable, it should probably be moved to something like The OSO documentation has this notion of “Enforcement by Layer”, which I like a lot: What is the best way for the example at hand? I just don't want to put out wrong information or uninformed decisions. |
Beta Was this translation helpful? Give feedback.
-
I am currently in the process of writing an end-to-end example for using OpenFGA in .NET at:
The application should be something similar to the Oso "GitClub" example (https://github.com/osohq/gitclub), that is being a non-trivial showcase for modelling a more advanced scenario with OpenFGA. The idea is to have something of a blueprint for OpenFGA and .NET, that I could rip out code from... and maybe it helps OpenFGA getting some traction.
The project uses the "GitHub Permission model" shared by the OpenFGA team at https://github.com/openfga/sample-stores.
It is not finished yet, but I would love to get some feedback or throw ideas around. There isn't much sample code out there, and I am not sure, what's the best practices in the area. Most of the abstractions I came up with look similar to what Oso does in the "GitCloud" example, so I think I am not too far off the track:
That said, Feedback is very welcome.
I think OpenFGA could benefit from end-to-end example in various languages, that show best practices or how to approach problems.
Beta Was this translation helpful? Give feedback.
All reactions