Group-based role assignment
Manually assigning roles to users in your application, such as viewer, member, editor, or admin, can be a time-consuming task for administrators, particularly in large enterprises where access needs frequently change. Scalekit streamlines this process by allowing administrators to establish workflows that automatically update your app about the roles to assign to users.
Introduction
Section titled “Introduction”A common strategy that organization administrators use for managing varying access levels is to group users based on their specific access requirements. For example, if you are developing an application similar to GitHub with roles like maintainer, writer, and viewer, customer administrators can create user groups for each role within their directory provider.
Scalekit notifies your application when administrators create groups or add users to them, enabling you to take necessary actions such as creating or modifying user roles as directed by the organization’s administrator. Regardless of the directory provider your customers use, Scalekit delivers normalized information, eliminating the need for data transformation across different providers. A user can belong to multiple groups and, as a result, may be assigned multiple roles in your application, depending on your role-mapping logic.
Enabling group-based role assignment
Section titled “Enabling group-based role assignment”To enable administrators to map groups to roles in your app:
- Go to the Scalekit dashboard
- Select “SCIM Provisioning”
- Switch to the “Role assignment” tab
- Register your app’s roles
The first role you create in your app becomes the default role automatically. This means users who don’t belong to any specific group will be assigned this role upon account creation. To change the default role, navigate to the role settings, click the ”…” menu next to the desired role, select “Edit,” and toggle the “Set as default role” option.
Listening to events
Section titled “Listening to events”Scalekit continuously monitors updates from your customers’ directory providers and sends event payloads to your application via a registered webhook endpoint. To set up these endpoints and manage subscriptions, refer to the Scalekit dashboard documentation.
In this scenario, you will listen for the organization.directory.user_updated
event to determine a user’s role from the payload. Scalekit automatically includes a role property relevant to your app, based on the role information configured in the Scalekit dashboard.
Webhook endpoint for role updates
// Webhook endpointapp.post('/webhook', async (req, res) => { // Extract event data const event = req.body; const { email, name, roles } = event.data; console.log('Admin added user to Viewer Group -> Scalekit informs Your App\n');
// Destructure role_name from roles array const roleName = roles.length > 0 ? roles[0].role_name : null; console.log('Role name received:', roleName);
// Logic to update user role and permissions await assignRole(roleName, email); console.log('App updated access for user:', email);
res.status(201).json({ message: 'Role assigned', });});
from fastapi import FastAPI, Request
app = FastAPI()
@app.post("/webhook")async def api_webhook(request: Request): # Parse request body body = await request.body() payload = json.loads(body.decode())
# Extract user data user_roles = payload['data']['roles'] user_email = payload['data']['email']
print("User Roles:", str(roles)) print("User email:", str(email))
# Business logic to assign role await assign_role(roles[0], email)
return JSONResponse( status_code=201, content='' )
@PostMapping("/webhook")public String webhook(@RequestBody String body, @RequestHeader Map<String, String> headers) { ObjectMapper mapper = new ObjectMapper();
try { JsonNode node = mapper.readTree(body); JsonNode roles = node.get("data").get("roles"); String email = node.get("data").get("email").asText();
System.out.println(roles); System.out.println(email); // Add role to user
} catch (IOException e) { return "error"; }
return "ok";}
mux.HandleFunc("POST /webhook", func(w http.ResponseWriter, r *http.Request) { // Read request body bodyBytes, err := io.ReadAll(r.Body) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return }
// Parse webhook payload var body struct { Data map[string]interface{} `json:"data"` }
err = json.Unmarshal(bodyBytes, &body) if err != nil { http.Error(w, err.Error(), http.StatusBadRequest) return }
// Extract user data roles := body.Data["roles"] email := body.Data["email"]
fmt.Println("Roles: ", roles) fmt.Println("Email: ", email)
w.WriteHeader(http.StatusOK)})