Skip to content

Commit

Permalink
Merge branch 'main' into snyk-fix-3c90eb39aee93710c23466064c8406e9
Browse files Browse the repository at this point in the history
  • Loading branch information
rhamzeh authored Feb 24, 2024
2 parents ee6a33c + eff44f3 commit c0556ae
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 51 deletions.
13 changes: 5 additions & 8 deletions docs/content/getting-started/create-store.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ This article explains how to setup an OpenFGA store.
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';

const openFga = new OpenFgaClient({
apiScheme: process.env.FGA_API_SCHEME, // optional, 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)
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
});

const { id: storeId } = await openFga.createStore({
Expand All @@ -51,10 +50,9 @@ import (

func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional. Can be "http" or "https". Defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, can be overridden per request
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // Optional, can be overridden per request
})

if err != nil {
Expand Down Expand Up @@ -107,8 +105,7 @@ from openfga_sdk.models.create_store_request import CreateStoreRequest

async def main():
configuration = openfga_sdk.ClientConfiguration(
api_scheme = os.environ.get('FGA_API_SCHEME'),
api_host = os.environ.get('FGA_API_HOST'),
api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example
)

async with OpenFgaClient(configuration) as fga_client:
Expand Down
6 changes: 2 additions & 4 deletions docs/content/getting-started/framework.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -324,8 +324,7 @@ module.exports = fp(async function (fastify, opts) {
try {
// configure the openfga api client
const fgaClient = new OpenFgaClient({
apiScheme: process.env.FGA_API_SCHEME, // Optional. Can be "http" or "https". Defaults to "https"
apiHost: process.env.FGA_API_HOST,
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
});
const { allowed } = await fgaClient.check({
Expand Down Expand Up @@ -479,8 +478,7 @@ func preauthorize(c *fiber.Ctx) error {
// Middleware to check whether user is authorized to access document
func checkAuthorization(c *fiber.Ctx) error {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional. Can be "http" or "https". Defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, can be overridden per request
})
Expand Down
3 changes: 1 addition & 2 deletions docs/content/getting-started/install-sdk.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,7 @@ import (

func main() {
configuration, err := openfga.NewConfiguration(openfga.Configuration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional, 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)
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
})

if err != nil {
Expand Down
41 changes: 16 additions & 25 deletions docs/content/getting-started/setup-sdk-client.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,9 @@ This is a simple setup but it is not recommended for production use.
const { OpenFgaClient } = require('@openfga/sdk'); // OR import { OpenFgaClient } from '@openfga/sdk';

const openFga = new OpenFgaClient({
apiScheme: process.env.FGA_API_SCHEME, // optional. Can be "http" or "https". Defaults to "https"
apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
storeId: process.env.FGA_STORE_ID, // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorizationModelId: process.env.FGA_MODEL_ID, // optional, can be overridden per request
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request
});
```

Expand All @@ -52,10 +51,9 @@ import (

func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional. Can be "http" or "https". Defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, can be overridden per request
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // Optional, can be overridden per request
})

if err != nil {
Expand Down Expand Up @@ -98,10 +96,9 @@ from openfga_sdk.client import OpenFgaClient

async def main():
configuration = openfga_sdk.ClientConfiguration(
api_scheme = os.environ.get('FGA_API_SCHEME'), # optional. Can be "http" or "https". Defaults to "https"
api_host = os.environ.get('FGA_API_HOST'), # required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example
store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # optional, can be overridden per request
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request
)

async with OpenFgaClient(configuration) as fga_client:
Expand Down Expand Up @@ -161,8 +158,7 @@ If you are going to use this setup in production, you should enable TLS in your
const { CredentialsMethod, OpenFgaClient } = require('@openfga/sdk'); // OR import { CredentialsMethod, OpenFgaClient } from '@openfga/sdk';

const openFga = new OpenFgaClient({
apiScheme: process.env.FGA_API_SCHEME, // optional. Can be "http" or "https". Defaults to "https"
apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID, // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorizationModelId: process.env.FGA_MODEL_ID, // optional, can be overridden per request
credentials: {
Expand All @@ -187,8 +183,7 @@ import (

func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional. Can be "http" or "https". Defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, can be overridden per request
Credentials: &credentials.Credentials{
Expand Down Expand Up @@ -252,10 +247,9 @@ async def main():
)
)
configuration = openfga_sdk.ClientConfiguration(
api_scheme = os.environ.get('FGA_API_SCHEME'), # optional. Can be "http" or "https". Defaults to "https"
api_host = os.environ.get('FGA_API_HOST'), # required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example
store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # optional, can be overridden per request
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request
credentials = credentials,
)

Expand Down Expand Up @@ -316,8 +310,7 @@ The OpenFGA server does not support the client credentials flow, however if you
const { CredentialsMethod, OpenFgaClient } = require('@openfga/sdk'); // OR import { CredentialsMethod, OpenFgaClient } from '@openfga/sdk';

const openFga = new OpenFgaClient({
apiScheme: process.env.FGA_API_SCHEME, // optional. Can be "http" or "https". Defaults to "https"
apiHost: process.env.FGA_API_HOST, // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID, // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorizationModelId: process.env.FGA_MODEL_ID, // optional, can be overridden per request
credentials: {
Expand Down Expand Up @@ -345,8 +338,7 @@ import (

func main() {
fgaClient, err := NewSdkClient(&ClientConfiguration{
ApiScheme: os.Getenv("FGA_API_SCHEME"), // optional. Can be "http" or "https". Defaults to "https"
ApiHost: os.Getenv("FGA_API_HOST"), // required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // optional, can be overridden per request
Credentials: &credentials.Credentials{
Expand Down Expand Up @@ -419,10 +411,9 @@ async def main():
)
)
configuration = openfga_sdk.ClientConfiguration(
api_scheme = os.environ.get('FGA_API_SCHEME'), # optional. Can be "http" or "https". Defaults to "https"
api_host = os.environ.get('FGA_API_HOST'), # required, define without the scheme (e.g. api.fga.example instead of https://api.fga.example)
api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example
store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # optional, can be overridden per request
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request
credentials = credentials,
)

Expand Down
8 changes: 3 additions & 5 deletions docs/content/modeling/token-claims-contextual-tuples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,12 @@ import {

Contextual Tuples allow authorization checks that depend on dynamic or contextual relationships that have not been written to the <ProductName format={ProductNameFormat.ShortForm}/> store, enabling some Attribute Based Access Control (ABAC) use cases.

To enable more ABAC use-cases that rely on specific attributes and conditions, you can also use {ProductNameFormat.ShortForm}/>`s [conditions](./conditions.mdx).
To enable more ABAC use-cases that rely on specific attributes and conditions, you can also use <ProductName format={ProductNameFormat.ShortForm}/>`s [conditions](./conditions.mdx).

## Before You Start

To follow this guide, familiarize yourself with the following <ProductConcept />:

### <ProductName format={ProductNameFormat.ShortForm}/> Concepts

- A <ProductConcept section="what-is-a-relation" linkName="Relation" />: is a string defined in the type definition of an authorization model that defines the possibility of a relationship between an object of the same type as the type definition and a user in the system.
- A <ProductConcept section="what-is-a-check-request" linkName="Check Request" />: is a call to the <ProductName format={ProductNameFormat.ShortForm}/> check endpoint that returns whether the user has a certain relationship with an object.
- A <ProductConcept section="what-is-a-relationship-tuple" linkName="Relationship Tuple" />: a grouping consisting of a user, a relation and an object stored in <ProductName format={ProductNameFormat.ShortForm}/>
Expand All @@ -41,7 +39,7 @@ To follow this guide, familiarize yourself with the following <ProductConcept />

User directories store user information that's accessed when making authorization decisions, like the group the user belongs to, their roles, or their department. The natural way to use those relationships in a Relationship-Based Access Control system like <ProductName format={ProductNameFormat.ShortForm}/> is to create tuples for each relation. However, implementing a synchronization mechanism to keep the user directory data up to date with tuples in the store can be challenging.

When applications implement authentication using an OIDC authorization service, they receive an ID Token or an Access token, with certain claims that can be customized based on the application's needs. Instead of writing tuples to the <ProductName format={ProductNameFormat.ShortForm}/>, you can use Contextual Tuples to make authorization checks, understanding that, if those relationships change while the token has not expired, users will still get access to the resources the content of the token entitled them to.
When applications implement authentication using an OIDC authorization service, they receive an ID Token or an Access token, with certain claims that can be customized based on the application's needs. Instead of writing tuples to the <ProductName format={ProductNameFormat.ShortForm}/>, you can use the content of the token in Contextual Tuples to make authorization checks, understanding that, if those relationships change while the token has not expired, users will still get access to the resources the content of the token entitled them to.

## Example

Expand Down Expand Up @@ -114,7 +112,7 @@ When a group is added as a viewer of a document, the application writes tuples l
}
]} />

The Access Token the application receives has a list of the groups the user belongs to:
Let's assume that the Access Token the application receives has a list of the groups the user belongs to:

```json
{
Expand Down
11 changes: 4 additions & 7 deletions src/components/Docs/SnippetViewer/SdkSetup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,7 @@ ${importSdkStatement(lang, languageMappings)}
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
const fgaClient = new ${languageMappings['js'].apiName}({
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.fga.example instead of https://api.fga.example)
apiUrl: process.env.FGA_API_URL, // required, e.g. https://api.fga.example
storeId: process.env.FGA_STORE_ID,
authorizationModelId: process.env.FGA_MODEL_ID, // Optional, can be overridden per request
});`;
Expand All @@ -61,8 +60,7 @@ const fgaClient = new ${languageMappings['js'].apiName}({
func main() {
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
fgaClient, err := NewSdkClient(&ClientConfiguration{
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.fga.example instead of https://api.fga.example)
ApiUrl: os.Getenv("FGA_API_URL"), // required, e.g. https://api.fga.example
StoreId: os.Getenv("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId: os.Getenv("FGA_MODEL_ID"), // Optional, can be overridden per request
})
Expand All @@ -84,7 +82,7 @@ class Example {
public static async Task Main() {
// Initialize the SDK with no auth - see "How to setup SDK client" for more options
var configuration = new ClientConfiguration() {
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL") ?? "http://localhost:8080", // required, e.g. https://api.fga.example
ApiUrl = Environment.GetEnvironmentVariable("FGA_API_URL"), ?? "http://localhost:8080", // required, e.g. https://api.fga.example
StoreId = Environment.GetEnvironmentVariable("FGA_STORE_ID"), // optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
AuthorizationModelId = Environment.GetEnvironmentVariable("FGA_MODEL_ID"), // Optional, can be overridden per request
};
Expand All @@ -98,8 +96,7 @@ ${importSdkStatement(lang, languageMappings)}
async def main():
configuration = ClientConfiguration(
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.fga.example instead of https://api.fga.example)
api_url = os.environ.get('FGA_API_URL'), # required, e.g. https://api.fga.example
store_id = os.environ.get('FGA_STORE_ID'), # optional, not needed for \`CreateStore\` and \`ListStores\`, required before calling for all other methods
authorization_model_id = os.environ.get('FGA_MODEL_ID'), # Optional, can be overridden per request
)
Expand Down

0 comments on commit c0556ae

Please sign in to comment.