<@U04UQ68083H> My application needs to grant permi...
# ory-copilot
f
@chilly-king-10285 My application needs to grant permissions to a Document to existing users as well as people who are not yet registered. For unregistered users, we only have their email How do I handle permissions in such cases ?
c
A message from kapa.ai
To handle permissions for both registered and unregistered users, you can use Ory Keto and Ory Kratos together. Ory Keto is a tool that allows you to define advanced permission rules, also known as "Access Control Policies". You can use it to authenticate different types of credentials and define who has access to what resources in your application. For example, you can create a permission model where a
Document
class has different types of related users (owners, editors, viewers) and define what actions each type of user can perform on a document. Here is an example of how you can define such permissions in Ory Keto:
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"      class User implements Namespace {}      class Document implements Namespace {     related: {       owners: User[]       editors: User[]       viewers: User[]       parents: Folder[]     }        permits = {       view: (ctx: Context): boolean =>         this.related.viewers.includes(ctx.subject) ||         this.related.editors.includes(ctx.subject) ||         this.related.owners.includes(ctx.subject) ||         this.related.parents.traverse((parent) => parent.permits.view(ctx)),       edit: (ctx: Context): boolean =>         this.related.editors.includes(ctx.subject) ||         this.related.owners.includes(ctx.subject) ||         this.related.parents.traverse((parent) => parent.permits.edit(ctx)),       delete: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.delete(ctx)),       share: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.share(ctx)),     }   }
(Source: [Ory Keto Documentation](https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl)) For unregistered users, you can use Ory Kratos to invite them to your application. The process involves creating a basic user account for the user you want to invite using their email address as the account identifier, triggering account recovery for the user account you created, getting the recovery link from the API response and sending it to the user's email address. The user then performs account recovery which forces them to define new credentials and gets a fully functional account with the credentials they defined. (Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/manage-identities/invite-users)) Remember to follow best practices such as not caching permission checks, performing permission checks in every critical path of the application, using fine-grained permissions, and auditing permissions regularly. (Source: [Ory Keto Documentation](https://www.ory.sh/docs/keto/guides/simple-access-check-guide#best-practices))
f
@chilly-king-10285 I tried the approach you described but when new user is linking their account with social-sign in, the Identity traits are not being updated. For example, fields like name, id_from_provider, etc are empty
c
A message from kapa.ai
When a user is linking their account with a social sign-in provider, the data returned by the provider needs to be mapped to the Identity traits of your project. This is done using a Jsonnet data mapper. If the data returned by the JsonNet data mapper does not validate against the Identity Schema of your project, the user will be redirected to the registration page where they need to update the missing fields. Here is an example of how you can set the identity metadata using a Jsonnet data mapper:
Copy code
jsonnet local claims = std.extVar('claims');      {     identity: {       traits: {         email: claims.email       },       metadata_public: {         discord_username: claims.discord_username,       },       metadata_admin: {         // ...       },     }   }
(Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#set-identity-metadata)) If the social sign-in provider does not return all the data you expect, Ory will ask the user to fill in the missing data. For example, if the user did not agree to share their email address when performing the consent step, they will need to agree to your terms of service and provide their email address. The data provided by the user and the data coming from the OpenID Connect / OAuth2 provider will be merged. This process repeats itself until the Identity's traits are valid against the defined JSON Schema. (Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#fill-in-the-data-gaps)) If you're still having issues, please ensure that your Jsonnet data mapper is correctly mapping the data from the social sign-in provider to the Identity traits of your project. You can find examples of how to create a data mapping for different social sign-in providers in the Ory Kratos documentation. (Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping))
f
@chilly-king-10285 I have the jsonnet mapping and it works when a user registers on their own using social sign-in. The issue I'm seeing is when I create account using admin APIs and user links social sign during recovery
c
A message from kapa.ai
When you create an account using the admin APIs and the user links their account during recovery, the data from the social sign-in provider should still be mapped to the Identity traits of your project using the Jsonnet data mapper. However, if the Identity traits are not being updated, it could be due to the data returned by the social sign-in provider not validating against the Identity Schema of your project. In such a case, the user will be redirected to the registration page where they need to update the missing fields. Here is an example of how you can set the identity metadata using a Jsonnet data mapper:
Copy code
jsonnet local claims = std.extVar('claims');      {     identity: {       traits: {         email: claims.email       },       metadata_public: {         discord_username: claims.discord_username,       },       metadata_admin: {         // ...       },     }   }
(Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#set-identity-metadata)) If the social sign-in provider does not return all the data you expect, Ory will ask the user to fill in the missing data. For example, if the user did not agree to share their email address when performing the consent step, they will need to agree to your terms of service and provide their email address. The data provided by the user and the data coming from the OpenID Connect / OAuth2 provider will be merged. This process repeats itself until the Identity's traits are valid against the defined JSON Schema. (Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping#fill-in-the-data-gaps)) If you're still having issues, please ensure that your Jsonnet data mapper is correctly mapping the data from the social sign-in provider to the Identity traits of your project. You can find examples of how to create a data mapping for different social sign-in providers in the Ory Kratos documentation. (Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/social-signin/data-mapping))
f
@chilly-king-10285 What API should I use to create subjects for which permissions are to be managed ?
c
A message from kapa.ai
In Ory, subjects are typically represented by identities. To create subjects for which permissions are to be managed, you would typically create identities using the Ory Kratos Admin API. However, the specific API endpoint to use for creating identities is not explicitly mentioned in the provided knowledge sources. For more detailed information on how to create identities (subjects) using the Ory Kratos Admin API, you can refer to the [Ory Kratos Admin API documentation](https://www.ory.sh/kratos/docs/reference/api#administrative-api). Once you have created identities, you can then manage their permissions using Ory Keto. You can perform permission checks by calling the check method of the OryPermissions client. The check method takes the subject, permission, and object as parameters and returns a boolean value indicating whether the permission is granted or not ([source](https://www.ory.sh/docs/keto/guides/simple-access-check-guide#synchronous-authorization-flow)). Remember, it's crucial that all permission checks are performed using Ory Permissions. This means that before any action is taken, the required permission should be checked to ensure that the action is allowed.
f
@chilly-king-10285 So, for subjects too we need to define a schema in ory console ?
c
A message from kapa.ai
In Ory, subjects are typically represented by identities. The structure of an identity is defined by an Identity Schema. This schema specifies the types of data the system can store for users, such as their names, email addresses, phone numbers, and birthdays. Through schemas, you can also define additional fields that can be added to user profiles, such as job titles, company names, or locales ([source](https://www.ory.sh/docs/kratos/manage-identities/identity-schema)). So, yes, you would typically define a schema for subjects (identities) in the Ory console. This schema would then be used to validate the identity data when new identities are created. If you use custom Identity Schemas, it can help to keep track of changes ([source](https://www.ory.sh/docs/guides/gitops#identity-schema)). Here's an example of how you can create a custom identity schema in Ory Network: 1. Sign in to Ory Console and select [Identity Schema](https://console.ory.sh/projects/current/identity-schema). 2. Using the dropdown menu, select one of the preset schemas or the empty template as the starting point for your custom schema. 3. Check the Customize Identity Schema box to enable editing of the schema. 4. Adjust the schema to your needs. Add, remove, or adjust traits. 5. Define the name of the custom schema in the Identity Model Schema text box. 6. Click the Update button to save.
Copy code
bash # Encode your schema to Base64 and export it to a variable.   schema=$(cat {path-to-json-with-identity-schema} | base64)      # Update your project's configuration.   ory patch identity-config {your-project-id} \    --replace '/identity/default_schema_id="{unique-schema-id}"' \    --replace '/identity/schemas=[{"id":"{unique-schema-id}","url":"base64://'$schema'"}]'
([source](https://www.ory.sh/docs/identities/model/manage-identity-schema))
f
@chilly-king-10285 are there any examples of Subject schema like documents or folders, etc
c
A message from kapa.ai
In Ory, subjects are typically represented by identities, and the structure of an identity is defined by an Identity Schema. This schema specifies the types of data the system can store for users, such as their names, email addresses, phone numbers, and birthdays. However, the provided knowledge sources do not include specific examples of a Subject schema like documents or folders. The examples provided are more focused on how to define permissions and relationships between subjects (users) and objects (documents, folders) in Ory Keto. Here's an example of how you can define permissions in Ory Keto:
Copy code
typescript import { Namespace, Context } from "@ory/keto-namespace-types"      class User implements Namespace {}      class Document implements Namespace {     related: {       owners: User[]       editors: User[]       viewers: User[]       parents: Folder[]     }        permits = {       view: (ctx: Context): boolean =>         this.related.viewers.includes(ctx.subject) ||         this.related.editors.includes(ctx.subject) ||         this.related.owners.includes(ctx.subject) ||         this.related.parents.traverse((parent) => parent.permits.view(ctx)),       edit: (ctx: Context): boolean =>         this.related.editors.includes(ctx.subject) ||         this.related.owners.includes(ctx.subject) ||         this.related.parents.traverse((parent) => parent.permits.edit(ctx)),       delete: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.delete(ctx)),       share: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.share(ctx)),     }   }      class Folder implements Namespace {     related: {       owners: User[]       editors: User[]       viewers: User[]       parents: Folder[]     }        permits = {       delete: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.delete(ctx)),       share: (ctx: Context): boolean =>         this.related.owners.includes(ctx.subject) || this.related.parents.traverse((parent) => parent.permits.share(ctx)),     }   }
(Source: [Ory Keto Documentation](https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl)) For more detailed examples of Identity Schemas, you can refer to the [Ory Kratos Identity Schema documentation](https://www.ory.sh/kratos/docs/concepts/identity-schema).
f
@chilly-king-10285 What would identity schema be for a subject say Folder which can be identified using path ?
c
A message from kapa.ai
In Ory, an Identity Schema is used to define the structure of an identity, which typically represents a user. However, if you want to represent a non-user entity like a
Folder
as a subject, you could potentially create an Identity Schema for it. Here's an example of how you might define an Identity Schema for a
Folder
subject, identified by a `path`:
Copy code
json {   "$id": "<https://schemas.ory.sh/presets/kratos/quickstart/folder.schema.json>",   "$schema": "<http://json-schema.org/draft-07/schema#>",   "title": "Folder",   "type": "object",   "properties": {     "path": {       "type": "string",       "description": "The path of the folder",       "format": "uri"     }   },   "required": ["path"] }
In this schema,
path
is a required property of type
string
and it should be a valid URI. Please note that this is a hypothetical example. In a typical use case, Ory Kratos is used to manage user identities, and Ory Keto is used to manage permissions for these identities on various resources (like folders). The identities (subjects) are usually users, not resources themselves. For more information on how to define Identity Schemas, you can refer to the [Ory Kratos Identity Schema documentation](https://www.ory.sh/kratos/docs/concepts/identity-schema).
f
@chilly-king-10285 Can a Ory project have multiple identity schema ?
c
A message from kapa.ai
Yes, an Ory project can have multiple Identity Schemas. Each identity can, theoretically, have a different JSON Schema. This can be useful in the following situations: - There is more than one type of identity in the system for example: customers, support, staff. - The system includes both human users and "robots" (sometimes also known as named service accounts). - The system needs to ingest another company's Identity Schema. - The system's Identity Schema changes or grows over time and requires versioning. For example, you might have three types of identities: regular customers, grandfather accounts, and service accounts. Each identity has one JSON schema that defines it: - Customers:
<http://mydomain.com/schemas/v2/customer.schema.json>
- Grandfather Accounts:
<http://mydomain.com/schemas/v1/customer.schema.json>
- Service Accounts:
<http://mydomain.com/schemas/service-account.schema.json>
Ory Identities expects the JSON Schemas in its configuration file:
Copy code
json identity:     # This will be the default JSON Schema. If `schema_id` is empty when creating an identity using the     # Admin API or a user signs up using a selfservice flow, this schema will be used.     #     # This is a required configuration field!     default_schema_id: person        # Optionally define additional schemas here:     schemas:       # When creating an identity that uses this schema, `traits_schema_id: customer` are set for that identity.       - id: customer
(Source: [Ory Kratos Documentation](https://www.ory.sh/docs/kratos/manage-identities/managing-users-identities-metadata#traits))