Skip to main content

A project example

Background

Pluggoo is an AI powered web application helping students to learn vocabularies in different languages. Typically, flow:

  1. Teacher creates a homework with words the students should learn in a foreign language
  2. The student can read their homeworks and practice on the words

Pluggoo can also be used privately - a parent or student could set their own Pluggoo community and manage the homeworks themselves.

Roles

Pluggoo needs access control for the following roles:

  • System administrator - can do anything and used for support and setting up the system
  • Community administrator - can manage the community like adding groups, teachers and students and even delete the community
  • Group administrator - can manage the group like adding students and homeworks
  • Student - can read and practice on the homeworks
  • Backend service - need a role used by the backend which is used when enrolling new communities to ensure that the limit of communities per person is not exceeded

Entities

Pluggoo uses the following entities:

  • Community - represents typically a school or family
  • Group - represents typically a school class
  • Vocabulary - represents a homework for training words

Implementation

Pluggoo uses Akkess for storing all data. The data is stored as actors and nodes. The actors are the users and the nodes is used for the different entities.

Architecture

Pluggoo consists of the following parts:

  • FE app - a front end application built in React. FE is responsible for user interaction.
  • BE app - a back end application built in Node.js. BE is responsible for data validation, throttling, business logic etc. All sensitive traffic is proxied through BE before Akkess is called. BE also keeps secrets like API keys and is also responsible for integration with other systems.

Nodes

To store the Pluggoo data, the following Akkess nodes are used. The nodes are organized in a tree structure and the users are added to the nodes to give them access.

Authentication

Lots of schools use Chromebooks and Google accounts. Initially Pluggoo will only support Google as IdP. This can easily be extended to support other IdPs in future if needed.

IdP configuration example

The IdP configuration is made via Akkess IAM Console or via Authentication API. The configuration includes the issuer and audience for the IdP. The configuration also includes the mapping of the user's attributes to Akkess actor.

The example below shows the configuration for Google sign-in that will map email in the token to the actor's username attribute and name to the actor's name attribute.

{
"adapter": "OIDC",
"name": "Google sign-in",
"visibility": "PUBLIC",
"description": "Used for sign-in with Google account",
"adapterConfigOidc": {
"issuer": "accounts.google.com",
"audience": "*******************.apps.googleusercontent.com",
"usernameMapping": {
"attribute": "email"
},
"nameMapping": {
"attribute": "name",
"syncOption": "ALWAYS"
}
}
}

Permissions

Pluggoo has a set of custom permissions that are used to show / hide actions in the Pluggoo FE.

For example a GROUP_ADMIN is allowed to add users to a group meanwhile a STUDENT is not allowed to do that. Based on the signed-in user the Pluggoo FE will show / hide the actions.

Pluggoo permissions

  • pgoo.community-admin.manage
  • pgoo.community.manage
  • pgoo.group-admin.manage
  • pgoo.group.manage
  • pgoo.student.manage
  • pgoo.vocab.manage pgoo.vocab.practice

Permission configuration example

Permissions are configured in Akkess using the Akkess Account Console. The example below shows the configuration for the Pluggoo service.

// Endpoint
// policy/v1/applications/{applicationId}/service-definitions?returnUpdated=true

Partial payload

{
"key": "pgoo",
"name": "Pluggoo",
"keyLevelSeparator": ".",
"permissionDefinitions": [
{
"key": "pgoo.community-admin.manage",
"name": "Community admin",
"description": "Admin of a community. Is allowed to delete it.",
"status": "GA"
},
{
"key": "pgoo.community.manage",
"name": "Manage community",
"description": "Manage community name and participants",
"status": "GA"
},
{
"key": "pgoo.group-admin.manage",
"name": "Manage group admin",
"description": "Allowed to add and remove group admins",
"status": "GA"
},
{
"key": "pgoo.group.manage",
"name": "Manage group",
"description": "Manage group name and participants",
"status": "GA"
},
{
"key": "pgoo.student.manage",
"name": "Manage students",
"description": "Manage users with role STUDENT",
"status": "GA"
},
{
"key": "pgoo.vocab.manage",
"name": "Manage vocabulary homework",
"status": "GA"
},
{
"key": "pgoo.vocab.practice",
"name": "Practice vocabulary homework",
"description": "Allowed read and practice vocabulary homeworks",
"status": "GA"
}
]
}

Roles

Following roles are configured in Akkess. The roles are preferable configured using the Akkess Account Console.

  • SYSTEM_ADMIN
  • COMMUNITY_ADMIN
  • GROUP_ADMIN
  • STUDENT
  • BE_SERVICE

STUDENT role configuration example

The STUDENT has a mix of Akkess permissions for managing its actor data - manage myself. The permissions will be evaluated by Akkess when a user tries to access the data.

STUDENT also has a Pluggoo specific permission pgoo.vocab.practice which allows the student to practice on the vocabularies. The permission will be evaluated by Pluggoo FE when a user tries to access the data and hide actions that are not allowed for a STUDENT user.

// Endpoint
policy/v1/applications/{applicationId}/role-definitions?returnUpdated=true
Partial payload
{
"key": "STUDENT",
"name": "Student",
"servicePolicies": [
{
"serviceDefinitionSource": "CATALOG",
"serviceDefinitionKey": "iam.actor",
"permissions": [
{
"key": "permission.actor.myself.deactivate"
},
{
"key": "permission.actor.myself.delete"
},
{
"key": "permission.actor.myself.invite.delete"
},
{
"key": "permission.actor.myself.name.manage"
},
{
"key": "permission.actor.myself.read"
},
{
"key": "permission.actor.myself.withdraw"
}
]
},
{
"serviceDefinitionSource": "CATALOG",
"serviceDefinitionKey": "iam.node",
"permissions": [
{
"key": "permission.node.read",
"entities": [
{
"key": "entity.node",
"filterCondition": {
"fieldCondition": {
"field": "type",
"operator": "ANY_OF",
"values": [
"VOCABULARY",
"GROUP",
"COMMUNITY"
]
}
}
}
],
"rules": [
{
"key": "rule.node.access-on-level",
"operator": "ANY_OF",
"values": [
"NODE_DIRECT",
"NODE_DESCENDANT"
]
}
]
}
]
},
{
"serviceDefinitionSource": "APPLICATION",
"serviceDefinitionKey": "pgoo",
"permissions": [
{
"key": "pgoo.vocab.practice"
}
]
}
]
}