From 36bc8adf8148752884a0a5915b367d432ec15abf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9s=20Aguiar?= Date: Fri, 23 Feb 2024 14:45:44 -0300 Subject: [PATCH 1/2] chore(docs): Minor fixes on token-claims-contextual-tuples page (#659) --- docs/content/modeling/token-claims-contextual-tuples.mdx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docs/content/modeling/token-claims-contextual-tuples.mdx b/docs/content/modeling/token-claims-contextual-tuples.mdx index b343dd7a4..cc28ed2b3 100644 --- a/docs/content/modeling/token-claims-contextual-tuples.mdx +++ b/docs/content/modeling/token-claims-contextual-tuples.mdx @@ -25,14 +25,12 @@ import { Contextual Tuples allow authorization checks that depend on dynamic or contextual relationships that have not been written to the 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 `s [conditions](./conditions.mdx). ## Before You Start To follow this guide, familiarize yourself with the following : -### Concepts - - A : 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 : is a call to the check endpoint that returns whether the user has a certain relationship with an object. - A : a grouping consisting of a user, a relation and an object stored in @@ -41,7 +39,7 @@ To follow this guide, familiarize yourself with the following 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 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 , 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 , 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 @@ -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 { From eff44f318397a0006ee058e7c3caa6351bf8312d Mon Sep 17 00:00:00 2001 From: Ewan Harris Date: Sat, 24 Feb 2024 02:04:40 +0000 Subject: [PATCH 2/2] chore: replace host/scheme usage with url (#660) --- docs/content/getting-started/create-store.mdx | 13 +++--- docs/content/getting-started/framework.mdx | 6 +-- docs/content/getting-started/install-sdk.mdx | 3 +- .../getting-started/setup-sdk-client.mdx | 41 ++++++++----------- .../Docs/SnippetViewer/SdkSetup.tsx | 11 ++--- 5 files changed, 28 insertions(+), 46 deletions(-) diff --git a/docs/content/getting-started/create-store.mdx b/docs/content/getting-started/create-store.mdx index 6d84f2925..4f20611c5 100644 --- a/docs/content/getting-started/create-store.mdx +++ b/docs/content/getting-started/create-store.mdx @@ -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({ @@ -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 { @@ -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: diff --git a/docs/content/getting-started/framework.mdx b/docs/content/getting-started/framework.mdx index 0b1d6d9c7..bec01e8d2 100644 --- a/docs/content/getting-started/framework.mdx +++ b/docs/content/getting-started/framework.mdx @@ -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({ @@ -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 }) diff --git a/docs/content/getting-started/install-sdk.mdx b/docs/content/getting-started/install-sdk.mdx index dcca4eb4f..c939592b3 100644 --- a/docs/content/getting-started/install-sdk.mdx +++ b/docs/content/getting-started/install-sdk.mdx @@ -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 { diff --git a/docs/content/getting-started/setup-sdk-client.mdx b/docs/content/getting-started/setup-sdk-client.mdx index 404dba76f..52de9720c 100644 --- a/docs/content/getting-started/setup-sdk-client.mdx +++ b/docs/content/getting-started/setup-sdk-client.mdx @@ -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 }); ``` @@ -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 { @@ -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: @@ -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: { @@ -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{ @@ -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, ) @@ -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: { @@ -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{ @@ -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, ) diff --git a/src/components/Docs/SnippetViewer/SdkSetup.tsx b/src/components/Docs/SnippetViewer/SdkSetup.tsx index d04369711..66d654f3b 100644 --- a/src/components/Docs/SnippetViewer/SdkSetup.tsx +++ b/src/components/Docs/SnippetViewer/SdkSetup.tsx @@ -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 });`; @@ -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 }) @@ -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 }; @@ -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 )