Skip to content

Commit

Permalink
docs: add multitenancy keycloak integration tutorials (#793)
Browse files Browse the repository at this point in the history
Signed-off-by: Pat Losoponkul <[email protected]>
Signed-off-by: Pete Vielhaber <[email protected]>
Signed-off-by: patlo-iog <[email protected]>
Co-authored-by: Pete Vielhaber <[email protected]>
Co-authored-by: Yurii Shynbuiev - IOHK <[email protected]>
  • Loading branch information
3 people authored Nov 22, 2023
1 parent 042da36 commit f050e35
Show file tree
Hide file tree
Showing 7 changed files with 668 additions and 4 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ As a result, you can concentrate on crafting self-sovereign identity solutions u
* HTTP events notification
* Cardano as a distributed ledger
* Secrets management with Hashicorp vault
* Multi-tenancy (coming soon)
* Multi-tenancy

## Example use cases

Expand Down
1 change: 1 addition & 0 deletions docs/docusaurus/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Whether you are new to [self-sovereign identity (SSI)](/docs/concepts/glossary#s


Throughout all code examples in tutorials, the following conventions are in use:
* Issuer Keycloak is hosted at `http://localhost:9980/`
* Issuer Agent is hosted at `http://localhost:8080/prism-agent/`
* Holder Agent is hosted at `http://localhost:8090/prism-agent/`
* Verifier Agent is hosted at `http://localhost:8100/prism-agent/`
Expand Down
175 changes: 175 additions & 0 deletions docs/docusaurus/multitenancy/tenant-migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Migration from `apikey` to `JWT` authentication

PRISM Agent authentication supports multiple authentication methods simultaneously, which means the user can seamlessly use any available credentials including `apikey` or `JWT` to access the wallet.
The agent's [UMA](/docs/concepts/glossary#uma) permission resource also exposes self-service permission endpoint, allowing users to manage the permissions for their wallets.
It allows users to transition from `apikey` to `JWT` authentication without admin intervention.intervention.

## Roles

In the migration process from `apikey` to `JWT`, there is only one role:

1. Tenant

## Prerequisites

1. Keycloak up and running
2. Keycloak is configured the same as in [Tenant Onboarding Self-Service](./tenant-onboarding-self-service.md)
3. PRISM Agent up and running
4. PRISM Agent is configured the same as in [Tenant Onboarding Self-Service](./tenant-onboarding-self-service.md)
5. The user has access to the wallet using `apikey`. (See [Tenant Onboarding](./tenant-onboarding.md))
6. The user has an account registered on Keycloak

## Overview

This tutorial outlines the steps to transition from `apikey` to `JWT` authentication.
Initially, users have wallet access through the `apikey` method.
To migrate to `JWT` authentication, users can create a new UMA permission for their wallet and grant permission to their Keycloak account.

## Endpoints

### Agent endpoints
| Endpoint | Description | Role |
|--------------------------------------------|--------------------------------------|--------|
| `GET /wallets` | List the wallets on PRISM Agent | Tenant |
| `POST /wallets` | Create a new wallet on PRISM Agent | Tenant |
| `POST /wallets/{walletId}/uma-permissions` | Create a uma-permission for a wallet | Tenant |
| `GET /did-registrar/dids` | List the DIDs inside the wallet | Tenant |

### Keycloak endpoints
| Endpoint | Description | Role |
|------------------------------------------------------|-----------------------|--------|
| `POST /realms/{realm}/protocol/openid-connect/token` | Issue a new JWT token | Tenant |

## Tenant interactions

### 1. Check the existing wallets using `apikey`

This tutorial assumes the tenant can access the wallet using `apikey`.
Before granting more permission to the wallet, the `walletId` must be identified.
To find the wallet, list them using `apikey`.

```bash
curl -X 'GET' \
'http://localhost:8080/prism-agent/wallets' \
-H 'accept: application/json' \
-H "apikey: my-tenant-token"
```

Make sure to use the correct `apikey` from the pre-requisite.

Response Example:

```json
{
"self": "/wallets",
"kind": "WalletPage",
"pageOf": "/wallets",
"contents": [
{
"id": "99734c87-5c9d-4697-b5fd-dea4e9590ba7",
"name": "my-wallet",
"createdAt": "2023-01-01T00:00:00Z",
"updatedAt": "2023-01-01T00:00:00Z"
}
]
}
```

### 2. Get the access token on keycloak

Run this command to log in and get the access token

```bash
curl -X 'POST' \
'http://localhost:9980/realms/my-realm/protocol/openid-connect/token' \
-d "grant_type=password" \
-d "client_id=admin-cli" \
-d "username=alice" \
-d "password=1234"
```

Make sure to use the correct username and password.
Special attention on the `client_id`; this should be the actual `client_id` of the frontend application that logs the user in.
For this tutorial, it is OK to use `admin-cli`

Example token response (some fields omitted for readability)

```json
{
"access_token": "eyJhbGciOi...7ocDHofUDQ",
"refresh_token": "eyJhbGciOi...otsEEi4eQA",
...
}
```

### 3. Extract the subject ID from JWT

When creating a UMA permission, it is important to provide the subject ID to grant permission.
To get the subject ID of the tenant, one can inspect the JWT payload `sub` claim.

Run this command to extract the `sub` claim of the token from previous step.

```bash
echo 'eyJhbGciOi...7ocDHofUDQ' | cut --delimiter='.' --fields=2 | base64 --decode | jq -r '.sub'
```

Example result

```log
4a5c6ac9-12f5-4d1e-b8f2-667525c083fd
```

### 4. Grant the user permission to the wallet

UMA permission can be added to the current wallet, giving Keycloak users access.
To do this, invoke the `POST /wallets/{walletId}/uma-permissions` endpoint on the agent.

```bash
curl -X 'POST' \
'http://localhost:8080/prism-agent/wallets/99734c87-5c9d-4697-b5fd-dea4e9590ba7/uma-permissions' \
-v \
-H 'accept: */*' \
-H "apikey: my-tenant-token" \
-H 'Content-Type: application/json' \
-d '{
"subject": "205e04b7-0158-41b0-89c3-f91c3a09f89b"
}'
```

Make sure to use the correct `subject` for the user and the correct `walletId` from the step earlier.

The response should return the status `200 OK` in case of successful permission creation.

### 5. Perform a simple action to verify access to PRISM Agent

After successful UMA permission creation, the user should be able to use the `JWT` token to authenticate the wallet.
List the wallet using a new `Authorization` header. The listed wallets should contain the wallet with the same ID in step 1.

```bash
curl -X 'GET' \
'http://localhost:8080/prism-agent/wallets' \
-H 'accept: application/json' \
-H 'Authorization: Bearer eyJhbGciOi...7ocDHofUDQ'
```

Make sure to use the correct `JWT` from step 2.

Response Example:

```json
{
"self": "/wallets",
"kind": "WalletPage",
"pageOf": "/wallets",
"contents": [
{
"id": "99734c87-5c9d-4697-b5fd-dea4e9590ba7",
"name": "my-wallet",
"createdAt": "2023-01-01T00:00:00Z",
"updatedAt": "2023-01-01T00:00:00Z"
}
]
}
```

This response indicates that the user should be able to perform any wallet interaction with the `JWT` and `apikey` interchangeably.
Loading

0 comments on commit f050e35

Please sign in to comment.