@oandriie/backstage-plugin-keycloak-backend
Version:
A Backend backend plugin for Keycloak
170 lines (123 loc) • 7.06 kB
Markdown
The Keycloak backend plugin integrates Keycloak into Backstage.
The Keycloak backend plugin has the following capabilities:
- Synchronization of Keycloak users in a realm
- Synchronization of Keycloak groups and their users in a realm
Install the Backstage package into the backend. When not integrating with a published package, clone the repository locally and add the Backstage as follows:
```console
yarn workspace backend add @janus-idp/backstage-plugin-keycloak-backend
```
1. Add the following configuration to the `app-config.yaml` file. The default schedule is a frequency of 30 minutes and a timeout of 3 minutes, please configure the schedule in the `app-config.yaml` as per your requirement.
```yaml title="app-config.yaml"
catalog:
providers:
keycloakOrg:
default:
baseUrl: https://<keycloak_host>
loginRealm: ${KEYCLOAK_REALM}
realm: ${KEYCLOAK_REALM}
clientId: ${KEYCLOAK_CLIENTID}
clientSecret: ${KEYCLOAK_CLIENTSECRET}
schedule:
frequency: { minutes: 30 }
timeout: { minutes: 3 }
```
1. Register the plugin in the `packages/backend/src/index.ts` file:
```ts title="packages/backend/src/index.ts"
const backend = createBackend();
/* highlight-add-next-line */
backend.add(import('@janus-idp/backstage-plugin-keycloak-backend'));
backend.start();
```
1. Optional: To configure custom transformer function for user/group to mutate the entity generated by the keycloak-backend. Create a new backend module with the `yarn new` command and add your custom user and group transformers to the `keycloakTransformerExtensionPoint`. Then install this new backend module into your backstage backend. Below is an example of how the backend module can be defined:
```ts title="plugins/<module-name>/src/module.ts"
/* highlight-add-start */
import {
GroupTransformer,
keycloakTransformerExtensionPoint,
UserTransformer,
} from '@janus-idp/backstage-plugin-keycloak-backend';
const customGroupTransformer: GroupTransformer = async (
entity,
realm,
groups,
) => {
/* apply transformations */
return entity;
};
const customUserTransformer: UserTransformer = async (
entity,
user,
realm,
groups,
) => {
/* apply transformations */
return entity;
};
/* highlight-add-end */
export const keycloakBackendModuleTransformer = createBackendModule({
pluginId: 'catalog',
moduleId: 'keycloak-transformer',
register(reg) {
reg.registerInit({
deps: {
/* highlight-add-start */
keycloak: keycloakTransformerExtensionPoint,
/* highlight-add-end */
},
/* highlight-add-start */
async init({ keycloak }) {
keycloak.setUserTransformer(customUserTransformer);
keycloak.setGroupTransformer(customGroupTransformer);
/* highlight-add-end */
},
});
},
});
```
***
**IMPORTANT**
The `pluginId` for the module **MUST** be set to `catalog` to match the `pluginId` of the `keycloak-backend` or else the module will fail to initialize.
***
Communication between Backstage and Keycloak is enabled by using the Keycloak API. Username/password or client credentials are supported authentication methods.
The following table describes the parameters that you can configure to enable the plugin under `catalog.providers.keycloakOrg.<ENVIRONMENT_NAME>` object in the `app-config.yaml` file:
| Name | Description | Default Value | Required |
| ---------------- | ------------------------------------------------------------------ | ------------- | ---------------------------------------------------- |
| `baseUrl` | Location of the Keycloak server, such as `https://localhost:8443`. | "" | Yes |
| `realm` | Realm to synchronize | `master` | No |
| `loginRealm` | Realm used to authenticate | `master` | No |
| `username` | Username to authenticate | "" | Yes if using password based authentication |
| `password` | Password to authenticate | "" | Yes if using password based authentication |
| `clientId` | Client ID to authenticate | "" | Yes if using client credentials based authentication |
| `clientSecret` | Client Secret to authenticate | "" | Yes if using client credentials based authentication |
| `userQuerySize` | Number of users to query at a time | `100` | No |
| `groupQuerySize` | Number of groups to query at a time | `100` | No |
When using client credentials, the access type must be set to `confidential` and service accounts must be enabled. You must also add the following roles from the `realm-management` client role:
- `query-groups`
- `query-users`
- `view-users`
If you have self-signed or corporate certificate issues, you can set the following environment variable before starting Backstage:
`NODE_TLS_REJECT_UNAUTHORIZED=0`
---
**NOTE**
The solution of setting the `NODE_TLS_REJECT_UNAUTHORIZED` environment variable is not recommended.
---
After configuring the plugin successfully, the plugin imports the users and groups each time when started.
After the first import is complete, you can select **User** to list the users from the catalog page:

You can see the list of users on the page:

When you select a user, you can see the information imported from Keycloak:

You can also select a group, view the list, and select or view the information imported from Keycloak for a group:
