OpenFga.Sdk
0.2.0
See the version list below for details.
dotnet add package OpenFga.Sdk --version 0.2.0
NuGet\Install-Package OpenFga.Sdk -Version 0.2.0
<PackageReference Include="OpenFga.Sdk" Version="0.2.0" />
paket add OpenFga.Sdk --version 0.2.0
#r "nuget: OpenFga.Sdk, 0.2.0"
// Install OpenFga.Sdk as a Cake Addin #addin nuget:?package=OpenFga.Sdk&version=0.2.0 // Install OpenFga.Sdk as a Cake Tool #tool nuget:?package=OpenFga.Sdk&version=0.2.0
.NET SDK for OpenFGA
This is an autogenerated SDK for OpenFGA. It provides a wrapper around the OpenFGA API definition.
Table of Contents
- About OpenFGA
- Resources
- Installation
- Getting Started
- Contributing
- License
About
OpenFGA is an open source Fine-Grained Authorization solution inspired by Google's Zanzibar paper. It was created by the FGA team at Auth0 based on Auth0 Fine-Grained Authorization (FGA), available under a permissive license (Apache-2) and welcomes community contributions.
OpenFGA is designed to make it easy for application builders to model their permission layer, and to add and integrate fine-grained authorization into their applications. OpenFGA’s design is optimized for reliability and low latency at a high scale.
Resources
- OpenFGA Documentation
- OpenFGA API Documentation
- OpenFGA Discord Community
- Zanzibar Academy
- Google's Zanzibar Paper (2019)
Installation
The OpenFGA .NET SDK is available on NuGet.
You can install it using:
- The dotnet CLI
dotnet add package OpenFga.Sdk
- The Package Manager Console inside Visual Studio:
Install-Package OpenFga.Sdk
Search for and install OpenFga.Sdk
in each of their respective package manager UIs.
Getting Started
Initializing the API Client
Learn how to initialize your SDK
Without an API Token
using OpenFga.Sdk.Api;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Configuration;
using OpenFga.Sdk.Model;
namespace Example {
public class Example {
public static void Main() {
try {
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"), // optional, defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
};
var openFgaApi = new OpenFgaApi(configuration);
var response = openFgaApi.ReadAuthorizationModels();
} catch (ApiException e) {
Debug.Print("Status Code: "+ e.ErrorCode);
}
}
}
}
With an API Token
using OpenFga.Sdk.Api;
using OpenFga.Sdk.Client;
using OpenFga.Sdk.Configuration;
using OpenFga.Sdk.Model;
namespace Example {
public class Example {
public static async void Main() {
try {
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"), // optional, defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"), // not needed when calling `CreateStore` or `ListStores`
Credentials = new Credentials() {
Method = CredentialsMethod.ApiToken,
Config = new CredentialsConfig() {
ApiToken = Environment.GetEnvironmentVariable("OPENFGA_API_TOKEN"), // will be passed as the "Authorization: Bearer ${ApiToken}" request header
}
}
};
var openFgaApi = new OpenFgaApi(configuration);
var response = await openFgaApi.ReadAuthorizationModels();
} catch (ApiException e) {
Debug.Print("Status Code: "+ e.ErrorCode);
}
}
}
}
Get your Store ID
You need your store id to call the OpenFGA API (unless it is to call the CreateStore or ListStores methods).
If your server is configured with authentication enabled, you also need to have your credentials ready.
Calling the API
List Stores
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"),
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"),
};
var openFgaApi = new OpenFgaApi(configuration);
var response = await openFgaApi.ListStores();
// stores = [{ "id": "01FQH7V8BEG3GPQW93KTRFR8JB", "name": "FGA Demo Store", "created_at": "2022-01-01T00:00:00.000Z", "updated_at": "2022-01-01T00:00:00.000Z" }]
Create Store
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"),
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"),
};
var openFgaApi = new OpenFgaApi(configuration);
var store = await openFgaApi.CreateStore(new CreateStoreRequest(){Name = "FGA Demo"})
// store.Id = "01FQH7V8BEG3GPQW93KTRFR8JB"
// store store.Id in database
// update the storeId of the current instance
openFgaApi.StoreId = storeId;
// continue calling the API normally
Get Store
Requires a client initialized with a storeId
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("OPENFGA_API_SCHEME"),
ApiHost = Environment.GetEnvironmentVariable("OPENFGA_API_HOST"),
StoreId = Environment.GetEnvironmentVariable("OPENFGA_STORE_ID"),
};
var openFgaApi = new OpenFgaApi(configuration);
var store = await openFgaApi.GetStore();
// store = { "id": "01FQH7V8BEG3GPQW93KTRFR8JB", "name": "FGA Demo Store", "created_at": "2022-01-01T00:00:00.000Z", "updated_at": "2022-01-01T00:00:00.000Z" }
Delete Store
Requires a client initialized with a storeId
var store = await openFgaApi.DeleteStore();
Write Authorization Model
Note: To learn how to build your authorization model, check the Docs at https://openfga.dev/docs.
Learn more about the OpenFGA configuration language.
var documentRelations = new Dictionary<string, Userset>()
{
{"writer", new Userset(_this: new object())},
{
"viewer",
new Userset(union: new Usersets(new List<Userset>()
{new(new object(), new ObjectRelation("", "writer"))}))
}
};
var userRelations = new Dictionary<string, Userset>()
{
};
var body = new WriteAuthorizationModelRequest(new List<TypeDefinition>() {new("document", documentRelations), new("user", userRelations)});
var response = await openFgaApi.WriteAuthorizationModel(body);
// response.AuthorizationModelId = 1uHxCSuTP0VKPYSnkq1pbb1jeZw
Read a Single Authorization Model
string authorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"; // Assuming `1uHxCSuTP0VKPYSnkq1pbb1jeZw` is an id of an existing model
var response = await openFgaApi.ReadAuthorizationModel(authorizationModelId);
// response.AuthorizationModel.Id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
// response.AuthorizationModel.TypeDefinitions = [{ "type": "document", "relations": { ... } }, { "type": "user", "relations": { ... }}]
Read Authorization Model IDs
var response = await openFgaApi.ReadAuthorizationModels();
// response.AuthorizationModelIds = ["1uHxCSuTP0VKPYSnkq1pbb1jeZw", "GtQpMohWezFmIbyXxVEocOCxxgq"];
Check
var body =
new CheckRequest{tupleKey: new TupleKey("document:roadmap", "viewer", "user:81684243-9356-4421-8fbf-a4f8d36aa31b"), AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"};
var response = await openFgaApi.Check(body);
// response.Allowed = true
Write Tuples
var body = new WriteRequest{Writes = new TupleKeys(new List<TupleKey>
{new("document:roadmap", "viewer", "user:81684243-9356-4421-8fbf-a4f8d36aa31b")}), AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"};
var response = await openFgaApi.Write(body);
Delete Tuples
var body = new WriteRequest{Deletes = new TupleKeys(new List<TupleKey>
{new("document:roadmap", "viewer", "user:81684243-9356-4421-8fbf-a4f8d36aa31b")}), AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"};
var response = await openFgaApi.Write(body);
Expand
var body = new ExpandRequest{TupleKey = new TupleKey("document:roadmap", "viewer"), AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"};
var response = await openFgaApi.Expand(body);
// response.Tree.Root = {"name":"document:roadmap#viewer","leaf":{"users":{"users":["user:81684243-9356-4421-8fbf-a4f8d36aa31b","user:f52a4f7a-054d-47ff-bb6e-3ac81269988f"]}}}
Read Changes
// Find if a relationship tuple stating that a certain user is a viewer of a certain document
var body = new ReadRequest(new TupleKey(
_object: "document:roadmap",
relation: "viewer",
user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b");
// Find all relationship tuples where a certain user has a relationship as any relation to a certain document
var body = new ReadRequest(new TupleKey(
_object: "document:roadmap",
user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b"));
// Find all relationship tuples where a certain user is a viewer of any document
var body = new ReadRequest(new TupleKey(
_object: "document:",
relation: "viewer",
user: "user:81684243-9356-4421-8fbf-a4f8d36aa31b"));
// Find all relationship tuples where any user has a relationship as any relation with a particular document
var body = new ReadRequest(new TupleKey(
_object: "document:roadmap"));
// Read all stored relationship tuples
body := ReadRequest()
var response = await openFgaApi.Read(body);
// In all the above situations, the response will be of the form:
// response = {"tuples":[{"key":{"user":"...","relation":"...","object":"..."},"timestamp":"..."}]}
Read Changes (Watch)
var type = 'document';
var pageSize = 25;
var continuationToken = 'eyJwayI6IkxBVEVTVF9OU0NPTkZJR19hdXRoMHN0b3JlIiwic2siOiIxem1qbXF3MWZLZExTcUoyN01MdTdqTjh0cWgifQ==';
var response = await openFgaApi.ReadChanges(type, pageSize, continuationToken);
// response.continuation_token = ...
// response.changes = [
// { tuple_key: { user, relation, object }, operation: "writer", timestamp: ... },
// { tuple_key: { user, relation, object }, operation: "viewer", timestamp: ... }
// ]
List Objects
var body = new ListObjectsRequest{
AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw",
User = "user:81684243-9356-4421-8fbf-a4f8d36aa31b",
Relation = "viewer",
Type = "document",
ContextualTuples = new ContextualTupleKeys() {
TupleKeys = new List<TupleKey> {
new("document:budget", "writer", "user:81684243-9356-4421-8fbf-a4f8d36aa31b")
}
}
};
var response = await openFgaApi.ListObjects(body);
// response.Objects = ["document:roadmap"]
API Endpoints
Method | HTTP request | Description |
---|---|---|
Check | POST /stores/{store_id}/check | Check whether a user is authorized to access an object |
CreateStore | POST /stores | Create a store |
DeleteStore | DELETE /stores/{store_id} | Delete a store |
Expand | POST /stores/{store_id}/expand | Expand all relationships in userset tree format, and following userset rewrite rules. Useful to reason about and debug a certain relationship |
GetStore | GET /stores/{store_id} | Get a store |
ListObjects | POST /stores/{store_id}/list-objects | [EXPERIMENTAL] Get all object ids of the given type that the user has a relation with |
ListStores | GET /stores | List all stores |
Read | POST /stores/{store_id}/read | Get tuples from the store that matches a query, without following userset rewrite rules |
ReadAssertions | GET /stores/{store_id}/assertions/{authorization_model_id} | Read assertions for an authorization model ID |
ReadAuthorizationModel | GET /stores/{store_id}/authorization-models/{id} | Return a particular version of an authorization model |
ReadAuthorizationModels | GET /stores/{store_id}/authorization-models | Return all the authorization models for a particular store |
ReadChanges | GET /stores/{store_id}/changes | Return a list of all the tuple changes |
Write | POST /stores/{store_id}/write | Add or delete tuples from the store |
WriteAssertions | PUT /stores/{store_id}/assertions/{authorization_model_id} | Upsert assertions for an authorization model ID |
WriteAuthorizationModel | POST /stores/{store_id}/authorization-models | Create a new authorization model |
Models
- Model.Any
- Model.Assertion
- Model.AuthorizationModel
- Model.CheckRequest
- Model.CheckResponse
- Model.Computed
- Model.ContextualTupleKeys
- Model.CreateStoreRequest
- Model.CreateStoreResponse
- Model.Difference
- Model.ErrorCode
- Model.ExpandRequest
- Model.ExpandResponse
- Model.GetStoreResponse
- Model.InternalErrorCode
- Model.InternalErrorMessageResponse
- Model.Leaf
- Model.ListObjectsRequest
- Model.ListObjectsResponse
- Model.ListStoresResponse
- Model.Metadata
- Model.Node
- Model.Nodes
- Model.NotFoundErrorCode
- Model.ObjectRelation
- Model.PathUnknownErrorMessageResponse
- Model.ReadAssertionsResponse
- Model.ReadAuthorizationModelResponse
- Model.ReadAuthorizationModelsResponse
- Model.ReadChangesResponse
- Model.ReadRequest
- Model.ReadResponse
- Model.RelationMetadata
- Model.RelationReference
- Model.Status
- Model.Store
- Model.Tuple
- Model.TupleChange
- Model.TupleKey
- Model.TupleKeys
- Model.TupleOperation
- Model.TupleToUserset
- Model.TypeDefinition
- Model.Users
- Model.Userset
- Model.UsersetTree
- Model.UsersetTreeDifference
- Model.UsersetTreeTupleToUserset
- Model.Usersets
- Model.ValidationErrorMessageResponse
- Model.WriteAssertionsRequest
- Model.WriteAuthorizationModelRequest
- Model.WriteAuthorizationModelResponse
- Model.WriteRequest
Contributing
Issues
If you have found a bug or if you have a feature request, please report them on the sdk-generator repo issues section. Please do not report security vulnerabilities on the public GitHub issue tracker.
Pull Requests
All changes made to this repo will be overwritten on the next generation, so we kindly ask that you send all pull requests related to the SDKs to the sdk-generator repo instead.
Author
License
This project is licensed under the Apache-2.0 license. See the LICENSE file for more info.
The code in this repo was auto generated by OpenAPI Generator from a template based on the csharp-netcore template, licensed under the Apache License 2.0.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
-
net6.0
- No dependencies.
NuGet packages (3)
Showing the top 3 NuGet packages that depend on OpenFga.Sdk:
Package | Downloads |
---|---|
Fga.Net.DependencyInjection
Auth0 Fine Grained Authorization for .NET. This package includes DI collection extensions for the FGA Client. |
|
FlowtideDotNet.Connector.OpenFGA
Package Description |
|
Saturn.OpenTelemetry
For the easy open telemetry instrumentation of saturn apps |
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
0.5.1 | 18,008 | 9/10/2024 |
0.5.0 | 4,138 | 8/28/2024 |
0.4.0 | 96 | 8/28/2024 |
0.3.2 | 43,342 | 4/30/2024 |
0.3.1 | 28,066 | 2/13/2024 |
0.3.0 | 20,563 | 12/20/2023 |
0.2.5 | 1,307 | 12/1/2023 |
0.2.4 | 48,021 | 5/1/2023 |
0.2.3 | 1,501 | 4/13/2023 |
0.2.2 | 428 | 4/12/2023 |
0.2.1 | 4,393 | 1/17/2023 |
0.2.0 | 2,286 | 12/15/2022 |
0.1.2 | 962 | 11/16/2022 |
0.1.1 | 956 | 10/7/2022 |
0.1.0 | 1,839 | 9/30/2022 |
0.0.3 | 643 | 9/9/2022 |
0.0.2 | 789 | 8/16/2022 |
0.0.1 | 727 | 6/17/2022 |