RBAC Examples

This chapter aims to provide a step-by-step tutorial on how to set up RBAC and see it in action, with an end-to-end use case. The chosen use case demonstrates how RBAC with workspaces can be coupled to achieve a flexible organization of teams and users in complex hierarchies.

Use case

For the sake of example, let’s say a given company has a Kong Gateway cluster to be shared with two teams: teamA and teamB. While the Kong clusters are shared among these teams, they want to be able to segment their entities in such a way that management of entities in one team doesn’t disrupt operation in some other team. As shown in the Workspaces Page, such a use case is possible with workspaces. On top of workspaces, though, each team wants to enforce access control over their Workspace, which is possible with RBAC.

To sum up, workspaces and RBAC are complementary: workspaces provide segmentation of Admin API entities, while RBAC provides access control.

Note: The example responses in this guide are often excerpts of full responses, focusing on the most relevant part of the response, as the full response can be very long.

Bootstrapping the first RBAC user

The first RBAC user is called the super admin.

Kong recommends that you create a super admin user before actually enforcing RBAC and restarting Kong Gateway with RBAC enabled.

It’s possible to create the first super admin at installation time. If you chose this option, skip to Enforcing RBAC.

Kong Gateway ships with a set of default RBAC roles: super-admin, the admin, and read-only, which makes the task of creating a super admin user easy:

  1. Create the RBAC user, named super-admin:

    1. curl -i -X POST http://localhost:8001/rbac/users \
    2. -H 'Kong-Admin-Token:secureadmintoken' \
    3. --data name=super-admin \
    4. --data user_token=exampletoken

    Response:

    1. {
    2. "user_token": "M8J5A88xKXa7FNKsMbgLMjkm6zI2anOY",
    3. "id": "da80838d-49f8-40f6-b673-6fff3e2c305b",
    4. "enabled": true,
    5. "created_at": 1531009435,
    6. "updated_at": 1531009435,
    7. "name": "super-admin"
    8. }

    As the super-admin username coincides with an existing super-admin role, it gets automatically added to the super-admin role.

  2. Confirm using the following command:

    1. curl -i -X GET http://localhost:8001/rbac/users/super-admin/roles

    Response:

    1. {
    2. "roles": [
    3. {
    4. "comment": "Full access to all endpoints, across all workspaces",
    5. "created_at": 1531009724,
    6. "updated_at": 1531009724,
    7. "name": "super-admin",
    8. "id": "b924ac91-e83f-4136-a5a4-4a7ff92594a8"
    9. }
    10. ],
    11. "user": {
    12. "created_at": 1531009435,
    13. "updated_at": 1531009724,
    14. "id": "e6897cc0-0c34-4a9c-9f0b-cc65b4f04d68",
    15. "name": "super-admin",
    16. "enabled": true,
    17. "user_token": "vajeOlkybsn0q0VD9qw9B3nHYOErgY7b8"
    18. }
    19. }

Enforcing RBAC

With the super-admin user created, the Kong admin can now restart Kong Gateway with RBAC enforced:

  1. KONG_ENFORCE_RBAC=on kong restart

This is one of the possible ways of enforcing RBAC and restarting Kong. Another option is editing the Kong Gateway configuration file and restarting.

Before moving on, note that this guide uses the super admin user, but you could move on without RBAC enabled, and have the Kong admin set up the whole RBAC hierarchy.

However, we want to stress the fact that RBAC is powerful enough to allow a flexible separation of tasks. To summarize:

  • Kong admin: This user has physical access to Kong infrastructure. Their task is to bootstrap the Kong cluster as well as its configuration, including initial RBAC users.
  • RBAC super admin: Created by the Kong admin, has the role of managing RBAC users, roles, and permissions. While this could all be done by the Kong admin, we recommend separating the responsibility for better security.

Super admin creates the team workspaces

The super admin now sets up two teams: teamA and teamB, creating one workspace for each and one admin for each.

  1. Create the workspace for teamA:

    1. curl -i -X POST http://localhost:8001/workspaces \
    2. --data name=teamA \
    3. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "name": "teamA",
    3. "created_at": 1531014100,
    4. "updated_at": 1531014100,
    5. "id": "1412f3a6-4d9b-4b9d-964e-60d8d63a9d46"
    6. }
  2. Create the workspace for teamB:

    1. curl -i -X POST http://localhost:8001/workspaces \
    2. --data name=teamB \
    3. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "name": "teamB",
    3. "created_at": 1531014143,
    4. "updated_at": 1531014143,
    5. "id": "7dee8c56-c6db-4125-b87a-b508baa33c66"
    6. }

Super admin creates one admin for each team

  1. Create an admin for teamA:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users \
    2. --data name=adminA \
    3. --data user_token=exampletokenA \
    4. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "user_token": "qv1VLIpl8kHj7lC1QOKwRdCMXanqEDii",
    3. "id": "4d315ff9-8c1a-4844-9ea2-21b16204a154",
    4. "enabled": true,
    5. "created_at": 1531015165,
    6. "updated_at": 1531015165,
    7. "name": "adminA"
    8. }
  2. Create an admin for teamB:

    1. curl -i -X POST http://localhost:8001/teamB/rbac/users \
    2. --data name=adminB \
    3. --data user_token=exampletokenB \
    4. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "user_token": "IX5vHVgYqM40tLcctdmzRtHyfxB4ToYv",
    3. "id": "49641fc0-8c9d-4507-bc7a-2acac8f2903a",
    4. "enabled": true,
    5. "created_at": 1531015221,
    6. "updated_at": 1531015221,
    7. "name": "adminB"
    8. }
  3. Both of the teams now have one admin and each admin can only be seen in their corresponding workspace. To verify, run:

    1. curl -i -X GET http://localhost:8001/teamA/rbac/users \
    2. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "total": 1,
    3. "data": [
    4. {
    5. "created_at": 1531014784,
    6. "updated_at": 1531014784,
    7. "id": "1faaacd1-709f-4762-8c3e-79f268ec8faf",
    8. "name": "adminA",
    9. "enabled": true,
    10. "user_token": "n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG"
    11. }
    12. ]
    13. }

    Similarly, workspace teamB only shows its own admin:

    1. curl -i -X GET http://localhost:8001/teamB/rbac/users \
    2. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "total": 1,
    3. "data": [
    4. {
    5. "created_at": 1531014805,
    6. "updated_at": 1531014805,
    7. "id": "3a829408-c1ee-4764-8222-2d280a5de441",
    8. "name": "adminB",
    9. "enabled": true,
    10. "user_token": "C8b6kTTN10JFyU63ORjmCQwVbvK4maeq"
    11. }
    12. ]
    13. }

Super admin creates admin roles for teams

The super admin is now done creating RBAC admin users for each team. The next task is to create admin roles that will effectively grant permissions to admin users.

The admin role must have access to all of the Admin API, restricted to its workspace.

  1. Set up the admin role, paying close attention to the request parameters:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/ \
    2. --data name=admin \
    3. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "created_at": 1531016728,
    3. "updated_at": 1531016728,
    4. "id": "d40e61ab-8dad-4ef2-a48b-d11379f7b8d1",
    5. "name": "admin"
    6. }
  2. Create role endpoint permissions:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/admin/endpoints/ \
    2. --data 'endpoint=*' \
    3. --data 'workspace=teamA' \
    4. --data 'actions=*' \
    5. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "total": 1,
    3. "data": [
    4. {
    5. "endpoint": "*",
    6. "created_at": 1531017322,
    7. "updated_at": 1531017322,
    8. "role_id": "d40e61ab-8dad-4ef2-a48b-d11379f7b8d1",
    9. "actions": [
    10. "delete",
    11. "create",
    12. "update",
    13. "read"
    14. ],
    15. "negative": false,
    16. "workspace": "teamA"
    17. }
    18. ]
    19. }
  3. Add the adminA user to the admin role in their workspace:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users/adminA/roles/ \
    2. --data roles=admin \
    3. -H 'Kong-Admin-Token:vajeOlkbsn0q0VD9qw9B3nHYOErgY7b8'

    Response:

    1. {
    2. "roles": [
    3. {
    4. "created_at": 1685551877,
    5. "updated_at": 1531014805,
    6. "id": "42809ada-650c-4575-b0a0-d464a64ffb70",
    7. "name": "admin",
    8. "ws_id": "9dc7adbb-9b64-4121-bf76-653cf5871bc2"
    9. }
    10. ],
    11. "user": {
    12. "comment": "null",
    13. "created_at": 1685552809,
    14. "updated_at": 1531014805,
    15. "enabled": true,
    16. "id": "bca4e390-fbbf-4a46-b55d-f4642efc14bb",
    17. "name": "adminA",
    18. "user_token": "$2b$09$oLyKTIDuKriPZ.SD5wYtxeMclGYNDn4udJkQG0NGx/Aq3j9j/tWsa",
    19. "user_token_ident": "0ebb5"
    20. }
    21. }
  4. Team A’s admin user is now able to manage their team. To validate that, let’s try to list RBAC users in Team B using Team A’s admin user token:

    1. curl -i -X GET http://localhost:8001/teamB/rbac/users \
    2. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Notice that you can’t access the endpoint:

    1. {
    2. "message": "Invalid RBAC credentials"
    3. }
  5. Now try listing RBAC users in Team A’s workspace:

    1. curl -i -X GET http://localhost:8001/teamA/rbac/users \
    2. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "total": 1,
    3. "data": [
    4. {
    5. "created_at": 1531014784,
    6. "updated_at": 1531014784,
    7. "id": "1faaacd1-709f-4762-8c3e-79f268ec8faf",
    8. "name": "adminA",
    9. "enabled": true,
    10. "user_token": "n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG"
    11. }
    12. ]
    13. }

If the same procedure is repeated for Team B, they will end up with a similar set up, with an admin role and an admin user, both restricted to the team’s workspace.

The super admin’s job is now done. Individual team admins are now able to set up their team’s users and entities!

Team admins create regular users

From this point on, team admins are able to drive the process. The next step is to create team users, such as engineers that are part of Team A or B. Let’s go ahead and do that, using Admin A’s user token.

Before regular users can be created, a role needs to be available for them. This role needs to have permissions to all of the Admin API endpoints, except RBAC and workspaces. Regular users don’t need access to these endpoints, and if they do, the admin can grant them individually.

Create the users role

  1. As a team admin, create the regular users role:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/ \
    2. --data name=users \
    3. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "created_at": 1531020346,
    3. "updated_at": 1531020346,
    4. "id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    5. "name": "users"
    6. }
  2. Create a permission for all of the Admin API, which requires a positive permission on \*:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/users/endpoints/ \
    2. --data 'endpoint=*' \
    3. --data 'workspace=teamA' \
    4. --data 'actions=*' \
    5. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "endpoint": "*",
    3. "created_at": 1531020573,
    4. "udpated_at": 1531020573,
    5. "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    6. "actions": [
    7. "delete",
    8. "create",
    9. "update",
    10. "read"
    11. ],
    12. "negative": false,
    13. "workspace": "teamA"
    14. }
  3. Then, filter out RBAC and workspaces with negative permissions:

    Filter out RBAC endpoints:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/users/endpoints/ \
    2. --data 'endpoint=/rbac/*' \
    3. --data 'workspace=teamA' \
    4. --data 'actions=*' \
    5. --data 'negative=true' \
    6. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "endpoint": "/rbac/*",
    3. "created_at": 1531020744,
    4. "updated_at": 1531020744,
    5. "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    6. "actions": [
    7. "delete",
    8. "create",
    9. "update",
    10. "read"
    11. ],
    12. "negative": true,
    13. "workspace": "teamA"
    14. }

    Filter out workspaces endpoints:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/users/endpoints/ \
    2. --data 'endpoint=/workspaces/*' \
    3. --data 'workspace=teamA' \
    4. --data 'actions=*' \
    5. --data 'negative=true' \
    6. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "endpoint": "/workspaces/*",
    3. "created_at": 1531020778,
    4. "updated_at": 1531020778,
    5. "role_id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    6. "actions": [
    7. "delete",
    8. "create",
    9. "update",
    10. "read"
    11. ],
    12. "negative": true,
    13. "workspace": "teamA"
    14. }

Important: As explained in the Wildcards in Permissions section, the meaning of * is not the same as generic globbing. As such, /rbac/* or /workspaces/* do not match all of the RBAC and Workspaces endpoints. For example, to cover all of the RBAC API, you would have to define permissions for the following endpoints:

  • /rbac/*
  • /rbac/*/*
  • /rbac/*/*/*
  • /rbac/*/*/*/*
  • /rbac/*/*/*/*/*

Add members to a team

Team A just got two new members: foogineer and bargineer. Admin A welcomes them to the team by creating RBAC users for them and giving them access to Kong.

  1. Create foogineer:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users \
    2. --data name=foogineer \
    3. --data user_token=exampletokenfoo \
    4. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "created_at": 1531019797,
    3. "updated_at": 1531019797,
    4. "id": "0b4111da-2827-4767-8651-a327f7a559e9",
    5. "name": "foogineer",
    6. "enabled": true,
    7. "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI"
    8. }
  2. Add foogineer to the users role:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users/foogineer/roles \
    2. --data roles=users \
    3. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "roles": [
    3. {
    4. "comment": "Default user role generated for foogineer",
    5. "created_at": 1531019797,
    6. "updated_at": 1531019797,
    7. "id": "125c4212-b882-432d-a323-9cbe38b1d0df",
    8. "name": "foogineer"
    9. },
    10. {
    11. "created_at": 1531020346,
    12. "updated_at": 1531020346,
    13. "id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    14. "name": "users"
    15. }
    16. ],
    17. "user": {
    18. "created_at": 1531019797,
    19. "updated_at": 1531019797,
    20. "id": "0b4111da-2827-4767-8651-a327f7a559e9",
    21. "name": "foogineer",
    22. "enabled": true,
    23. "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI"
    24. }
    25. }
  3. Create bargineer:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users \
    2. --data name=bargineer \
    3. --data user_token=exampletokenbar \
    4. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "created_at": 1531019797,
    3. "updated_at": 1531019797,
    4. "id": "e8926efa-11b4-43a3-9a28-767c05d8e9d8",
    5. "name": "bargineer",
    6. "enabled": true,
    7. "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI"
    8. }
  4. Add bargineer to the users role:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users/foogineer/roles \
    2. --data roles=users \
    3. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "roles": [
    3. {
    4. "comment": "Default user role generated for bargineer",
    5. "created_at": 1531019797,
    6. "updated_at": 1531019797,
    7. "id": "125c4212-b882-432d-a323-9cbe38b1d0df",
    8. "name": "bargineer"
    9. },
    10. {
    11. "created_at": 1531020346,
    12. "updated_at": 1531020346,
    13. "id": "9846b92c-6820-4741-ac31-425b3d6abc5b",
    14. "name": "users"
    15. }
    16. ],
    17. "user": {
    18. "created_at": 1531019797,
    19. "updated_at": 1531019797,
    20. "id": "e8926efa-11b4-43a3-9a28-767c05d8e9d8",
    21. "name": "bargineer",
    22. "enabled": true,
    23. "user_token": "dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI"
    24. }
    25. }

Regular team users use their tokens

foogineer and bargineer have gotten their RBAC user tokens from their Team A admin, and are now allowed to explore Kong Gateway within the confines of their Team A workspace. Let’s validate this.

  1. As foogineer, try listing workspaces:

    1. curl -i -X GET http://localhost:8001/teamA/workspaces/ \
    2. -H 'Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI'

    Respone:

    1. {
    2. "message": "foogineer, you do not have permissions to read this resource"
    3. }
  2. Enable some plugin, for example key-auth:

    1. curl -i -X POST http://localhost:8001/teamA/plugins \
    2. --data name=key-auth \
    3. -H 'Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI'

    Response:

    1. {
    2. "created_at": 1531021732,
    3. "updated_at": 1531021732,
    4. "config": {
    5. "key_in_body": false,
    6. "run_on_preflight": true,
    7. "anonymous": "",
    8. "hide_credentials": false,
    9. "key_names": [
    10. "apikey"
    11. ]
    12. },
    13. "id": "cdc85ef0-804b-4f92-aafd-3ff58512e445",
    14. "enabled": true,
    15. "name": "key-auth"
    16. }
  3. List currently enabled plugins:

    1. curl -i -X GET http://localhost:8001/teamA/plugins \
    2. -H 'Kong-Admin-Token:dNeYvYAwvjOJdoReVJZXF8vLBXQioKkI'

    Response:

    1. {
    2. "total": 1,
    3. "data": [
    4. {
    5. "created_at": 1531021732,
    6. "updated_at": 1531021732,
    7. "config": {
    8. "key_in_body": false,
    9. "run_on_preflight": true,
    10. "anonymous": "",
    11. "hide_credentials": false,
    12. "key_names": [
    13. "apikey"
    14. ]
    15. },
    16. "id": "cdc85ef0-804b-4f92-aafd-3ff58512e445",
    17. "name": "key-auth",
    18. "enabled": true
    19. }
    20. ]
    21. }

This ends the use case tutorial, which demonstrates the power of RBAC and workspaces with a real-world scenario.

Entity-level RBAC

In addition to endpoint permissions, RBAC in Kong Gateway supports entity-level permissions, meaning that particular entities, identified by their unique ID, can be allowed or disallowed access in a role.

RBAC is enforced with the enforce_rbac configuration directive, or with its KONG_ENFORCE_RBAC environment variable counterpart. The directive is an enum, with the following possible values:

  • on: Applies endpoint-levelaccess control
  • entity: Applies only Entity-level access control
  • both: Applies both Endpoint and Entity level access control
  • off: disables RBAC enforcement

If set to entity or both, Kong enforces entity-level access control. However, as with endpoint-level access control, permissions must be bootstrapped before enforcement is enabled.

Creating entity-level permissions

Team A just got one new, temporary, team member: qux. Admin A, the admin of Team A, has already created the qux RBAC user.

Next, the admin needs to limit the access that qux has over entities in the Team A workspace, giving the user read access to only a couple of entities. For that, the admin needs to use entity-level RBAC.

  1. As Admin A, create a role for the temporary user qux:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles \
    2. --data name=qux-role \
    3. -H Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG

    Response:

    1. {
    2. "name": "qux-role",
    3. "created_at": 1531065975,
    4. "updated_at": 1531065975,
    5. "id": "ffe93269-7993-4308-965e-0286d0bc87b9"
    6. }
  2. Grant the user read access to two entities: a service and a route. Reference each entity by its ID:

    For example, using service1 with the ID 3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 and route1 with the ID d25afc46-dc59-48b2-b04f-d3ebe19f6d4b:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/admin/entities \
    2. --data entity_id=3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 \
    3. --data entity_type=services \
    4. --data actions=read \
    5. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "created_at": 1531066684,
    3. "updated_at": 1531066684,
    4. "role_id": "ffe93269-7993-4308-965e-0286d0bc87b9",
    5. "entity_id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43",
    6. "negative": false,
    7. "entity_type": "services",
    8. "actions": [
    9. "read"
    10. ]
    11. }
    1. curl -i -X POST http://localhost:8001/teamA/rbac/roles/qux-role/entities \
    2. --data entity_id=d25afc46-dc59-48b2-b04f-d3ebe19f6d4b \
    3. --data entity_type=routes \
    4. --data actions=read \
    5. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "created_at": 1531066684,
    3. "updated_at": 1531066684,
    4. "role_id": "ffe93269-7993-4308-965e-0286d0bc87b9",
    5. "entity_id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b",
    6. "negative": false,
    7. "entity_type": "routes",
    8. "actions": [
    9. "read"
    10. ]
    11. }
  3. Add the user qux to qux-role:

    1. curl -i -X POST http://localhost:8001/teamA/rbac/users/qux/roles \
    2. --data roles=qux-role \
    3. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "roles": [
    3. {
    4. "comment": "Default user role generated for qux",
    5. "created_at": 1531065373,
    6. "updated_at": 1531065373,
    7. "name": "qux",
    8. "id": "31614171-4174-42b4-9fae-43c9ce14830f"
    9. },
    10. {
    11. "created_at": 1531065975,
    12. "updated_at": 1531065975,
    13. "name": "qux-role",
    14. "id": "ffe93269-7993-4308-965e-0286d0bc87b9"
    15. }
    16. ],
    17. "user": {
    18. "created_at": 1531065373,
    19. "created_at": 1531065373,
    20. "id": "4d87bf78-5824-4756-b0d0-ceaa9bd9b2d5",
    21. "name": "qux",
    22. "enabled": true,
    23. "user_token": "sUnv6uBehM91amYRNWESsgX3HzqoBnR5"
    24. }
    25. }
  4. Check that the correct permissions are listed for qux:

    1. curl -i -X GET http://localhost:8001/teamA/rbac/users/qux/permissions \
    2. -H 'Kong-Admin-Token:n5bhjgv0speXp4N7rSUzUj8PGnl3F5eG'

    Response:

    1. {
    2. "entities": {
    3. "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b": {
    4. "actions": [
    5. "read"
    6. ],
    7. "negative": false
    8. },
    9. "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43": {
    10. "actions": [
    11. "read"
    12. ],
    13. "negative": false
    14. }
    15. },
    16. "endpoints": {}
    17. }

    qux should have two entity permissions and no endpoint permissions.

Admin A is done setting up qux, and qux can now use their user token to read the two entities over Kong’s admin API.

Let’s assume that Admin A enabled entity-level enforcement as well. Note that as qux has no endpoint-level permissions. If both endpoint and entity-level enforcement is enabled, qux won’t be able to read their entities, as endpoint-level validation comes before entity-level.

  1. As qux, try listing all RBAC users:

    1. curl -i -X GET http://localhost:8001/teamA/rbac/users/ \
    2. -H Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5

    Response:

    1. {
    2. "message": "qux, you do not have permissions to read this resource"
    3. }
  2. As qux, try to access service1:

    1. curl -i -X GET http://localhost:8001/teamA/services/service1 \
    2. -H Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5

    Response:

    1. {
    2. "host": "httpbin.org",
    3. "created_at": 1531066074,
    4. "updated_at": 1531066074,
    5. "connect_timeout": 60000,
    6. "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43",
    7. "protocol": "http",
    8. "name": "service1",
    9. "read_timeout": 60000,
    10. "port": 80,
    11. "path": null,
    12. "updated_at": 1531066074,
    13. "retries": 5,
    14. "write_timeout": 60000
    15. }

Wildcards in permissions

RBAC supports the use of wildcards (*) in many aspects of permissions.

Creating endpoint permissions

To create an endpoint permission via /rbac/roles/:role/endpoints, you must pass the parameters below, all of which can be replaced by a * character:

  • endpoint: * matches any endpoint
  • workspace: * matches any workspace
  • actions: * evaluates to all actions—read, update, create, delete

Special case: endpoint, in addition to a single *, also accepts * within the endpoint itself, replacing a URL segment between /. For example, all of the following are valid endpoints:

  • /rbac/*: where * replaces any possible segment, for example /rbac/users and /rbac/roles
  • /services/*/plugins: * matches any service name or ID

Note * is not a generic, shell-like, glob pattern.

If workspace is omitted, it defaults to the current request’s workspace. For example, a role-endpoint permission created with /teamA/roles/admin/endpoints is scoped to workspace teamA.

Creating entity permissions

For entity permissions created via /rbac/roles/:role/entities, the following parameter accepts a * character:

  • entity_id: * matches any entity ID

Entities nested in entity-level RBAC

With entity-level RBAC enabled, endpoints that list all entities of a particular collection will only list entities that the user has access to.

In the example above, if user qux listed all routes, they would only get the entities they have access to in the response, even though there could be more in the workspace:

  1. curl -i -X GET http://localhost:8001/teamA/routes \
  2. -H 'Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5'

Response:

  1. {
  2. "next": null,
  3. "data": [
  4. {
  5. "created_at": 1531066253,
  6. "updated_at": 1531066253,
  7. "id": "d25afc46-dc59-48b2-b04f-d3ebe19f6d4b",
  8. "hosts": null,
  9. "preserve_host": false,
  10. "regex_priority": 0,
  11. "service": {
  12. "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43"
  13. },
  14. "paths": [
  15. "/anything"
  16. ],
  17. "methods": null,
  18. "strip_path": false,
  19. "protocols": [
  20. "http",
  21. "https"
  22. ]
  23. }
  24. ]
  25. }

Some Kong endpoints carry a total field in responses. With entity-level RBAC enabled, the global count of entities is displayed, but only entities the user has access to are themselves shown.

For example, if Team A has a number of plugins configured, but qux only has access to one of them, the following would be the expected output for a GET request to /teamA/plugins:

  1. curl -i -X GET http://localhost:8001/teamA/plugins \
  2. -H 'Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5'

Response:

  1. {
  2. "total": 2,
  3. "data": [
  4. {
  5. "created_at": 1531070344,
  6. "updated_at": 1531070344,
  7. "config": {
  8. "key_in_body": false,
  9. "run_on_preflight": true,
  10. "anonymous": "",
  11. "hide_credentials": false,
  12. "key_names": [
  13. "apikey"
  14. ]
  15. },
  16. "id": "8813dd0b-3e9d-4bcf-8a10-3112654f86e7",
  17. "name": "key-auth",
  18. "enabled": true
  19. }
  20. ]
  21. }

Notice the total field is 2, but qux only got one entity in the response.

Creating entities in entity-level RBAC

As entity-level RBAC provides access control to individual existing entities, it does not apply to creation of new entities. For that, endpoint-level permissions must be configured and enforced.

For example, if endpoint-level permissions are not enforced, qux will be able to create new entities, and will automatically have permissions to perform any actions to entities they create:

  1. curl -i -X POST http://localhost:8001/teamA/routes \
  2. --data paths[]=/anything \
  3. --data service.id=3ed24101-19a7-4a0b-a10f-2f47bcd4ff43 \
  4. --data strip_path=false \
  5. -H 'Kong-Admin-Token:sUnv6uBehM91amYRNWESsgX3HzqoBnR5'

Response:

  1. {
  2. "created_at": 1531070828,
  3. "updated_at": 1531070828,
  4. "strip_path": false,
  5. "hosts": null,
  6. "preserve_host": false,
  7. "regex_priority": 0,
  8. "paths": [
  9. "/anything"
  10. ],
  11. "service": {
  12. "id": "3ed24101-19a7-4a0b-a10f-2f47bcd4ff43"
  13. },
  14. "methods": null,
  15. "protocols": [
  16. "http",
  17. "https"
  18. ],
  19. "id": "6ee76f74-3c96-46a9-ae48-72df0717d244"
  20. }