Single Sign On (SSO)
IP Fabric includes support for single sign-on. We have opted for Dex (A Federated OpenID Connect Provider) as a key building block to allow a broader set of Identity providers (IdP).
sequenceDiagram
IPF->>IPF: User selects SSO on the IPF login screen.
IPF->>Dex: Redirect after starting SSO auth.
Dex->>IdP: Dex redirects to selected and cofigured IdP.
IdP->>IdP: User authenticates, provides MFA etc.
IdP->>Dex: User is redirected back to Dex with code.
Dex->>IdP: Dex fetches token from IdP.
Dex->>IPF: Dex redirects the user back to IPF with code.
IPF->>Dex: IPF fetches token from Dex.
Complex Configuration
Implementation of SSO configuration can be complex, and because of that, it is recommended to be configured for you by our Solution Architects. If you are unsure who your Solution Architect is, contact our Support Team.
Requirements
Certificate
Prior to configuring SSO the IP Fabric server must not be using a self-signed certificate. To create a new signed TLS certificate please see instructions located at IP Fabric Web Certificate.
Internal CA
By default, IP Fabric only trusts certificates issued by CAs listed in the node.js. If your company use certificates signed by an internal CA please reach out to your Solution Architect or open a Support ticket for further configuration in order to properly enable SSO.
CLI Access
In order to make changes to certain files you must have access to the osadmin
account to log into the CLI and gain root access. For more information please see CLI Overview.
justin@ubuntu:~$ ssh osadmin@demo.ipfabric.io
osadmin@demo:~$ sudo -s
[sudo] password for osadmin:
root@demo:/home/osadmin#
API Configuration api.json
The IP Fabric API configuration is stored at /opt/nimpee/conf.d/api.json
. This
file needs to be created during first configuration as it does not exist in the
default image. It will also be persistent during upgrades and will not be
changed. Below is a full example of the api.json
config file.
{
"app": {
"url": "https://<FQDN>/api"
},
"web": {
"url": "https://<FQDN>"
},
"dex": {
"url": "https://<FQDN>/dex",
"providers": [
{
"name": "sso",
"clientId": "ipfabric",
"clientSecret": "<RANDOM_SECRET>",
"roleAssignments": [
{
"groupName": "any",
"roleId": null
},
{
"groupName": "admin",
"roleId": "admin"
},
{
"groupName": "read",
"roleId": "2356575453"
}
]
}
]
}
}
Changing Default Token Expiration
In this file you can also change the default token expiration of 30 minutes for accessToken and 24 hours for refreshToken. If you would like to learn more about this please visit API Authentication.
URL Configuration
Inside the app
, web
, dex
configuration the url
field needs to be updated
with the FQDN of the IP Fabric system.
The dex: url
must match ipf-dex.yaml
issuer URL.
Example:
{
"app": {
"url": "https://demo.ipfabric.io/api"
},
"web": {
"url": "https://demo.ipfabric.io"
},
"dex": {
"url": "https://demo.ipfabric.io/dex"
}
}
Providers Configuration
The providers
sections have to contain at least one SSO provider (which
corresponds to staticClient
in the Dex configuration).
{
"dex": {
"providers": [
{
"name": "sso",
"clientId": "ipfabric",
"clientSecret": "jqv-W_khLSwJdJMHCjhJefyu-QdeXq9kcz8sAfMrO1Q",
"roleAssignments": [
{
"groupName": "any",
"roleId": null
},
{
"groupName": "admin",
"roleId": "admin"
},
{
"groupName": "read",
"roleId": "2356575453"
}
]
}
]
}
}
name
- User defined name of the Identity Provider (IdP) displayed in GUI- Can only contain
a-z0-9_
. Do not use uppercase. - Used in ipf-dex.yaml for
redirectURIs
understaticClients
- This name will be displayed on the login page of the GUI. This name will be
capitalized (
sso
->Sso
) therefore it is recommended to use names such asazure
orokta
.
- Can only contain
clientId
- User defined value (suggested to leave asipfabric
)- Used in ipf-dex.yaml for
id
understaticClients
- Used in ipf-dex.yaml for
clientSecret
- User defined value for a shared secret between IP Fabric and Dex only.- Can be randomly created for instance using
Python:
python -c "import secrets; print(secrets.token_urlsafe())"
- Used in ipf-dex.yaml for
secret
understaticClients
- Can be randomly created for instance using
Python:
roleAssignments
- An array of objects.- Objects are in the format of
{groupName: string, roleId: string | null }
groupName
- The name of the group that is configured on the SSO side.any
will provide default access to any user.- Multiple mappings with the same
groupName
will get merged (so the user will receive all corresponding roles on IP Fabric side).
roleId
- The ID of the IP Fabric role.- A value of
null
will provide no access. - Please do not confuse
roleId
withroleName
as these are different values.roleId
must be retrieved using browser Developer Tools or using the API (example below). Feature has been opened to allow forroleName
.
- A value of
- Objects are in the format of
Example to find roleId
:
SSO Configuration ipf-dex.yaml
While Dex supports various connectors, we strongly recommend using OpenID Connect (OIDC) for SSO integration (Azure uses a special microsoft
connector and an example is provided below along with SAML). Please, check official Dex documentation for their
overview.
Dex configuration is located at /etc/ipf-dex.yaml
on the IP Fabric appliance. It has several configuration sections and a full example of the file is located below. Please note that OIDC, SAML, and Azure have different syntax's for the connectors
configuration portion, which are covered separately.
# /etc/ipf-dex.yaml
# example config in both devOps/etc/ipf-dex.yaml and devOps-install/install/ipf-dex.yaml
issuer: https://<FQDN>/dex
staticClients:
- id: ipfabric
redirectURIs:
- "https://<FQDN>/api/<API_VERSION>/auth/external/<API-DEX-PROVIDERS-NAME>"
name: IP Fabric
secret: <RANDOM_SECRET>
storage:
type: memory
logger:
level: debug
web:
http: 127.0.0.1:5556
telemetry:
http: 127.0.0.1:5558
grpc:
addr: 127.0.0.1:5557
oauth2:
skipApprovalScreen: true
connectors:
- type: oidc
id: sso_oidc
name: SSO OIDC
config:
issuer: <SSO_ISSUER>
redirectURI: https://<FQDN>/dex/callback
clientID: <SSO_CLIENT_ID>
clientSecret: <SSO_CLIENT_SECRET>
getUserInfo: true
insecureEnableGroups: true
scopes:
- openid
- profile
- email
- groups
Leave Default Values
The following lines should be left to the default values:
storage:
type:
memory
logger:
level: debug
web:
http: 127.0.0.1:5556
telemetry:
http: 127.0.0.1:5558
grpc:
addr: 127.0.0.1:5557
Issuer
Dex configuration has at the very top attribute called issuer
. This needs to be configured to be equal to the url
in api.json
under dex
.
For example:
issuer: https://demo.ipfabric.io/dex
Skip Approval Screen
The following lines of configuration controls if you would like a "Grant Access" screen to be presented to your users on every login. By setting it to true this will not display the below message.
oauth2:
skipApprovalScreen: true
Static Clients
Section staticClients
contains configuration for the IP Fabric portal, which
acts as a client to dex
.
staticClients:
- id: ipfabric
redirectURIs:
- "https://demo.ipfabric.io/api/v5.0/auth/external/sso"
name: IP Fabric
secret: jqv-W_khLSwJdJMHCjhJefyu-QdeXq9kcz8sAfMrO1Q
id
- Unique ID of the client within Dex configuration.- Found in api.json for
clientId
underproviders
- Found in api.json for
redirectURIs
- Full path to the callback endpoint of the IP Fabric client.- It is in the format
of
https://<FQDN>/api/<API_VERSION>/auth/external/<API-DEX-PROVIDERS-NAME>
API-DEX-PROVIDERS-NAME
is found in api.json forname
underproviders
.- Can only contain
a-z0-9_
. Do not use uppercase.
- Can only contain
- Please, be aware of the
API_VERSION
property.- Updated with every major IPF release (i.e. after IP Fabric is upgraded
to
v5.5
leaving the URL atv5.0
will not cause any issues). - Unlike other API calls this has to be set with
v{major}.{minor}
and cannot usev{major}
(/api/v5/auth
will not work; must be/api/v5.0/auth
) - This will require manual changes when going from
v5.0
->v6.0
.
- Updated with every major IPF release (i.e. after IP Fabric is upgraded
to
- It is in the format
of
name
- Arbitrary name of the client.- This will be displayed in the "Grant Access" screen .
secret
- User defined secret- Found in api.json for
clientSecret
underproviders
- It is a shared secret between IP Fabric and Dex only.
- Found in api.json for
Config File Mapping
Here is a nice illustration on how the /opt/nimpee/conf.d/api.json
values map
to /etc/ipf-dex.yaml
:
OpenID Connect (OIDC)
Please review the Dex documentation on OIDC for all configuration options and potential caveats.
Well-known Configuration
Many of the variables required can be found in the OIDC well-known configuration endpoint for example take a look at Google: .well-known/openid-configuration.
connectors:
- type: oidc
id: sso_oidc
name: SSO OIDC
config:
issuer: <SSO_ISSUER>
redirectURI: https://<FQDN>/dex/callback
clientID: <SSO_CLIENT_ID>
clientSecret: <SSO_CLIENT_SECRET>
getUserInfo: true
insecureEnableGroups: true
scopes:
- openid
- profile
- email
- groups
claimMapping:
groups: roles
type
- Dex connector type.id
- User defined arbitrary ID (not used anywhere).name
- User defined arbitrary name (not used anywhere).redirectURI
-issuer
URL with/callback
appended at the end.- Can be found in api.json under
dex
, OR - Can be found in ipf-dex.yaml.
- Can be found in api.json under
getUserInfo
- When enabled, the OpenID Connector will query the UserInfo endpoint for additional claims.insecureEnableGroups
- Groups claims only refresh when the id token is refreshed meaning the regular refresh flow doesn't update the groups claim. As such by default the oidc connector doesn't allow groups claims. If you are okay with having potentially stale group claims you can use this option to enable groups claims through the oidc connector on a per-connector basis.clientID
- A client ID configured or generated on the Identity Provider.clientSecret
- A client secret configured or generated on the Identity. Provider.scopes
- A list of scopes to return from the Identity Provider.- The ones listed above are the most common however these can differ provider to provider.
- Scopes are normally found in the
.well-known/openid-configuration
which is discussed in the OIDC section.
claimMapping
- Some providers return non-standard claims (i.e. roles) use claimMapping to map those claims to standard claims.
Azure
Azure
Please review the Dex documentation on Azure for all configuration options and potential caveats as Azure requires special configuration for proper enablement.
connectors:
- type: microsoft
id: sso_azure
name: SSO Azure
config:
clientID: <SSO_CLIENT_ID>
clientSecret: <SSO_CLIENT_SECRET>
redirectURI: https://<FQDN>/dex/callback
tenant: <TENANT_ID>
scopes:
- openid
- profile
- email
- groups
claimMapping:
groups: roles
type
- Dex connector type.id
- User defined arbitrary ID (not used anywhere).name
- User defined arbitrary name (not used anywhere).redirectURI
-issuer
URL with/callback
appended at the end.- Can be found in api.json under
dex
, OR - Can be found in ipf-dex.yaml.
- Can be found in api.json under
tenant
- UUID or Name of specific tenant accounts belong to.- Required in order to obtain
groups
claim from Azure
- Required in order to obtain
clientID
- A client ID configured or generated on the Identity Provider.clientSecret
- A client secret configured or generated on the Identity. Provider.scopes
- A list of scopes to return from the Identity Provider.- The ones listed above are the most common however these can differ provider to provider.
- Scopes are normally found in the
.well-known/openid-configuration
which is discussed in the OIDC section.
claimMapping
- Some providers return non-standard claims (i.e. roles) use claimMapping to map those claims to standard claims.
SAML Connector
Please review the Dex documentation on SAML for all configuration options and potential caveats.
connectors:
- type: saml
id: sso_saml
name: SSO SAML
config:
ssoURL: <SSO_URL>
ssoIssuer: <SSO_ISSUER>
redirectURI: https://<FQDN>/dex/callback
caData: "LS0t ... 0tLS0tCg=="
# ca: /path/to/file
usernameAttr: name
emailAttr: email
groupsAttr: groups
nameIDPolicyFormat: emailAddress
type
- Dex connector type.id
- User defined arbitrary ID (not used anywhere).name
- User defined arbitrary name (not used anywhere).redirectURI
-issuer
URL with/callback
appended at the end.- Can be found in api.json under
dex
, OR - Can be found in ipf-dex.yaml.
- Can be found in api.json under
ssoURL
- SSO URL used for POST value.ssoIssuer
- Optional: Issuer value expected in the SAML response.- Pick and use one option to validate the signature of the SAML response:
caData
- Base64 encoded certification chainca
- File location of containing certification chain
usernameAttr
- Maps SAMLname
value to IP Fabric'susername
emailAttr
- Maps SAMLemail
value to IP Fabric'semail
groupsAttr
- Maps SAMLgroups
value to IP Fabric'sgroupName
nameIDPolicyFormat
- The connector uses the value of the NameID element as the user’s unique identifier which dex assumes is both unique and never changes. Use thenameIDPolicyFormat
to ensure this is set to a value which satisfies these requirements.
Restarting Services
After making changes to the /opt/nimpee/conf.d/api.json
it is required to restart the API service:
systemctl restart nimpee-api.service
Consequently, after making changes to /etc/ipf-dex.yaml
the Dex service needs to be restarted:
systemctl restart ipf-dex.service