Configure Authorization Model for a Store
This article explains how to configure an authorization model for a store in an OpenFGA server.
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, created the store and setup the SDK client.
- 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, created the store and setup the SDK client.
- 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, created the store and setup the SDK client.
- 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, created the store and setup the SDK client.
- 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 created the store and have loaded
FGA_STORE_ID
andFGA_API_HOST
as environment variables.
Step By Step
Assume that you want to configure your store with the following model.
- DSL
- JSON
model
schema 1.1
type user
type document
relations
define reader: [user]
define writer: [user]
define owner: [user]
{
"schema_version": "1.1",
"type_definitions": [
{
"type": "user"
},
{
"type": "document",
"relations": {
"reader": {
"this": {}
},
"writer": {
"this": {}
},
"owner": {
"this": {}
}
},
"metadata": {
"relations": {
"reader": {
"directly_related_user_types": [
{
"type": "user"
}
]
},
"writer": {
"directly_related_user_types": [
{
"type": "user"
}
]
},
"owner": {
"directly_related_user_types": [
{
"type": "user"
}
]
}
}
}
}
]
}
To configure authorization model, we can invoke the write authorization models API.
- Node.js
- Go
- .NET
- Python
- curl
Initialize the SDK
// ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
// 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"
});
const { authorization_model_id: id } = await fgaClient.writeAuthorizationModel({
"schema_version": "1.1",
"type_definitions": [
{
"type": "document",
"relations": {
"reader": {
"this": {}
},
"writer": {
"this": {}
},
"owner": {
"this": {}
}
},
"metadata": {
"relations": {
"reader": {
"directly_related_user_types": [
{
"type": "user"
}
]
},
"writer": {
"directly_related_user_types": [
{
"type": "user"
}
]
},
"owner": {
"directly_related_user_types": [
{
"type": "user"
}
]
}
}
}
}
]
});
// id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
Initialize the SDK
// ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
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)
}
var writeAuthorizationModelRequestString = "{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}},\"writer\":{\"this\":{}},\"owner\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}"
var body WriteAuthorizationModelRequest
if err := json.Unmarshal([]byte(writeAuthorizationModelRequestString), &body); err != nil {
t.Errorf("%v", err)
// .. Handle error
return
}
data, response, err := fgaClient.OpenFgaApi.WriteAuthorizationModel(context.Background()).Body(body).Execute()
if err != nil {
// .. Handle error
}
// data.AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
Initialize the SDK
// ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
// 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);
}
}
var modelJson = "{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}},\"writer\":{\"this\":{}},\"owner\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}";
var body = JsonSerializer.Deserialize<OpenFga.Sdk.Model.WriteAuthorizationModelRequest>(modelJson);
var response = await fgaClient.WriteAuthorizationModel(body);
// response.AuthorizationModelId = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
Initialize the SDK
# ApiTokenIssuer, ApiAudience, ClientId and ClientSecret are optional.
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))
# from openfga_sdk.models.write_authorization_model_request import WriteAuthorizationModelRequest
async def write_authorization_model():
body_string = "{\"schema_version\":\"1.1\",\"type_definitions\":[{\"type\":\"document\",\"relations\":{\"reader\":{\"this\":{}},\"writer\":{\"this\":{}},\"owner\":{\"this\":{}}},\"metadata\":{\"relations\":{\"reader\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"writer\":{\"directly_related_user_types\":[{\"type\":\"user\"}]},\"owner\":{\"directly_related_user_types\":[{\"type\":\"user\"}]}}}}]}"
response = await fga_client_instance.write_authorization_model(json.loads(body))
# response.authorization_model_id = "1uHxCSuTP0VKPYSnkq1pbb1jeZw"
Get the Bearer Token and set up the FGA_API_URL environment variable
Set FGA_API_URL according to the service you are using
curl -X POST $FGA_API_URL/stores/$FGA_STORE_ID/authorization-models \
-H "Authorization: Bearer $FGA_BEARER_TOKEN" \ # Not needed if service does not require authorization
-H "content-type: application/json" \
-d '{"schema_version":"1.1","type_definitions":[{"type":"document","relations":{"reader":{"this":{}},"writer":{"this":{}},"owner":{"this":{}}},"metadata":{"relations":{"reader":{"directly_related_user_types":[{"type":"user"}]},"writer":{"directly_related_user_types":[{"type":"user"}]},"owner":{"directly_related_user_types":[{"type":"user"}]}}}}]}'
The API will then return the authorization model ID.
Note
The OpenFGA API only accepts an authorization model in the API's JSON syntax.
To convert between the API Syntax and the friendly DSL, you can use the syntax transformer or Auth0 FGA's Playground.