LoveTropics / LTPermissions

Lightweight permissions system developed for use during Love Tropics
Mozilla Public License 2.0
0 stars 0 forks source link

Add Keycloak integration #1

Open NotActuallyTerry opened 1 year ago

NotActuallyTerry commented 1 year ago

Keycloak is an extensible Java-based Identity Provider that allows sysadmins to configure how users can authenticate with services. My main areas of interest for integration are:

Our current Keycloak instance allows users to specify their Minecraft username in their profile, which will then be reported as attribute minecraft-username

NotActuallyTerry commented 1 year ago

It's possible to query for user via custom attribute, see https://stackoverflow.com/questions/54667407/how-to-get-users-by-custom-attributes-in-keycloak This would allow LTPermissions to query for the specified user simply by passing the user's Minecraft username to the API

ashhhleyyy commented 11 months ago

Random notes from some command line testing:

Curl to get initial access/refresh token

curl -X POST https://auth.cocytus.services/realms/master/protocol/openid-connect/token --user admin-cli:REDACTED -H 'content-type: application/x-www-form-urlencoded' -d 'username=ltpermissions-dev&password=REDACTED&grant_type=password'

Gives a response like

{
    "access_token":"ey...",
    "expires_in":600,
    "refresh_expires_in":1800,
    "refresh_token":"ey...",
    "token_type":"Bearer",
    "not-before-policy":0,
    "session_state":"...",
    "scope":"profile email"
}
ashhhleyyy commented 11 months ago

with these tokens the mod probably needs to run a check periodically as to whether the access token has expired, could probably do this in the server tick

ashhhleyyy commented 11 months ago

steps to fetch user groups:

query by minecraft username:

curl -v -H "Authorization: Bearer $auth_token" 'https://auth.cocytus.services/admin/realms/master/users?q=minecraftUsername:AshhhleyyyB'

Extract user id from response:

[
    {
        "id":"d25d85a5-5d93-4a3f-b535-daee4fb88080",
        "createdTimestamp":1692614614582,
        "username":"ashhhleyyy",
        "enabled":true,
        "totp":false,
        "emailVerified":true,
        "firstName":"Ashley",
        "lastName":"",
        "email":"...",
        "attributes":{"minecraftUsername":["AshhhleyyyB"]},"disableableCredentialTypes":[],"requiredActions":[],"notBefore":0,
        "access":{"manageGroupMembership":true,"view":true,"mapRoles":true,"impersonate":true,"manage":true}
    }
]

user id can be used to query the list of user groups

curl -v -H "Authorization: Bearer $auth_token" 'https://auth.cocytus.services/admin/realms/master/users/d25d85a5-5d93-4a3f-b535-daee4fb88080/groups'

then provide a config mapping keycloak group id -> ltpermissions roles, as well as functionality for whitelisting

[
    {"id":"a2b39cb0-8b0e-4ba5-a887-d96fcf452811","name":"Builders","path":"/Builders"},
    {"id":"87547a11-3bb4-4bc2-bb2f-3fbb25c49e90","name":"Helpers","path":"/Helpers"},
    {"id":"2fee7881-df2e-421a-b266-85fb48a54a16","name":"Modders","path":"/Modders"}
]
Rushmead commented 10 months ago

It would likely be beneficial to have a separate service that provided this data from Keycloak so not only is it available to other projects but also so that only the actual relevant data is returned.

NotActuallyTerry commented 9 months ago

For the purposes of LTPerms, I don't think tying it into a LT-specific service is a good idea. It'd be handy if it were standalone, allowing others (and us) to use the mod without needing a 'stack running

Rushmead commented 9 months ago

One of the reasons I suggested this is so that the mod is not directly communicating with Keycloak and having access to any data it likes, having an extra service outside of the mod ensures it only has access to the actual relevant data.

NotActuallyTerry commented 9 months ago

I don't think that will actually be an issue, considering fine-grained admin permissions is coming down the pipeline (which would prevent anything major) I also don't think tying LTPerms to work with our services specifically is a good idea. Right now (as far as I'm aware) it has no dependency on our technical infrastructure, and I want to keep it that way.

Rushmead commented 9 months ago

To be clear, I never specified one of our internal services. It could just as easy be a separate application. Allowing the mod direct access to the Keycloak instance makes me uncomfortable, but that's just my 2c.

NotActuallyTerry commented 9 months ago

There's probably a Keycloak extension that abstracts custom attributes out already anyway tbh