Skip to main content

Setup OpenFGA Server

This article explains how to start your own OpenFGA server using Docker, and how to configure it.

Step By Step

If you want to run OpenFGA locally as a Docker container, follow these steps:

  1. Install Docker (if not already installed).
  2. Run docker pull openfga/openfga to get the latest docker image.
  3. Run docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 openfga/openfga run.

This will start an HTTP server and gRPC server with the default configuration options. Port 8080 is used to serve the HTTP API, 8081 is used to serve the gRPC API, and 3000 is used for the Playground.

Configuring The Server

You may configure the OpenFGA server with a config.yaml file. The config.yaml can be specified in either:

  • /etc/openfga
  • $HOME/.openfga
  • . (i.e., the current working directory).

The OpenFGA will server search for the configuration file in the above order.

Here is a sample configuration to run OpenFGA with postgres and using a preshared key for authentication:

datastore:
engine: postgres
uri: postgres://user:[email protected]:5432/mydatabase
authn:
method: preshared
preshared:
keys: ["key1", "key2"]

All possible configurations and their default values are defined in config-schema.json.

Information

The OpenFGA server supports environment variables for configuration, it will take priority against your configuration file. Each variable must be prefixed with OPENFGA_ and followed by your option in uppercase (e.g --grpc-tls-key becomes OPENFGA_GRPC_TLS_KEY).

Configuring Data Storage

OpenFGA supports multiple storage engine options including:

  • memory - The memory storage engine is the default, but it is not persistent (data is lost between server restarts).
  • postgres - The Postgres storage engine requires a Postgres instance that the OpenFGA server can reach.
  • mysql - The MySQL storage engine requires a MySQL instance that the OpenFGA server can reach, and that the connection uri specifies the query parseTime=true.

Postgres

Let's assume you want to run OpenFGA and Postgres in containers. The first thing we should do is create a new network as this will make communication between containers a bit simpler:

docker network create openfga

Start Postgres in the network you created above:

docker run -d --name postgres --network=openfga -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=password postgres:14

You should now have Postgres running in a container in the openfga network. However, it will not have the tables required for running OpenFGA. You can use the migrate command to create the tables. Using the OpenFGA container, this will look like:

docker run --rm --network=openfga openfga/openfga migrate \
--datastore-engine postgres \
--datastore-uri 'postgres://postgres:[email protected]:5432/postgres?sslmode=disable'

Finally, start OpenFGA:

docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \
--datastore-engine postgres \
--datastore-uri 'postgres://postgres:[email protected]:5432/postgres?sslmode=disable'

This will start the postgres database, run openfga migrate to configure the database and finally start the OpenFGA server. OpenFGA should start and you should see using 'postgres' storage engine in the logs.

Now you can try to Create a Store.

MySQL

Setting up MySQL and OpenFGA is very similar to setting up Postgres and OpenFGA. We first make a network:

docker network create openfga

Then, start MySQL in the network you created above:

docker run -d --name mysql --network=openfga -e MYSQL_ROOT_PASSWORD=secret -e MYSQL_DATABASE=openfga mysql:8

You should now have MySQL running in a container in the openfga network. But we still have to migrate all the tables to be able to run OpenFGA. You can use the migrate command to create the tables. Using the OpenFGA container, this will look like:

docker run --rm --network=openfga openfga/openfga migrate \
--datastore-engine mysql \
--datastore-uri 'root:[email protected](mysql:3306)/openfga?parseTime=true'

Finally, start OpenFGA:

docker run --name openfga --network=openfga -p 3000:3000 -p 8080:8080 -p 8081:8081 openfga/openfga run \
--datastore-engine mysql \
--datastore-uri 'root:[email protected](mysql:3306)/openfga?parseTime=true'

OpenFGA should start and you should see using 'mysql' storage engine in the logs.

Now you can try to Create a Store.

MySQL Limitations

Note that the MySQL datastore has stricter limits for the max length of some fields for tuples compared to other datastore engines, in particular:

  • object type is at most 128 characters (down from 256)
  • object id is at most 128 characters (down from 256)
  • user is at most 256 characters (down from 512)

Configuring Authentication

You can configure authentication in your OpenFGA server in three ways: no authentication (the default), pre-shared key authentication or via OIDC.

Pre-shared Key Authentication

If using Pre-shared key authentication, you will configure OpenFGA with a secret key and your application calling OpenFGA will have to set an Authorization: Bearer <YOUR-KEY-HERE> header. You can configure multiple keys.

Warning

If you are going to use this setup in production, you should enable HTTP TLS in your OpenFGA server. You will need to configure the TLS certificate and key.

Update the config.yaml file to

authn:
method: preshared
preshared:
keys: ["key1", "key2"]
http:
tls:
enabled: true
cert: /Users/myuser/key/server.crt
key: /Users/myuser/key/server.key

OIDC

To configure with OIDC authentication, you will first need to obtain the OIDC issuer and audience from your provider.

Warning

If you are going to use this setup in production, you should enable HTTP TLS in your OpenFGA server. You will need to configure the TLS certificate and key.

Update the config.yaml file to

authn:
method: oidc
oidc:
issuer: "oidc-issuer"
audience: "oidc-audience"

http:
tls:
enabled: true
cert: /Users/myuser/key/server.crt
key: /Users/myuser/key/server.key

Playground

The Playground facilitates rapid development by allowing you to visualize and model your application's authorization model(s) and manage relationship tuples with a locally running OpenFGA instance.

The Playground is enabled on port 3000 by default and accessible at http://localhost:3000/playground (if using the docker make sure port 3000 is exposed to your local network). To disable the Playground, please take a look at Configuring the Server for more information.

Profiler (pprof)

Warning

Continuous pprof profiling can be used in production deployments, but we recommend disabling it unless it is needed to troubleshoot specific performance or memory problems.

Profiling through pprof can be enabled on the OpenFGA server by providing the --profiler-enabled flag.

docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 -p 3001:3001 openfga/openfga run --profiler-enabled
note

Remember to expose the profiler port if you're running OpenFGA via docker. For example docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 -p 3001:3001 openfga/openfga run --profiler-enabled.

If you need to serve the profiler on a different address than the default :3001, you can do so by specifying the --profiler-addr flag. For example,

docker run -p 8080:8080 -p 8081:8081 -p 3000:3000 -p 3002:3002 openfga/openfga run --profiler-enabled --profiler-addr :3002

Health Check

OpenFGA is configured with an HTTP health check endpoint /healthz and a gRPC health check grpc.health.v1.Health/Check, which is wired to datastore testing. Possible response values are

  • UNKNOWN
  • SERVING
  • NOT_SERVING
  • SERVICE_UNKNOWN

For HTTP health check

curl -X GET $FGA_API_HOST/healthz

# {"status":"SERVING"}

For gRPC health check

grpcurl -plaintext $FGA_API_HOST grpc.health.v1.Health/Check

# {"status":"SERVING"}

Experimental Features

Various releases of OpenFGA may have experimental features that can be enabled by providing the --experimentals flag or the experimentals config.

docker run -p 8080:8080 -p 8081:8081 openfga/openfga run --experimentals="feature1, feature2"

or if you're using environment variables,

docker run -p 8080:8080 -p 8081:8081 openfga/openfga -e OPENFGA_EXPERIMENTALS="feature1, feature2" run

The following table table enumerates the experimental flags, a description of what they do, and the versions of OpenFGA the flag is supported in:

namedescriptionopenfga version
otel-metricsEnables support for exposing OpenFGA metrics through OpenTelemetry>= v0.3.2
Warning

Experimental features are not guaranteed to be stable and may lead to server instabilities. It is not recommended to enable experimental features for anything other than experimentation.

Experimental feature flags are also not considered part of API compatibility and are subject to change, so please refer to each OpenFGA specific release for a list of the experimental feature flags that can be enabled for that release.

Telemetry (Metrics and Tracing)

Metrics

To expose OpenFGA metrics you must enable the otel-metrics experimental feature (see Experimental Features).

info

OpenTelemetry metrics are exported in otlp format.

Other export formats may be supported in the future, but in the meantime you can setup an OpenTelemetry Collector to receive, process, and publish metrics in other formats. For more information see the official OpenTelemetry Collector documentation.

If you need to configure the OpenTelemetry integration with non-default values you can supply the --otel-telemetry-endpoint and --otel-telemetry-protocol flags. These flags wire up the OpenTelemetry exporter with the provided collector endpoint and configures the exporter protocol (grpc or http). For more information see OTLP gRPC Exporter and OTLP HTTP Exporter. For example,

openfga run --experimentals=otel-metrics --otel-telemetry-endpoint=127.0.0.1:4317 --otel-telemetry-protocol=http

Tracing

OpenFGA, when run in standalone server mode, does not yet support tracing. This work is in our roadmap and we will update this section with more information when the time comes.

Production Best Practices

Learn the best practices of running OpenFGA in a production environment