Skip to content

Commit

Permalink
feat: Automatically import all the required configurations into the K…
Browse files Browse the repository at this point in the history
…eycloak and OpenFGA platforms. The new docker compose file, called 'docker-compose-import.yaml, uses the 'openfga/cli' image to import the OpenFga authorization schema
  • Loading branch information
embesozzi committed Nov 7, 2023
1 parent a816d52 commit ba93d12
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 163 deletions.
51 changes: 17 additions & 34 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Another cool feature of custom extension is its capability to discover the OpenF
2. Execute following Docker Compose command to start the deployment

```sh
docker-compose -f docker-compose.yml -f docker-compose-apps.yml -f docker-compose-openfga.yml up
docker-compose -f docker-compose.yml -f docker-compose-apps.yml -f docker-compose-openfga.yml -f docker-compose-import.yml up
```

3. To be able to use this environment, you need to add this line to your local HOSTS file:
Expand All @@ -62,43 +62,31 @@ Another cool feature of custom extension is its capability to discover the OpenF
| Store API | http://store-api:9091 | | Custom image |


## Post configuration steps

### OpenFGA
1. Import the [OpenFGA authorization schema for Keycloak](openfga/keycloak-authorization-model.json):
```bash
cd openfga
./import.sh
```
2. As the result you will see the following OpenFGA Authorization Model in the [OpenFGA Playground Console](http://localhost:8080/playground) :
## Review configuration (optional)

![openfga-keycloak-authorization-model](doc/images/openfga-authz-model.png)
>
> In this new version of the workshop, we automatically import all the required configurations into the Keycloak and OpenFGA platforms 😄 🪄
>
### Keycloak Platform
- You will find that the OpenFGA Event Listener 'openfga-events-publisher' extension in Keycloak is enabled.

### Keycloak
1. Enable the Keycloak OpenFGA Event Listener extension in Keycloak:

* Open [administration console](http://keycloak:8081)
* Choose realm
* Realm settings
* Select `Events` tab and add `openfga-events-publisher` to Event Listeners.
* [Administration console](http://keycloak:8081) > Realm settings > `openfga-events-publisher`

<img src="doc/images/kc-admin-events.png" width="80%" height="80%">

2. Proceed to initialize the PoC:

Execute the following [script](keycloak/initialize-poc.sh) to initialize the PoC:

```bash
docker exec keycloak /bin/bash /opt/keycloak/initialize-poc.sh
```

This script will create the OAuth Clients and the following Users and Role Model:
- The following roles and demo users have already been created in Keycloak.

![users](doc/images/users.png)

The password for all the users is `demo1234!`

Once these steps are finished, the Keycloak OpenFGA Event Publisher extension has proceed to send these events over HTTP to the OpenFGA solution. Here, are all tuples stored.
### OpenFGA Platform
- You will see the following OpenFGA Authorization Model in the [OpenFGA Playground Console](http://localhost:3000/playground) and the Tuples tab:

<img src="doc/images/openfga-tuples.png" width="80%" height="80%">

- Once the workshop is deployed, the Keycloak OpenFGA Event Publisher extension proceeds to send these events over HTTP to the OpenFGA solution. Here, all tuples are stored.

| User | Relation | Object |
| ------------------------- |:-----------------------------:|:---------------------:|
Expand All @@ -109,16 +97,11 @@ Another cool feature of custom extension is its capability to discover the OpenF
| user:richard | assignee | role:admin-catalog |


The users are identified by the value of the claim sub in the [OpenFGA Playground](http://localhost:3000/playground), see the Tuples tab:

<img src="doc/images/openfga-tuples.png" width="50%" height="50%">


3. Restart the apps (containers: `store` and `store-api`)
The users are identified by the value of the claim sub.

## Test cases
As an example, we will implement an Product Catalog web application that has the following requirements:
* Only authenticated user with MFA can access to the application
* Only authenticated user can access to the application
* Product can be viewed by their Analyst
* Product can be edited by their Admin
* Global Admin users can view or edit any Product
Expand Down
38 changes: 38 additions & 0 deletions docker-compose-import.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
version: '3.8'

services:
openfga-import:
depends_on:
openfga:
condition: service_healthy
image: openfga/cli:v0.2.0
container_name: openfga-import
restart: "no"
command: "store create --name keycloak --api-url http://openfga:8080 --model /tmp/model.dsl"
networks:
- default
volumes:
- $PWD/openfga:/tmp
keycloak-import:
depends_on:
openfga:
condition: service_healthy
keycloak:
condition: service_healthy
openfga-import:
condition: service_completed_successfully
image: quay.io/keycloak/keycloak:21.1
container_name: keycloak-import
restart: "no"
entrypoint: [
"sh",
"-c",
"echo 'Waiting 10 secs for importing Keycloak configuration...';sleep 10;/opt/keycloak/import.sh"
]
environment:
KEYCLOAK_URL: http://keycloak:8081
KEYCLOAK_USER: admin
KEYCLOAK_PASSWORD: password
volumes:
- $PWD/keycloak/initialize-poc.sh:/opt/keycloak/import.sh

7 changes: 6 additions & 1 deletion docker-compose-openfga.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,9 @@ services:
- default
ports:
- "8080:8080" #http
- "3000:3000" #playground
- "3000:3000" #playground
healthcheck:
test: ["CMD", "/usr/local/bin/grpc_health_probe", "-addr=openfga:8081"]
interval: 3s
timeout: 30s
retries: 3
13 changes: 7 additions & 6 deletions keycloak/initialize-poc.sh
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@

echo "Creating PoC Users, Role Model, User Role Assigments and Clients"

/opt/keycloak/bin/kcadm.sh config credentials --server http://localhost:8081 --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD
/opt/keycloak/bin/kcadm.sh config credentials --server $KEYCLOAK_URL --realm master --user $KEYCLOAK_USER --password $KEYCLOAK_PASSWORD

# Enable openfga-events
/opt/keycloak/bin/kcadm.sh update events/config -s 'eventsListeners=["openfga-events-publisher","jboss-logging"]'

# Clients
/opt/keycloak/bin/kcadm.sh create clients -r master -s clientId=portal -s publicClient=true -s 'redirectUris=["http://store:9090/callback"]' -s 'webOrigins=["http://store:9090"]' -s 'attributes={ "post.logout.redirect.uris": "http://store:9090/home?action=logout", "access.token.lifespan": 3600}' -o

# Users
/opt/keycloak/bin/kcadm.sh create users -r master -s username=paula -s firstName=Paula -s lastName=Von -s enabled=true -s [email protected]
Expand All @@ -25,8 +31,3 @@ echo "Creating PoC Users, Role Model, User Role Assigments and Clients"
/opt/keycloak/bin/kcadm.sh add-roles -r master --uusername paula --rolename analyst-catalog
/opt/keycloak/bin/kcadm.sh add-roles -r master --uusername richard --rolename admin-catalog


# Clients
/opt/keycloak/bin/kcadm.sh create clients -r master -s clientId=portal -s publicClient=true -s 'redirectUris=["http://store:9090/callback"]' -s 'webOrigins=["http://store:9090"]' -s 'attributes={ "post.logout.redirect.uris": "http://store:9090/home?action=logout", "access.token.lifespan": 3600}' -o


23 changes: 0 additions & 23 deletions openfga/import.sh

This file was deleted.

98 changes: 0 additions & 98 deletions openfga/keycloak-authorization-model.json

This file was deleted.

11 changes: 11 additions & 0 deletions openfga/model.dsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
model
schema 1.1
type group
relations
define assignee: [user]
type role
relations
define assignee: [user] or assignee from parent or assignee from parent_group
define parent: [role]
define parent_group: [group]
type user
3 changes: 2 additions & 1 deletion store-oidc-app/vue.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
module.exports = {
devServer: {
disableHostCheck: true
disableHostCheck: true,
progress: false
}
}

0 comments on commit ba93d12

Please sign in to comment.