Code Monkey home page Code Monkey logo

permify's Introduction

Permify logo
Permify - Open Source Authorization Service

Permify Go Version  Permify Go Report Card  Permify Licence  Permify Discord Channel  Permify Release  Permify Commit Activity  GitHub Workflow Status  Scrutinizer code quality (GitHub/Bitbucket)  Coveralls

Permify - Open source authorization as a service

Join Our Team

Permify is on the lookout for engineers eager to tackle challenges in authorization. Join us!

We are hiring 

What is Permify?

Permify is a open-source authorization service for creating and managing fine-grained permissions in your applications and services. Inspired by Google’s consistent, global authorization system, Google Zanzibar

Our goal is to make Google's Zanzibar available to everyone and help them build robust, flexible, and easily auditable authorization systems that perform well in scaled environments.

With Permify, you can:

🔮 Create permissions and policies using Permify's flexible authorization language that is compatible with traditional roles and permissions (RBAC), arbitrary relations between users and objects (ReBAC), and attributes (ABAC).

🔐 Manage and store authorization data in your preferred database with high availability and consistency.

Interact with the Permify API to perform access checks, filter your resources with specific permissions, perform bulk permission checks for various resources, and more.

🧪 Test your authorization logic with Permify's schema testing. You can conduct scenario-based testing, policy coverage analysis, and IDL parser integration to achieve end-to-end validations for your desired authorization schema.

⚙️ Create custom and isolated authorization models for different applications using Permify Multi-Tenancy support, all managed within a single place, Permify instance.

Getting Started

QuickStart

You can quickly start Permify on your local with running the docker command below:

docker run -p 3476:3476 -p 3478:3478  ghcr.io/permify/permify serve

This will start Permify with the default configuration options:

  • Port 3476 is used to serve the REST API.
  • Port 3478 is used to serve the GRPC Service.
  • Authorization data stored in memory.

See all of the options that you can use to set up and deploy Permify in your servers.

Test your connection

You can test your connection with creating an GET request,

localhost:3476/healthz

Community ♥️

We would love to hear from you!

Get the latest product updates, receive immediate assistance from our team members, and feel free to ask any questions about Permify or authorization in a broader context by joining our conversation on Discord!

Join Our Discord 

Contributing

The open source community thrives on contributions, offering an incredible space for learning, inspiration, and creation. Your contributions are immensely valued and appreciated!

Here are the ways to contribute to Permify:

  • Contribute to codebase: We're collaboratively working with our community to make Permify the best it can be! You can develop new features, fix existing issues or make third-party integrations/packages.
  • Improve documentation: Alongside our codebase, documentation one of the most significant part in our open-source journey. We're trying to give the best DX possible to explain ourselves and Permify. And you can help on that with importing resources or adding new ones.
  • Contribute to playground: Permify playground allows you to visualize and test your authorization logic. You can contribute to our playground by improving its user interface, fixing glitches, or adding new features.

Bounties

Open Bounties

We have a list of issues where you can contribute and gain bounty award! Bounties will be awarded for fixing issues via accepted Pull Requests (PR).

Before start please see our contributing guide.

Roadmap

You can find Permify's Public Roadmap here!

Contributors ♥️

Communication Channels

If you like Permify, please consider giving us a ⭐

permify | Discord permify | Twitter permify | Linkedin

permify's People

Contributors

ahmadkashif avatar ahmethakanbesel avatar anascann avatar berkeli avatar brandensilva avatar dependabot[bot] avatar egeaytin avatar filipenko-sennder avatar firatcand avatar gozeloglu avatar hungaikev avatar junwen-k avatar jwetzell avatar meesvandongen avatar mfridman avatar mohanish2504 avatar muratmirgun avatar neo773 avatar nitish-muddhey avatar obakeng-develops avatar phoenix24 avatar rimon-fedyuk avatar saifxd7 avatar sevkioruc avatar snyk-bot avatar step-security-bot avatar thecaffeinedev avatar thegeekywanderer avatar thilakreddyy avatar tolgaozen 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  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  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  avatar  avatar  avatar  avatar  avatar

permify's Issues

SchemaWrite Request gives TenantId value length error

When trying below following request with pasting the the schema directly in from the playground,

const client = new permify.grpc.newClient({
  endpoint: 'localhost:3478',
})

export const schemaWrite = async () => {
  try {
    const response = await client.schema.write({
      tenantId: 't1',
      schema: `"entity user {}\n        \nentity group {\n    relation member @user\n    \n}"`,
    })

    if (response) {
      console.log('response', response)
    }
  } catch (err) {
    console.log('err', err)
  }
}

schemaWrite()

It gives this following tenantıd value length error: "TenantId: value length must be at most 64 bytes"

err ClientError: /base.v1.Schema/Write INVALID_ARGUMENT: invalid SchemaWriteRequest.TenantId: value length must be at most 64 bytes
    at wrapClientError (/Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/[email protected]/node_modules/nice-grpc/lib/client/wrapClientError.js:9:16)
    at Object.callback (/Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/[email protected]/node_modules/nice-grpc/lib/client/createUnaryMethod.js:27:66)
    at Object.onReceiveStatus (/Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/@[email protected]/node_modules/@grpc/grpc-js/build/src/client.js:192:36)
    at Object.onReceiveStatus (/Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/@[email protected]/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:360:141)
    at Object.onReceiveStatus (/Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/@[email protected]/node_modules/@grpc/grpc-js/build/src/client-interceptors.js:323:181)
    at /Users/brandensilva/projects/nextjs/nexthub/node_modules/.pnpm/@[email protected]/node_modules/@grpc/grpc-js/build/src/resolving-call.js:94:78
    at processTicksAndRejections (node:internal/process/task_queues:78:11) {
  path: '/base.v1.Schema/Write',
  code: 3,
  details: 'invalid SchemaWriteRequest.TenantId: value length must be at most 64 bytes'

In Memory Cache Support

In memory cache support for getting access control decisions without visiting Authorization database (WriteDb). Cache responsible for storing namespace configs - Permify Schema.

Migration Command

Issue Summary:

The purpose of this issue is to request the addition of a new migrate command to our application's CLI. The migrate command should use the Goose library to apply database migrations, and should be implemented using the Cobra library. The command should include flags for specifying the database engine and database URI.

Expected Behavior:

The migrate command should have the following behavior:

  • It should accept a direction flag to specify whether to apply migrations (up), rollback migrations (down), or check the status of migrations (status).
  • It should accept a target flag to specify the target version for the migration.
  • It should accept an database_engine flag to specify the database engine (e.g. postgres).
  • It should accept a database_uri flag to specify the URI of the database to apply the migration to.
  • It should use the Goose library to apply the appropriate migration command based on the direction flag, using the specified database engine and database URI.
  • It should output success or failure messages for the migration command.

Permify currently uses the Cobra library to implement its CLI. We believe that adding a migrate command to the CLI would make it easier for developers to manage database migrations, and would ensure that all developers are using a consistent migration tool.

We would like the implementation of the migrate command to be consistent with the rest of the application's CLI, and to follow best practices for CLI design and implementation.

Potential Solution:

We suggest implementing the migrate command using the Cobra library, with the following structure:

$ permify migrate up --target=<version> --database-engine=<engine> --database-uri=<database_uri>
$ permify migrate down --target=<version> --engine=<engine> --database-uri=<database_uri>
$ permify migrate status --database-engine=<engine> --database-uri=<database_uri>

This structure should be familiar to developers who are already using the application's CLI, and should make it easy to manage database migrations.

The implementation of the migrate command should use the Goose library to apply the appropriate migration command based on the direction flag, using the specified database engine and database URI. The implementation should also provide informative success or failure messages for the migration command.

We can discuss the specific details of the implementation in the comments of this issue.

Note:
migration files are in the internal/repositories/postgres/migrations directory

Playground Graph Relation Bug on Visualizer

Graph relation bug on Permify Playground Visualizer, according to the model below the edit relations parent.admin and owner on the Visualizer should be connected with or not and

entity user {}
        
entity organization {

    // organizational roles
    relation admin @user
    relation member @user
    
}

entity repository {

    // represents repositories parent organization
    relation parent @organization
    
    // represents owner of this repository
    relation owner  @user
    
    // permissions
    action edit   = parent.admin or owner
    action delete = owner
    
} 

Screen Shot 2022-12-10 at 13 19 20

Deeply Tracing With Open Telemetry

Problem:
Users need better tracing and data analysis on the Permify.

Specifications:
Users should be able to trace the performance in every function of the application via Open Telemetry. Currently users can only trace request on high level; as example we trace check requests performance as below:

func (r *PermissionServer) Check(ctx context.Context, request *v1.PermissionCheckRequest) (*v1.PermissionCheckResponse, error) {

	ctx, span := tracer.Start(ctx, "permissions.check")
	defer span.End()

	..
        ..
        ..
}

The workflow is, above server/check function calls to services/check function, then calls commands/check etc . We want users to trace every point in a single process of coming requests, not just the function on the highest level.

CDC

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Reactive authourisation such that a change causes all micro services to see the altered authz rules .

Describe the solution you'd like
A clear and concise description of what you want to happen.

see above …

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context or screenshots about the feature request here.

I saw an issue relating to cdc

Would be nice if SQLite and postresql are supported

in terms of scoping I don’t know. A microservice subscribes for changes but how to scope ? Maybe tags .. not sure

[BUG] "NOT" usecase is not working

I have tried the below usecase in permify playground. but the below check is not working as expected.
Schema:
entity user {}
entity organization {
relation member @user
}
entity parent{
relation member @user
}
entity repo {
relation org @organization
relation parent @parent

action push =  **org.member and not parent.member**

}
Data:
user:1 is member of organization:1
user:2 is member of organization:1
user:1 is member of parent:1
organization:1 is org of repo:1
parent:1 is parent of repo:1

Permission check:
testcase1: can user:2 push repo:1
testcase2 :can user:1 push repo:1

testcase1 produces "false" even though its supposed to return "true"

Add testing relation tuples functionality

Functionality for testing and validating Permify Schema model with sample relational tuples. With this feature user can create and send sample relational tuples and authorization model (Permify Schema file) to an API endpoint (If its build as API endpoint) to examine model/relational tuples fit.

Note: Planing to move this feature to Permify Playground where the user can write tuples and models and test directly from there.

Powerful get all SQL filtering

Is your feature request related to a problem? Please describe.

Current version of version enables resource authorisation management based on resource ID. This is perfectly fine for API requests having ID like a Get, Add, Edit, Delete. However, it's more difficult for a kind of "get all" API query. In that case, you don't know resource IDs before fetching them from DB.

Describe the solution you'd like

First (bad) solution would be to request DB without any authz check and then run post filtering with returned IDs and using Permify API. This solution can be really slow and doesn't scale.
Second (bad) solution would be to use a kind of SQL WHERE IN operator requesting Permify API first to get all IDs. However, it can be incompatible with pagination (cursor or page based). Moreover, if you also need search, filter or ordering on a data column, you will end up with a post SQL query filtering, resulting in poor performance.
IMHO, the best solution is to filter SQL query based on Permify data. https://blog.openpolicyagent.org/write-policy-in-opa-enforce-policy-in-sql-d9d24db93bf4. For example, I believe JSONB column could be used for each row in database and SELECT * query can be filtered using Permify output to get only data a user has access to. It's not necessary data he is owner, it can be a shared data so we cannot just used a kind of "owner" column.

Describe alternatives you've considered

First or second solution but it can't scale.

Additional context
Add any other context or screenshots about the feature request here.

Documentation request:

Permify is very cool! Do you have a comparison with other Zanzibar OSS Go projects like:

SpiceDB did a blog post talking about having multiple data backends including Postgres and CockroachDB for durable storage, and an in-memory datastore for testing and development.

It looks like Permify does not yet support bounded staleness (Zookies).

I know Keto was originally a very different project that has been rewritten to be Zanzibar-like. It is missing some core Zanzibar functionality: horizontally scalable, bounded staleness (Zookies), and userset rewrites, for example.

Adding new keyword to DSL to make permission inheritance easier

Let's elaborate this with an example; lets say we have relation of team in repository ( team is parent of repository). Now i want to give edit access to org.admin. Org is parent of project, project is parent of team. I want to maintain that access should be given to org.admin whose org is parent of a project whose child is the team of repository.

This can be achievable with giving action reference to actions. In this scenario, repository edit action looks and depends on team action which depends project and project also depends the rule org.admin.

entity user {}

entity organization {
    relation admin @user
    relation member @user
}
entity project {
    relation org @organization
    action edit = org.admin
}
entity team {
    relation project @project
    action edit = project.edit
}
entity repository {
    relation team @team
    action edit = team.edit
}

Although this solves the problem, defining action to inherit parent permission decreases readability (especially when nested hierarchies goes deeper) and giving to much power to the action keyword. For this specific nested hierarchies case, creating new keyword can be solve this.

Consistent Hashing with Hash Ring for Scalable Access Checks.

Is your feature request related to a problem? Please describe.

A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like

The idea is to build scalable access checks through an in-memory caching mechanism by creating a mapping for the right data within the Permify instance in memory by using Consistent Hashing with Hash Ring.

Consistent Hashing is a distributed hashing scheme that operates independently of the number of objects in a distributed hash table.

Additional context

https://itnext.io/introducing-consistent-hashing-9a289769052e

User set validation on Permify Schema

Validating user sets when creating relation with DLS on Permify Schema. Keyword must be placed to use relation lock on Permify Schema.

Example Usage

entity user {}

entity organization {
    relation member @repository#member
}

entity repository {
    relation    member    @user
}

member can only be a repository member.

Change PostgreSQL CDC way to transaction logs

Transaction Logs

On the other hand, for modern DBMS, transaction logs (WAL for PostgreSQL) are commonly used for transaction logging and replication.

In PostgreSQL, all transactions like INSERT, UPDATE, DELETE are written to the WAL before a client receives a transaction result.

  • The advantage of this approach is that it does not affect the performance of the database in any way.
  • It also requires no modification to DB tables or the application. There is no need to create additional tables in the source database.
  • Log-based CDC is generally considered the superior approach to change data capture applicable to all possible scenarios, including systems with extremely high transaction volumes.

PostgresWAL drawio-1

source: https://dbconvert.com/blog/postgresql-change-data-capture-cdc/

Expand API

Expand API is represented by a userset tree whose leaf nodes are user IDs or usersets pointing to other ⟨object#relation⟩ pairs, and intermediate nodes represent union, intersection, or exclusion operators.

Expand is crucial for our clients to reason about the com- plete set of users and groups that have access to their ob- jects, which allows them to build efficient search indices for access-controlled content. Unlike the Read API, Expand follows indirect references expressed through userset rewrite rules.

Use Actions in Reference

Problem:
Creating hierarchy need to be improved, at the moment users can only create a long state of ors & ands. So users should be able to create relation hierarchies without creating a long list of relations

Specifications:

  • Users will be able to use actions and parents’ actions as a reference to actions.

Zookie Support

Support for Google Zanzibar's Zookie. To prevent casual ordering problem on relational tuples modification or content updates (New Enemy Problem), which causing false negative or false positive decision results on authorization checks, a token needed to be developed to get a snapshot of the permissions as evaluated at a single point in time. This token called Zookie on Google Zanzibar paper.

Zookie token can be used in two scenarios:

  1. On relational tuple or permify schema update, a snapshot timestamp ( Zookie ) needed to be send via request to ensure that all prior updates have lower timestamp.

  2. On checking access decisions, sending check access API call with Zookie token ensures getting a fresh decision response, or a response that only belongs a filtered time frame, which user specifies on purpose.

Team/Workspace management using Permify

Is your feature request related to a problem? Please describe.
I am developing few SaaS applications but facing challenge to implementing RBAC and ABAC in the application from scratch. Is it possible to provide some API's which can be integrated into any existing SaaS application. This feature is very much required when someone is building SaaS application for agencies or company with multiple teams. When I talked with some of the marketing agencies who are providing services to large B2B companies they wanted SaaS application to have such features in it. And as a indiehacker or team with small size cannot offer such solution unless they start implementing it from scratch. So having some APIs which can provide such functionality would be great. Please check below SaaS applications for reference.

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
Did not find anyone offering this solution.

Additional context
Examples:

SaaS application in which admin can create workspaces or projects or teams and can manage i.e add/remove participants in it.
You see these applications for reference:

  1. https://www.oneupapp.io/price --> Pricing includes team and team management for higher plans or enterprise plan
  2. https://www.cloudcampaign.com/plans ---> Pricing includes workspace management and unlimited users/teams etc

Add ASP.NET Core client SDK

Is your feature request related to a problem? Please describe.
The Permify service currently lacks an ASP .NET Core client SDK implementation

Describe the solution you'd like
A dependency injection based C# implementaion of the Permify SDK client (just like permify-node)

Describe alternatives you've considered
None, this is just an addition to the currently supported (and planned) client SDK languages (currently Node and Golang)

Additional context
I've already started a basic implementation of this client SDK at Permify.AspNetCore.
It is obviously pretty barebone right now, but I'd like to keep developing it in order to make it a fully-fledged client SDK implementation

Adding modeling gif to the docs

Adding the modeling gif/video to the "docs/getting-started/modeling" section between the main title and secondary title: "Permify Schema"

Video:
modeling-gif

Position of the video that need to be added:
Screen Shot 2022-12-23 at 14 23 51

gRPC support

gRPC communication protocol option for API calls.

Subject filtering according to entity

Getting all the users and their permissions to a specific resource?

Example:
in organization:1
user:1 is owner
user:2 is member
user:3 is member

I would like something like this:
Request: which users have access to organization:1
Response: [ "user:1#owner", "user:2#member", "user:3#member" ]

PostgreSQL custom configuration for connection options

Some of default database configurations needed to be customizable. These options are:

  • Minimum Open Connections
  • Max Connection Lifetime
  • Max Connection Idle Time
  • Health Check Period

Currently database options can be configured with using the "database" field on yaml configuration file or using flag options via permify CLI. So this options needed to be available both on configuration file and as well as flags.

We already have some customizable options available; "Max Open Connections" and "Connection Timeout". The development process above configurations similar to the development of these options.

All of the configurations can be defined and arranged in the "pkg/database/postgres" folder, which consists:

- consts.go file which have default values for configuration as below:

package postgres

import (
	"time"
)

const (
	_defaultMaxOpenConnections    = 20
	_defaultMinOpenConnections    = 1
	_defaultMaxConnectionLifetime = time.Hour
	_defaultMaxConnectionIdleTime = time.Minute * 30
	_defaultConnectionTimeout     = time.Second
	_defaultHealthCheckPeriod     = time.Minute
)

- options.go file, which only have code for configuration options "Max Open Connections" and "Connection Timeout"
- postgres.go file, which responsible for creating connection with respected configuration options.

Github Actions (CI)

Problem:
Users need to integrate Permify into the existing workflow.

Specifications:
Build action as a repo.

  • Users can add this repo to their projects.
  • This Repo will be for Schema validation and testing.
  • Users will be able to find these GitHub actions from ReadMe and Documents.
    • Deploy with CI/CD
  • GitHub action will recommend how to add your workflow.

Wildcard support for relationships

Based on this schema:

entity user {}

entity course {
    relation owner @user
    relation member @user
    action read = owner or member
    action write = owner
}

entity program {
    relation owner @user
    relation member @user
    action read = owner or member
    action write = owner
}

We can have:
For alice user:

  1. course:1#owner@user:alice
  2. course:2#member@user:alice

For alex user:

  1. program:1#owner@user:alex
  2. program:2#member@user:alex

Question:
How can I have a admin user who will be able to manage all resources?
This would be an application and not resource level permission. I only want to set/check if the user has a role (admin), without having to add a permission to each resource type as below:
course:#owner@user:admin and program:#owner@user:admin

Read API

This API endpoint aims to display and filter relational tuples that stored in WriteDB. API endpoint is "v1/relationship/read". Here is a example request and response,

Request:

“filter” : {
        “entity”: “organization”, //mandatory
        “id”: “1”
}

Example Response:

[
        {
            “entity”: {
                “type”: “organization”,
                “id”: “1”
            },
            “relation”: “member”,
            “subject”: {
                “type”: “user”,
                “id”: “1"
            }
        },
        {
            “entity”: {
                “type”: “organization”,
                “id”: “1”
            },
            “relation”: “admin”,
            “subject”: {
                “type”: “user”,
                “id”: “1"
            }
        }
    ]

Response (as Relational Tuples):
organization:1#admin@user:1
organization:1#member@user:1

Exclusion Support

Improvement on Permify Schema about not including (excluding) a relation in access decision. Additional to or and and operators that used to define actions of an entity, Permify now supports and or and *or and operators to define relations that don't have access to the action it defined.

For example, excluded operator and not used to exclude (no access) member on create action below.

entity campaign {

    relation member @user
    relation org @organization

    action create = org.admin and not member

} 

"nil pointer dereference" error when metadata is null

Metadata must be required for all requests.

Now:
Screen Shot 2022-12-22 at 22 09 37

Must be:
Screen Shot 2022-12-22 at 22 10 07

File Path

  • proto/base/v1/service.proto

Requests that need to be change

  • PermissionCheckRequest
  • PermissionExpandRequest
  • PermissionLookupSchemaRequest
  • PermissionLookupEntityRequest
  • SchemaReadRequest
  • RelationshipWriteRequest
  • RelationshipReadRequest

Database reconnection

Problem:
User should be able connect Permify automatically if database shuts down while Permify running.

Specifications:

  • The user shouldn’t be able to restart Permify, when connected to the database.
  • It should work with PostgreSQL (for now)

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.