janus-idp / backstage-plugins

Plugins for Backstage
https://janus-idp.io
Apache License 2.0
145 stars 147 forks source link

RBAC: Single PostgreSQL database not working (pluginDivisionMode: schema) #1865

Closed wnqueiroz closed 2 months ago

wnqueiroz commented 3 months ago

Describe the bug

I'm using the single database configuration with pluginDivisionMode: schema in the app.config.yaml of a Backstage instance:

This configuration allows that instead of creating new databases for each plugin, this division is done using PostgreSQL schemas.

When configuring the plugins:

I'm getting the following error in the backend:

{
  "actor": { "actorId": null },
  "errors": [
    {
      "message": "Unable to find all roles. Cause: error: select distinct \"v1\" from \"casbin_rule\" where \"v0\" in ($1, $2) - relation \"casbin_rule\" does not exist",
      "name": "Error",
      "stack": "Error: Unable to find all roles. Cause: error: select distinct \"v1\" from \"casbin_rule\" where \"v0\" in ($1, $2) - relation \"casbin_rule\" does not exist\n    at RoleMemberList.buildRoles (/home/wnqueiroz/www/github/wnqueiroz/backstage/node_modules/@janus-idp/backstage-plugin-rbac-backend/src/role-manager/member-list.ts:115:13)\n    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n    at BackstageRoleManager.getRoles (/home/wnqueiroz/www/github/wnqueiroz/backstage/node_modules/@janus-idp/backstage-plugin-rbac-backend/src/role-manager/role-manager.ts:230:9)\n    at EnforcerDelegate.getRolesForUser (/home/wnqueiroz/www/github/wnqueiroz/backstage/node_modules/@janus-idp/backstage-plugin-rbac-backend/src/service/enforcer-delegate.ts:48:12)\n    at RBACPermissionPolicy.handle (/home/wnqueiroz/www/github/wnqueiroz/backstage/node_modules/@janus-idp/backstage-plugin-rbac-backend/src/service/permission-policy.ts:324:21)\n    at async Promise.all (index 0)\n    at <anonymous> (/home/wnqueiroz/www/github/wnqueiroz/backstage/node_modules/@janus-idp/backstage-plugin-rbac-backend/node_modules/@backstage/plugin-permission-backend/src/service/router.ts:240:16)"
    }
  ],
  "eventName": "PermissionEvaluationFailed",
  "isAuditLog": true,
  "level": "info",
  "message": "Permission policy check failed",
  "meta": {},
  "plugin": "permission",
  "stage": "evaluatePermissionAccess",
  "status": "failed"
}

The error is thrown at: plugins/rbac-backend/src/role-manager/member-list.ts#L115

As a result, every GET /api/permission call returns status code 403... making it impossible to use the RBAC plugin...

Stacktrace ```plaintext Error: Unable to find all roles. Cause: error: select distinct \"v1\" from \"casbin_rule\" where \"v0\" in ($1, $2) - relation \"casbin_rule\" does not exist at RoleMemberList.buildRoles (@janus-idp/backstage-plugin-rbac-backend/src/role-manager/member-list.ts:115:13) at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at BackstageRoleManager.getRoles (@janus-idp/backstage-plugin-rbac-backend/src/role-manager/role-manager.ts:230:9) at EnforcerDelegate.getRolesForUser (@janus-idp/backstage-plugin-rbac-backend/src/service/enforcer-delegate.ts:48:12) at RBACPermissionPolicy.handle (@janus-idp/backstage-plugin-rbac-backend/src/service/permission-policy.ts:324:21) at async Promise.all (index 0) at (@janus-idp/backstage-plugin-rbac-backend/node_modules/@backstage/plugin-permission-backend/src/service/router.ts:240:16) ```

The admin button and no documents in the catalog are displayed:

image

Expected Behavior

RBAC plugin working correctly

image

💡 Image obtained by just changing database.client to better-sqlite3

What are the steps to reproduce this bug?

I created a public project with the error:

  1. Clone the repository: wnqueiroz/backstage
  2. Checkout the bug-report-janus-idp-backstage-plugin-rbac branch: git checkout bug-report-janus-idp-backstage-plugin-rbac
  3. With a Docker installation, run the commands:
cp .env.example .env
docker compose up -d

To "force" a clean run:

docker compose down --rmi local --remove-orphans --volumes
docker compose build --no-cache
docker compose up -d --force-recreate --remove-orphans
docker compose logs -f backstage

💡 Any changes on app-config.yaml file you must restart the container: docker compose restart backstage.

Versions of software used and environment

wnqueiroz commented 3 months ago

Adding more information, I noticed that the casbin_rule table, in this configuration, exists in the public schema. I didn't find any migration that creates this table by the way.

Shouldn't it be created in the permission schema?

I ran the SQL commands below and managed to make the division by schema work:

DROP TABLE IF EXISTS permission."policy-metadata";
DROP TABLE IF EXISTS permission."role-condition-policies";
DROP TABLE IF EXISTS permission."role-metadata";
DROP TABLE IF EXISTS permission.backstage_backend_public_keys__keys;
DROP TABLE IF EXISTS permission.backstage_backend_public_keys__knex_migrations;
DROP TABLE IF EXISTS permission.backstage_backend_public_keys__knex_migrations_lock;
DROP TABLE IF EXISTS permission.knex_migrations;
DROP TABLE IF EXISTS permission.knex_migrations_lock;
DROP TABLE IF EXISTS permission.casbin_rule;

CREATE TABLE IF NOT EXISTS permission.casbin_rule
(
 id SERIAL PRIMARY KEY,
 ptype character varying COLLATE pg_catalog."default",
 v0 character varying COLLATE pg_catalog."default",
 v1 character varying COLLATE pg_catalog."default",
 v2 character varying COLLATE pg_catalog."default",
 v3 character varying COLLATE pg_catalog."default",
 v4 character varying COLLATE pg_catalog."default",
 v5 character varying COLLATE pg_catalog."default",
 v6 character varying COLLATE pg_catalog."default"
)

I created the permission.casbin_rule table and then populated the data previously created by the plugin migrations:

INSERT INTO permission.casbin_rule (id, ptype, v0, v1, v2, v3, v4, v5)
SELECT id, ptype, v0, v1, v2, v3, v4, v5
FROM public.casbin_rule;

It worked but something still depends on public.casbin_rule, when it is deleted, the reported behavior happens again:

DROP TABLE IF EXISTS public.casbin_rule;
PatAKnight commented 2 months ago

Thanks for this bug report, this should be fixed as of rbac-backend 4.3.2 now that this PR has been merged.

wnqueiroz commented 2 months ago

Thanks for the feedback @PatAKnight! I looked for issues on the topic and couldn't find it, I forgot to check if there was any open PR 😅

I noticed that we have version 4.3.4, I will carry out the tests and report here if the behavior has changed.

wnqueiroz commented 2 months ago

I updated the packages in the backend with the versions:

It worked. Closing the issue. Thanks @PatAKnight! and also to @luangazin for the PR.

image image image