Skip to main content

SAML

SAML (Security Assertion Markup Language) is an open standard for exchanging authentication and authorization data between different systems, typically an identity provider and a service provider. It allows users to log in once with a central identity system, and then securely access multiple applications without needing to authenticate again. Our system provides SAML integration to ensure a seamless and secure experience for users of our platform, allowing them to move effortlessly across services without repeated logins.

NOTE: In order to be able to use the SAML feature, this needs to be requested to the Service Desk. The Service Desk will arrange the per-customer SAML tenant configuration on the Energyworx side (SP metadata, ACS URL, IdP metadata URL, attribute mapping) before the integration is usable.

tip

SAML provides an automated alternative to the manual whitelisting and permission assignment process. For the manual process, see How to add a new user.

In order to log in with SAML the user can click on the Sign in with SAML login button and it will automatically redirect to their organization's identity provider (Google Workspace, Microsoft Entra, Okta, etc.) for authentication. If not logged in already it will ask for the corresponding credentials for the user's account. Once authenticated, the identity provider posts the assertion back to Energyworx, which validates it, establishes a session, and redirects the user to the Energyworx homepage (dashboard page).

Automatic whitelisting

No longer evaluated as of 26.09

The allowed_email_domains billing-account property described below no longer grants anyone access: it registered a verified user on every namespace of the billing account at their first sign-in, and access is now a grant per user per namespace.

Its replacement is an access rule (IAM → Users → Access rules) per namespace, matching the same email domain and naming the groups its users should get. See How to add a new user.

SAML authentication allows for automatic whitelisting of users to the namespaces belonging to a certain billing account. In order to configure this mechanism the administrator has the ability to add email domains to a Billing Account property. This can be found in Administrator-> Billing Accounts and then after clicking on the details button of the corresponding Billing Account the property named allowed_email_domains allows to configure the email domains.

Allowed emails configuration in the Billing Account

Permissions Group mapping

Replaced by access rules as of 26.09

The iam_group_mapping namespace property described below is not evaluated at sign-in any more. Access is held in a grant per user per namespace (see How to Whitelist and Assign Permissions).

An access rule matching an identity-provider claim does the same job: name the claim your IdP sends (for example groups, or the full claim URI beside it — either works), the value it carries, and the platform groups to grant. Everyone whose assertion carries that claim value is granted those groups on their next sign-in, and loses them when the claim stops being asserted. A rule matching an email domain works the same way for "everyone at this company".

Two things are worth knowing before you rely on a claim rule:

  • The claim has to reach us in the sign-in. A SAML or OIDC sign-in carries one; an API token minted from client credentials does not, and minting one takes the claim-granted access away until the user next signs in through the identity provider. Grant access that must not come and go this way to the user directly instead.
  • If Microsoft Entra reports the user is in too many groups to fit in the token, it leaves the group claim out, and a rule reading it grants nothing. Configure the app registration to emit only the groups assigned to the application.

The property itself is left in place so nothing that reads it breaks; it simply has no effect, and can be removed once the rules replacing it are in.

Example access rules

An access rule needs three things: the claim name as your identity provider sends it, the value to match, and the platform groups to grant on a namespace. Values are matched without regard to case, and a claim carrying several values matches if any one of them does.

Microsoft Entra ID (Azure AD) — app roles

The tidiest option, and the one to prefer.

In Entra: Microsoft Entra admin center → Enterprise applications → your EWX app → Single sign-on → Attributes & Claims. On the app registration, define an app role, for example:

App role fieldValue
Display nameEWX Operators
ValueEWX.Operators
Allowed member typesUsers/Groups

Assign users or a directory group to that role under Users and groups. Entra then sends this in the assertion:

<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/role">
<AttributeValue>EWX.Operators</AttributeValue>
</Attribute>

The access rule:

FieldValue
Match typeIdentity provider claim
Claim namehttp://schemas.microsoft.com/ws/2008/06/identity/claims/role
Claim valueEWX.Operators
Groupsthe platform groups those users should have

App roles are worth the setup over group membership: the value is a name you chose, it does not change when somebody renames a directory group, and only the roles you defined are ever sent — so the token never runs out of room (see below).

Microsoft Entra ID (Azure AD) — group membership

If you would rather drive it from directory groups, configure the group claim under Attributes & Claims → Add a group claim, and choose "Groups assigned to the application".

What Entra sends by default is the group's object ID, not its name:

<Attribute Name="http://schemas.microsoft.com/ws/2008/06/identity/claims/groups">
<AttributeValue>8ab5f1cd-3c92-4f1e-9d0b-5a7c2e6f4b10</AttributeValue>
<AttributeValue>c74e0b21-9f38-4a6d-b1c5-3e8a7d2f9014</AttributeValue>
</Attribute>

The access rule, matching the first of those groups:

FieldValue
Match typeIdentity provider claim
Claim namehttp://schemas.microsoft.com/ws/2008/06/identity/claims/groups
Claim value8ab5f1cd-3c92-4f1e-9d0b-5a7c2e6f4b10
Groupsthe platform groups those users should have

The user is in two groups and the rule names one; a claim carrying several values matches if any one of them does, so this grants.

Two things to know before choosing this over app roles:

  • The value is a GUID, not a name. Entra can be configured to send names instead — under the group claim's Source attribute, sAMAccountName for groups synchronised from on-premises Active Directory, or cloud-only group display names where that option is available to you. If you have not changed it, write the rule against the GUID. Copy it from Entra admin center → Groups → your group → Object Id, or read it out of an assertion as below.
  • Keep the claim scoped to "Groups assigned to the application" rather than all groups. When a user belongs to more groups than fit in the token, Entra drops the claim entirely and sends a _claim_names pointer instead. A rule reading it then matches nothing, and those users quietly lose the access it gave them. The gateway logs a warning naming the omitted claim when this happens.

AD FS

AD FS sends the same claim types as Entra. A role claim, issued from an AD group membership by a claim rule on the relying party trust, matches the same way:

FieldValue
Claim namehttp://schemas.microsoft.com/ws/2008/06/identity/claims/role
Claim valuethe role name your claim rule issues, e.g. EWX-Operators
Groupsthe platform groups those users should have

Google Workspace

In Workspace: Admin console → Apps → Web and mobile apps → your EWX app → SAML attribute mapping → Group membership (optional). Pick the Google groups whose membership should be sent, and give the App attribute a name — Groups is the usual choice. Save.

Workspace then sends the group's display name, not its email address:

<saml2:Attribute Name="Groups">
<saml2:AttributeValue>Platform Operators</saml2:AttributeValue>
</saml2:Attribute>

The access rule:

FieldValue
Match typeIdentity provider claim
Claim nameGroups — whatever you typed in App attribute
Claim valuePlatform Operators
Groupsthe platform groups those users should have

Only the groups you selected in the mapping are ever sent, so a user in a group you did not list matches nothing. Add the group to the mapping before writing a rule for it.

The claim name is matched without regard to case, so a rule written for groups still matches an attribute named Groups. The value is matched the same way. Spaces are part of the value — Platform Operators is not PlatformOperators.

Seeing what your identity provider actually sends

Either name works: the claim URI (http://schemas.microsoft.com/ws/2008/06/identity/claims/groups) or the short friendly name beside it (groups), whichever your identity provider shows you. If a rule grants nothing, the value is usually the reason — an object ID where a name was expected, or the other way round. Rather than guess, read one assertion.

The claim names are in the platform log. Every SAML sign-in logs a SAML login completed line listing the attributes the assertion carried:

SAML login completed tenant=energyworx user_email=someone@yourcompany.com
asserted_claims=["http://schemas.microsoft.com/ws/2008/06/identity/claims/groups","email"]

If the attribute you configured is not in that list, the identity provider is not sending it and no rule will ever match it — fix that before looking any further.

The claim values are deliberately not logged: they are the user's group and role memberships, and a sign-in log is the wrong place to keep those. Read them from the assertion itself, which your own browser posts to the platform:

  1. Open your browser's developer tools, Network tab, and switch on Preserve log — the sign-in ends in a redirect that would otherwise clear it.

  2. Sign in through SAML as normal.

  3. Find the POST to .../identity/saml/<tenant>/acs, open its Payload / form data, and copy the value of the SAMLResponse field. It is base64.

  4. Decode it. Any base64 decoder will do; on a terminal:

    pbpaste | base64 --decode | xmllint --format -
  5. Look for the <AttributeStatement> block. Every <Attribute Name="..."> is a claim name, and each <AttributeValue> inside it is a value a rule can match.

A browser extension such as SAML-tracer does steps 1–4 in one window if you prefer.

The assertion is signed for this service provider and contains the user's own identity — treat a copy of it as you would a password, and do not paste it anywhere public.

The old mechanism, for reference

The rest of this section describes iam_group_mapping, which is no longer evaluated. It is kept so that an administrator who still has the property set can see what it used to do; use an access rule as above instead.

Another feature that is provided with SAML authentication is the ability to map Energyworx user groups (and their corresponding permissions) in the platform to user groups on an external system. This way any user, which has an account in the external system, and logs in for the first time in the Energyworx platform, will automatically acquire all the permissions from the Energyworx groups that the user belongs to. These groups mappings must be configured in two places:

  • The SAML authentication provider configuration (for instance a Google Workspace). The administrator must configure the sign_in_attributes field and this must specify the names of the groups to be mapped in the platform. This is a key-value pair in JSON format. For example:
    • "MappingGroupSchemaKey": ["Group1", "Group2"]
  • The Namespaces that the administrator wants to configure as the Namespaces that the users can have access to with the specific permissions. The administrator can configure the namespace property iam_group_mapping. This namespace property must contain the group mappings by specifying the key provided in the SAML configuration and using a map from name of external to identifier of internal group as follows: { "MappingGroupSchemaKey": { "Group1": 4587849705848832, "Group2": 4093456809854698} }

Note that this is not a Billing Account configuration but a Namespace configuration, otherwise it would be applied to all namespaces in that Billing Account, this way we give flexibility to the administrator to decide which namespaces are applicable to this mechanism.

User data mapping

User data from external applications can also be mapped into Energyworx user data attributes, for instance properties like LastSeenCountry or LastSeenRegion can be mapped from external user attributes. The user data mapping must be configured in two places:

  • The SAML authentication provider configuration (for instance a Google Workspace). The administrator can add any key-value property to the sign_in_attributes which holds user relevant information.
  • The Namespaces where the users can have access to. The administrator can configure the namespace property iam_user_property_mapping. This namespace property must contain the user data field mappings by specifying a key-value property in JSON format as follows: {"city":"last_seen_city", "region":"last_seen_region"}

The following list of user data attributes can be mapped in the platform:

  • last_seen_remote_address
  • last_seen_country
  • last_seen_region
  • last_seen_city