<@U04UQ68083H> what's the best way to make sure a ...
# ory-copilot
b
@chilly-king-10285 what's the best way to make sure a user is logged out when their session is ended using React SDK
b
A message from kapa.ai
To ensure a user is properly logged out when their session ends using the Ory React SDK, you should: 1. Check the session status on page load or at key points in your app. Use the Ory SDK’s
toSession()
method to verify if the user has an active session. If the session is invalid or expired, redirect the user to the login page. 2. Provide a logout mechanism that uses the Ory logout flow. Use the
createBrowserLogoutFlow()
method to generate a logout URL, and direct the user to this URL to terminate their session. Here’s a practical example from the Ory documentation:
Copy code
jsx import React, { useEffect, useState } from "react" import { FrontendApi, Configuration, Session, Identity } from "@ory/client"  const basePath = process.env.REACT_APP_ORY_URL || "<http://localhost:4000>" const ory = new FrontendApi(   new Configuration({     basePath,     baseOptions: {       withCredentials: true,     },   }), )  function App() {   const [session, setSession] = useState<Session | undefined>()   const [logoutUrl, setLogoutUrl] = useState<string | undefined>()    useEffect(() => {     ory       .toSession()       .then(({ data }) => {         setSession(data)         ory.createBrowserLogoutFlow().then(({ data }) => {           setLogoutUrl(data.logout_url)         })       })       .catch(() => {         // Redirect to login if session is invalid/expired         window.location.replace(`${basePath}/ui/login`)       })   }, [])    if (!session) {     return <h1>Loading...</h1>   }    return (     <div>       <p>Welcome, {session.identity.traits.email}</p>       <a href={logoutUrl}>Logout</a>     </div>   ) }  export default App
Key points: - The session is checked on load; if invalid, the user is redirected to login. - The logout link uses the Ory-generated logout URL, ensuring the session is properly terminated. This approach ensures that users are logged out both when they explicitly click "Logout" and when their session is no longer valid, providing a secure and seamless experience in your React application [Integrate authentication into React](https://www.ory.sh/docs/getting-started/integrate-auth/react#require-login-to-access-the-app-page).
b
@chilly-king-10285 is it possible to use ory permissions for permissions that are numeric and not boolean? For example, the seat entitlement count of a customer
b
A message from kapa.ai
Ory Permissions (Ory Keto) is designed primarily for boolean permission checks—determining whether a subject has a specific relation or permission on an object (e.g., "Can user X read document Y?"). The permission model and Ory Permission Language (OPL) are built around expressing and evaluating these boolean relationships and rules [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). Numeric entitlements, such as a "seat count" for a customer, are not natively supported as first-class concepts in Ory Permissions. The system does not provide built-in mechanisms to store or evaluate numeric values as part of permission checks. Instead, Ory Permissions expects the application to map its resources and relationships to unique identifiers and to use boolean logic for access control decisions [Create a permission model](https://www.ory.sh/docs/keto/modeling/create-permission-model). If you need to enforce numeric entitlements (like seat counts), you would typically handle this logic in your application layer. For example, you could: - Store the seat count in your application database. - Use Ory Permissions to check if a user is entitled to access a resource (boolean check). - In your application, combine the boolean result from Ory Permissions with your own logic to enforce the numeric limit. In summary, Ory Permissions is not designed for direct numeric permission checks or entitlements, and such logic should be implemented outside of Ory Permissions in your application code.
b
@chilly-king-10285 is there any way to pass additional context besides the user ID in OPL?
b
A message from kapa.ai
Based on the available knowledge sources, Ory Permission Language (OPL) permission functions receive a context object called ctx, which contains the subject (user ID) for which the permission check is conducted. The specification and examples consistently show ctx as having only the subject property (e.g., ctx = { subject: "some_user_id" }) [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). There is no mention in the documentation or examples of passing additional context or arbitrary properties (such as attributes, roles, or environmental data) into OPL permission checks. The OPL is designed to be a non-Turing-complete, TypeScript-like language focused on evaluating relationships and permissions based on the subject and the defined relations between objects and subjects. In summary: I'm sorry, but the knowledge sources do not indicate any way to pass additional context besides the user ID (subject) into OPL permission checks. All context appears to be limited to the subject property in ctx. Any additional logic or context must be handled outside of OPL, in your application code or by mapping attributes to subject IDs [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements) [Subjects](https://www.ory.sh/docs/keto/concepts/subjects).
b
@chilly-king-10285 in opl, is it possible to make decisions based on the permits in a different namespace?
b
A message from kapa.ai
In Ory Permission Language (OPL), it is possible to make permission decisions based on permits in a different namespace, as long as your relationships and permission model are structured to reference those namespaces. For example, you can define a relation in one namespace (e.g., Document) that points to objects in another namespace (e.g., Folder), and then call permissions on those related objects. This is commonly done using the traverse or transitive pattern:
Copy code
typescript class Document implements Namespace {   related: {     parents: Folder[]   }    permits = {     view: (ctx: Context): boolean =>       this.related.parents.traverse((parent) => parent.permits.view(ctx)),   } }
In this example, the Document's view permission checks the view permission on its related Folder(s), which is a different namespace. This pattern is supported and is a core part of how OPL enables hierarchical and cross-namespace permission checks [Define permissions in the OPL](https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl) [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). Summary: Yes, OPL allows you to make permission decisions based on permits in a different namespace by traversing relationships and invoking permissions on related objects in those namespaces.
b
@chilly-king-10285 can you explain the traverse function in opl?
b
A message from kapa.ai
The
traverse
function in Ory Permission Language (OPL) is used to evaluate permissions or relations across related objects, typically in hierarchical or graph-like structures. It allows you to delegate a permission check from one object to its related objects, often in a different namespace. For example, if a
Document
has one or more parent `Folder`s, and you want to allow a user to view the
Document
if they can view any of its parent `Folder`s, you would use
traverse
like this:
Copy code
typescript class Document implements Namespace {   related: {     parents: Folder[]   }    permits = {     view: (ctx: Context): boolean =>       this.related.parents.traverse((parent) => parent.permits.view(ctx)),   } }
In this example,
this.related.parents.traverse((parent) => parent.permits.view(ctx))
checks the
view
permission on each parent
Folder
. If any parent grants the permission, the check returns
true
for the
Document
as well [Define permissions in the OPL](https://www.ory.sh/docs/keto/modeling/create-permission-model#define-permissions-in-the-opl) [OPL Examples](https://www.ory.sh/docs/keto/reference/ory-permission-language#examples). This is especially useful for implementing permission inheritance in hierarchies, such as folders and files, or organizational structures. Summary: The
traverse
function lets you propagate permission checks through related objects, enabling flexible and hierarchical access control models in OPL.
b
@chilly-king-10285 do applications typically have a namespace for every type of permission protected resource? Is there any way to use inheritance to make it cleaner?
b
A message from kapa.ai
Applications using Ory Permissions typically define a namespace for each type of permission-protected resource. In OPL, a namespace is represented as a TypeScript class (e.g.,
User
,
Document
,
Folder
), and each namespace contains the relationships and permissions relevant to that resource type. This approach is shown in multiple examples, such as document stores and RBAC models, where each resource type (like
Document
,
Folder
,
Group
, etc.) has its own namespace [Namespaces](https://www.ory.sh/docs/keto/concepts/namespaces) [Create a permission model](https://www.ory.sh/docs/keto/modeling/create-permission-model). Regarding inheritance: The Ory Permission Language (OPL) does not currently support class inheritance or interface extension in the way that TypeScript or object-oriented languages do. Each namespace (class) is defined independently, and there is no mechanism in OPL to inherit relations or permissions from another namespace to "make it cleaner." All relationships and permissions must be explicitly declared in each namespace [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). Summary: - Yes, applications usually have a namespace for every type of permission-protected resource. - There is no built-in inheritance mechanism in OPL; each namespace must explicitly declare its own relationships and permissions. - You can, however, use patterns like permission delegation (e.g., using
traverse
) to reduce duplication in permission logic, but not in the structure of the namespace definitions themselves.
b
@chilly-king-10285 is this valid? class FeatureResource implements Namespace { related: { features: Feature[] } permits = { active: (ctx: Context): boolean => this.features.active(ctx.subject) } } class ConditionTemplate extends FeatureResource Feature:mvkgsma is features of ConditionTemplate:elevated_taxi_times
b
A message from kapa.ai
Based on the Ory Permission Language (OPL) specification and examples in the knowledge sources, the code you provided is not valid OPL for the following reasons: 1. Inheritance is not supported: OPL does not support class inheritance or extension (e.g.,
class ConditionTemplate extends FeatureResource
). Each namespace must be defined independently, and there is no mechanism to inherit relations or permissions from another namespace [Ory Permission Language specification](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). 2. Accessing relations and permissions: In OPL, you must access relations and permissions through the
this.related
and
this.permits
properties. For example, to check a permission on related features, you would use something like:
Copy code
typescript    this.related.features.traverse((feature) => feature.permits.active(ctx))
Directly calling
this.features.active(ctx.subject)
is not valid OPL syntax. 3. Relation declaration syntax: Relations must be declared inside the
related
property, and permissions inside the
permits
property, both within the class definition. The syntax must follow the OPL rules [OPL Statements](https://www.ory.sh/docs/keto/reference/ory-permission-language#statements). A corrected OPL example (without inheritance) might look like:
Copy code
typescript class Feature implements Namespace {   permits = {     active: (ctx: Context): boolean => {       // logic for active permission     }   } }  class ConditionTemplate implements Namespace {   related: {     features: Feature[]   }   permits = {     active: (ctx: Context): boolean =>       this.related.features.traverse((feature) => feature.permits.active(ctx))   } }
Summary: - OPL does not support class inheritance (
extends
). - You must use
this.related
and
traverse
to check permissions on related objects. - Each namespace must be defined independently. If you need to share permission logic, you must duplicate it in each namespace or use permission delegation patterns, but not inheritance [Namespaces](https://www.ory.sh/docs/keto/concepts/namespaces) [OPL Examples](https://www.ory.sh/docs/keto/reference/ory-permission-language#examples).
b
@chilly-king-10285 given the following permission model, how can I query for all the FeatureResources a given customer has read access to? Either with CLI or go SDK
Copy code
import { Namespace, SubjectSet, Context } from "@ory/keto-namespace-types";

class User implements Namespace { }

class Customer implements Namespace {
  related: {
    members: (User | Customer)[];
  };
}

// An Application to grant permissions to
class Application implements Namespace {
  related: {
    // Users or Customers that can use this Application
    users: (User | SubjectSet<Customer, "members">)[];
    // Application-level admins
    superadmins: User[];
  };

  permits = {
    use: (ctx: Context): boolean => this.related.users.includes(ctx.subject),
    superadmin: (ctx: Context): boolean => this.related.superadmins.includes(ctx.subject),
  };
}

class Package implements Namespace {
  related: {
    // Users or customers entitled for this package (and all the features it contains)
    // We can also add a package to another package to enable package "inheritance"
    entitled: (User | SubjectSet<Customer, "members"> | SubjectSet<Package, "entitled">)[];
  };

  permits = {
    entitled: (ctx: Context): boolean => this.related.entitled.includes(ctx.subject),
  };
}

class Feature implements Namespace {
  related: {
    // Users, customers, or package subscribers entitled for this Feature
    entitled: (User | SubjectSet<Customer, "members"> | SubjectSet<Package, "entitled"> | SubjectSet<Application, "users">)[];
    // Feature flag is enabled for these users - could be by role in the future
    enabled: (User | SubjectSet<Customer, "members"> | SubjectSet<Application, "users">)[];
    // For now only superadmins can edit features. This will probably change once roles are implemented
    editors: (SubjectSet<Application, "superadmins">)[];
  };
  permits = {
    entitled: (ctx: Context): boolean => this.related.entitled.includes(ctx.subject),
    enabled: (ctx: Context): boolean => this.related.enabled.includes(ctx.subject),
    // Feature flag is enabled AND feature is entitled
    active: (ctx: Context): boolean => this.permits.enabled(ctx) && this.permits.entitled(ctx),
    edit: (ctx: Context): boolean => this.related.editors.includes(ctx.subject),
  };
}

// A resource that belongs to a specific feature
// could potentially be more specific in the future
class FeatureResource implements Namespace {
  related: {
    features: Feature[]
  }
  permits = {
    read: (ctx: Context): boolean => this.related.features.traverse((parent) => parent.permits.active(ctx)),
  }
}
b
A message from kapa.ai
Given your permission model, to query for all the
FeatureResource
objects a given customer has
read
access to, you need to use Ory Keto's List API to find all
FeatureResource
objects where the customer is entitled to the underlying
Feature
(i.e., where the
read
permission is granted). ### Using the Keto CLI You can use the CLI to list all
FeatureResource
objects a customer has
read
access to by querying for relation tuples where: -
namespace
is
FeatureResource
-
relation
is
read
-
subject
is your customer (e.g.,
customers:customer-id
) The CLI command would look like:
Copy code
sh keto relation-tuple get --namespace FeatureResource --relation read --subject-id customers:customer-id --format json --read-remote <keto-read-api-url>
This will return all
FeatureResource
objects for which the given customer has the
read
permission, resolving all the permission logic (including traversing to the
Feature
and checking
active
) as defined in your OPL model [Display all objects a user has access to](https://www.ory.sh/docs/keto/guides/list-api-display-objects) [RBAC: Display all objects a user has access to](https://www.ory.sh/docs/keto/guides/rbac#display-all-objects-a-user-has-access-to). ### Using the Go SDK With the Go SDK, you would use the
ListRelationTuples
API to perform the same query. Here’s a simplified example:
Copy code
go import (     "context"     "fmt"     keto "<http://github.com/ory/keto-client-go|github.com/ory/keto-client-go>" )  func main() {     configuration := keto.NewConfiguration()     configuration.Servers = []keto.ServerConfiguration{         {URL: "<http://127.0.0.1:4466>"}, // Replace with your Keto read API URL     }     client := keto.NewAPIClient(configuration)      namespace := "FeatureResource"     relation := "read"     subjectId := "customers:customer-id" // Replace with your customer ID      resp, _, err := client.RelationTupleApi.GetRelationTuples(context.Background()).         Namespace(namespace).         Relation(relation).         SubjectId(subjectId).         Execute()     if err != nil {         panic(err)     }      for _, tuple := range resp.RelationTuples {         fmt.Printf("Customer has read access to FeatureResource: %s\n", tuple.Object)     } }
This will list all
FeatureResource
objects the customer can read, according to your permission model [Go SDK example](https://www.ory.sh/docs/keto/self-hosted/go). --- Note: - The permission logic (including traversing from
FeatureResource
to
Feature
and checking
active
) is handled by Keto according to your OPL model. You do not need to manually resolve the permission tree; just query for the
read
relation as shown above. - If you use subject sets (e.g.,
SubjectSet<Customer, "members">
), Keto will resolve those as part of the permission check. If you need to list all objects a user (or customer) has access to, this is the recommended approach in Ory Keto [List API: display all objects a user has access to](https://www.ory.sh/docs/keto/guides/list-api-display-objects).
b
@chilly-king-10285 can you do this with the ory cli?
Copy code
keto expand access files /photos/beach.jpg --format json-pretty --max-depth 3 --insecure-disable-transport-security
b
A message from kapa.ai
Yes, you can use the Ory Keto CLI to expand a subject set and see who has access to a specific object using a command like:
Copy code
sh keto expand access files /photos/beach.jpg --format json-pretty --max-depth 3 --insecure-disable-transport-security
This command is valid and will output the expansion tree for the
access
relation on the object
/photos/beach.jpg
in the
files
namespace, showing all subjects who have access, up to a depth of 3. The
--insecure-disable-transport-security
flag is required if you are running Keto without TLS, as noted in the documentation [Expand API: display who has access to an object](https://www.ory.sh/docs/keto/guides/expand-api-display-who-has-access#example) [keto expand](https://www.ory.sh/docs/keto/cli/keto-expand#keto-expand). You can also specify the output format (e.g.,
json-pretty
) and the maximum depth of the expansion tree with
--max-depth
. Summary: The command you provided is correct for expanding and visualizing access permissions using the Ory Keto CLI.
b
@chilly-king-10285 can you do this with the ory cli when using ory network?
Copy code
keto expand access files /photos/beach.jpg --format json-pretty --max-depth 3 --insecure-disable-transport-security
b
A message from kapa.ai
When using Ory Network, the CLI commands differ from the self-hosted Keto CLI commands. The
keto expand
command is specific to self-hosted Ory Keto and is not available in the Ory CLI for Ory Network. The Ory CLI provides its own set of commands for interacting with Ory Network resources, and there is no documentation indicating that you can use
keto expand
or an equivalent expand command directly with Ory Network via the Ory CLI. The knowledge sources do not mention support for the
keto expand
command or an equivalent in the Ory CLI when connected to Ory Network. Therefore, you cannot use the
keto expand
command with Ory Network using the Ory CLI
 [ory CLI reference](https://www.ory.sh/docs/cli/ory) [keto expand reference](https://www.ory.sh/docs/keto/cli/keto-expand#keto-expand). If you need to perform similar operations in Ory Network, you would need to use the available Ory CLI commands or APIs specific to Ory Network, but the expand functionality as described for self-hosted Keto is not documented for Ory Network.