Skip to main content

Role-Based Access Control

Symphony supports role-based access control (RBAC) to manage what authenticated users can see and do. RBAC maps group memberships from your identity provider to roles in Symphony, and each role defines the permissions granted to its members.

This page covers the complete process of configuring RBAC, from setting up groups in your identity provider through to creating roles and assignments in Symphony.

How RBAC Works

The RBAC flow has three stages:

  1. Groups—your identity provider (Keycloak, Okta, Azure AD, etc.) authenticates the user and includes their group memberships in the OIDC token as a claim (typically named groups).
  2. Assignments—Symphony reads the groups from the token and looks up which roles are assigned to each group.
  3. Roles—each matched role defines a set of permissions (which messaging subjects the user can publish to and subscribe from) and which extensions are visible in the UI.

The user's effective permissions are the union of all permissions from all matched roles.

Prerequisites

Before configuring RBAC you need:

  • A working Symphony deployment with OIDC authentication configured
  • Administrative access to your OIDC identity provider (to configure groups and claims)
  • Knowledge of the group structure you want to map to Symphony roles

Step 1: Configure Groups in Your Identity Provider

Symphony receives group memberships from the OIDC token. Your identity provider must be configured to include these groups in the token. The exact steps depend on your provider.

Keycloak

Keycloak is the default OIDC provider for Symphony deployments.

Creating Groups

  1. Log in to the Keycloak Admin Console.
  2. Select the realm used by Symphony (e.g., Symphony).
  3. Navigate to Groups in the left sidebar.
  4. Click Create group and enter a name, e.g., symphony-admins.
  5. Repeat for other groups you need, e.g., symphony-engineers, symphony-analysts.
  6. Navigate to Users, select a user, click the Groups tab, and click Join Group to add them to the appropriate groups.

Adding the Groups Claim to Tokens

By default, Keycloak does not include group memberships in OIDC tokens. You need to add a protocol mapper:

  1. Navigate to Clients and select the client used by Symphony (the one matching oidc.uiclientid in symphony.config).
  2. Select the Client scopes tab.
  3. Click on the dedicated scope for the client (e.g., symphony-ui-dedicated).
  4. Click Configure a new mapper (or Add mapper > By configuration).
  5. Select Group Membership.
  6. Configure the mapper:
    • Name: groups
    • Token Claim Name: groups
    • Full group path: Off (recommended—this provides short group names like symphony-admins rather than full paths like /symphony-admins)
    • Add to ID token: On
    • Add to access token: On
    • Add to userinfo: On
  7. Click Save.

If you have an LDAP or Active Directory federation configured in Keycloak, groups from the external directory are automatically available once the federation is set up with group mapping enabled. The protocol mapper above will include those federated groups in the token.

Federating Groups from LDAP/Active Directory

If your organisation manages groups in LDAP or Active Directory:

  1. Navigate to User Federation in the Keycloak Admin Console.
  2. Add or select your LDAP provider.
  3. Select the Mappers tab.
  4. Click Add mapper and select group-ldap-mapper.
  5. Configure the mapper:
    • Name: ldap-groups
    • LDAP Groups DN: the base DN for your groups, e.g., ou=Groups,dc=example,dc=com
    • Group Name LDAP Attribute: cn
    • Group Object Classes: groupOfNames (or group for Active Directory)
    • Membership LDAP Attribute: member
    • Membership Attribute Type: DN
    • Mode: READ_ONLY
  6. Click Save and then Sync LDAP Groups to Keycloak.

After synchronisation, LDAP groups appear in Keycloak's Groups section and will be included in tokens via the protocol mapper configured above.

Okta

  1. In the Okta Admin Console, navigate to Directory > Groups.
  2. Create groups (e.g., symphony-admins, symphony-engineers) or use existing groups.
  3. Assign users to groups.
  4. Navigate to Applications, select the Symphony application.
  5. Under Sign On > OpenID Connect ID Token, click Edit.
  6. Set Groups claim type to Filter.
  7. Set Groups claim filter: claim name groups, filter Matches regex with value .* (to include all groups) or a more specific pattern.
  8. Click Save.

If your Okta instance is connected to Active Directory via the Okta AD Agent, AD groups are available as Okta groups and can be included in the claim.

Azure AD (Microsoft Entra ID)

  1. In the Azure portal, navigate to Azure Active Directory > Groups.
  2. Create security groups (e.g., symphony-admins, symphony-engineers) or use existing ones.
  3. Assign users to the groups.
  4. Navigate to App registrations, select the Symphony application.
  5. Under Token configuration, click Add groups claim.
  6. Select Security groups (or All groups).
  7. Under Customize token properties by type, ensure Group ID is selected for both ID and Access tokens.
  8. Click Add.

By default, Azure AD includes group object IDs (GUIDs) rather than names. To use group names instead, you can configure the optional claim to emit dns_domain_and_sam_account_name or sam_account_name if your directory supports it. Alternatively, use the group object IDs as the group identifiers in your Symphony role assignments.

Auth0

  1. In the Auth0 Dashboard, navigate to User Management > Roles or use Organizations with role assignments.
  2. Create roles (e.g., symphony-admins, symphony-engineers).
  3. Assign users to roles.
  4. Create a Rule or Action (under Actions > Flows > Login) to add group/role information to the token:
exports.onExecutePostLogin = async (event, api) => {
const namespace = 'https://symphony.example.com/';
api.idToken.setCustomClaim(namespace + 'groups', event.authorization?.roles || []);
api.accessToken.setCustomClaim(namespace + 'groups', event.authorization?.roles || []);
};
  1. In symphony.config, set rbac.groups_claim to match the namespaced claim name:
{
"rbac": {
"groups_claim": "https://symphony.example.com/groups"
}
}

Auth0 requires a namespace prefix for custom claims in tokens. The groups_claim setting in Symphony must match the full claim name including the namespace.

Google Workspace

Google Workspace does not natively include group memberships in OIDC tokens. You can work around this by:

  • Using a third-party identity broker (such as Keycloak) that federates Google identities and adds group claims from Google Directory.
  • Using the admin_subject setting in symphony.config to designate administrators by their Google email address, and managing other access through API key capabilities.

Step 2: Configure symphony.config

Edit the rbac section of symphony.config to tell Symphony how to read group information from the OIDC token and which group or user should have administrative access.

{
"rbac": {
"groups_claim": "groups",
"default_role": "viewer",
"admin_group": "symphony-admins",
"admin_subject": ""
}
}
KeyDescription
groups_claimName of the JWT claim containing the user's group memberships. Default: groups. Change this if your identity provider uses a different claim name (e.g., a namespaced claim for Auth0).
default_roleRole assigned to users whose groups do not match any role assignment. Default: viewer.
admin_groupName of the group that grants the symphony-admin role. Users in this group have full administrative access.
admin_subjectOIDC subject identifier (typically a user ID or email) that grants the symphony-admin role. Use this when you cannot use group-based admin designation.
bootstrapSet to true to acknowledge that bootstrap mode is intentional and suppress the warning in the UI. Default: false.

You must set either admin_group or admin_subject (or both) to exit bootstrap mode. Until one of these is set, all authenticated users have administrator access.

Restart Symphony after editing the configuration:

# Linux
sudo systemctl restart symphony

# Docker Compose
docker compose restart symphony

# Kubernetes
kubectl rollout restart deployment/symphony

Step 3: Verify the Groups Claim

Before creating roles and assignments, confirm that Symphony is receiving group information from the OIDC token. Log in to Symphony and navigate to Administration > Users. Select a user to see their resolved roles.

If you have configured admin_group and the logged-in user is a member of that group, they should already have the symphony-admin role. If the user has no roles and is not in bootstrap mode, the default_role (typically viewer) is assigned.

You can also inspect the OIDC token directly to verify the groups claim is present. Most identity providers include a token introspection or debugging tool:

  • Keycloak: navigate to Clients > [your client] > Client scopes > Evaluate and select a user to preview the token content.
  • Okta: use the Token Preview tool under Security > API.
  • Azure AD: use the JWT decoder at jwt.ms to inspect a token.

Step 4: Create Roles

Symphony includes two built-in roles:

  • symphony-admin—full access to all messaging subjects and all extensions. Cannot be modified or deleted.
  • viewer—read-only access to services and extensions. Can invoke services but cannot control extensions.

For most deployments you will want to create additional roles that grant access to specific extensions or capabilities.

  1. Navigate to Administration > Roles.
  2. Click Create Role.
  3. Fill in the role definition:
FieldDescriptionExample
NameUnique identifierdata-engineer
DescriptionHuman-readable purposeAccess to data integration extensions
Publish AllowMessaging subjects the role can send to (one per line)cirata.extensions.datamigrator.>
Subscribe AllowMessaging subjects the role can receive from (one per line)cirata.extensions.datamigrator.>
Visible ExtensionsExtension prefixes visible in the sidebar (one per line, * for all)datamigrator
  1. Click Save.

How Extension Visibility Works

Extension visibility is determined by the role's Subscribe Allow permissions. An extension only appears in the sidebar if the user's effective subscribe permissions cover the extension's NATS subject namespace (cirata.extensions.<prefix>.>).

This means that even if an extension has been shared with a user's account, it will not appear in the UI unless the user has a role granting subscribe access to that extension's subjects. This ensures a consistent experience—users only see extensions they can actually interact with.

The Visible Extensions field provides additional explicit control over sidebar visibility beyond what the subject permissions allow. If both are configured, both conditions must be satisfied for the extension to appear.

Understanding Permissions

Permissions are defined as messaging subject patterns using the following wildcards:

  • *—matches exactly one segment (e.g., cirata.extensions.*.info matches cirata.extensions.myext.info)
  • >—matches one or more segments (e.g., cirata.extensions.> matches everything under cirata.extensions.)

Common permission patterns:

PatternGrants Access To
cirata.>Everything (admin level)
cirata.services.>All Symphony services (read/invoke)
cirata.extensions.>All extensions
cirata.extensions.iceflow.>Only the Ice Flow extension
cirata.extensions.datamigrator.>Only the Data Migrator extension

Infrastructure subjects (_INBOX.>, $JS.>, $KV.>, $SRV.>, $SYS.REQ.USER.INFO, $O.>) are included automatically for all users and do not need to be added to role definitions.

Example Roles

Data Engineer—access to data integration extensions:

Name:               data-engineer
Description: Access to data integration extensions
Publish Allow: cirata.extensions.datamigrator.>
cirata.extensions.iceflow.>
cirata.services.>
Subscribe Allow: cirata.extensions.datamigrator.>
cirata.extensions.iceflow.>
cirata.services.>
Visible Extensions: datamigrator
iceflow

Analyst—read-only access to dashboards and services:

Name:               analyst
Description: Read-only access to services and dashboards
Publish Allow: cirata.services.>
Subscribe Allow: cirata.services.>
cirata.extensions.>
Visible Extensions: *

Step 5: Create Role Assignments

Role assignments map groups from your identity provider to roles in Symphony.

  1. Navigate to Administration > Assignments.
  2. Click Create Assignment.
  3. Enter the Group identifier exactly as it appears in the OIDC token's groups claim. This might be:
    • A short group name: symphony-engineers
    • A full LDAP DN: CN=DataEngineers,OU=Groups,DC=corp,DC=example,DC=com
    • An Azure AD object ID: a1b2c3d4-e5f6-7890-abcd-ef1234567890
  4. Select one or more Roles to assign to members of this group.
  5. Click Save.

Example Assignments

GroupRoles
symphony-adminssymphony-admin
data-engineeringdata-engineer, viewer
analyticsanalyst
operationsviewer

A user who belongs to multiple groups receives the union of all roles assigned to those groups. For example, a user in both data-engineering and analytics would receive the permissions of data-engineer, viewer, and analyst combined.

Step 6: Verify the Configuration

After creating roles and assignments:

  1. Log out and log back in (or wait up to 15 minutes for the role cache to refresh).
  2. Navigate to Account to see your resolved roles.
  3. As an administrator, navigate to Administration > Users to review the roles assigned to each user and their effective permissions.

If a user's roles do not match expectations:

  • Check that the user's groups in the OIDC token match the group identifiers in the role assignments (the match is exact and case-sensitive).
  • Verify that the groups_claim in symphony.config matches the claim name used by your identity provider.
  • Check the Symphony log for role resolution messages.

Bootstrap Mode

When neither admin_group nor admin_subject is configured, Symphony operates in bootstrap mode:

  • All authenticated users have administrator access.
  • The Administration menu is visible to everyone.
  • Any user can create, modify, and delete roles and assignments.

This is intentional—it allows initial RBAC configuration before an administrator has been designated. Unauthenticated access is never permitted, even in bootstrap mode.

To exit bootstrap mode, set admin_group or admin_subject in symphony.config and restart. Once set, only designated administrators can access the Administration interface. All other users receive a 403 Forbidden response on admin endpoints.

If your deployment intentionally operates without admin restrictions (e.g., a single-user or development environment), set "bootstrap": true in the rbac configuration to suppress the bootstrap warning in the UI.

RBAC and API Keys

When RBAC is enabled, API key creation is constrained by the user's role permissions. Users cannot create API keys with capabilities that exceed their role's permission ceiling.

For example, a user with the viewer role (which allows cirata.services.>) cannot create an API key with cirata.extensions.datamigrator.> publish permission, because that subject is not covered by their role.

Users without any RBAC configuration (bootstrap mode) can create API keys with any capabilities.

Complete Example: Keycloak with LDAP Groups

This example walks through a complete RBAC setup using Keycloak as the identity provider with groups sourced from Active Directory.

1. Configure LDAP Federation in Keycloak

  • Add an LDAP User Federation provider pointing to your Active Directory.
  • Add a group-ldap-mapper to synchronise AD groups into Keycloak.
  • Sync groups so that AD groups like DataEngineers, Analysts, and SymphonyAdmins appear in Keycloak's Groups section.

2. Add the Groups Claim Mapper

  • In the Symphony client's dedicated scope, add a Group Membership mapper with token claim name groups and Full group path disabled.

3. Configure symphony.config

{
"rbac": {
"groups_claim": "groups",
"default_role": "viewer",
"admin_group": "SymphonyAdmins",
"admin_subject": ""
}
}

Restart Symphony.

4. Create Roles in Symphony

  • data-engineer with publish/subscribe access to cirata.extensions.datamigrator.> and cirata.extensions.iceflow.>
  • analyst with subscribe access to cirata.extensions.> and publish access to cirata.services.>

5. Create Assignments

GroupRoles
SymphonyAdminssymphony-admin
DataEngineersdata-engineer, viewer
Analystsanalyst

6. Test

  • Log in as a user in the DataEngineers AD group.
  • Verify they can see and use the Data Migrator and Ice Flow extensions but cannot access the Administration interface.
  • Log in as a user in the SymphonyAdmins group.
  • Verify they have full administrative access.

Troubleshooting

  • All users have admin access—check that admin_group or admin_subject is set in symphony.config. If both are empty, Symphony is in bootstrap mode.
  • Groups claim is empty—verify the protocol mapper (or equivalent) is configured in your identity provider to include groups in the OIDC token. Use the provider's token preview or debugging tools to inspect the token content.
  • Group names don't match—the group identifier in the role assignment must exactly match the value in the OIDC token. Check whether your provider sends short names (SymphonyAdmins), full LDAP DNs (CN=SymphonyAdmins,OU=Groups,DC=example,DC=com), or object IDs. Disable Full group path in Keycloak's group mapper to use short names.
  • Roles not updating after group changes—Symphony caches resolved roles for up to 15 minutes. The user must log out and back in, or wait for the cache to expire.
  • User has no roles—if the user's groups do not match any role assignment, the default_role (typically viewer) is assigned. If the user has no groups at all, verify the groups_claim setting matches the claim name in the OIDC token.
  • Cannot create API key—when RBAC is enabled, API key capabilities are constrained to the user's role permissions. Request a role with broader permissions from your administrator if needed.

See Also