SAML 2.0
SAML 2.0 lets your users sign in to MaestroHub with the account they already have at your company's identity provider — Okta, Microsoft Entra ID (Azure AD), Keycloak, OneLogin, PingFederate, Google Workspace, Active Directory Federation Services, or any other SAML 2.0 service.
Once it is set up, your users click a Sign in with … button on the MaestroHub login page, authenticate wherever they normally do, and land back in MaestroHub already signed in. You never store their password, and when someone leaves the company, disabling their account at the identity provider stops them signing in here too.
New to SAML? Read this first
Three terms appear constantly and everything else builds on them.
| Term | What it means |
|---|---|
| Identity provider (IdP) | The system that knows who your users are and checks their password — Okta, Entra ID, Keycloak, and so on. |
| Service provider (SP) | The application the user wants to get into. In this guide, that is MaestroHub. |
| Assertion | The signed document the IdP sends back saying "this really is alice@example.com, and she is in these groups". |
A login works like this:
- The user clicks Sign in with
{Provider Name}on the MaestroHub login page. - MaestroHub sends them to the identity provider.
- They sign in there — password, MFA, whatever your company requires.
- The identity provider sends a signed assertion back to MaestroHub.
- MaestroHub checks the signature, reads the user's details out of it, and signs them in.
The two sides have to be introduced to each other before any of that works. That is all the setup below is: telling MaestroHub where the identity provider lives, and telling the identity provider where MaestroHub lives.
This is the part that trips people up, because it is circular — each system wants information from the other. It resolves easily once you know the order:
MaestroHub needs from the IdP: where to send users to sign in, and the certificate to check signatures with. Both come from the IdP's metadata, so in practice you need one metadata URL.
The IdP needs from MaestroHub: the ACS URL (where to send the assertion) and the SP Entity ID (MaestroHub's name for itself). Both are decided by you when you create the provider, before you save it — so you can copy them into the IdP first.
Before you begin
- SSO requires a licence that includes it. If SSO is not part of your plan, the SAML endpoints return "SSO is not available with your current license."
- You need an administrator account in MaestroHub, and enough access at your identity provider to create a new application.
- The MaestroHub server must be reachable from the user's browser at a stable URL, and if you use a metadata URL, the server must be able to reach your identity provider over the network. That is the server, not your laptop — a metadata URL that opens fine in your browser can still be unreachable from the machine MaestroHub runs on.
- Clocks must be in sync. Assertions carry a validity window that is checked exactly, with no tolerance for drift. If the two servers disagree by even a few seconds, logins fail. Run NTP on both.
MaestroHub verifies signatures but cannot decrypt encrypted assertions. If you turn on assertion encryption at your identity provider, every login fails with "encrypted assertions not yet supported".
Leave encryption off. Signing is what makes SAML safe here, and signing is fully supported — encryption protects the assertion's contents from the user's own browser, which is a much narrower concern.
Setup guide
Step 1 — Start the provider in MaestroHub
- Go to Identity & Access → SSO Configuration.
- Click Add Provider and choose SAML 2.0.
- Fill in:
- Name — what users see on the login button, e.g.
Company SSO. - Slug — a short URL-safe identifier, e.g.
okta. Choose this carefully: the ACS URL is built from it, and changing it later means reconfiguring the identity provider.
- Name — what users see on the login button, e.g.
Step 2 — Copy the two values your IdP needs
Scroll to Service Provider (SP) Settings.
-
ACS URL — click into the field and MaestroHub fills in the correct value from your slug:
https://maestrohub.example.com/auth/saml/providers/okta/callbackThis is where the identity provider sends the assertion. Some IdPs call it the Reply URL, Single sign-on URL, or Consumer URL.
-
SP Entity ID — MaestroHub's identifier. Any stable URI works as long as it is identical on both sides. A conventional choice:
https://maestrohub.example.com/saml/metadataSome IdPs call this the Audience, Audience URI, or Identifier.
Leave the form open and copy both values.
Step 3 — Create the application at your identity provider
In your IdP's admin console, create a new SAML 2.0 application and paste in the two values from step 2. Then set up the attributes it will send.
At minimum MaestroHub needs the user's email address, sent either as the NameID or as an attribute. Send first name, last name and group membership too if you want names filled in and roles assigned.
A typical attribute statement:
| Attribute name | Example value |
|---|---|
email | alice@example.com |
firstName | Alice |
lastName | Smith |
groups | maestrohub-admins, engineering |
Set the NameID format to email address unless you have a reason not to, and make sure signing is enabled — see Signature requirements, because the defaults differ between products and this is the most common cause of a failed first login.
Finally, copy your IdP's metadata URL. Most products publish one; it usually
ends in /metadata or is offered as a download link on the application's page.
Step 4 — Point MaestroHub at the identity provider
Back in the MaestroHub form, under Identity Provider (IdP) Settings, choose how you want to describe your IdP. The three options are alternatives — pick one.
| Option | When to use it |
|---|---|
| Metadata URL | Recommended. Paste the URL you copied. MaestroHub reads it and fills in everything else. |
| Metadata XML | Your IdP publishes a descriptor but the MaestroHub server cannot reach it — download the file and paste its contents. |
| Enter manually | Your IdP publishes no descriptor, or you want to set each endpoint yourself. |
Click Fetch to preview what MaestroHub reads. You should see the SSO URL and at least one signing certificate. Getting this right now saves you debugging a failed login later.
Step 5 — Save and test
- Save the provider. MaestroHub reads the descriptor and fills in the IdP entity ID, SSO URL, logout URL and signing certificate. If it cannot, the save is refused and the message names what is missing.
- Confirm Resolved from metadata shows an SSO URL and at least one certificate.
- Make sure the provider is enabled.
- Open the MaestroHub login page in a private browsing window. You should see a
Sign in with
{Name}button. - Sign in as a test user.
If it fails, go to Troubleshooting — the error message on screen names the specific cause.
Worked example: Keycloak
Assume MaestroHub is at https://maestrohub.example.com, the Keycloak realm is
company at https://sso.example.com, and the slug is keycloak.
In MaestroHub, create a SAML provider with name Company SSO and slug
keycloak, which gives:
- ACS URL:
https://maestrohub.example.com/auth/saml/providers/keycloak/callback - SP Entity ID:
https://maestrohub.example.com/saml/metadata
In Keycloak, create a SAML client:
| Keycloak setting | Value |
|---|---|
| Client ID | https://maestrohub.example.com/saml/metadata (must equal the SP Entity ID) |
| Valid redirect URIs | https://maestrohub.example.com/auth/saml/providers/keycloak/callback |
| Master SAML Processing URL | https://maestrohub.example.com/auth/saml/providers/keycloak/callback |
| Name ID format | email |
| Sign documents | On (this is Keycloak's default) |
| Sign assertions | Off is fine — see the note below |
Add a group membership mapper so groups arrive: set the token claim name to
groups and turn Full group path off, so you get admins rather than
/admins.
Back in MaestroHub, choose Metadata URL and enter:
https://sso.example.com/realms/company/protocol/saml/descriptor
Click Fetch, confirm a certificate appears, and save.
Keycloak's defaults are Sign Documents on and Sign Assertions off, so it signs the response envelope and leaves the assertion itself unsigned.
MaestroHub's Require Signed Assertions switch is on by default, which asks for the opposite. Turn on Sign Assertions in Keycloak, or turn off Require Signed Assertions in MaestroHub. Either is secure — a verified signature is always required at one level or the other, and neither switch can disable that.
Other identity providers
The flow is identical everywhere; only the wording changes.
| Product | Calls the ACS URL | Calls the SP Entity ID | Watch out for |
|---|---|---|---|
| Okta | Single sign-on URL | Audience URI (SP Entity ID) | Add attribute statements explicitly — Okta sends none by default. |
| Microsoft Entra ID | Reply URL | Identifier (Entity ID) | Claims arrive as long schema URLs, e.g. http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress. See Attribute mapping. |
| Google Workspace | ACS URL | Entity ID | Add each attribute under Attribute mapping in the app's settings. |
| AD FS | Relying party SAML 2.0 SSO service URL | Relying party trust identifier | Add a rule sending LDAP attributes as claims; without one nothing is sent. |
| OneLogin / PingFederate | ACS (Consumer) URL | Audience (Entity ID) | Confirm the NameID format is email address. |
Signature requirements
Signatures are what make a SAML login trustworthy, so this is the part worth understanding.
A response with no verified signature is always rejected. MaestroHub requires
a valid signature — checked against your IdP's certificate — on either the
<Response> envelope or the <Assertion> inside it. This is not configurable.
No combination of settings will make MaestroHub accept an unsigned login.
On top of that floor, two switches let you demand a signature at a specific level:
| Switch | Default | What it means |
|---|---|---|
| Require Signed Assertions | On | The <Assertion> element itself must be signed. |
| Require Signed Response | Off | The <Response> envelope itself must be signed. |
Each switch means exactly what it names. A signed response does not satisfy Require Signed Assertions, and vice versa. This is why the Keycloak default needs one of the two adjustments described above.
Identity providers vary: Keycloak signs the response only, Okta and Entra ID sign the assertion by default, and many can be told to sign both. Signing both is the safest configuration, and works with the defaults here.
Configuration reference
Identity provider settings
| Field | Required | Description |
|---|---|---|
| IdP Metadata URL | One of the three | Where the IdP publishes its descriptor. Read when you save. |
| IdP Metadata XML | One of the three | The descriptor's contents, pasted. Read when you save. |
| IdP Entity ID | Manual mode | The identity provider's unique identifier. |
| IdP SSO URL | Manual mode | Where MaestroHub sends users to sign in. |
| IdP X.509 Certificate | Manual mode | The IdP's signing certificate, in PEM format, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines. |
| IdP Single Logout URL | No | The IdP's logout endpoint. See Single Logout. |
When you use metadata, MaestroHub fills in the entity ID, SSO URL, logout URL and certificate for you, and shows them read-only under Resolved from metadata so you can see exactly what your logins will use.
When your identity provider rotates its signing certificate, open the provider and save it again to pick up the new one. If the descriptor publishes two certificates — which identity providers do during a rotation — MaestroHub trusts both, so logins keep working throughout the changeover.
If you switch to Enter manually after using metadata, the resolved values carry over as a starting point and stop being refreshed. From then on your values are the configuration.
If MaestroHub cannot reach the descriptor, or the descriptor carries no signing certificate, the save fails rather than storing a provider that could never log anyone in. Without a certificate no assertion can be verified.
A descriptor with no signing certificate is usually a sign that the URL points at the service provider's descriptor rather than the identity provider's.
Service provider settings
| Field | Required | Description |
|---|---|---|
| SP Entity ID | Yes | MaestroHub's SAML identifier. Must exactly match the audience configured at the IdP. |
| ACS URL | Yes | Where the IdP posts the assertion. Filled in from the slug when you click into the empty field. Must exactly match what you configure at the IdP. |
Security settings
| Switch | Default | Description |
|---|---|---|
| Sign Requests | Off | Sign the authentication requests MaestroHub sends. See Signing outbound requests. |
| Require Signed Assertions | On | Require the <Assertion> element to be signed. |
| Require Signed Response | Off | Require the <Response> envelope to be signed. |
| Allow IdP-Initiated SSO | Off | Accept logins that start at the identity provider's portal. See IdP-initiated SSO. |
| Allow Unencrypted | Off | Has no effect. Assertions must be unencrypted either way — see the note in Before you begin. |
Name ID format
| Field | Default | Description |
|---|---|---|
| Name ID Format | urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress | The NameID format MaestroHub asks the IdP for. Leave it alone unless your IdP requires something else. |
Common alternatives are
urn:oasis:names:tc:SAML:2.0:nameid-format:persistent and
urn:oasis:names:tc:SAML:2.0:nameid-format:transient.
MaestroHub identifies a returning user by their NameID. A transient format gives a different value on every login, so each sign-in looks like a brand-new user. Use email address or persistent.
Attribute mapping
Identity providers name their attributes differently. These fields tell MaestroHub which attribute holds what.
| Field | Description |
|---|---|
| Email Attribute | The user's email address |
| First Name Attribute | Given name |
| Last Name Attribute | Family name |
| Display Name Attribute | Full display name |
| Groups Attribute | Group membership, used for role mapping |
You can usually leave these blank. If a field is empty, MaestroHub tries a list of conventional names, which covers most identity providers out of the box:
| Field | Names tried when left blank |
|---|---|
email, mail, emailAddress, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress, urn:oid:0.9.2342.19200300.100.1.3 | |
| First name | givenName, firstName, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname, urn:oid:2.5.4.42 |
| Last name | sn, surname, lastName, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname, urn:oid:2.5.4.4 |
| Display name | displayName, name, cn, http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name, urn:oid:2.16.840.1.113730.3.1.241 |
| Groups | groups, memberOf, role, http://schemas.microsoft.com/ws/2008/06/identity/claims/groups, http://schemas.xmlsoap.org/claims/Group |
Fill a field in only when your IdP uses a name that is not on the list. The name must match the assertion exactly, including case and any URL prefix. If your IdP labels an attribute with a friendly name as well as a formal one, either will work.
Use a browser SAML tracer extension, or your IdP's own assertion preview, to see exactly what is being sent. Guessing at attribute names is the second most common setup problem after signature settings.
What MaestroHub requires
- A NameID is required. It is how a returning user is recognised. A login with no NameID is rejected.
- An email address is required. MaestroHub looks at the email attribute first; if that is empty it uses the NameID when it looks like an email address, then the username attribute on the same basis. If none of those yields an email, the login fails.
- First name, last name and display name are optional — they populate the user's profile.
If someone already has a MaestroHub account with the same email address, their first SSO login links that existing account to the identity provider rather than creating a duplicate. They keep their existing roles and history.
Role mapping
Role mapping turns group membership at your identity provider into MaestroHub roles, so you manage access in one place.
| Field | Default | Description |
|---|---|---|
| Enable Role Mapping | Off | Turn role mapping on for this provider. |
| Role Claim / Attribute Name | — | The attribute holding group membership. Leave blank to use the same fallbacks as the Groups Attribute above. |
| Default Role | Organization.Member | Assigned when no mapping matches. |
| Strict Enrollment | Off | Refuse the login entirely when no mapping matches, instead of granting the default role. |
| Mappings | — | Each row maps one IdP group name to one MaestroHub role. |
An example set of mappings:
| IdP group | MaestroHub role |
|---|---|
maestrohub-admins | Organization.Admin |
data-engineering | Persona.DataEngineer |
plant-floor | Persona.PlantOperator |
Group names must match the assertion exactly — Admins and admins are
different groups. A user in several mapped groups receives every role those
groups map to.
Mapped roles are applied when the account is first created in MaestroHub. Changing someone's groups at the identity provider afterwards does not change their MaestroHub roles — adjust those under Identity & Access → Users.
Set your mappings up before your users sign in for the first time. If you turn role mapping on after people have already logged in, existing users keep the roles they were given at their first login.
Platform administrator is granted at platform scope, not per organization, so it is not available as a mapping target. The role picker shows it disabled and points to where it is granted. Grant it under Admin → Identity & Access → System Administrators.
Signing outbound requests
By default MaestroHub sends unsigned authentication requests, which nearly every identity provider accepts. Turn on Sign Requests when your IdP is configured to require signed requests — Keycloak calls this Client signature required.
To enable it you must supply an SP certificate and private key:
| Field | Description |
|---|---|
| SP Certificate | Your certificate in PEM format. The IdP uses it to verify your requests. |
| SP Private Key | The matching private key in PEM format. Never shared. |
A self-signed pair is fine — this key proves requests come from your MaestroHub instance; it is not a public web certificate. For example:
openssl req -x509 -newkey rsa:2048 -nodes -days 3650 \
-keyout sp-private-key.pem -out sp-certificate.pem \
-subj "/CN=maestrohub.example.com"
Paste the contents of each file into the matching field, including the
-----BEGIN …----- and -----END …----- lines.
MaestroHub checks the pair when you save, including that the key actually matches the certificate, so a mismatch is reported immediately rather than at the first login.
Then give your identity provider the certificate. The easiest route is to point it at MaestroHub's own SP metadata, which publishes the certificate automatically whenever Sign Requests is on:
https://maestrohub.example.com/auth/saml/providers/keycloak/metadata
Many identity providers can import that URL directly and configure themselves
from it. Otherwise upload sp-certificate.pem to the IdP by hand.
The moment Sign Requests is on, MaestroHub's metadata tells identity providers that its requests are signed. If your IdP enforces that promise before you have given it the certificate, logins fail with a signature error. Import the metadata or upload the certificate first, then enable the requirement at the IdP.
IdP-initiated SSO
Normally a login starts at MaestroHub. Allow IdP-Initiated SSO additionally lets users start from a tile in their identity provider's portal.
It is off by default, and worth leaving off unless you need it. A login that starts at MaestroHub can be tied back to the request that began it; an unsolicited one cannot, which makes it the flow most exposed to someone replaying a captured assertion. Turn it on only if your users genuinely launch MaestroHub from a portal.
Single Logout (SLO)
Logging out at your identity provider signs the user out of MaestroHub. When the IdP sends a logout request — because the user signed out of the portal or another application — MaestroHub verifies it and ends that user's session.
Their existing access token remains usable until it expires — 15 minutes by default — after which it cannot be renewed and the session ends. Sessions are not cut off instantly.
Logging out of MaestroHub signs the user out at the identity provider too.
Clicking Log out ends the MaestroHub session, then sends the user to the
IdP's Single Logout endpoint so the provider session ends as well. Clicking
Sign in with {Name} afterwards asks them to authenticate again.
This needs the IdP Single Logout URL to be set. It is filled in from your IdP's metadata when the descriptor publishes one — leave it as it is. If your descriptor omits it, enter the endpoint by hand.
When the field is empty, Log out ends the MaestroHub session and nothing else. The identity provider session stays active, so signing in again may go straight through without a password prompt.
On a shared computer, users should sign out of the identity provider too.
Managing users after setup
- New users are created automatically on first SSO login. There is no invitation step.
- Removing or disabling a user at the identity provider stops them signing in, but does not delete their MaestroHub account or its roles. Deactivate the account under Identity & Access → Users as well when someone leaves.
- Changing a user's roles is done in MaestroHub, not by editing their groups — see the note under Role mapping.
Troubleshooting
Start with the exact message on screen; each row below matches one.
| Message or symptom | Cause and fix |
|---|---|
| "SSO is not available with your current license." | SSO is not included in your plan. Contact your account representative. |
| "the SAML assertion is not signed but this provider requires it" | The IdP signs the response but not the assertion — Keycloak's default. Turn on Sign Assertions at the IdP, or turn off Require Signed Assertions here. |
| "the SAML Response is not signed but this provider requires it" | The mirror image: the IdP signs the assertion but not the envelope. Turn on document/response signing at the IdP, or turn off Require Signed Response here. |
| "the SAML response carries no signature…" | The IdP is not signing anything. Turn signing on at the IdP. This cannot be configured away — an unsigned response cannot be trusted. |
| Signature verification failed | Usually a rotated IdP certificate. If you configured the provider with metadata, open it and save it again to re-read the descriptor. If you configured it manually, paste the new certificate. |
| "encrypted assertions not yet supported" | Assertion encryption is enabled at the IdP. Turn it off; leave signing on. |
| Audience restriction not satisfied | The SP Entity ID here and the audience at the IdP do not match. They must be identical — check for a trailing slash or http versus https. |
| Recipient does not match | The ACS URL here and the one at the IdP do not match. Compare them character by character. |
| Assertion has expired / is not yet valid | The two servers' clocks disagree. Validity windows are checked exactly, with no tolerance. Run NTP on both. |
| Issuer mismatch | The IdP Entity ID does not match what the IdP actually sends. Re-read the metadata, or correct it by hand. |
| Save refused: metadata could not be fetched | The URL must be reachable from the MaestroHub server, not just your browser. Check firewall rules, DNS and any proxy. If it is genuinely unreachable, switch to Metadata XML and paste the descriptor. |
| Save refused: no signing certificate in the metadata | The URL probably points at a service provider descriptor. You want the identity provider's — look for one containing an IDPSSODescriptor element. |
| Certificate errors | The certificate must be PEM, including the -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- lines, with no stray characters. |
| Login succeeds but the name or email is wrong or empty | The attribute names do not match what the IdP sends. Inspect a real assertion with a SAML tracer and set the mapping fields explicitly. |
| "user email is required" | The assertion carries no email address and the NameID is not one either. Add an email attribute at the IdP, or set the NameID format to email address. |
| Users get no roles, or the wrong ones | Check the Groups Attribute matches the assertion and that group names in Mappings match exactly, including case. Remember roles are applied at a user's first login only. |
| "user does not have required role/group membership" | Strict Enrollment is on and the user is in no mapped group. Add a mapping for one of their groups, or turn Strict Enrollment off. |
| The login button does not appear | The provider is disabled, or SSO is not in your licence. Check the provider is enabled in the list. |