casbin / casbin-server Goto Github PK
View Code? Open in Web Editor NEWCasbin as a Service (CaaS)
Home Page: https://casbin.org/docs/service
License: Apache License 2.0
Casbin as a Service (CaaS)
Home Page: https://casbin.org/docs/service
License: Apache License 2.0
Hi All, I'm trying to run casbin-server in docker-compose along with a postgresql database based on the instructions here. I'm mounting a volume with the connection config json file and the model configuration files in the casbin-server container and setting up the environment variable ( to point to the config file. The casbin-server container logs says that it is Listening on 50051. I have mapped the local port 5005 to the port 50051 of the container. But I'm getting the error ERR_INVALID_HTTP_RESPONSE
when trying to load the URL. I verified that I can connect to the database from the casbin-server container. I also tried running curl inside the casbin-server container on the port 50051, but I get a Connection reset by peer
error.
What might be the issue here? Can you provide some guidance on the running casbin-server in docker compose?
I'm on a Macbook running macOS Ventura 13.1. Here is the docker-compose file I'm using:
services:
auth-service:
image: casbin/casbin-server:v1.9.0
container_name: casbin-server
ports:
- 5005:50051
volumes:
- ./config:/config
- ./data/model:/model
environment:
- DB_DRIVER=postgres
- DB_HOST=db
- DB_PORT=5432
- DB_NAME=auth
- DB_USERNAME=postgres
- DB_PASSWORD=postgres
- CONNECTION_CONFIG_PATH=/config/connection_config.json
depends_on:
db:
condition: service_healthy
db:
image: postgres:12.2
container_name: casbin_db
ports:
- 5432:5432
restart: always
volumes:
- ./postgresql:/var/lib/postgresql
healthcheck:
test: ["CMD", "pg_isready", "-q", "-d", "auth", "-U", "postgres"]
interval: 10s
timeout: 5s
retries: 5
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_DB=auth
The connection_config.json file is given below:
{
"driver": "postgres",
"connection": "host=db port=5432 user=postgres dbname=auth password=postgres",
"enforcer": "/model/model.conf",
"dbSpecified" : true
}
Some of my questions are:
1.How can I update the policy through the HTTP interface?
2.How to update model through HTTP interface?
3.Where is the API for verifying permissions(I mean HTTP interface)?
4.Do I need to implement it myself, or if there are detailed HTTP interface documents, can you provide them?
The path for config/connection_config.json is currently hardcoded in server/enforcer.go and server/adapter.go. Proposing an enhancement to read the connection_config.json location from an environment variable for ease of deployments. We can fall back to the existing config/connection_config.json path if no environment variable is set.
I downloaded the image you provided from the docker, but I don't know how to start it. Is it 'docker run -- name xxx - p 50051:50051 casbin/casbin-server'? Don't need to specify additional env variables?
Thanks.
How to provide multi tenant isolation? Do you have detailed documentation? For example, what are the detailed interfaces?
Hi,
I wanted to try casbin server with MSSQL, but I found out that the repo: github.com/jinzhu/gorm/dialects/mssql doesn't exist anymore.
So my question is: is or will MSSQL still be supported in casbin server?
TIA
Bert
I would like to propose the following gRPC proto definition to be implemented on what I believe to be the V2 of casbin-server
syntax = "proto3";
option java_multiple_files = true;
option java_package = "grpc.CasbinOrg.proto";
option java_outer_classname = "CasbinProto";
option go_package = "./;proto";
option csharp_namespace = "CasbinOrg.Grpc";
package casbin.rpc;
// How this works
// Upon installation, you would get a empty cluster with the root domain
// representing the cluster itself. It would also contain a single user
// and a single JWKS config pointing to a local, pre-installed key-pair
// (which ideally you would change right away, but you can also "disable").
// The base domain would be backed by a local file adapter.
// First the casbin admin would register the adapters for the domains. Then
// he would register the JWKSs. Thirdly he would then register the domains,
// point out which domain is backed by which adapter, being the requests
// validated against one or more key-pair
service ClusterManagementService{
rpc GetAdapters (EmptyRequest) returns (stream AdapterDescription) {}
rpc AddAdapter (AdapterDescription) returns (EmptyReply) {}
rpc DeleteAdapter (AdapterDescription) returns (EmptyReply) {}
rpc RegisterJWKS (JwksUri) returns (EmptyReply) {}
rpc GetRegistredJWKSs (FilteredRequest) returns (GetRegistredJWKSsReply) {}
rpc DeleteRegistredJWKS (JwksUri) returns (EmptyReply){}
rpc RegisterDomain (DomainRegistry) returns (EmptyReply) {}
rpc GetDomains (FilteredRequest) returns (stream DomainRegistry) {}
rpc DeleteDomain (DomainRegistry) returns (EmptyReply) {}
}
// The main Casbin service definition.
// The client would instantiate this service, request a enforce compatible
// with its scope and then enforce away
service EnforcementService {
// Retrieves a enforcer based on the name of the domain provided. If security
// is up, the sub identified on the JWT would be enforced as:
// myMicroservice, domainNameInformedOnTheRequest, enforcers, read
// If security is turned off
rpc GetEnforcer (GetEnforcerRequest) returns (GetEnforcerReply) {}
//Unary request for enforcement
rpc Enforce (EnforceRequest) returns (BoolReply) {}
//Stream based, out of order request for enforcement. Designed for extremely
//high-throughput scenarios
rpc Enforce (stream StreamEnforceRequest) returns (stream StreamBoolReply) {}
}
service PolicesManagementService{
rpc SavePolicy (EmptyRequest) returns (EmptyReply) {}
//Removed "named" version of the api granting PolicyRequest a "name" field
rpc AddPolicy (PolicyRequest) returns (BoolReply) {}
rpc RemovePolicy (PolicyRequest) returns (BoolReply) {}
rpc RemoveFilteredPolicy (FilteredPolicyRequest) returns (BoolReply) {}
rpc GetPolicy (FilteredRequest) returns (Array2DReply) {}
rpc GetFilteredPolicy (FilteredPolicyRequest) returns (Array2DReply) {}
rpc AddGroupingPolicy (PolicyRequest) returns (BoolReply) {}
rpc RemoveGroupingPolicy (PolicyRequest) returns (BoolReply) {}
rpc RemoveFilteredGroupingPolicy (FilteredPolicyRequest) returns (BoolReply) {}
rpc GetGroupingPolicy (FilteredRequest) returns (Array2DReply) {}
rpc GetFilteredGroupingPolicy (FilteredPolicyRequest) returns (Array2DReply) {}
}
service UsersAndRolesManagementService{
rpc GetAllSubjects (FilteredRequest) returns (ArrayReply) {}
rpc GetAllObjects (FilteredRequest) returns (ArrayReply) {}
rpc GetAllActions (FilteredRequest) returns (ArrayReply) {}
rpc GetAllRoles (FilteredRequest) returns (ArrayReply) {}
rpc HasPolicy (PolicyRequest) returns (BoolReply) {}
rpc HasGroupingPolicy (PolicyRequest) returns (BoolReply) {}
rpc GetRolesForUser (GetRolesForUserRequest) returns (ArrayReply) {}
rpc GetUsersForRole (UserRoleRequest) returns (ArrayReply) {}
rpc HasRoleForUser (UserRoleRequest) returns (BoolReply) {}
rpc AddRoleForUser (UserRoleRequest) returns (BoolReply) {}
rpc DeleteRoleForUser (UserRoleRequest) returns (BoolReply) {}
rpc DeleteRolesForUser (UserRoleRequest) returns (BoolReply) {}
rpc DeleteUser (UserRoleRequest) returns (BoolReply) {}
rpc DeleteRole (UserRoleRequest) returns (EmptyReply) {}
rpc GetPermissionsForUser (GetPermissionsForUserRequest) returns (Array2DReply) {}
rpc DeletePermission (PermissionRequest) returns (BoolReply) {}
rpc AddPermissionForUser (PermissionRequest) returns (BoolReply) {}
rpc DeletePermissionForUser (PermissionRequest) returns (BoolReply) {}
rpc DeletePermissionsForUser (PermissionRequest) returns (BoolReply) {}
rpc HasPermissionForUser (PermissionRequest) returns (BoolReply) {}
}
message DomainRegistry{
string name = 1;
AdapterDescription adapter = 2;
string owner = 3;
repeated JwksUri jwks_settings = 4;
int32 created_at = 5;
int32 last_updated = 6;
string created_by = 7;
string last_updated_by = 8;
}
message GetRegistredJWKSsReply{
repeated RegistredJWKS RegistredJWKSs = 1;
}
message RegistredJWKS{
JwksUri uri = 1;
repeated DomainRegistry usedBy = 2;
}
message JwksUri{
string uri = 1;
}
message AdapterDescription{
string realm = 1;
string connectionString = 2;
bool active = 3;
int32 createdAt = 4;
int32 lastUpdated = 5;
string createdBy = 6;
string lastUpdatedBy = 7;
}
message GetEnforcerRequest {
string domainName = 1;
}
message EnforcerHandler {
int32 handler = 1;
}
message NewAdapterRequest {
string adapterName = 1;
string driverName = 2;
string connectString = 3;
bool dbSpecified = 4;
}
message NewAdapterReply {
int32 handler = 1;
}
message EnforceRequest {
int32 enforcerHandler = 1;
repeated string params = 2;
}
message StreamEnforceRequest {
int32 operationId = 1;
int32 enforcerHandler = 2;
repeated string params = 3;
}
message StreamBoolReply {
int32 operationId = 1;
bool res = 2;
}
message BoolReply {
bool res = 1;
}
message EmptyRequest {
int32 handler = 1;
}
message EmptyReply {
}
message PolicyRequest {
int32 enforcerHandler = 1;
string pType = 2;
string name = 3;
repeated string params = 4;
}
message FilteredRequest {
int32 enforcerHandler = 1;
repeated string filters = 2;
int32 skip = 3;
int32 take = 4;
}
message ArrayReply {
repeated string array = 1;
}
message FilteredPolicyRequest {
int32 enforcerHandler = 1;
string pType = 2;
string name = 3;
int32 fieldIndex = 4;
repeated string fieldValues = 5;
}
message UserRoleRequest {
int32 enforcerHandler = 1;
string user = 2;
string role = 3;
}
message GetRolesForUserRequest{
int32 enforcerHandler = 1;
string user = 2;
bool implicit_roles_only = 3;
}
message PermissionRequest {
int32 enforcerHandler = 1;
string user = 2;
repeated string permissions = 3;
}
message GetPermissionsForUserRequest {
int32 enforcerHandler = 1;
string user = 2;
repeated string permissions = 3;
bool implicit_permissions_only = 4;
}
message Array2DReply {
message d {
repeated string d1 = 1;
}
repeated d d2 = 1;
}
Most important changes:
There should be a way to use environment variables for the config file used by the adapter creation of CaaS. Hence, I suggest that users can add environment variables to casbin-server/config/connection_config.json
by using $
followed by the name of the respective variable. Furthermore, users should be allowed to define whether a database has been created (through the dbSpecified
keyword).
I'm creating the issue for extend the life cycle for this project.
Quick scenario:
Imagine that I have a deployment of 2 Casbin-Servers behind a load balancer without sticky session. The client starts the flow by requesting a Adapter. This request gets balanced to server A. The next request, for an enforcer, will be balanced to server B, which will not have any idea about the Adapter and that will result in a error.
Correct?
Hi,
I would like to ask about how to use Casbin Server with ABAC. If I understand correctly, I need to serialize a Go structure to protobuf and send it to the enforce
function, but looking at the code I can't clearly understand whether I can pass a structure (not a string) as a subject/object.
In other words, is something like https://github.com/casbin/casbin/blob/master/model_test.go#L307-L312 possible with casbin-server?
Hi,
I am wondering if having a first capital character for ABAC attributes is a Casbin requirement because I didn't see it mentioned anywhere and it caused me trouble when I was trying to understand my problem.
Line 68 in bbee114
I'm either going insane, or a lot of code used to exist in this repo?
Hello, it's more a question than an issue.
Can you please explain what the point of having the adapter in the client API?
I genuily expect from a casbin-server to have some kind of config file or command line parameters to start a server with a specific adapter, listening port, etc...
And the client should only know the server's uri.
If the client has to create the adapter, I don't see any reason to use the casbin-server over the classic casbin lib.
Am I missing something?
I am trying to spin up a docker with the postgres example here: https://github.com/casbin/casbin-server/blob/master/config/connection_config_psql_example.json
Is there a way to enable Debug logging as the server seems to spin up but anytime I make a call to the API I get "missing enforcer" which leads me to believe that the config file isn't loaded properly.
Logs don't show anything by default so wasn't sure if there was a config or ENV variable for Debug logging?
I've notices some strange behavior using ABAC. For example, I have a resource with two attributes "id" and "status". I print attrList in logs and when I see log like this "{verified 1 map[Id:V1 Status:V0]}" the result is right, but when it's "{verified 1 map[Status:V0, Id:V1 ]}" - the result is wrong. Mapping still seems correct, but the result is wrong
I create one adapter and one enforcer, that are saved in maps in server/enforcer.go, than I make several enforce requests with ABAC resource. Resource is parsed to attribute list and the enforcer model is also changes (e.x. resource attrList is like {1 verified} [Id:V0, Status:V1], model matcher changes to "m = g(r_sub, r_resource.V0) && r_resource.V1 != 'unverified' ") and due to golang random iteration attrList can be different each time. And the enforcer and its model are the shared resource between several enforce requests, so even though the resource mapping seems correct, the result is wrong sometimes because the model can be changed by another request before current request is done.
Probably enforcers must be locked, so different requests won't change it's model value concurrently
The ideia of casbin is perfect, but for a enterprise scenario, casbin-server lacks a couple of features:
Are there any plans on this area? if not can I draft some?
thanks
if i have many application on the k8s
every application has their own casbin-server or all applications have only one common casbin-server ??
I looked through the code and don't see any compute intensive operations designed to result in a computation expense for each policy access.
Also, isn't this a central policy storage as its a Casbin-server that could be used by a backend to enforce access policies? Or am I misunderstanding the project?
Backstory is that I'd like to add Casbin support to my backend restful api. I think I have a model I can understand and I'm able to insert that into my restful framework (go-swagger generated) but I'm looking at whether I should create another docker container just for Casbin and use casbin-server, and if I can then easily plug in the casbin/web-ui to this Casbin server to provide a way to debug policies. The backend will of course manage some of that itself, for example creating policies when users add new devices for example, but of course maintenance access is required to see what is going on there.
See: https://hub.docker.com/r/casbin/casbin-server/tags
Casbin-Server should use a similar way like Casdoor:
The support for Casbin Management & RBAC APIs is not most up to date by comparing the numbers of the APIs seen in the official document and the protobuf file.
error output:
rikenkiyoshis-MacBook-Pro:casbin-server bigticket$ go run main.go
# github.com/casbin/casbin-server/server
server/adapter.go:47:6: assignment mismatch: 1 variable but gormadapter.NewAdapter returns 2 values
server/enforcer.go:82:5: assignment mismatch: 1 variable but casbin.NewEnforcer returns 2 values
server/enforcer.go:82:26: undefined: casbin.NewModel
server/enforcer.go:84:5: assignment mismatch: 1 variable but casbin.NewEnforcer returns 2 values
server/enforcer.go:84:26: undefined: casbin.NewModel
server/enforcer.go:118:6: assignment mismatch: 1 variable but e.Enforce returns 2 values
server/management_api.go:204:44: multiple-value e.AddNamedPolicy() in single-value context
server/management_api.go:213:6: assignment mismatch: 1 variable but e.RemovePolicy returns 2 values
server/management_api.go:224:6: assignment mismatch: 1 variable but e.RemoveNamedPolicy returns 2 values
server/management_api.go:236:55: multiple-value e.RemoveFilteredNamedPolicy() in single-value context
server/management_api.go:236:55: too many errors
for example, casbin.proto.go
file:
RemoveNamedPolicy(ctx context.Context, in *PolicyRequest, opts ...grpc.CallOption) (*BoolReply, error)
but in management_api.go
file:
res := e.RemoveNamedPolicy(in.PType, in.Params)
it should be like this?
res,err := e.RemoveNamedPolicy(in.PType, in.Params)
Issue
If the client starts enforcer with an empty config adapter from config is not applied
Client code
cxt := context.Background()
c, err := client.NewClient(cxt, "127.0.0.1:50051", grpc.WithInsecure())
if err != nil {
panic(err)
}
enforcer, err := c.NewEnforcer(cxt, client.Config{})
casbin-server/server/rbac_api.go
Line 42 in 759993b
casbin-server/server/rbac_api.go
Line 202 in 759993b
when run: go run main.go
./main.go:39:2: undefined: "github.com/casbin/casbin-server/proto".RegisterCasbinServer
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.