Update Relationship Tuples
This section will illustrate how to update relationship tuples.
Before You Start
- Node.js
- Go
- .NET
- Python
- curl
- Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_HOST and, if needed, FGA_API_TOKEN.
- You have installed the SDK.
- You have configured the authorization model.
- You have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
- Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_HOST and, if needed, FGA_API_TOKEN.
- You have installed the SDK.
- You have configured the authorization model.
- You have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
- Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_HOST and, if needed, FGA_API_TOKEN.
- You have installed the SDK.
- You have configured the authorization model.
- You have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
- Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_HOST and, if needed, FGA_API_TOKEN.
- You have installed the SDK.
- You have configured the authorization model.
- You have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
- Deploy an instance of the OpenFGA server, and have ready the values for your setup: FGA_STORE_ID, FGA_API_HOST and, if needed, FGA_API_TOKEN.
- You have configured the authorization model.
- You have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
Step By Step
Assume that you want to add user user:anne
to have relationship reader
with object document:Z
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
}
01. Configure The OpenFGA API Client
Before calling the write API, you will need to configure the API client.
- Node.js
- Go
- .NET
- Python
- curl
// import the SDK
const { OpenFgaApi } = require('@openfga/sdk');
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new OpenFgaApi({
apiScheme: process.env.FGA_API_SCHEME, // Either "http" or "https", defaults to "https"
apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
storeId: process.env.FGA_STORE_ID, // Either "http" or "https", defaults to "https"
});
import (
fgaSdk "github.com/openfga/go-sdk"
"os"
)
func main() {
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
configuration, err := fgaSdk.NewConfiguration(fgaSdk.UserConfiguration{
ApiScheme: os.Getenv("FGA_SCHEME"), // Either "http" or "https", defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods
})
if err != nil {
// .. Handle error
}
fgaClient := fgaSdk.NewAPIClient(configuration)
}
// import the SDK
using OpenFga.Sdk.Api;
using OpenFga.Sdk.Configuration;
using Environment = System.Environment;
namespace ExampleApp;
class MyProgram {
static async Task Main() {
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
var configuration = new Configuration() {
ApiScheme = Environment.GetEnvironmentVariable("FGA_API_SCHEME"), // Either "http" or "https", defaults to "https"
ApiHost = Environment.GetEnvironmentVariable("FGA_API_HOST"), // required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods
};
var fgaClient = new OpenFgaApi(configuration);
}
}
import os
import json
import openfga_sdk
from openfga_sdk.api import open_fga_api
configuration = openfga_sdk.Configuration(
api_scheme = os.environ.get('FGA_API_SCHEME'), # Either "http" or "https", defaults to "https"
api_host = os.environ.get('FGA_API_HOST'), # required, define without the scheme (e.g. api.openfga.example instead of https://api.openfga.example)
store_id = os.environ.get('FGA_STORE_ID') # optional, not needed for `CreateStore` and `ListStores`, required before calling for all other methods
)
# Create an instance of the API class
fga_client_instance = open_fga_api.OpenFgaApi(openfga_sdk.ApiClient(configuration))
To obtain the access token:
Set FGA_API_URL according to the service you are using
02. Calling Write API To Add New Relationship Tuples
To add the relationship tuples, we can invoke the write API.
- Node.js
- Go
- .NET
- Python
- curl
await fgaClient.write({
writes: {
tuple_keys: [
{ user: 'user:anne', relation: 'reader', object: 'document:Z'}
]
},
authorization_model_id: "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
});
body := fgaSdk.WriteRequest{
Writes: &fgaSdk.TupleKeys{
TupleKeys: []fgaSdk.TupleKey {
{
User: fgaSdk.PtrString("user:anne"),
Relation: fgaSdk.PtrString("reader"),
Object: fgaSdk.PtrString("document:Z"),
},
},
},
AuthorizationModelId: fgaSdk.PtrString("1uHxCSuTP0VKPYSnkq1pbb1jeZw")}
_, response, err := fgaClient.OpenFgaApi.Write(context.Background()).Body(body).Execute()
if err != nil {
// .. Handle error
}
await fgaClient.Write(new WriteRequest{
Writes = new TupleKeys(new List<TupleKey>() {
new() { User = "user:anne", Relation = "reader", Object = "document:Z" }
}),
AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
});
# from openfga_sdk.models.tuple_key import TupleKey
# from openfga_sdk.models.tuple_keys import TupleKeys
# from openfga_sdk.models.write_request import WriteRequest
async def write():
body = WriteRequest(
writes=TupleKeys(
tuple_keys=[
TupleKey(
user="user:anne",
relation="reader",
object="document:Z",
),
],
),
authorization_model_id="1uHxCSuTP0VKPYSnkq1pbb1jeZw",
)
await fga_client_instance.write(body)
curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/write \
-H "Authorization: Bearer $FGA_BEARER_TOKEN" \ # Not needed if service does not require authorization
-H "content-type: application/json" \
-d '{"writes": { "tuple_keys" : [{"user":"user:anne","relation":"reader","object":"document:Z"}] }, "authorization_model_id": "1uHxCSuTP0VKPYSnkq1pbb1jeZw"}'
03. Calling Write API To Delete Relationship Tuples
To delete relationship tuples, we can invoke the write API.
Assume that you want to delete user user:anne
's reader
relationship with object document:Z
{
user: 'user:anne',
relation: 'reader',
object: 'document:Z',
}
- Node.js
- Go
- .NET
- Python
- curl
await fgaClient.write({
deletes: {
tuple_keys : [
{ user: 'user:anne', relation: 'reader', object: 'document:Z'}
]
},
authorization_model_id: "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
});
body := fgaSdk.WriteRequest{
Deletes: &fgaSdk.TupleKeys{
TupleKeys: []fgaSdk.TupleKey {
{
User: fgaSdk.PtrString("user:anne"),
Relation: fgaSdk.PtrString("reader"),
Object: fgaSdk.PtrString("document:Z"),
},
},
},
AuthorizationModelId: fgaSdk.PtrString("1uHxCSuTP0VKPYSnkq1pbb1jeZw")}
_, response, err := fgaClient.OpenFgaApi.Write(context.Background()).Body(body).Execute()
if err != nil {
// .. Handle error
}
await fgaClient.Write(new WriteRequest{
Deletes = new TupleKeys(new List<TupleKey>() {
new() { User = "user:anne", Relation = "reader", Object = "document:Z" }
}),
AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
});
# from openfga_sdk.models.tuple_key import TupleKey
# from openfga_sdk.models.tuple_keys import TupleKeys
# from openfga_sdk.models.write_request import WriteRequest
async def write():
body = WriteRequest(
deletes=TupleKeys(
tuple_keys=[
TupleKey(
user="user:anne",
relation="reader",
object="document:Z",
),
],
),
authorization_model_id="1uHxCSuTP0VKPYSnkq1pbb1jeZw",
)
await fga_client_instance.write(body)
curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/write \
-H "Authorization: Bearer $FGA_BEARER_TOKEN" \ # Not needed if service does not require authorization
-H "content-type: application/json" \
-d '{"deletes": { "tuple_keys" : [{"user":"user:anne","relation":"reader","object":"document:Z"}] }, "authorization_model_id": "1uHxCSuTP0VKPYSnkq1pbb1jeZw"}'