...
Open the “Projects” tab and make sure you’re on the “Cluster IAM” root organization. Then click on “Create New Project” and enter a name for the project (e.g.: “unique”).
...
3.0.1 Project Settings
Once you have created the project, make sure you have these settings checked.
...
3.1 Setup an application
Once you’ve created a project in the root organization an application needs to be setup and configured inside that project. Click on the tile with the “+” and enter an application name (e.g.: “unique-app”). For the type of the application, choose “WEB”.
...
5. Adding Zitadel Actions
tbd - work in progress
6. Configuring SSO
tbd - work in progress
OLD DOCS (will get removed soon - wip)
Scope
This tutorial only applies for clients with a Customer Managed Tenant.
...
Note |
---|
If you add any action the function must string match the name of the action else it is not called. |
Add one new action called addGrant
with this content
ZITADEL Actions are custom scripts that you can define to run at specific points during the authentication and authorization processes. After an action was added, it needs to be used by assigning it to one of the available Trigger Types.
Currently the following Actions need to be configured (as required).
Action: addGrant
Create a new
addGrant
actionNote: add the appropriate roles based on needs
Code Block |
---|
function addGrant(ctx, api) {
api.userGrants.push({
projectID: '<Resource ID of granted project Unique Apps>',
projectGrantID: '<Grant ID of granted project Unique Apps>',
roles: ['chat.chat.basic'] // default roles users get
});
} |
The addGrant
actions needs to react on the Trigger Type “Post Creation” because we want to add the default roles for the user after creation.
...
Action: addUserGroupsMetadataEntra
If Entra is used as an IDP, create the action
addUserGroupsMetadataEntra
...
Code Block | ||
---|---|---|
| ||
const logger = require("zitadel/log") const http = require('zitadel/http') function addUserGroupsMetadataEntra(ctx, api) { logger.log('Writing 'chat.chat.unlimited', 'chat.chat.upload', 'chat.knowledge.read', 'chat.knowledge.write'] }); } |
This action has to be added as a Post Creation trigger in External Authentication flow.
Add another action called setEmailVerified
with this content
Code Block |
---|
function setEmailVerifiedgroup info on user metadata.'); const claims = ctx.claimsJSON(); const parsedGroups = JSON.parse(claims).groups; // Enable for debugging // logger.log('Claims: ' + JSON.stringify(claims)); // logger.log('Parsed groups: ' + JSON.stringify(parsedGroups)); // Get names with additional call to Graph API const batchRequests = []; for (const groupId of parsedGroups) { batchRequests.push({ "id": groupId, "method": "GET", "url": `/groups/${groupId}` }); } const graphApiBatchResponse = http.fetch('https://graph.microsoft.com/v1.0/$batch', { method: 'POST', headers: { "Authorization": `Bearer ${ctx.accessToken}`, "Content-Type": "application/json" }, body: { requests: batchRequests } }).json(); const entraGroups = []; for (const apiResponse of graphApiBatchResponse.responses) { const groupId = apiResponse.id; const groupName = apiResponse.body.displayName; entraGroups.push({ "id": groupId, "displayName": groupName, }); } // Check if groups are valid and do not contain empty string values if (entraGroups.some(group => group.id === "" || group.displayName === "")) { logger.log('Invalid groups found, skipping metadata update.'); return; } // append metadata to user api.v1.user.appendMetadata("groups", entraGroups); } |
After you’ve added the action, you need to assign it to a trigger.
...
Action: addUserGroupsMetadataOidc
Code:
Code Block |
---|
const logger = require("zitadel/log")
function addUserGroupsMetadataOidc(ctx, api) {
logger.log('Writing group info on user metadata.');
const claims = ctx.claimsJSON();
const parsedGroups = JSON.parse(claims).groups;
// Enable for debugging
// logger.log('Claims: ' + JSON.stringify(claims));
// logger.log('Parsed groups: ' + JSON.stringify(parsedGroups));
// To sync we need need the external groups' ID and display name
// Verify how the groups are sent on the ID token and adapt to the desired format.
let groups = parsedGroups.map(group => {
return {
"id": group.id,
"displayName": group.displayName,
};
});
// Check if groups are valid and do not contain empty string values
if (groups.some(group => group.id === "" || group.displayName === "")) {
logger.log('Invalid groups found, skipping metadata update.');
return;
}
// append metadata to user
api.v1.user.appendMetadata("groups", groups);
} |
Flow Type: External Authentication
Trigger Type: Post Authentication
Actions: addUserGroupsMetadataOidc
...
Action: addUserGroupsMetadataSaml
Code:
Code Block |
---|
const logger = require("zitadel/log")
function addUserGroupsMetadataSaml(ctx, api) {
logger.log('Writing group info on user metadata.');
const sentGroups = ctx.v1.providerInfo?.attributes["groups"];
// Enable for debugging
// logger.log('Parsed groups: ' + JSON.stringify(sentGroups));
// To sync we need need the external groups' ID and display name
// Verify how the groups are sent on the ID token and adapt to the desired format.
let groups = sentGroups.map(group => {
return {
"id": group.id,
"displayName": group.displayName,
};
});
// Check if groups are valid and do not contain empty string values
if (groups.some(group => group.id === "" || group.displayName === "")) {
logger.log('Invalid groups found, skipping metadata update.');
return;
}
// append metadata to user
api.v1.user.appendMetadata("groups", groups);
} |
Flow Type: External Authentication
Trigger Type: Post Authentication
Action: addUserGroupsMetadataSaml
This action needs an additional action:
Action: prefilRegisterFromSAML
Code:
Code Block |
---|
function prefilRegisterFromSAML(ctx, api) { if (ctx.v1.externalUser?.externalIdpId != "xxxxxxx") { return } let firstname = ctx.v1.providerInfo?.attributes["GivenName"]; let lastname = ctx.v1.providerInfo?.attributes["Surname"]; let email = ctx.v1.providerInfo?.attributes["emailaddress"]; if (firstname) { api.setFirstName(firstname[0]); } if (lastname) { api.setLastName(lastname[0]); } if (email) { api.setEmail(email[0]); api.setEmailVerified(true); api.setPreferredUsername(email[0]); } } |
This action has to be added as a Pre Creation trigger in External Authentication flow.
...
|
Flow Type: External Authentication
Trigger Type: Post Authentication
Actions: prefilRegisterFromSAML
Don’t forget to add the IDP ID in the code above. You will find it in the IDP settings when clicking on the IDP and getting the ID from the URL
...
6. Configuring SSO
tbd - work in progress
...
Author |
---|