SSO Integration
EmberNet has no separate dashboard password. Sign-in is delegated to your identity provider, and your identity there determines both your role and which tenants you can see. This page covers configuring Microsoft Entra ID (Azure AD) as that provider.
How authentication works
Two paths run against the same directory tenant.
Browser sign-in uses OIDC. An authenticating proxy sits in front of the dashboard, redirects unauthenticated users to Microsoft, and injects the resulting identity into the request:
User request
│
▼
Ingress ──► authenticating proxy ──► Microsoft Entra ID (OIDC)
│
▼ (identity headers injected)
Dashboard backend
│
▼ (role + tenant scope resolved from group claims)
The view for that user
First-party API clients (EmberNet Endpoint on Windows and Linux) use bearer tokens instead. The daemon obtains a token audienced for the dashboard's own API, and the token is validated locally against the directory's published signing keys. There is no round-trip to Microsoft Graph on each request.
Both paths depend on the group claim. The same claim resolves your role and the tenants you are bound to, so a directory that does not emit group IDs will authenticate users successfully and then show them nothing.
Prerequisites
- A Microsoft Entra ID tenant with administrator access
- A cluster with an ingress controller
- DNS pointing at your ingress
- A TLS certificate
Step 1: Register the application
In the Azure portal, under Entra ID → App registrations, create a registration:
- Supported account types: single tenant
- Redirect URI:
https://<your-dashboard-host>/oauth2/callback
From the overview page, record the Application (client) ID and the Directory (tenant) ID.
Under Certificates & secrets, create a client secret and copy its value immediately. It is not shown again.
Under API permissions, add the Microsoft Graph delegated permissions
openid, email, and profile, then grant admin consent.
Enable group claims
This step is not optional if you use more than one tenant.
- Go to Token configuration → Add groups claim
- Select Security groups
- For both ID and Access tokens, choose Group ID
- Save
Emitting group IDs rather than names is what makes tenant resolution work on both the browser and the bearer-token path.
Expose the API (first-party clients only)
If you are enrolling EmberNet Endpoint clients, create a second app registration
for the API itself. Under Expose an API, set an Application ID URI and add a
scope named access_as_user, then authorize your client applications to request
it.
Step 2: Create security groups
Create one directory security group per role and record each group's Object ID. Names are yours to choose; the object IDs are what the platform matches on.
| Example group | Maps to |
|---|---|
EmberNet-Admins | Admin |
EmberNet-Engineers | Engineer |
EmberNet-Operators | Operator |
Add users to the appropriate group. A user in several groups receives the highest privilege among them.
Step 3: Supply the credentials
Generate a cookie secret:
openssl rand -base64 32
Create a secret in the platform namespace holding the client ID, the client secret, and the generated cookie secret. Then reference it from your deployment values along with your tenant ID, issuer URL, redirect URL, and the three group object IDs.
For first-party bearer-token support, the proxy also needs to be told to accept JWT bearer tokens and given the issuer and audience pairs to trust. Microsoft issues tokens under two issuer formats depending on how the scope was requested, so both must be allowed or endpoint daemons will authenticate inconsistently.
Do not enable group enforcement at the proxy layer. The dashboard's own permission layer already enforces the same boundary, and first-party bearer tokens do not carry a group claim under the service flow. Turning it on causes every endpoint daemon request to fail with an unhelpful 403.
Role resolution
Roles resolve in priority order, first match wins:
| Priority | Source |
|---|---|
| 1 | Email domain (platform staff domains resolve to Global Command) |
| 2 | An explicit role recorded in the platform's own user store |
| 3 | Directory group membership |
| 4 | Fallback: Operator |
The user store at priority 2 holds role assignments, not credentials. There is still no local password anywhere in the system.
Verifying
- Open the dashboard. You should be redirected to Microsoft sign-in.
- After authenticating, check the header for your username and the view you landed in.
- If the role is wrong, check the dashboard pod logs for the resolved role line; it names both the role and the user it resolved for.
- If sign-in succeeds but no tenants appear, the group claim is almost always the cause. Confirm the app registration emits Group ID and that the user is actually a member of a mapped group.
Next steps
- Multi-Tenancy: how tenants and roles fit together
- Dashboard Overview: the views each role lands in
- API Reference: how the same identity governs API access