feat: enforce PAT scope on permission checks by AmanGIT07 · Pull Request #1446 · raystack/frontier

@AmanGIT07, can you add some manual testing examples here (or in the PR description) that we can try ourselves (e.g., with curl)?

@whoAbhishekSah It would be really difficult to add all the different manual test scenarios or the curl that you can just hit and run (since DB IDs and setup will be different). However, sharing some sample here, you can also take a look at the e2e test file, it's built on the same philosophy.

Create PAT:

grpcurl \
	-plaintext \
	-H 'cookie':'sid=' \
	-emit-defaults \
	-d '{"expires_at":"2026-04-29T15:15:37.870Z","org_id":"eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683","project_ids":["6a08822f-22e5-471d-8311-47cbaf8229ee"],"role_ids":["b5763e25-fc5b-42fc-8657-85e03e197395","c4095deb-0cfd-4f24-9259-a022079f181b"],"title":"custom-resource-test"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.CreateCurrentUserPAT

(The roles are org view & project view)

Test Samples

1. RPC call with PAT tokens

Get Org RPC call works, curl:

grpcurl \
	-plaintext \
	-H 'Authorization':'Bearer <Your key>' \
	-emit-defaults \
	-d '{"id":"eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.GetOrganization

Update org RPC call fails with unauthorized:

grpcurl \
	-plaintext \
	-H 'Authorization':'Bearer <Your key>' \
	-emit-defaults \
	-d '{"body":{"title":"updated-title"},"id":"eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.UpdateOrganization

Same for Project get and update RPCs.

2. CheckResourcePermission

For org update, gives false.

Request:

grpcurl \
	-plaintext \
	-H 'Authorization':'Bearer <Your key>' \
	-emit-defaults \
	-d '{"permission":"update","resource":"app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.CheckResourcePermission

Response:

For org get, gives true

Request:

grpcurl \
	-plaintext \
	-H 'Authorization':'Bearer <Your key>' \
	-emit-defaults \
	-d '{"permission":"get","resource":"app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.CheckResourcePermission

Response:

3. BatchCheckPermission

Check permission gives false for org update and true for org get

Request:

grpcurl \
	-plaintext \
	-H 'Authorization':'Bearer <Your key>' \
	-emit-defaults \
	-d '{"bodies":[{"permission":"update","resource":"app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"},{"permission":"get","resource":"app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"}]}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.FrontierService.BatchCheckPermission

Response:

{
    "pairs": [
        {
            "body": {
                "permission": "update",
                "resource": "app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"
            },
            "status": false
        },
        {
            "body": {
                "permission": "get",
                "resource": "app/organization:eefb7622-fd9a-4bf1-9ef6-2c0ca2cde683"
            },
            "status": true
        }
    ]
}

4. CheckFederatedResourcePermission

Federated check accepts the PAT id and returns false for an org that doesn't belong to the PAT

Request:

grpcurl \
	-plaintext \
	-H 'cookie':'sid=' \
	-emit-defaults \
	-d '{"permission":"update","resource":"app/organization:ec42536a-e936-48d9-a447-01f7f99f4542","subject":"app/pat:22d2fe0d-e89f-42bb-86a5-d940f3a26f3d"}' \
	'localhost:8002' \
	raystack.frontier.v1beta1.AdminService.CheckFederatedResourcePermission

Response:

Similar tests were done for projects and custom respources