Code Monkey home page Code Monkey logo

js-sdk's Introduction

OpenFGA

Go Reference GitHub release (latest SemVer) Docker Pulls Codecov Go Report CII Best Practices Join our community Twitter FOSSA Status Artifact HUB OpenSSF Scorecard SLSA 3

A high-performance and flexible authorization/permission engine built for developers and inspired by Google Zanzibar.

OpenFGA is designed to make it easy for developers to model their application permissions and add and integrate fine-grained authorization into their applications.

It allows in-memory data storage for quick development, as well as pluggable database modules. It currently supports PostgreSQL 14 and MySQL 8.

It offers an HTTP API and a gRPC API. It has SDKs for Java, Node.js/JavaScript, GoLang, Python and .NET. Look in our Community section for third-party SDKs and tools. It can also be used as a library (see example).

Getting Started

The following section aims to help you get started quickly. Please look at our official documentation for in-depth information.

Setup and Installation

โ„น๏ธ The following sections setup an OpenFGA server using the default configuration values. These are for rapid development and not for a production environment. Data written to an OpenFGA instance using the default configuration with the memory storage engine will not persist after the service is stopped.

For more information on how to configure the OpenFGA server, please take a look at our official documentation on Running in Production.

Docker

OpenFGA is available on Dockerhub, so you can quickly start it using the in-memory datastore by running the following commands:

docker pull openfga/openfga
docker run -p 8080:8080 -p 3000:3000 openfga/openfga run

Tip

The OPENFGA_HTTP_ADDR environment variable can used to configure the address at which the playground expects the OpenFGA server to be. For example, docker run -e OPENFGA_PLAYGROUND_ENABLED=true -e OPENFGA_HTTP_ADDR=0.0.0.0:4000 -p 4000:4000 -p 3000:3000 openfga/openfga run will start the OpenFGA server on port 4000, and configure the playground too.

Docker Compose

docker-compose.yaml provides an example of how to launch OpenFGA with Postgres using docker compose.

  1. First, either clone this repo or curl the docker-compose.yaml file with the following command:

    curl -LO https://openfga.dev/docker-compose.yaml
  2. Then, run the following command:

    docker compose up

Package Managers

If you are a Homebrew user, you can install OpenFGA with the following command:

brew install openfga

Pre-compiled Binaries

Download your platform's latest release and extract it. Then run the binary with the command:

./openfga run

Building from Source

There are two recommended options for building OpenFGA from source code:

Building from source with go install

Make sure you have Go 1.20 or later installed. See the Go downloads page.

You can install from source using Go modules:

  1. First, make sure $GOBIN is on your shell $PATH:

    export PATH=$PATH:$(go env GOBIN)
  2. Then use the install command:

    go install github.com/openfga/openfga/cmd/openfga
  3. Run the server with:

    ./openfga run

Building from source with go build

Alternatively you can build OpenFGA by cloning the project from this Github repo, and then building it with the go build command:

  1. Clone the repo to a local directory, and navigate to that directory:

    git clone https://github.com/openfga/openfga.git && cd openfga
  2. Then use the build command:

    go build -o ./openfga ./cmd/openfga
  3. Run the server with:

    ./openfga run

Verifying the Installation

Now that you have Set up and Installed OpenFGA, you can test your installation by creating an OpenFGA Store.

curl -X POST 'localhost:8080/stores' \
--header 'Content-Type: application/json' \
--data-raw '{
    "name": "openfga-demo"
}'

If everything is running correctly, you should get a response with information about the newly created store, for example:

{
  "id": "01G3EMTKQRKJ93PFVDA1SJHWD2",
  "name": "openfga-demo",
  "created_at": "2022-05-19T17:11:12.888680Z",
  "updated_at": "2022-05-19T17:11:12.888680Z"
}

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.

To run OpenFGA with the Playground disabled, provide the --playground-enabled=false flag.

./openfga run --playground-enabled=false

Once OpenFGA is running, by default, the Playground can be accessed at http://localhost:3000/playground.

In the event that a port other than the default port is required, the --playground-port flag can be set to change it. For example,

./openfga run --playground-enabled --playground-port 3001

Profiler (pprof)

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

./openfga run --profiler-enabled

This will start serving profiling data on port 3001. You can see that data by visiting http://localhost:3001/debug/pprof.

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

./openfga run --profiler-enabled --profiler-addr :3002

Once the OpenFGA server is running, in another window you can run the following command to generate a compressed CPU profile:

go tool pprof -proto -seconds 60 http://localhost:3001/debug/pprof/profile
# will collect data for 60 seconds and generate a file like pprof.samples.cpu.001.pb.gz

That file can be analyzed visually by running the following command and then visiting http://localhost:8084:

go tool pprof -http=localhost:8084 pprof.samples.cpu.001.pb.gz

Next Steps

Take a look at examples of how to:

Don't hesitate to browse the official Documentation, API Reference.

Limitations

MySQL Storage engine

The MySQL storage engine has a lower length limit for some properties of a tuple compared with other storage backends. For more information see the docs.

OpenFGA's MySQL Storage Adapter was contributed to OpenFGA by @twintag. Thanks!

Production Readiness

The core OpenFGA service has been in use by Okta FGA in production since December 2021.

OpenFGA's Memory Storage Adapter was built for development purposes only and is not recommended for a production environment, because it is not designed for scalable queries and has no support for persistence.

You can learn about more organizations using OpenFGA in production here. If your organization is using OpenFGA in production please consider adding it to the list.

The OpenFGA team will do its best to address all production issues with high priority.

Contributing

See CONTRIBUTING.

Community Meetings

We hold a monthly meeting to interact with the community, collaborate and receive/provide feedback. You can find more details, including the time, our agenda, and the meeting minutes here.

js-sdk's People

Contributors

aaguiarz avatar adriantam avatar dependabot[bot] avatar evansims avatar ewanharris avatar klausvii avatar rhamzeh avatar snyk-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-sdk's Issues

Credentials expiry is broken

Description

When using ClientCredentials for auth, the token is not cached properly because the expires_in amount is treated as milliseconds instead of seconds

Version of SDK

0.2.6

Version of OpenFGA (if known)

N/A

Reproduction

Run the client with ClientCredentials enabled and observe how many requests are made to your auth token service.

The issue is (here)[https://github.com/openfga/js-sdk/blob/main/credentials/credentials.ts#L155]

this.accessTokenExpiryDate = new Date(Date.now() + response.data.expires_in);

Date.now() returns the time in milliseconds, expires_in is in seconds -> the expiry gets set 1000 times too soon!

Expected behavior

I do not DDOS my auth service because of openFGA

Additional context

Add any other context about the problem here.

Support for migrations

Checklist

Describe the problem you'd like to have solved

I currently have the problem that an authorization model have to be migrated after a software rollout. The following guide explains how to do this manually:

https://openfga.dev/docs/modeling/migrating/migrating-relations

These changes are cumbersome and error-prone.

Describe the ideal solution

I would like to use an integrated functionality, such as a dedicated CLI application, to perform automated migrations.

As this is a known problem in the database world, I would like to use a similar solution. As an example I would like to mention the migrations of sequelize:

https://sequelize.org/v5/manual/migrations

Alternatives and current workarounds

No response

References

No response

Additional context

No response

Support for Deno

Currently, the axios dependency causes issues when attempting to run the SDK from Deno

Deno 1.41.1
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import {OpenFgaClient} from "https://dev.jspm.io/@openfga/sdk"
undefined
> const fgaClient = new OpenFgaClient({ apiUrl: "https://api.playground.fga.dev" })
undefined
> fgaClient.createStore({ name: "test-deno-store" })
Promise {
  <rejected> AxiosError: There is no suitable adapter to dispatch the request since :
- adapter xhr is not supported by the environment
- adapter http is not available in the build
    at Object.getAdapter (https://dev.jspm.io/npm:[email protected]!cjs:2123:13)
    at Axios.dispatchRequest (https://dev.jspm.io/npm:[email protected]!cjs:2162:28)
    at Axios.request (https://dev.jspm.io/npm:[email protected]!cjs:2470:33)
    at wrap (https://dev.jspm.io/npm:[email protected]!cjs:8:15)
    at https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:675:24
    at Generator.next (<anonymous>)
    at https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:572:69
    at new Promise (<anonymous>)
    at __awaiter (https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:554:12)
    at attemptHttpRequest (https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:670:12) {
    name: "FgaApiError",
    statusCode: undefined,
    statusText: undefined,
    requestData: undefined,
    requestURL: undefined,
    method: undefined,
    storeId: "",
    endpointCategory: "",
    apiErrorMessage: undefined,
    responseData: undefined,
    responseHeader: undefined,
    requestId: undefined
  }
}
Uncaught AxiosError: There is no suitable adapter to dispatch the request since :
- adapter xhr is not supported by the environment
- adapter http is not available in the build
    at Object.getAdapter (https://dev.jspm.io/npm:[email protected]!cjs:2123:13)
    at Axios.dispatchRequest (https://dev.jspm.io/npm:[email protected]!cjs:2162:28)
    at Axios.request (https://dev.jspm.io/npm:[email protected]!cjs:2470:33)
    at wrap (https://dev.jspm.io/npm:[email protected]!cjs:8:15)
    at https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:675:24
    at Generator.next (<anonymous>)
    at https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:572:69
    at new Promise (<anonymous>)
    at __awaiter (https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:554:12)
    at attemptHttpRequest (https://dev.jspm.io/npm:@openfga/[email protected]/_/F1S5_afg.js:670:12)

Replace axios

Summary

axios v1 has brought a few breaking changes, so now's the time to reconsider whether it still is the best solution we have.

Motivation(s)

  • http2/http3 support
  • streaming support
  • reduce dependencies

Downsides

  • Breaking change - axios is very tied to our responses, anyone who currently depends on them will have some work to do before they can upgrade

Alternatives to consider

  • axios: it's working, stick to it, but update to a v1.x.x+ version (no http2 support yet)
  • fetch: built into recent browsers and node 18+
  • gaxios: close to the axios interface, supports http2, no browser support
  • got: Seems to satisfy a lot constraints. No browser support and has a lot of dependencies
  • ky: tiny, no dependencies, supports deno
  • undici: from the core node devs
  • ...

Criteria for success

  • Compatible license (required)
  • Node.js 18+ support (required)
  • Brings in a minimal set of dependencies (required)
  • Promise based (required)
  • Preferably not another dependency
  • Streaming support: allows us to expose the streaming ListObjects
  • http2/http3 support: reduces request overhead
  • Browser support: needed for the Playground
  • Deno support (#17)
  • Error handling and automated retries (bonus - lets us drop our own implementation)
  • Credential flow support (bonus - lets us drop our own implementation)
  • Built-in caching support (bonus)

Including js-sdk version in request headers

๐Ÿ‘‹ hello! I would like to request that the OpenFGA js-sdk version is included in the request headers. This will allow us to properly route the requests to the right OpenFGA server based on the sdk-version (if there are breaking changes) using load balancers.

Support for Cloudflare Workers/Vercel Edge Runtime

Deploying Functions on the Cloudflare Workers/Vercel Edge Runtime to interact with the FGA SDK

Currently the SDK depends on the Node.js http module. This prevents us from leveraging the SDK in these newer javascript runtimes.

Describe the ideal solution

A clear and concise description of what you want to happen.

Alternatives and current workarounds

We would have to manually craft the requests to the FGA APIs to interact with the service.

Additional context

When calling an SDK function such as:

const result = await fgaClient.listObjects({ user, relation, type, });

we receive the following exception being thrown:

[Error: The edge runtime does not support Node.js 'http' module.

HTTP connection pooling

Hey there,
methods like batchCheck and listRelations can potentially issue a lot of individual requests. We noticed some rather severe performance issues which we narrowed down to each of those requests doing a new DNS lookup and TCP connection setup.

Once we enabled connection re-use/pooling/keep alive (whatever you want to call it) we saw big improvements.

http.globalAgent = new http.Agent({ keepAlive: true });
https.globalAgent = new https.Agent({ keepAlive: true });

I think this should either be the default for the SDK's axios instance, a parameter for the OpenFgaClient or the very least mentioned in the docs.

What do you think?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.