Skip to main content

Setup OpenFGA Server

note
OpenFGA is an open source Fine-Grained Authorization solution based on Google's Zanzibar. We welcome community contribution to this project.

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 Docker was 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.

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 two ways: no authentication (the default) or 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 TLS in your OpenFGA server.

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"}

Production Recommendations

If you have tried OpenFGA locally, decided it works as expected, and now want to deploy it to production, we recommend the following preparation:

  • Update the configuration as follows:
    • Configure authentication on the server as explained above.
    • Enable TLS on the server.
    • Enable production logging by changing the log.format in the config.yaml configuration file to json.
    • Disable Playground.
  • Add a rate limiter interceptor (for example, in the server configuration) that protects your OpenFGA server against bursts in traffic.
  • Add a logger interceptor (for example, in the server configuration) that sends logs to your logging platform of choice.